···2233import (
44 "fmt"
55+ "sort"
56 "strings"
67 "time"
78···157158 PullRoundIdx: pullRoundIdx,
158159 }, nil
159160}
161161+162162+type CommentListItem struct {
163163+ Self *Comment
164164+ Replies []*Comment
165165+}
166166+167167+func (it *CommentListItem) Participants() []syntax.DID {
168168+ participantSet := make(map[syntax.DID]struct{})
169169+ participants := []syntax.DID{}
170170+171171+ addParticipant := func(did syntax.DID) {
172172+ if _, exists := participantSet[did]; !exists {
173173+ participantSet[did] = struct{}{}
174174+ participants = append(participants, did)
175175+ }
176176+ }
177177+178178+ addParticipant(syntax.DID(it.Self.Did))
179179+180180+ for _, c := range it.Replies {
181181+ addParticipant(syntax.DID(c.Did))
182182+ }
183183+184184+ return participants
185185+}
186186+187187+func NewCommentList(comments []Comment) []CommentListItem {
188188+ // Create a map to quickly find comments by their aturi
189189+ toplevel := make(map[syntax.ATURI]*CommentListItem)
190190+ var replies []*Comment
191191+192192+ // collect top level comments into the map
193193+ for _, comment := range comments {
194194+ if comment.IsTopLevel() {
195195+ toplevel[comment.AtUri()] = &CommentListItem{
196196+ Self: &comment,
197197+ }
198198+ } else {
199199+ replies = append(replies, &comment)
200200+ }
201201+ }
202202+203203+ for _, r := range replies {
204204+ if r.ReplyTo == nil {
205205+ continue
206206+ }
207207+ if parent, exists := toplevel[syntax.ATURI(r.ReplyTo.Uri)]; exists {
208208+ parent.Replies = append(parent.Replies, r)
209209+ }
210210+ }
211211+212212+ var listing []CommentListItem
213213+ for _, v := range toplevel {
214214+ listing = append(listing, *v)
215215+ }
216216+217217+ // sort everything
218218+ sortFunc := func(a, b *Comment) bool {
219219+ return a.Created.Before(b.Created)
220220+ }
221221+ sort.Slice(listing, func(i, j int) bool {
222222+ return sortFunc(listing[i].Self, listing[j].Self)
223223+ })
224224+ for _, r := range listing {
225225+ sort.Slice(r.Replies, func(i, j int) bool {
226226+ return sortFunc(r.Replies[i], r.Replies[j])
227227+ })
228228+ }
229229+230230+ return listing
231231+}
-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() []syntax.DID {
+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)