From 56721612fcd1562f134b0862fc34d0ac9382eb9e Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 06 Oct 2025 06:36:45 +0000 Subject: [PATCH] appview/{db,pages,models}: show tooltips for user handles when hovering on reactions Signed-off-by: Cameron Smith --- appview/db/reaction.go | 45 ++++++++++++++++++++++++++++++++++++--------- appview/issues/issues.go | 4 ++-- appview/models/reaction.go | 5 +++++ appview/pages/pages.go | 5 +++-- appview/pulls/pulls.go | 4 ++-- appview/state/reaction.go | 14 ++++++++------ appview/pages/templates/repo/fragments/reaction.html | 7 ++++++- appview/pages/templates/repo/issues/issue.html | 6 ++++-- appview/pages/templates/repo/pulls/fragments/pullHeader.html | 6 ++++-- 9 file(s) changed, 70 insertion(s)(+), 26 deletion(s)(-) diff --git a/appview/db/reaction.go b/appview/db/reaction.go --- a/appview/db/reaction.go +++ b/appview/db/reaction.go @@ -62,16 +62,43 @@ return count, nil } -func GetReactionCountMap(e Execer, threadAt syntax.ATURI) (map[models.ReactionKind]int, error) { - countMap := map[models.ReactionKind]int{} - for _, kind := range models.OrderedReactionKinds { - count, err := GetReactionCount(e, threadAt, kind) - if err != nil { - return map[models.ReactionKind]int{}, nil - } - countMap[kind] = count +func GetReactionMap(e Execer, userLimit int, threadAt syntax.ATURI) (map[models.ReactionKind]models.ReactionDisplayData, error) { + query := ` + select kind, reacted_by_did, + row_number() over (partition by kind order by created asc) as rn, + count(*) over (partition by kind) as total + from reactions + where thread_at = ? + order by kind, created asc` + + rows, err := e.Query(query, threadAt) + if err != nil { + return nil, err } - return countMap, nil + defer rows.Close() + + reactionMap := map[models.ReactionKind]models.ReactionDisplayData{} + for _, kind := range models.OrderedReactionKinds { + reactionMap[kind] = models.ReactionDisplayData{Count: 0, Users: []string{}} + } + + for rows.Next() { + var kind models.ReactionKind + var did string + var rn, total int + if err := rows.Scan(&kind, &did, &rn, &total); err != nil { + return nil, err + } + + data := reactionMap[kind] + data.Count = total + if userLimit > 0 && rn <= userLimit { + data.Users = append(data.Users, did) + } + reactionMap[kind] = data + } + + return reactionMap, rows.Err() } func GetReactionStatus(e Execer, userDid string, threadAt syntax.ATURI, kind models.ReactionKind) bool { diff --git a/appview/issues/issues.go b/appview/issues/issues.go --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -83,7 +83,7 @@ return } - reactionCountMap, err := db.GetReactionCountMap(rp.db, issue.AtUri()) + reactionMap, err := db.GetReactionMap(rp.db, 20, issue.AtUri()) if err != nil { l.Error("failed to get issue reactions", "err", err) } @@ -115,7 +115,7 @@ Issue: issue, CommentList: issue.CommentList(), OrderedReactionKinds: models.OrderedReactionKinds, - Reactions: reactionCountMap, + Reactions: reactionMap, UserReacted: userReactions, LabelDefs: defs, }) diff --git a/appview/models/reaction.go b/appview/models/reaction.go --- a/appview/models/reaction.go +++ b/appview/models/reaction.go @@ -55,3 +55,8 @@ Rkey string Kind ReactionKind } + +type ReactionDisplayData struct { + Count int + Users []string +} diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -985,7 +985,7 @@ LabelDefs map[string]*models.LabelDefinition OrderedReactionKinds []models.ReactionKind - Reactions map[models.ReactionKind]int + Reactions map[models.ReactionKind]models.ReactionDisplayData UserReacted map[models.ReactionKind]bool } @@ -1010,6 +1010,7 @@ ThreadAt syntax.ATURI Kind models.ReactionKind Count int + Users []string IsReacted bool } @@ -1138,7 +1139,7 @@ Pipelines map[string]models.Pipeline OrderedReactionKinds []models.ReactionKind - Reactions map[models.ReactionKind]int + Reactions map[models.ReactionKind]models.ReactionDisplayData UserReacted map[models.ReactionKind]bool LabelDefs map[string]*models.LabelDefinition diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -189,7 +189,7 @@ m[p.Sha] = p } - reactionCountMap, err := db.GetReactionCountMap(s.db, pull.PullAt()) + reactionMap, err := db.GetReactionMap(s.db, 20, pull.PullAt()) if err != nil { log.Println("failed to get pull reactions") s.pages.Notice(w, "pulls", "Failed to load pull. Try again later.") @@ -227,7 +227,7 @@ Pipelines: m, OrderedReactionKinds: models.OrderedReactionKinds, - Reactions: reactionCountMap, + Reactions: reactionMap, UserReacted: userReactions, LabelDefs: defs, diff --git a/appview/state/reaction.go b/appview/state/reaction.go --- a/appview/state/reaction.go +++ b/appview/state/reaction.go @@ -70,9 +70,9 @@ return } - count, err := db.GetReactionCount(s.db, subjectUri, reactionKind) + reactionMap, err := db.GetReactionMap(s.db, 20, subjectUri) if err != nil { - log.Println("failed to get reaction count for ", subjectUri) + log.Println("failed to get reactions for ", subjectUri) } log.Println("created atproto record: ", resp.Uri) @@ -80,7 +80,8 @@ s.pages.ThreadReactionFragment(w, pages.ThreadReactionFragmentParams{ ThreadAt: subjectUri, Kind: reactionKind, - Count: count, + Count: reactionMap[reactionKind].Count, + Users: reactionMap[reactionKind].Users, IsReacted: true, }) @@ -109,16 +110,17 @@ // this is not an issue, the firehose event might have already done this } - count, err := db.GetReactionCount(s.db, subjectUri, reactionKind) + reactionMap, err := db.GetReactionMap(s.db, 20, subjectUri) if err != nil { - log.Println("failed to get reaction count for ", subjectUri) + log.Println("failed to get reactions for ", subjectUri) return } s.pages.ThreadReactionFragment(w, pages.ThreadReactionFragmentParams{ ThreadAt: subjectUri, Kind: reactionKind, - Count: count, + Count: reactionMap[reactionKind].Count, + Users: reactionMap[reactionKind].Users, IsReacted: false, }) diff --git a/appview/pages/templates/repo/fragments/reaction.html b/appview/pages/templates/repo/fragments/reaction.html --- a/appview/pages/templates/repo/fragments/reaction.html +++ b/appview/pages/templates/repo/fragments/reaction.html @@ -2,7 +2,7 @@