package models import ( "fmt" "strings" "time" "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/api/tangled" ) type Comment struct { Id int64 Did syntax.DID Rkey string Subject syntax.ATURI ReplyTo *syntax.ATURI Body string Created time.Time Edited *time.Time Deleted *time.Time Mentions []syntax.DID References []syntax.ATURI PullSubmissionId *int } func (c *Comment) AtUri() syntax.ATURI { return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", c.Did, tangled.CommentNSID, c.Rkey)) } func (c *Comment) AsRecord() tangled.Comment { mentions := make([]string, len(c.Mentions)) for i, did := range c.Mentions { mentions[i] = string(did) } references := make([]string, len(c.References)) for i, uri := range c.References { references[i] = string(uri) } var replyTo *string if c.ReplyTo != nil { replyToStr := c.ReplyTo.String() replyTo = &replyToStr } return tangled.Comment{ Subject: c.Subject.String(), Body: c.Body, CreatedAt: c.Created.Format(time.RFC3339), ReplyTo: replyTo, Mentions: mentions, References: references, } } func (c *Comment) IsTopLevel() bool { return c.ReplyTo == nil } func (c *Comment) IsReply() bool { return c.ReplyTo != nil } func (c *Comment) Validate() error { // TODO: sanitize the body and then trim space if sb := strings.TrimSpace(c.Body); sb == "" { return fmt.Errorf("body is empty after HTML sanitization") } // if it's for PR, PullSubmissionId should not be nil if c.Subject.Collection().String() == tangled.RepoPullNSID { if c.PullSubmissionId == nil { return fmt.Errorf("PullSubmissionId should not be nil") } } return nil } func CommentFromRecord(did, rkey string, record tangled.Comment) (*Comment, error) { created, err := time.Parse(time.RFC3339, record.CreatedAt) if err != nil { created = time.Now() } ownerDid := did if _, err = syntax.ParseATURI(record.Subject); err != nil { return nil, err } i := record mentions := make([]syntax.DID, len(record.Mentions)) for i, did := range record.Mentions { mentions[i] = syntax.DID(did) } references := make([]syntax.ATURI, len(record.References)) for i, uri := range i.References { references[i] = syntax.ATURI(uri) } var replyTo *syntax.ATURI if record.ReplyTo != nil { replyToAtUri := syntax.ATURI(*record.ReplyTo) replyTo = &replyToAtUri } comment := Comment{ Did: syntax.DID(ownerDid), Rkey: rkey, Body: record.Body, Subject: syntax.ATURI(record.Subject), ReplyTo: replyTo, Created: created, Mentions: mentions, References: references, } return &comment, nil }