···2233import (
44 "fmt"
55+ "sort"
56 "strings"
67 "time"
78···156157 PullRoundIdx: pullRoundIdx,
157158 }, nil
158159}
160160+161161+type CommentListItem struct {
162162+ Self *Comment
163163+ Replies []*Comment
164164+}
165165+166166+func (it *CommentListItem) Participants() []syntax.DID {
167167+ participantSet := make(map[syntax.DID]struct{})
168168+ participants := []syntax.DID{}
169169+170170+ addParticipant := func(did syntax.DID) {
171171+ if _, exists := participantSet[did]; !exists {
172172+ participantSet[did] = struct{}{}
173173+ participants = append(participants, did)
174174+ }
175175+ }
176176+177177+ addParticipant(syntax.DID(it.Self.Did))
178178+179179+ for _, c := range it.Replies {
180180+ addParticipant(syntax.DID(c.Did))
181181+ }
182182+183183+ return participants
184184+}
185185+186186+func NewCommentList(comments []Comment) []CommentListItem {
187187+ // Create a map to quickly find comments by their aturi
188188+ toplevel := make(map[syntax.ATURI]*CommentListItem)
189189+ var replies []*Comment
190190+191191+ // collect top level comments into the map
192192+ for _, comment := range comments {
193193+ if comment.IsTopLevel() {
194194+ toplevel[comment.AtUri()] = &CommentListItem{
195195+ Self: &comment,
196196+ }
197197+ } else {
198198+ replies = append(replies, &comment)
199199+ }
200200+ }
201201+202202+ for _, r := range replies {
203203+ if r.ReplyTo == nil {
204204+ continue
205205+ }
206206+ if parent, exists := toplevel[syntax.ATURI(r.ReplyTo.Uri)]; exists {
207207+ parent.Replies = append(parent.Replies, r)
208208+ }
209209+ }
210210+211211+ var listing []CommentListItem
212212+ for _, v := range toplevel {
213213+ listing = append(listing, *v)
214214+ }
215215+216216+ // sort everything
217217+ sortFunc := func(a, b *Comment) bool {
218218+ return a.Created.Before(b.Created)
219219+ }
220220+ sort.Slice(listing, func(i, j int) bool {
221221+ return sortFunc(listing[i].Self, listing[j].Self)
222222+ })
223223+ for _, r := range listing {
224224+ sort.Slice(r.Replies, func(i, j int) bool {
225225+ return sortFunc(r.Replies[i], r.Replies[j])
226226+ })
227227+ }
228228+229229+ return listing
230230+}
-72
appview/models/issue.go
···2233import (
44 "fmt"
55- "sort"
65 "time"
7687 "github.com/bluesky-social/indigo/atproto/syntax"
···6463 return "open"
6564 }
6665 return "closed"
6767-}
6868-6969-type CommentListItem struct {
7070- Self *Comment
7171- Replies []*Comment
7272-}
7373-7474-func (it *CommentListItem) Participants() []syntax.DID {
7575- participantSet := make(map[syntax.DID]struct{})
7676- participants := []syntax.DID{}
7777-7878- addParticipant := func(did syntax.DID) {
7979- if _, exists := participantSet[did]; !exists {
8080- participantSet[did] = struct{}{}
8181- participants = append(participants, did)
8282- }
8383- }
8484-8585- addParticipant(syntax.DID(it.Self.Did))
8686-8787- for _, c := range it.Replies {
8888- addParticipant(syntax.DID(c.Did))
8989- }
9090-9191- return participants
9292-}
9393-9494-func (i *Issue) CommentList() []CommentListItem {
9595- // Create a map to quickly find comments by their aturi
9696- toplevel := make(map[syntax.ATURI]*CommentListItem)
9797- var replies []*Comment
9898-9999- // collect top level comments into the map
100100- for _, comment := range i.Comments {
101101- if comment.IsTopLevel() {
102102- toplevel[comment.AtUri()] = &CommentListItem{
103103- Self: &comment,
104104- }
105105- } else {
106106- replies = append(replies, &comment)
107107- }
108108- }
109109-110110- for _, r := range replies {
111111- if r.ReplyTo == nil {
112112- continue
113113- }
114114- if parent, exists := toplevel[syntax.ATURI(r.ReplyTo.Uri)]; exists {
115115- parent.Replies = append(parent.Replies, r)
116116- }
117117- }
118118-119119- var listing []CommentListItem
120120- for _, v := range toplevel {
121121- listing = append(listing, *v)
122122- }
123123-124124- // sort everything
125125- sortFunc := func(a, b *Comment) bool {
126126- return a.Created.Before(b.Created)
127127- }
128128- sort.Slice(listing, func(i, j int) bool {
129129- return sortFunc(listing[i].Self, listing[j].Self)
130130- })
131131- for _, r := range listing {
132132- sort.Slice(r.Replies, func(i, j int) bool {
133133- return sortFunc(r.Replies[i], r.Replies[j])
134134- })
135135- }
136136-137137- return listing
13866}
1396714068func (i *Issue) Participants() []string {
+1-1
appview/notify/db/db.go
···121121 parent := *comment.ReplyTo
122122123123 // find the parent thread, and add all DIDs from here to the recipient list
124124- for _, t := range issue.CommentList() {
124124+ for _, t := range models.NewCommentList(issue.Comments) {
125125 if t.Self.AtUri() == syntax.ATURI(parent.Uri) {
126126 for _, p := range t.Participants() {
127127 recipients.Insert(p)