···1+package models
2+3+import (
4+ "fmt"
5+ "strings"
6+ "time"
7+8+ "github.com/bluesky-social/indigo/atproto/syntax"
9+ "tangled.org/core/api/tangled"
10+)
11+12+type Comment struct {
13+ Id int64
14+ Did syntax.DID
15+ Rkey string
16+ Subject syntax.ATURI
17+ ReplyTo *syntax.ATURI
18+ Body string
19+ Created time.Time
20+ Edited *time.Time
21+ Deleted *time.Time
22+ Mentions []syntax.DID
23+ References []syntax.ATURI
24+ PullSubmissionId *int
25+}
26+27+func (c *Comment) AtUri() syntax.ATURI {
28+ return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", c.Did, tangled.CommentNSID, c.Rkey))
29+}
30+31+func (c *Comment) AsRecord() tangled.Comment {
32+ mentions := make([]string, len(c.Mentions))
33+ for i, did := range c.Mentions {
34+ mentions[i] = string(did)
35+ }
36+ references := make([]string, len(c.References))
37+ for i, uri := range c.References {
38+ references[i] = string(uri)
39+ }
40+ var replyTo *string
41+ if c.ReplyTo != nil {
42+ replyToStr := c.ReplyTo.String()
43+ replyTo = &replyToStr
44+ }
45+ return tangled.Comment{
46+ Subject: c.Subject.String(),
47+ Body: c.Body,
48+ CreatedAt: c.Created.Format(time.RFC3339),
49+ ReplyTo: replyTo,
50+ Mentions: mentions,
51+ References: references,
52+ }
53+}
54+55+func (c *Comment) IsTopLevel() bool {
56+ return c.ReplyTo == nil
57+}
58+59+func (c *Comment) IsReply() bool {
60+ return c.ReplyTo != nil
61+}
62+63+func (c *Comment) Validate() error {
64+ // TODO: sanitize the body and then trim space
65+ if sb := strings.TrimSpace(c.Body); sb == "" {
66+ return fmt.Errorf("body is empty after HTML sanitization")
67+ }
68+69+ // if it's for PR, PullSubmissionId should not be nil
70+ if c.Subject.Collection().String() == tangled.RepoPullNSID {
71+ if c.PullSubmissionId == nil {
72+ return fmt.Errorf("PullSubmissionId should not be nil")
73+ }
74+ }
75+ return nil
76+}
77+78+func CommentFromRecord(did, rkey string, record tangled.Comment) (*Comment, error) {
79+ created, err := time.Parse(time.RFC3339, record.CreatedAt)
80+ if err != nil {
81+ created = time.Now()
82+ }
83+84+ ownerDid := did
85+86+ if _, err = syntax.ParseATURI(record.Subject); err != nil {
87+ return nil, err
88+ }
89+90+ i := record
91+ mentions := make([]syntax.DID, len(record.Mentions))
92+ for i, did := range record.Mentions {
93+ mentions[i] = syntax.DID(did)
94+ }
95+ references := make([]syntax.ATURI, len(record.References))
96+ for i, uri := range i.References {
97+ references[i] = syntax.ATURI(uri)
98+ }
99+ var replyTo *syntax.ATURI
100+ if record.ReplyTo != nil {
101+ replyToAtUri := syntax.ATURI(*record.ReplyTo)
102+ replyTo = &replyToAtUri
103+ }
104+105+ comment := Comment{
106+ Did: syntax.DID(ownerDid),
107+ Rkey: rkey,
108+ Body: record.Body,
109+ Subject: syntax.ATURI(record.Subject),
110+ ReplyTo: replyTo,
111+ Created: created,
112+ Mentions: mentions,
113+ References: references,
114+ }
115+116+ return &comment, nil
117+}
+2-46
appview/models/pull.go
···138 RoundNumber int
139 Patch string
140 Combined string
141- Comments []PullComment
142 SourceRev string // include the rev that was used to create this submission: only for branch/fork PRs
143144 // meta
145 Created time.Time
146}
147-148-type PullComment struct {
149- // ids
150- ID int
151- PullId int
152- SubmissionId int
153-154- // at ids
155- RepoAt string
156- OwnerDid string
157- CommentAt string
158-159- // content
160- Body string
161-162- // meta
163- Mentions []syntax.DID
164- References []syntax.ATURI
165-166- // meta
167- Created time.Time
168-}
169-170-func (p *PullComment) AtUri() syntax.ATURI {
171- return syntax.ATURI(p.CommentAt)
172-}
173-174-// func (p *PullComment) AsRecord() tangled.RepoPullComment {
175-// mentions := make([]string, len(p.Mentions))
176-// for i, did := range p.Mentions {
177-// mentions[i] = string(did)
178-// }
179-// references := make([]string, len(p.References))
180-// for i, uri := range p.References {
181-// references[i] = string(uri)
182-// }
183-// return tangled.RepoPullComment{
184-// Pull: p.PullAt,
185-// Body: p.Body,
186-// Mentions: mentions,
187-// References: references,
188-// CreatedAt: p.Created.Format(time.RFC3339),
189-// }
190-// }
191192func (p *Pull) LastRoundNumber() int {
193 return len(p.Submissions) - 1
···289 addParticipant(s.PullAt.Authority().String())
290291 for _, c := range s.Comments {
292- addParticipant(c.OwnerDid)
293 }
294295 return participants
···138 RoundNumber int
139 Patch string
140 Combined string
141+ Comments []Comment
142 SourceRev string // include the rev that was used to create this submission: only for branch/fork PRs
143144 // meta
145 Created time.Time
146}
00000000000000000000000000000000000000000000147148func (p *Pull) LastRoundNumber() int {
149 return len(p.Submissions) - 1
···245 addParticipant(s.PullAt.Authority().String())
246247 for _, c := range s.Comments {
248+ addParticipant(c.Did.String())
249 }
250251 return participants