+36
-7
appview/db/reaction.go
+36
-7
appview/db/reaction.go
···
62
62
return count, nil
63
63
}
64
64
65
-
func GetReactionCountMap(e Execer, threadAt syntax.ATURI) (map[models.ReactionKind]int, error) {
66
-
countMap := map[models.ReactionKind]int{}
65
+
func GetReactionMap(e Execer, threadAt syntax.ATURI) (map[models.ReactionKind]models.ReactionDisplayData, error) {
66
+
const maxUsersPerKind = 20
67
+
68
+
query := `
69
+
select kind, reacted_by_did,
70
+
row_number() over (partition by kind order by created asc) as rn,
71
+
count(*) over (partition by kind) as total
72
+
from reactions
73
+
where thread_at = ?
74
+
order by kind, created asc`
75
+
76
+
rows, err := e.Query(query, threadAt)
77
+
if err != nil {
78
+
return nil, err
79
+
}
80
+
defer rows.Close()
81
+
82
+
reactionMap := map[models.ReactionKind]models.ReactionDisplayData{}
67
83
for _, kind := range models.OrderedReactionKinds {
68
-
count, err := GetReactionCount(e, threadAt, kind)
69
-
if err != nil {
70
-
return map[models.ReactionKind]int{}, nil
84
+
reactionMap[kind] = models.ReactionDisplayData{Count: 0, Users: []string{}}
85
+
}
86
+
87
+
for rows.Next() {
88
+
var kind models.ReactionKind
89
+
var did string
90
+
var rn, total int
91
+
if err := rows.Scan(&kind, &did, &rn, &total); err != nil {
92
+
return nil, err
93
+
}
94
+
95
+
data := reactionMap[kind]
96
+
data.Count = total
97
+
if rn <= maxUsersPerKind {
98
+
data.Users = append(data.Users, did)
71
99
}
72
-
countMap[kind] = count
100
+
reactionMap[kind] = data
73
101
}
74
-
return countMap, nil
102
+
103
+
return reactionMap, rows.Err()
75
104
}
76
105
77
106
func GetReactionStatus(e Execer, userDid string, threadAt syntax.ATURI, kind models.ReactionKind) bool {
+2
-2
appview/issues/issues.go
+2
-2
appview/issues/issues.go
···
83
83
return
84
84
}
85
85
86
-
reactionCountMap, err := db.GetReactionCountMap(rp.db, issue.AtUri())
86
+
reactionMap, err := db.GetReactionMap(rp.db, issue.AtUri())
87
87
if err != nil {
88
88
l.Error("failed to get issue reactions", "err", err)
89
89
}
···
115
115
Issue: issue,
116
116
CommentList: issue.CommentList(),
117
117
OrderedReactionKinds: models.OrderedReactionKinds,
118
-
Reactions: reactionCountMap,
118
+
Reactions: reactionMap,
119
119
UserReacted: userReactions,
120
120
LabelDefs: defs,
121
121
})
+5
appview/models/reaction.go
+5
appview/models/reaction.go
+2
-2
appview/pages/pages.go
+2
-2
appview/pages/pages.go
···
985
985
LabelDefs map[string]*models.LabelDefinition
986
986
987
987
OrderedReactionKinds []models.ReactionKind
988
-
Reactions map[models.ReactionKind]int
988
+
Reactions map[models.ReactionKind]models.ReactionDisplayData
989
989
UserReacted map[models.ReactionKind]bool
990
990
}
991
991
···
1138
1138
Pipelines map[string]models.Pipeline
1139
1139
1140
1140
OrderedReactionKinds []models.ReactionKind
1141
-
Reactions map[models.ReactionKind]int
1141
+
Reactions map[models.ReactionKind]models.ReactionDisplayData
1142
1142
UserReacted map[models.ReactionKind]bool
1143
1143
1144
1144
LabelDefs map[string]*models.LabelDefinition
+7
-1
appview/pages/templates/repo/fragments/reaction.html
+7
-1
appview/pages/templates/repo/fragments/reaction.html
···
2
2
<button
3
3
id="reactIndi-{{ .Kind }}"
4
4
class="flex justify-center items-center min-w-8 min-h-8 rounded border
5
-
leading-4 px-3 gap-1
5
+
leading-4 px-3 gap-1 relative group
6
6
{{ if eq .Count 0 }}
7
7
hidden
8
8
{{ end }}
···
30
30
hx-disabled-elt="this"
31
31
>
32
32
<span>{{ .Kind }}</span> <span>{{ .Count }}</span>
33
+
{{ if gt (length .Users) 0 }}
34
+
<div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 dark:bg-gray-700 text-white text-sm rounded shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-opacity pointer-events-none w-96 break-words z-10">
35
+
{{ range $i, $did := .Users }}{{ if $i }}, {{ end }}{{ resolve $did }}{{ end }}{{ if gt .Count (length .Users) }}, and {{ sub .Count (length .Users) }} more{{ end }}
36
+
<div class="absolute top-full left-1/2 -translate-x-1/2 -mt-1 border-4 border-transparent border-t-gray-900 dark:border-t-gray-700"></div>
37
+
</div>
38
+
{{ end }}
33
39
</button>
34
40
{{ end }}
+4
-2
appview/pages/templates/repo/issues/issue.html
+4
-2
appview/pages/templates/repo/issues/issue.html
···
110
110
<div class="flex items-center gap-2">
111
111
{{ template "repo/fragments/reactionsPopUp" .OrderedReactionKinds }}
112
112
{{ range $kind := .OrderedReactionKinds }}
113
+
{{ $reactionData := index $.Reactions $kind }}
113
114
{{
114
115
template "repo/fragments/reaction"
115
116
(dict
116
117
"Kind" $kind
117
-
"Count" (index $.Reactions $kind)
118
+
"Count" $reactionData.Count
118
119
"IsReacted" (index $.UserReacted $kind)
119
-
"ThreadAt" $.Issue.AtUri)
120
+
"ThreadAt" $.Issue.AtUri
121
+
"Users" $reactionData.Users)
120
122
}}
121
123
{{ end }}
122
124
</div>
+4
-2
appview/pages/templates/repo/pulls/fragments/pullHeader.html
+4
-2
appview/pages/templates/repo/pulls/fragments/pullHeader.html
···
66
66
<div class="flex items-center gap-2 mt-2">
67
67
{{ template "repo/fragments/reactionsPopUp" . }}
68
68
{{ range $kind := . }}
69
+
{{ $reactionData := index $.Reactions $kind }}
69
70
{{
70
71
template "repo/fragments/reaction"
71
72
(dict
72
73
"Kind" $kind
73
-
"Count" (index $.Reactions $kind)
74
+
"Count" $reactionData.Count
74
75
"IsReacted" (index $.UserReacted $kind)
75
-
"ThreadAt" $.Pull.PullAt)
76
+
"ThreadAt" $.Pull.PullAt
77
+
"Users" $reactionData.Users)
76
78
}}
77
79
{{ end }}
78
80
</div>
+2
-2
appview/pulls/pulls.go
+2
-2
appview/pulls/pulls.go
···
189
189
m[p.Sha] = p
190
190
}
191
191
192
-
reactionCountMap, err := db.GetReactionCountMap(s.db, pull.PullAt())
192
+
reactionMap, err := db.GetReactionMap(s.db, pull.PullAt())
193
193
if err != nil {
194
194
log.Println("failed to get pull reactions")
195
195
s.pages.Notice(w, "pulls", "Failed to load pull. Try again later.")
···
227
227
Pipelines: m,
228
228
229
229
OrderedReactionKinds: models.OrderedReactionKinds,
230
-
Reactions: reactionCountMap,
230
+
Reactions: reactionMap,
231
231
UserReacted: userReactions,
232
232
233
233
LabelDefs: defs,