From 679fbc09e663b8404edfb06b67e79836c3810c4a Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Mon, 12 Jan 2026 07:25:44 +0000 Subject: [PATCH] appview: move `CommentList` out of `Issue` So that we can render reply comments from non-issue threads. Signed-off-by: Seongmin Lee --- appview/issues/issues.go | 2 +- appview/models/comment.go | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ appview/models/issue.go | 72 ------------------------------------------------------------------------ appview/notify/db/db.go | 2 +- appview/pages/templates/fragments/comment/commentList.html | 11 +++++------ appview/pages/templates/repo/issues/issue.html | 6 ++---- 6 file(s) changed, 81 insertion(s)(+), 84 deletion(s)(-) diff --git a/appview/issues/issues.go b/appview/issues/issues.go --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -135,7 +135,7 @@ err = rp.pages.RepoSingleIssue(w, pages.RepoSingleIssueParams{ LoggedInUser: user, RepoInfo: rp.repoResolver.GetRepoInfo(r, user), Issue: issue, - CommentList: issue.CommentList(), + CommentList: models.NewCommentList(issue.Comments), Backlinks: backlinks, Reactions: reactionMap, UserReacted: userReactions, diff --git a/appview/models/comment.go b/appview/models/comment.go --- a/appview/models/comment.go +++ b/appview/models/comment.go @@ -2,6 +2,7 @@ package models import ( "fmt" + "sort" "strings" "time" @@ -156,3 +157,74 @@ ReplyTo: record.ReplyTo, PullRoundIdx: pullRoundIdx, }, nil } + +type CommentListItem struct { + Self *Comment + Replies []*Comment +} + +func (it *CommentListItem) Participants() []syntax.DID { + participantSet := make(map[syntax.DID]struct{}) + participants := []syntax.DID{} + + addParticipant := func(did syntax.DID) { + if _, exists := participantSet[did]; !exists { + participantSet[did] = struct{}{} + participants = append(participants, did) + } + } + + addParticipant(syntax.DID(it.Self.Did)) + + for _, c := range it.Replies { + addParticipant(syntax.DID(c.Did)) + } + + return participants +} + +func NewCommentList(comments []Comment) []CommentListItem { + // Create a map to quickly find comments by their aturi + toplevel := make(map[syntax.ATURI]*CommentListItem) + var replies []*Comment + + // collect top level comments into the map + for _, comment := range comments { + if comment.IsTopLevel() { + toplevel[comment.AtUri()] = &CommentListItem{ + Self: &comment, + } + } else { + replies = append(replies, &comment) + } + } + + for _, r := range replies { + if r.ReplyTo == nil { + continue + } + if parent, exists := toplevel[syntax.ATURI(r.ReplyTo.Uri)]; exists { + parent.Replies = append(parent.Replies, r) + } + } + + var listing []CommentListItem + for _, v := range toplevel { + listing = append(listing, *v) + } + + // sort everything + sortFunc := func(a, b *Comment) bool { + return a.Created.Before(b.Created) + } + sort.Slice(listing, func(i, j int) bool { + return sortFunc(listing[i].Self, listing[j].Self) + }) + for _, r := range listing { + sort.Slice(r.Replies, func(i, j int) bool { + return sortFunc(r.Replies[i], r.Replies[j]) + }) + } + + return listing +} diff --git a/appview/models/issue.go b/appview/models/issue.go --- a/appview/models/issue.go +++ b/appview/models/issue.go @@ -2,7 +2,6 @@ package models import ( "fmt" - "sort" "time" "github.com/bluesky-social/indigo/atproto/syntax" @@ -64,77 +63,6 @@ if i.Open { return "open" } return "closed" -} - -type CommentListItem struct { - Self *Comment - Replies []*Comment -} - -func (it *CommentListItem) Participants() []syntax.DID { - participantSet := make(map[syntax.DID]struct{}) - participants := []syntax.DID{} - - addParticipant := func(did syntax.DID) { - if _, exists := participantSet[did]; !exists { - participantSet[did] = struct{}{} - participants = append(participants, did) - } - } - - addParticipant(syntax.DID(it.Self.Did)) - - for _, c := range it.Replies { - addParticipant(syntax.DID(c.Did)) - } - - return participants -} - -func (i *Issue) CommentList() []CommentListItem { - // Create a map to quickly find comments by their aturi - toplevel := make(map[syntax.ATURI]*CommentListItem) - var replies []*Comment - - // collect top level comments into the map - for _, comment := range i.Comments { - if comment.IsTopLevel() { - toplevel[comment.AtUri()] = &CommentListItem{ - Self: &comment, - } - } else { - replies = append(replies, &comment) - } - } - - for _, r := range replies { - if r.ReplyTo == nil { - continue - } - if parent, exists := toplevel[syntax.ATURI(r.ReplyTo.Uri)]; exists { - parent.Replies = append(parent.Replies, r) - } - } - - var listing []CommentListItem - for _, v := range toplevel { - listing = append(listing, *v) - } - - // sort everything - sortFunc := func(a, b *Comment) bool { - return a.Created.Before(b.Created) - } - sort.Slice(listing, func(i, j int) bool { - return sortFunc(listing[i].Self, listing[j].Self) - }) - for _, r := range listing { - sort.Slice(r.Replies, func(i, j int) bool { - return sortFunc(r.Replies[i], r.Replies[j]) - }) - } - - return listing } func (i *Issue) Participants() []string { diff --git a/appview/notify/db/db.go b/appview/notify/db/db.go --- a/appview/notify/db/db.go +++ b/appview/notify/db/db.go @@ -121,7 +121,7 @@ // if this comment is a reply, then notify everybody in that thread parent := *comment.ReplyTo // find the parent thread, and add all DIDs from here to the recipient list - for _, t := range issue.CommentList() { + for _, t := range models.NewCommentList(issue.Comments) { if t.Self.AtUri() == syntax.ATURI(parent.Uri) { for _, p := range t.Participants() { recipients.Insert(p) diff --git a/appview/pages/templates/repo/issues/fragments/commentList.html b/appview/pages/templates/fragments/comment/commentList.html rename from appview/pages/templates/repo/issues/fragments/commentList.html rename to appview/pages/templates/fragments/comment/commentList.html --- a/appview/pages/templates/repo/issues/fragments/commentList.html +++ b/appview/pages/templates/fragments/comment/commentList.html @@ -1,4 +1,4 @@ -{{ define "repo/issues/fragments/commentList" }} +{{ define "fragments/comment/commentList" }}
{{ range $item := .CommentList }} {{ template "commentListItem" (list $ .) }} @@ -9,13 +9,12 @@ {{ define "commentListItem" }} {{ $root := index . 0 }} {{ $item := index . 1 }} - {{ $params := - (dict - "LoggedInUser" $root.LoggedInUser - "Comment" $item.Self) }}
- {{ template "topLevelComment" $params }} + {{ template "topLevelComment" + (dict + "LoggedInUser" $root.LoggedInUser + "Comment" $item.Self) }}
{{ range $index, $reply := $item.Replies }} diff --git a/appview/pages/templates/repo/issues/issue.html b/appview/pages/templates/repo/issues/issue.html --- a/appview/pages/templates/repo/issues/issue.html +++ b/appview/pages/templates/repo/issues/issue.html @@ -113,12 +113,10 @@ {{ define "repoAfter" }}
{{ - template "repo/issues/fragments/commentList" + template "fragments/comment/commentList" (dict - "RepoInfo" $.RepoInfo "LoggedInUser" $.LoggedInUser - "Issue" $.Issue - "CommentList" $.Issue.CommentList) + "CommentList" $.CommentList) }} {{ template "repo/issues/fragments/newComment" . }} -- tangled.sh