Signed-off-by: Seongmin Lee git@boltless.me
+81
-22
Diff
round #3
+3
appview/issues/issues.go
+3
appview/issues/issues.go
···
99
99
}
100
100
101
101
entities := []syntax.ATURI{issue.AtUri()}
102
+
for _, c := range issue.Comments {
103
+
entities = append(entities, c.AtUri())
104
+
}
102
105
reactions, err := db.ListReactionDisplayDataMap(rp.db, entities, 20)
103
106
if err != nil {
104
107
l.Error("failed to get reactions", "err", err)
+17
appview/pages/funcmap.go
+17
appview/pages/funcmap.go
···
23
23
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
24
24
"github.com/alecthomas/chroma/v2/lexers"
25
25
"github.com/alecthomas/chroma/v2/styles"
26
+
"github.com/bluesky-social/indigo/atproto/syntax"
26
27
"github.com/dustin/go-humanize"
27
28
"github.com/go-enry/go-enry/v2"
28
29
"github.com/yuin/goldmark"
···
487
488
"isGenerated": func(path string) bool {
488
489
return enry.IsGenerated(path, nil)
489
490
},
491
+
// NOTE(boltless): I know... I hate doing this too
492
+
"asReactionMapMap": func(dict any) map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData {
493
+
if dict == nil {
494
+
return make(map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData)
495
+
}
496
+
m, _ := dict.(map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData)
497
+
return m
498
+
},
499
+
"asReactionStatusMapMap": func(dict any) map[syntax.ATURI]map[models.ReactionKind]bool {
500
+
if dict == nil {
501
+
log.Println("returning empty map")
502
+
return make(map[syntax.ATURI]map[models.ReactionKind]bool)
503
+
}
504
+
m, _ := dict.(map[syntax.ATURI]map[models.ReactionKind]bool)
505
+
return m
506
+
},
490
507
// constant values used to define a template
491
508
"const": func() map[string]any {
492
509
return map[string]any{
+2
-1
appview/pages/pages.go
+2
-1
appview/pages/pages.go
···
1152
1152
}
1153
1153
1154
1154
type ThreadReactionFragmentParams struct {
1155
-
ThreadAt syntax.ATURI
1156
1155
Kind models.ReactionKind
1157
1156
Count int
1158
1157
Users []string
···
1599
1598
StarCount int
1600
1599
Owner identity.Identity
1601
1600
CommentList []models.CommentListItem
1601
+
Reactions map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData
1602
+
UserReacted map[syntax.ATURI]map[models.ReactionKind]bool
1602
1603
}
1603
1604
1604
1605
func (p *Pages) SingleString(w io.Writer, params SingleStringParams) error {
+4
appview/pages/templates/fragments/comment/commentBody.html
+4
appview/pages/templates/fragments/comment/commentBody.html
···
2
2
<div class="comment-body">
3
3
{{ if not .Comment.Deleted }}
4
4
<div class="prose dark:prose-invert">{{ .Comment.Body.Text | markdown }}</div>
5
+
{{ template "repo/fragments/reactions"
6
+
(dict "Reactions" .Reactions
7
+
"UserReacted" .UserReacted
8
+
"ThreadAt" .Comment.AtUri) }}
5
9
{{ else }}
6
10
<div class="prose dark:prose-invert italic text-gray-500 dark:text-gray-400">[deleted by author]</div>
7
11
{{ end }}
+9
-3
appview/pages/templates/fragments/comment/commentList.html
+9
-3
appview/pages/templates/fragments/comment/commentList.html
···
11
11
{{ $item := index . 1 }}
12
12
13
13
<div class="rounded border border-gray-200 dark:border-gray-700 w-full overflow-hidden shadow-sm bg-gray-50 dark:bg-gray-800/50">
14
-
{{ template "topLevelComment"
14
+
{{
15
+
template "topLevelComment"
15
16
(dict
16
17
"LoggedInUser" $root.LoggedInUser
17
-
"Comment" $item.Self) }}
18
+
"Reactions" (index (asReactionMapMap $root.Reactions) $item.Self.AtUri)
19
+
"UserReacted" (index (asReactionStatusMapMap $root.UserReacted) $item.Self.AtUri)
20
+
"Comment" $item.Self)
21
+
}}
18
22
19
23
<div class="relative ml-10 border-l-2 border-gray-200 dark:border-gray-700">
20
24
{{ range $index, $reply := $item.Replies }}
···
23
27
template "replyComment"
24
28
(dict
25
29
"LoggedInUser" $root.LoggedInUser
30
+
"Reactions" (index (asReactionMapMap $root.Reactions) $reply.AtUri)
31
+
"UserReacted" (index (asReactionStatusMapMap $root.UserReacted) $reply.AtUri)
26
32
"Comment" $reply)
27
33
}}
28
34
</div>
···
58
64
{{ end }}
59
65
60
66
{{ define "replyComment" }}
61
-
<div class="py-4 pr-4 w-full mx-auto overflow-hidden flex gap-2 ">
67
+
<div class="py-4 pr-4 w-full mx-auto flex gap-2 ">
62
68
<div class="flex-shrink-0">
63
69
{{ template "user/fragments/picLink" (list .Comment.Did.String "size-8 mr-1") }}
64
70
</div>
+3
-4
appview/pages/templates/repo/fragments/reaction.html
+3
-4
appview/pages/templates/repo/fragments/reaction.html
···
1
1
{{ define "repo/fragments/reaction" }}
2
2
<button
3
-
id="reactIndi-{{ .Kind }}"
4
3
class="flex justify-center items-center min-w-8 min-h-8 rounded border
5
4
leading-4 px-3 gap-1 relative group
6
5
{{ if eq .Count 0 }}
···
26
25
title="{{ .Kind }}"
27
26
{{ end }}
28
27
{{ if .IsReacted }}
29
-
hx-delete="/react?subject={{ .ThreadAt }}&kind={{ .Kind }}"
28
+
hx-delete="/react?kind={{ .Kind }}"
30
29
{{ else }}
31
-
hx-post="/react?subject={{ .ThreadAt }}&kind={{ .Kind }}"
30
+
hx-post="/react?kind={{ .Kind }}"
32
31
{{ end }}
33
32
hx-swap="outerHTML"
34
-
hx-trigger="click from:(#reactBtn-{{ .Kind }}, #reactIndi-{{ .Kind }})"
33
+
hx-trigger="click from:(previous #reactBtn-{{ .Kind }}, closest button)"
35
34
hx-disabled-elt="this"
36
35
>
37
36
<span>{{ .Kind }}</span> <span>{{ .Count }}</span>
+6
-7
appview/pages/templates/repo/fragments/reactions.html
+6
-7
appview/pages/templates/repo/fragments/reactions.html
···
1
1
{{ define "repo/fragments/reactions" }}
2
-
<div class="flex flex-wrap items-center gap-2">
2
+
<div class="reactions flex flex-wrap items-center gap-2" hx-include="this">
3
3
{{- $reactions := .Reactions -}}
4
4
{{- $userReacted := .UserReacted -}}
5
5
{{- $threadAt := .ThreadAt -}}
6
6
7
+
<input name="subject-uri" type="hidden" value="{{ $threadAt }}">
8
+
7
9
{{ template "reactionsPopup" }}
10
+
8
11
{{ range $kind := const.OrderedReactionKinds }}
9
12
{{ $reactionData := index $reactions $kind }}
10
13
{{ template "repo/fragments/reaction"
···
12
15
"Kind" $kind
13
16
"Count" $reactionData.Count
14
17
"IsReacted" (index $userReacted $kind)
15
-
"ThreadAt" $threadAt
16
18
"Users" $reactionData.Users) }}
17
19
{{ end }}
18
20
</div>
19
21
{{ end }}
20
22
21
23
{{ define "reactionsPopup" }}
22
-
<details
23
-
id="reactionsPopUp"
24
-
class="relative inline-block"
25
-
>
24
+
<details class="relative inline-block">
26
25
<summary
27
26
class="flex justify-center items-center min-w-8 min-h-8 rounded border border-gray-200 dark:border-gray-700
28
27
hover:bg-gray-50
···
44
43
>
45
44
{{ $kind }}
46
45
</button>
47
-
{{ end }}
46
+
{{ end }}
48
47
</div>
49
48
</details>
50
49
{{ end }}
+3
-1
appview/pages/templates/repo/issues/issue.html
+3
-1
appview/pages/templates/repo/issues/issue.html
···
117
117
template "fragments/comment/commentList"
118
118
(dict
119
119
"LoggedInUser" $.LoggedInUser
120
-
"CommentList" $.CommentList)
120
+
"CommentList" $.CommentList
121
+
"Reactions" $.Reactions
122
+
"UserReacted" $.UserReacted)
121
123
}}
122
124
123
125
{{ template "repo/issues/fragments/newComment" . }}
+5
-1
appview/pages/templates/repo/pulls/pull.html
+5
-1
appview/pages/templates/repo/pulls/pull.html
···
593
593
<div>
594
594
{{ range $item.Comments }}
595
595
{{/* template "submissionComment" . */}}
596
-
{{ template "comment" (dict "LoggedInUser" $root.LoggedInUser "Comment" .) }}
596
+
{{ template "comment"
597
+
(dict "LoggedInUser" $root.LoggedInUser
598
+
"Reactions" (index (asReactionMapMap $root.Reactions) .AtUri)
599
+
"UserReacted" (index (asReactionStatusMapMap $root.UserReacted) .AtUri)
600
+
"Comment" .) }}
597
601
{{ end }}
598
602
</div>
599
603
{{ if gt $c 0}}
+4
-2
appview/pages/templates/strings/string.html
+4
-2
appview/pages/templates/strings/string.html
···
98
98
{{
99
99
template "fragments/comment/commentList"
100
100
(dict
101
-
"LoggedInUser" .LoggedInUser
102
-
"CommentList" .CommentList)
101
+
"LoggedInUser" $.LoggedInUser
102
+
"CommentList" $.CommentList
103
+
"Reactions" $.Reactions
104
+
"UserReacted" $.UserReacted)
103
105
}}
104
106
{{ template "newComment" . }}
105
107
</div>
+5
appview/pulls/pulls.go
+5
appview/pulls/pulls.go
···
241
241
}
242
242
243
243
entities := []syntax.ATURI{pull.AtUri()}
244
+
for _, s := range pull.Submissions {
245
+
for _, c := range s.Comments {
246
+
entities = append(entities, c.AtUri())
247
+
}
248
+
}
244
249
reactions, err := db.ListReactionDisplayDataMap(s.db, entities, 20)
245
250
if err != nil {
246
251
l.Error("failed to get pull reactions", "err", err)
+1
-3
appview/state/reaction.go
+1
-3
appview/state/reaction.go
···
19
19
l := s.logger.With("handler", "React")
20
20
currentUser := s.oauth.GetMultiAccountUser(r)
21
21
22
-
subject := r.URL.Query().Get("subject")
22
+
subject := r.FormValue("subject-uri")
23
23
if subject == "" {
24
24
l.Warn("invalid form")
25
25
return
···
78
78
l.Info("created atproto record", "uri", resp.Uri)
79
79
80
80
s.pages.ThreadReactionFragment(w, pages.ThreadReactionFragmentParams{
81
-
ThreadAt: subjectUri,
82
81
Kind: reactionKind,
83
82
Count: reactionMap[reactionKind].Count,
84
83
Users: reactionMap[reactionKind].Users,
···
117
116
}
118
117
119
118
s.pages.ThreadReactionFragment(w, pages.ThreadReactionFragmentParams{
120
-
ThreadAt: subjectUri,
121
119
Kind: reactionKind,
122
120
Count: reactionMap[reactionKind].Count,
123
121
Users: reactionMap[reactionKind].Users,
+19
appview/strings/strings.go
+19
appview/strings/strings.go
···
161
161
l.Error("failed to get comments", "err", err)
162
162
}
163
163
164
+
entities := []syntax.ATURI{string.AtUri()}
165
+
for _, c := range comments {
166
+
entities = append(entities, c.AtUri())
167
+
}
168
+
reactions, err := db.ListReactionDisplayDataMap(s.Db, entities, 20)
169
+
if err != nil {
170
+
l.Error("failed to get reactions", "err", err)
171
+
}
172
+
173
+
var userReactions map[syntax.ATURI]map[models.ReactionKind]bool
174
+
if user != nil {
175
+
userReactions, err = db.ListReactionStatusMap(s.Db, entities, syntax.DID(user.Active.Did))
176
+
if err != nil {
177
+
l.Error("failed to get user reactions", "err", err)
178
+
}
179
+
}
180
+
164
181
s.Pages.SingleString(w, pages.SingleStringParams{
165
182
LoggedInUser: user,
166
183
RenderToggle: renderToggle,
···
171
188
StarCount: starCount,
172
189
Owner: id,
173
190
CommentList: models.NewCommentList(comments),
191
+
Reactions: reactions,
192
+
UserReacted: userReactions,
174
193
})
175
194
}
176
195
History
4 rounds
0 comments
boltless.me
submitted
#3
1 commit
expand
collapse
appview: add reactions to comments
Signed-off-by: Seongmin Lee <git@boltless.me>
3/3 failed
expand
collapse
no conflicts, ready to merge
expand 0 comments
boltless.me
submitted
#2
1 commit
expand
collapse
appview: add reactions to comments
Signed-off-by: Seongmin Lee <git@boltless.me>
3/3 failed
expand
collapse
expand 0 comments
boltless.me
submitted
#1
1 commit
expand
collapse
appview: add reactions to comments
Signed-off-by: Seongmin Lee <git@boltless.me>
3/3 failed
expand
collapse
expand 0 comments
boltless.me
submitted
#0
1 commit
expand
collapse
appview: add reactions to comments
Signed-off-by: Seongmin Lee <git@boltless.me>