From 74430d1e4cc5d46014fc0ab6cbcd155e426f5326 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Fri, 14 Nov 2025 13:24:53 +0900 Subject: [PATCH] appview: replace `PullComment` to `Comment` Change-Id: zytspqzqwvosuxpkooqyqwvzkmqmxtnz Signed-off-by: Seongmin Lee --- appview/db/comments.go | 197 +++++++++++++++++++ appview/db/db.go | 32 +++ appview/db/pulls.go | 127 +----------- appview/db/reference.go | 15 +- appview/models/comment.go | 117 +++++++++++ appview/models/pull.go | 48 +---- appview/notify/db/db.go | 17 +- appview/notify/merged_notifier.go | 2 +- appview/notify/notifier.go | 4 +- appview/notify/posthog/notifier.go | 7 +- appview/pages/templates/repo/pulls/pull.html | 6 +- appview/pulls/opengraph.go | 2 +- appview/pulls/pulls.go | 47 ++--- 13 files changed, 406 insertions(+), 215 deletions(-) create mode 100644 appview/db/comments.go create mode 100644 appview/models/comment.go diff --git a/appview/db/comments.go b/appview/db/comments.go new file mode 100644 index 00000000..a0cf6782 --- /dev/null +++ b/appview/db/comments.go @@ -0,0 +1,197 @@ +package db + +import ( + "database/sql" + "fmt" + "maps" + "slices" + "sort" + "strings" + "time" + + "github.com/bluesky-social/indigo/atproto/syntax" + "tangled.org/core/appview/models" +) + +func PutComment(tx *sql.Tx, c *models.Comment) error { + result, err := tx.Exec( + `insert into comments ( + did, + rkey, + subject_at, + reply_to, + body, + pull_submission_id, + created + ) + values (?, ?, ?, ?, ?, ?, ?) + on conflict(did, rkey) do update set + subject_at = excluded.subject_at, + reply_to = excluded.reply_to, + body = excluded.body, + edited = case + when + comments.subject_at != excluded.subject_at + or comments.body != excluded.body + or comments.reply_to != excluded.reply_to + then ? + else comments.edited + end`, + c.Did, + c.Rkey, + c.Subject, + c.ReplyTo, + c.Body, + c.PullSubmissionId, + c.Created.Format(time.RFC3339), + time.Now().Format(time.RFC3339), + ) + if err != nil { + return err + } + + c.Id, err = result.LastInsertId() + if err != nil { + return err + } + + if err := putReferences(tx, c.AtUri(), c.References); err != nil { + return fmt.Errorf("put reference_links: %w", err) + } + + return nil +} + +func DeleteComments(e Execer, filters ...filter) error { + var conditions []string + var args []any + for _, filter := range filters { + conditions = append(conditions, filter.Condition()) + args = append(args, filter.Arg()...) + } + + whereClause := "" + if conditions != nil { + whereClause = " where " + strings.Join(conditions, " and ") + } + + query := fmt.Sprintf(`update comments set body = "", deleted = strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', 'now') %s`, whereClause) + + _, err := e.Exec(query, args...) + return err +} + +func GetComments(e Execer, filters ...filter) ([]models.Comment, error) { + commentMap := make(map[string]*models.Comment) + + var conditions []string + var args []any + for _, filter := range filters { + conditions = append(conditions, filter.Condition()) + args = append(args, filter.Arg()...) + } + + whereClause := "" + if conditions != nil { + whereClause = " where " + strings.Join(conditions, " and ") + } + + query := fmt.Sprintf(` + select + id, + did, + rkey, + subject_at, + reply_to, + body, + pull_submission_id, + created, + edited, + deleted + from + comments + %s + `, whereClause) + + rows, err := e.Query(query, args...) + if err != nil { + return nil, err + } + + for rows.Next() { + var comment models.Comment + var created string + var rkey, edited, deleted, replyTo sql.Null[string] + err := rows.Scan( + &comment.Id, + &comment.Did, + &rkey, + &comment.Subject, + &replyTo, + &comment.Body, + &comment.PullSubmissionId, + &created, + &edited, + &deleted, + ) + if err != nil { + return nil, err + } + + // this is a remnant from old times, newer comments always have rkey + if rkey.Valid { + comment.Rkey = rkey.V + } + + if t, err := time.Parse(time.RFC3339, created); err == nil { + comment.Created = t + } + + if edited.Valid { + if t, err := time.Parse(time.RFC3339, edited.V); err == nil { + comment.Edited = &t + } + } + + if deleted.Valid { + if t, err := time.Parse(time.RFC3339, deleted.V); err == nil { + comment.Deleted = &t + } + } + + if replyTo.Valid { + rt := syntax.ATURI(replyTo.V) + comment.ReplyTo = &rt + } + + atUri := comment.AtUri().String() + commentMap[atUri] = &comment + } + + if err := rows.Err(); err != nil { + return nil, err + } + + // collect references from each comments + commentAts := slices.Collect(maps.Keys(commentMap)) + allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts)) + if err != nil { + return nil, fmt.Errorf("failed to query reference_links: %w", err) + } + for commentAt, references := range allReferencs { + if comment, ok := commentMap[commentAt.String()]; ok { + comment.References = references + } + } + + var comments []models.Comment + for _, c := range commentMap { + comments = append(comments, *c) + } + + sort.Slice(comments, func(i, j int) bool { + return comments[i].Created.After(comments[j].Created) + }) + + return comments, nil +} diff --git a/appview/db/db.go b/appview/db/db.go index f11bd391..bb184467 100644 --- a/appview/db/db.go +++ b/appview/db/db.go @@ -1174,6 +1174,38 @@ func Make(ctx context.Context, dbPath string) (*DB, error) { return err }) + // not migrating existing comments here + // all legacy comments will be dropped + runMigration(conn, logger, "add-comments-table", func(tx *sql.Tx) error { + _, err := tx.Exec(` + drop table comments; + + create table comments ( + -- identifiers + id integer primary key autoincrement, + did text not null, + rkey text not null, + at_uri text generated always as ('at://' || did || '/' || 'sh.tangled.comment' || '/' || rkey) stored, + + -- at identifiers + subject_at text not null, + reply_to text, -- at_uri of parent comment + + pull_submission_id integer, -- dirty fix until we atprotate the pull-rounds + + -- content + body text not null, + created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), + edited text, + deleted text, + + -- constraints + unique(did, rkey) + ); + `) + return err + }) + return &DB{ db, logger, diff --git a/appview/db/pulls.go b/appview/db/pulls.go index e765a340..ee91ab37 100644 --- a/appview/db/pulls.go +++ b/appview/db/pulls.go @@ -446,15 +446,17 @@ func GetPullSubmissions(e Execer, filters ...filter) (map[syntax.ATURI][]*models return nil, err } - // Get comments for all submissions using GetPullComments + // Get comments for all submissions using GetComments submissionIds := slices.Collect(maps.Keys(submissionMap)) - comments, err := GetPullComments(e, FilterIn("submission_id", submissionIds)) + comments, err := GetComments(e, FilterIn("pull_submission_id", submissionIds)) if err != nil { return nil, fmt.Errorf("failed to get pull comments: %w", err) } for _, comment := range comments { - if submission, ok := submissionMap[comment.SubmissionId]; ok { - submission.Comments = append(submission.Comments, comment) + if comment.PullSubmissionId != nil { + if submission, ok := submissionMap[*comment.PullSubmissionId]; ok { + submission.Comments = append(submission.Comments, comment) + } } } @@ -474,96 +476,6 @@ func GetPullSubmissions(e Execer, filters ...filter) (map[syntax.ATURI][]*models return m, nil } -func GetPullComments(e Execer, filters ...filter) ([]models.PullComment, error) { - var conditions []string - var args []any - for _, filter := range filters { - conditions = append(conditions, filter.Condition()) - args = append(args, filter.Arg()...) - } - - whereClause := "" - if conditions != nil { - whereClause = " where " + strings.Join(conditions, " and ") - } - - query := fmt.Sprintf(` - select - id, - pull_id, - submission_id, - repo_at, - owner_did, - comment_at, - body, - created - from - pull_comments - %s - order by - created asc - `, whereClause) - - rows, err := e.Query(query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - commentMap := make(map[string]*models.PullComment) - for rows.Next() { - var comment models.PullComment - var createdAt string - err := rows.Scan( - &comment.ID, - &comment.PullId, - &comment.SubmissionId, - &comment.RepoAt, - &comment.OwnerDid, - &comment.CommentAt, - &comment.Body, - &createdAt, - ) - if err != nil { - return nil, err - } - - if t, err := time.Parse(time.RFC3339, createdAt); err == nil { - comment.Created = t - } - - atUri := comment.AtUri().String() - commentMap[atUri] = &comment - } - - if err := rows.Err(); err != nil { - return nil, err - } - - // collect references for each comments - commentAts := slices.Collect(maps.Keys(commentMap)) - allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts)) - if err != nil { - return nil, fmt.Errorf("failed to query reference_links: %w", err) - } - for commentAt, references := range allReferencs { - if comment, ok := commentMap[commentAt.String()]; ok { - comment.References = references - } - } - - var comments []models.PullComment - for _, c := range commentMap { - comments = append(comments, *c) - } - - sort.Slice(comments, func(i, j int) bool { - return comments[i].Created.Before(comments[j].Created) - }) - - return comments, nil -} - // timeframe here is directly passed into the sql query filter, and any // timeframe in the past should be negative; e.g.: "-3 months" func GetPullsByOwnerDid(e Execer, did, timeframe string) ([]models.Pull, error) { @@ -640,33 +552,6 @@ func GetPullsByOwnerDid(e Execer, did, timeframe string) ([]models.Pull, error) return pulls, nil } -func NewPullComment(tx *sql.Tx, comment *models.PullComment) (int64, error) { - query := `insert into pull_comments (owner_did, repo_at, submission_id, comment_at, pull_id, body) values (?, ?, ?, ?, ?, ?)` - res, err := tx.Exec( - query, - comment.OwnerDid, - comment.RepoAt, - comment.SubmissionId, - comment.CommentAt, - comment.PullId, - comment.Body, - ) - if err != nil { - return 0, err - } - - i, err := res.LastInsertId() - if err != nil { - return 0, err - } - - if err := putReferences(tx, comment.AtUri(), comment.References); err != nil { - return 0, fmt.Errorf("put reference_links: %w", err) - } - - return i, nil -} - func SetPullState(e Execer, repoAt syntax.ATURI, pullId int, pullState models.PullState) error { _, err := e.Exec( `update pulls set state = ? where repo_at = ? and pull_id = ? and (state <> ? or state <> ?)`, diff --git a/appview/db/reference.go b/appview/db/reference.go index ca56d865..eabe6811 100644 --- a/appview/db/reference.go +++ b/appview/db/reference.go @@ -123,8 +123,7 @@ func findPullReferences(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATU values %s ) select - p.owner_did, p.rkey, - c.comment_at + p.owner_did, p.rkey, c.at_uri from input inp join repos r on r.did = inp.owner_did @@ -132,9 +131,9 @@ func findPullReferences(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATU join pulls p on p.repo_at = r.at_uri and p.pull_id = inp.pull_id - left join pull_comments c + left join comments c on inp.comment_id is not null - and c.repo_at = r.at_uri and c.pull_id = p.pull_id + and c.subject_at = ('at://' || p.owner_did || '/' || 'sh.tangled.repo.pull' || '/' || p.rkey) and c.id = inp.comment_id `, strings.Join(vals, ","), @@ -292,7 +291,7 @@ func GetBacklinks(e Execer, target syntax.ATURI) ([]models.RichReferenceLink, er return nil, fmt.Errorf("get pull backlinks: %w", err) } backlinks = append(backlinks, ls...) - ls, err = getPullCommentBacklinks(e, backlinksMap[tangled.RepoPullCommentNSID]) + ls, err = getPullCommentBacklinks(e, backlinksMap[tangled.CommentNSID]) if err != nil { return nil, fmt.Errorf("get pull_comment backlinks: %w", err) } @@ -427,15 +426,15 @@ func getPullCommentBacklinks(e Execer, aturis []syntax.ATURI) ([]models.RichRefe if len(aturis) == 0 { return nil, nil } - filter := FilterIn("c.comment_at", aturis) + filter := FilterIn("c.at_uri", aturis) rows, err := e.Query( fmt.Sprintf( `select r.did, r.name, p.pull_id, c.id, p.title, p.state from repos r join pulls p on r.at_uri = p.repo_at - join pull_comments c - on r.at_uri = c.repo_at and p.pull_id = c.pull_id + join comments c + on ('at://' || p.owner_did || '/' || 'sh.tangled.repo.pull' || '/' || p.rkey) = c.subject_at where %s`, filter.Condition(), ), diff --git a/appview/models/comment.go b/appview/models/comment.go new file mode 100644 index 00000000..5bd97a04 --- /dev/null +++ b/appview/models/comment.go @@ -0,0 +1,117 @@ +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 +} diff --git a/appview/models/pull.go b/appview/models/pull.go index af34e9ea..5063890f 100644 --- a/appview/models/pull.go +++ b/appview/models/pull.go @@ -138,57 +138,13 @@ type PullSubmission struct { RoundNumber int Patch string Combined string - Comments []PullComment + Comments []Comment SourceRev string // include the rev that was used to create this submission: only for branch/fork PRs // meta Created time.Time } -type PullComment struct { - // ids - ID int - PullId int - SubmissionId int - - // at ids - RepoAt string - OwnerDid string - CommentAt string - - // content - Body string - - // meta - Mentions []syntax.DID - References []syntax.ATURI - - // meta - Created time.Time -} - -func (p *PullComment) AtUri() syntax.ATURI { - return syntax.ATURI(p.CommentAt) -} - -// func (p *PullComment) AsRecord() tangled.RepoPullComment { -// mentions := make([]string, len(p.Mentions)) -// for i, did := range p.Mentions { -// mentions[i] = string(did) -// } -// references := make([]string, len(p.References)) -// for i, uri := range p.References { -// references[i] = string(uri) -// } -// return tangled.RepoPullComment{ -// Pull: p.PullAt, -// Body: p.Body, -// Mentions: mentions, -// References: references, -// CreatedAt: p.Created.Format(time.RFC3339), -// } -// } - func (p *Pull) LastRoundNumber() int { return len(p.Submissions) - 1 } @@ -289,7 +245,7 @@ func (s *PullSubmission) Participants() []string { addParticipant(s.PullAt.Authority().String()) for _, c := range s.Comments { - addParticipant(c.OwnerDid) + addParticipant(c.Did.String()) } return participants diff --git a/appview/notify/db/db.go b/appview/notify/db/db.go index 0cd55892..f1cb50bc 100644 --- a/appview/notify/db/db.go +++ b/appview/notify/db/db.go @@ -248,17 +248,22 @@ func (n *databaseNotifier) NewPull(ctx context.Context, pull *models.Pull) { ) } -func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { - pull, err := db.GetPull(n.db, - syntax.ATURI(comment.RepoAt), - comment.PullId, +func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { + pulls, err := db.GetPulls(n.db, + db.FilterEq("owner_did", comment.Subject.Authority()), + db.FilterEq("rkey", comment.Subject.RecordKey()), ) if err != nil { log.Printf("NewPullComment: failed to get pulls: %v", err) return } + if len(pulls) == 0 { + log.Printf("NewPullComment: no pull found for %s", comment.Subject) + return + } + pull := pulls[0] - repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", comment.RepoAt)) + repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", pull.RepoAt)) if err != nil { log.Printf("NewPullComment: failed to get repos: %v", err) return @@ -273,7 +278,7 @@ func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.P recipients = append(recipients, syntax.DID(p)) } - actorDid := syntax.DID(comment.OwnerDid) + actorDid := comment.Did eventType := models.NotificationTypePullCommented entityType := "pull" entityId := pull.AtUri().String() diff --git a/appview/notify/merged_notifier.go b/appview/notify/merged_notifier.go index deaf57e5..d744494b 100644 --- a/appview/notify/merged_notifier.go +++ b/appview/notify/merged_notifier.go @@ -82,7 +82,7 @@ func (m *mergedNotifier) NewPull(ctx context.Context, pull *models.Pull) { m.fanout("NewPull", ctx, pull) } -func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { +func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { m.fanout("NewPullComment", ctx, comment, mentions) } diff --git a/appview/notify/notifier.go b/appview/notify/notifier.go index 72462ce0..45e7e11c 100644 --- a/appview/notify/notifier.go +++ b/appview/notify/notifier.go @@ -22,7 +22,7 @@ type Notifier interface { DeleteFollow(ctx context.Context, follow *models.Follow) NewPull(ctx context.Context, pull *models.Pull) - NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) + NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) UpdateProfile(ctx context.Context, profile *models.Profile) @@ -52,7 +52,7 @@ func (m *BaseNotifier) NewFollow(ctx context.Context, follow *models.Follow) func (m *BaseNotifier) DeleteFollow(ctx context.Context, follow *models.Follow) {} func (m *BaseNotifier) NewPull(ctx context.Context, pull *models.Pull) {} -func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.PullComment, mentions []syntax.DID) { +func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.Comment, mentions []syntax.DID) { } func (m *BaseNotifier) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) {} diff --git a/appview/notify/posthog/notifier.go b/appview/notify/posthog/notifier.go index 2679d946..8b2accf3 100644 --- a/appview/notify/posthog/notifier.go +++ b/appview/notify/posthog/notifier.go @@ -86,13 +86,12 @@ func (n *posthogNotifier) NewPull(ctx context.Context, pull *models.Pull) { } } -func (n *posthogNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { +func (n *posthogNotifier) NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { err := n.client.Enqueue(posthog.Capture{ - DistinctId: comment.OwnerDid, + DistinctId: comment.Did.String(), Event: "new_pull_comment", Properties: posthog.Properties{ - "repo_at": comment.RepoAt, - "pull_id": comment.PullId, + "pull_at": comment.Subject, "mentions": mentions, }, }) diff --git a/appview/pages/templates/repo/pulls/pull.html b/appview/pages/templates/repo/pulls/pull.html index 0dca0b7e..7f602102 100644 --- a/appview/pages/templates/repo/pulls/pull.html +++ b/appview/pages/templates/repo/pulls/pull.html @@ -165,14 +165,14 @@
{{ range $cidx, $c := .Comments }} -
+
{{ if gt $cidx 0 }}
{{ end }}
- {{ template "user/fragments/picHandleLink" $c.OwnerDid }} + {{ template "user/fragments/picHandleLink" $c.Did.String }} - {{ template "repo/fragments/time" $c.Created }} + {{ template "repo/fragments/time" $c.Created }}
{{ $c.Body | markdown }} diff --git a/appview/pulls/opengraph.go b/appview/pulls/opengraph.go index c0b4bdd2..5e1878ad 100644 --- a/appview/pulls/opengraph.go +++ b/appview/pulls/opengraph.go @@ -276,7 +276,7 @@ func (s *Pulls) PullOpenGraphSummary(w http.ResponseWriter, r *http.Request) { } // Get comment count from database - comments, err := db.GetPullComments(s.db, db.FilterEq("pull_id", pull.ID)) + comments, err := db.GetComments(s.db, db.FilterEq("subject_at", pull.AtUri())) if err != nil { log.Printf("failed to get pull comments: %v", err) } diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go index 40864603..ce33af69 100644 --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -740,7 +740,23 @@ func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) { } defer tx.Rollback() - createdAt := time.Now().Format(time.RFC3339) + comment := models.Comment{ + Did: syntax.DID(user.Did), + Rkey: tid.TID(), + Subject: pull.AtUri(), + ReplyTo: nil, + Body: body, + Created: time.Now(), + Mentions: mentions, + References: references, + PullSubmissionId: &pull.Submissions[roundNumber].ID, + } + if err = comment.Validate(); err != nil { + log.Println("failed to validate comment", err) + s.pages.Notice(w, "pull-comment", "Failed to create comment.") + return + } + record := comment.AsRecord() client, err := s.oauth.AuthorizedClient(r) if err != nil { @@ -748,16 +764,12 @@ func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) { s.pages.Notice(w, "pull-comment", "Failed to create comment.") return } - atResp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ - Collection: tangled.RepoPullCommentNSID, + _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ + Collection: tangled.CommentNSID, Repo: user.Did, - Rkey: tid.TID(), + Rkey: comment.Rkey, Record: &lexutil.LexiconTypeDecoder{ - Val: &tangled.RepoPullComment{ - Pull: pull.AtUri().String(), - Body: body, - CreatedAt: createdAt, - }, + Val: &record, }, }) if err != nil { @@ -766,19 +778,8 @@ func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) { return } - comment := &models.PullComment{ - OwnerDid: user.Did, - RepoAt: f.RepoAt().String(), - PullId: pull.PullId, - Body: body, - CommentAt: atResp.Uri, - SubmissionId: pull.Submissions[roundNumber].ID, - Mentions: mentions, - References: references, - } - // Create the pull comment in the database with the commentAt field - commentId, err := db.NewPullComment(tx, comment) + err = db.PutComment(tx, &comment) if err != nil { log.Println("failed to create pull comment", err) s.pages.Notice(w, "pull-comment", "Failed to create comment.") @@ -792,10 +793,10 @@ func (s *Pulls) PullComment(w http.ResponseWriter, r *http.Request) { return } - s.notifier.NewPullComment(r.Context(), comment, mentions) + s.notifier.NewPullComment(r.Context(), &comment, mentions) ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f) - s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", ownerSlashRepo, pull.PullId, commentId)) + s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", ownerSlashRepo, pull.PullId, comment.Id)) return } } -- 2.43.0