Monorepo for Tangled tangled.org
855
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: add reactions to comments

Signed-off-by: Seongmin Lee <git@boltless.me>

+73 -19
+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)
+16
appview/pages/funcmap.go
··· 481 481 "isGenerated": func(path string) bool { 482 482 return enry.IsGenerated(path, nil) 483 483 }, 484 + // NOTE(boltless): I know... I hate doing this too 485 + "asReactionMapMap": func(dict any) map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData { 486 + if dict == nil { 487 + return make(map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData) 488 + } 489 + m, _ := dict.(map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData) 490 + return m 491 + }, 492 + "asReactionStatusMapMap": func(dict any) map[syntax.ATURI]map[models.ReactionKind]bool { 493 + if dict == nil { 494 + log.Println("returning empty map") 495 + return make(map[syntax.ATURI]map[models.ReactionKind]bool) 496 + } 497 + m, _ := dict.(map[syntax.ATURI]map[models.ReactionKind]bool) 498 + return m 499 + }, 484 500 // constant values used to define a template 485 501 "const": func() map[string]any { 486 502 return map[string]any{
+2 -1
appview/pages/pages.go
··· 1211 1211 } 1212 1212 1213 1213 type ThreadReactionFragmentParams struct { 1214 - ThreadAt syntax.ATURI 1215 1214 Kind models.ReactionKind 1216 1215 Count int 1217 1216 Users []string ··· 1614 1613 Owner identity.Identity 1615 1614 CommentList []models.CommentListItem 1616 1615 1616 + Reactions map[syntax.ATURI]map[models.ReactionKind]models.ReactionDisplayData 1617 + UserReacted map[syntax.ATURI]map[models.ReactionKind]bool 1617 1618 VouchRelationships map[syntax.DID]*models.VouchRelationship 1618 1619 } 1619 1620
+5 -1
appview/pages/templates/fragments/comment/commentBody.html
··· 1 1 {{ define "fragments/comment/commentBody" }} 2 2 <div class="comment-body"> 3 3 {{ if not .Comment.Deleted }} 4 - <div class="prose dark:prose-invert">{{ .Comment.Body.Text | markdown }}</div> 4 + <div class="prose dark:prose-invert mb-1">{{ .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 }}
+5 -1
appview/pages/templates/fragments/comment/commentList.html
··· 14 14 {{ template "topLevelComment" 15 15 (dict 16 16 "LoggedInUser" $root.LoggedInUser 17 + "Reactions" (index (asReactionMapMap $root.Reactions) $item.Self.AtUri) 18 + "UserReacted" (index (asReactionStatusMapMap $root.UserReacted) $item.Self.AtUri) 17 19 "VouchRelationship" (index $root.VouchRelationships $item.Self.Did) 18 20 "Comment" $item.Self) }} 19 21 ··· 23 25 {{ template "replyComment" 24 26 (dict 25 27 "LoggedInUser" $root.LoggedInUser 28 + "Reactions" (index (asReactionMapMap $root.Reactions) $reply.AtUri) 29 + "UserReacted" (index (asReactionStatusMapMap $root.UserReacted) $reply.AtUri) 26 30 "VouchRelationship" (index $root.VouchRelationships $reply.Did) 27 31 "Comment" $reply) }} 28 32 </div> ··· 58 62 {{ end }} 59 63 60 64 {{ define "replyComment" }} 61 - <div class="py-4 pr-4 w-full mx-auto overflow-hidden flex gap-2 "> 65 + <div class="py-4 pr-4 w-full mx-auto flex gap-2 "> 62 66 <div class="flex-shrink-0"> 63 67 {{ template "user/fragments/picLink" (list .Comment.Did.String "size-8 mr-1" .VouchRelationship) }} 64 68 </div>
+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
··· 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 + 7 + <input name="subject-uri" type="hidden" value="{{ $threadAt }}"> 6 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 }}
+2
appview/pages/templates/repo/issues/issue.html
··· 118 118 template "fragments/comment/commentList" 119 119 (dict 120 120 "LoggedInUser" $.LoggedInUser 121 + "Reactions" $.Reactions 122 + "UserReacted" $.UserReacted 121 123 "VouchRelationships" $.VouchRelationships 122 124 "CommentList" $.CommentList) 123 125 }}
+4 -2
appview/pages/templates/repo/pulls/pull.html
··· 597 597 {{ range $item.Comments }} 598 598 {{/* template "submissionComment" . */}} 599 599 {{ template "comment" 600 - (dict "LoggedInUser" $root.LoggedInUser 600 + (dict "LoggedInUser" $root.LoggedInUser 601 + "Reactions" (index (asReactionMapMap $root.Reactions) .AtUri) 602 + "UserReacted" (index (asReactionStatusMapMap $root.UserReacted) .AtUri) 601 603 "VouchRelationship" (index $root.VouchRelationships .Did) 602 - "Comment" .) }} 604 + "Comment" .) }} 603 605 {{ end }} 604 606 </div> 605 607 {{ if gt $c 0}}
+2
appview/pages/templates/strings/string.html
··· 99 99 template "fragments/comment/commentList" 100 100 (dict 101 101 "LoggedInUser" .LoggedInUser 102 + "Reactions" .Reactions 103 + "UserReacted" .UserReacted 102 104 "VouchRelationships" .VouchRelationships 103 105 "CommentList" .CommentList) 104 106 }}
+5
appview/pulls/single.go
··· 163 163 } 164 164 165 165 entities := []syntax.ATURI{pull.AtUri()} 166 + for _, s := range pull.Submissions { 167 + for _, c := range s.Comments { 168 + entities = append(entities, c.AtUri()) 169 + } 170 + } 166 171 reactions, err := db.ListReactionDisplayDataMap(s.db, entities, 20) 167 172 if err != nil { 168 173 l.Error("failed to get pull reactions", "err", err)
+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
··· 161 161 l.Error("failed to get comments", "err", err) 162 162 } 163 163 164 + var entities []syntax.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.Did)) 176 + if err != nil { 177 + l.Error("failed to get user reactions", "err", err) 178 + } 179 + } 180 + 164 181 vouchRelationships := make(map[syntax.DID]*models.VouchRelationship) 165 182 if user != nil { 166 183 var participants []syntax.DID ··· 184 201 Owner: id, 185 202 CommentList: models.NewCommentList(comments), 186 203 204 + Reactions: reactions, 205 + UserReacted: userReactions, 187 206 VouchRelationships: vouchRelationships, 188 207 }) 189 208 }