44 "database/sql"
55 "fmt"
66 "net/http"
7+ "sort"
78 "strconv"
89 "strings"
910
@@ -39,13 +40,111 @@ type ProfileData struct {
3940 TopShows []db.Show
4041 ShowCount int
4142 MemberSince string
43+ TasteSummary string
4244 ActivePartners []ActivePartner
4345 PendingPartners []PendingPartner
4446 IncomingRequests []IncomingRequest
4547 PartnerError string
4648 PartnerSuccess string
4749}
4850
51+ func buildTasteSummary (ratings []db.GetUserRatingsWithShowsRow ) string {
52+ if len (ratings ) == 0 {
53+ return ""
54+ }
55+
56+ likedGenres := map [string ]int {}
57+ dislikedGenres := map [string ]int {}
58+ var totalLiked , totalDisliked int
59+
60+ for _ , r := range ratings {
61+ genre := r .Genre .String
62+ if genre == "" {
63+ continue
64+ }
65+ switch r .Rating {
66+ case "favourite" , "liked" :
67+ likedGenres [genre ]++
68+ totalLiked ++
69+ case "disliked" :
70+ dislikedGenres [genre ]++
71+ totalDisliked ++
72+ }
73+ }
74+
75+ if totalLiked == 0 {
76+ return ""
77+ }
78+
79+ type genreCount struct {
80+ name string
81+ count int
82+ }
83+ ranked := make ([]genreCount , 0 , len (likedGenres ))
84+ for g , c := range likedGenres {
85+ ranked = append (ranked , genreCount {g , c })
86+ }
87+ sort .Slice (ranked , func (i , j int ) bool {
88+ if ranked [i ].count != ranked [j ].count {
89+ return ranked [i ].count > ranked [j ].count
90+ }
91+ return ranked [i ].name < ranked [j ].name
92+ })
93+
94+ // Top genres the user enjoys
95+ topN := ranked
96+ if len (topN ) > 3 {
97+ topN = topN [:3 ]
98+ }
99+ names := make ([]string , len (topN ))
100+ for i , g := range topN {
101+ names [i ] = strings .ToLower (g .name )
102+ }
103+
104+ var parts []string
105+ switch len (names ) {
106+ case 1 :
107+ parts = append (parts , fmt .Sprintf ("You're drawn to %s" , names [0 ]))
108+ case 2 :
109+ parts = append (parts , fmt .Sprintf ("You're drawn to %s and %s" , names [0 ], names [1 ]))
110+ default :
111+ parts = append (parts , fmt .Sprintf ("You're drawn to %s, %s, and %s" , names [0 ], names [1 ], names [2 ]))
112+ }
113+
114+ if len (ranked ) > 4 {
115+ parts [0 ] += ", with broad taste across many genres"
116+ }
117+
118+ // Genres the user tends to avoid
119+ if totalDisliked > 0 {
120+ avoided := make ([]genreCount , 0 , len (dislikedGenres ))
121+ for g , c := range dislikedGenres {
122+ if likedGenres [g ] == 0 || c > likedGenres [g ] {
123+ avoided = append (avoided , genreCount {g , c })
124+ }
125+ }
126+ sort .Slice (avoided , func (i , j int ) bool {
127+ return avoided [i ].count > avoided [j ].count
128+ })
129+ if len (avoided ) > 2 {
130+ avoided = avoided [:2 ]
131+ }
132+ if len (avoided ) > 0 {
133+ avoidNames := make ([]string , len (avoided ))
134+ for i , g := range avoided {
135+ avoidNames [i ] = strings .ToLower (g .name )
136+ }
137+ if len (avoidNames ) == 1 {
138+ parts = append (parts , fmt .Sprintf ("and tend to skip %s" , avoidNames [0 ]))
139+ } else {
140+ parts = append (parts , fmt .Sprintf ("and tend to skip %s and %s" , avoidNames [0 ], avoidNames [1 ]))
141+ }
142+ }
143+ }
144+
145+ return strings .Join (parts , ", " ) + "."
146+ }
147+
49148func (h * Handler ) Profile (w http.ResponseWriter , r * http.Request ) {
50149 userID := middleware .GetUserID (r .Context ())
51150 userEmail := middleware .GetUserEmail (r .Context ())
@@ -64,17 +163,19 @@ func (h *Handler) Profile(w http.ResponseWriter, r *http.Request) {
64163 }
65164
66165 user , _ := h .queries .GetUserByID (r .Context (), userID )
166+ ratingsWithShows , _ := h .queries .GetUserRatingsWithShows (r .Context (), userID )
67167
68168 data := ProfileData {
69- PageData : h .basePageDataWithPartners (r , "profile" ),
70- Favourite : favourite ,
71- Liked : liked ,
72- Disliked : disliked ,
73- Total : counts .Total ,
74- LikedShows : likedShows ,
75- TopShows : topShows ,
76- ShowCount : len (shows ),
77- MemberSince : user .CreatedAt .Format ("January 2006" ),
169+ PageData : h .basePageDataWithPartners (r , "profile" ),
170+ Favourite : favourite ,
171+ Liked : liked ,
172+ Disliked : disliked ,
173+ Total : counts .Total ,
174+ LikedShows : likedShows ,
175+ TopShows : topShows ,
176+ ShowCount : len (shows ),
177+ MemberSince : user .CreatedAt .Format ("January 2006" ),
178+ TasteSummary : buildTasteSummary (ratingsWithShows ),
78179 }
79180
80181 // Active partnerships (as owner)
0 commit comments