Monorepo for Tangled tangled.org

appview: replace PullComment to Comment #865

open opened by boltless.me targeting master from sl/wnrvrwyvrlzo
Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:xasnlahkri4ewmbuzly2rlc5/sh.tangled.repo.pull/3m7iohv2yb422
+406 -215
Diff #0
+197
appview/db/comments.go
··· 1 + package db 2 + 3 + import ( 4 + "database/sql" 5 + "fmt" 6 + "maps" 7 + "slices" 8 + "sort" 9 + "strings" 10 + "time" 11 + 12 + "github.com/bluesky-social/indigo/atproto/syntax" 13 + "tangled.org/core/appview/models" 14 + ) 15 + 16 + func PutComment(tx *sql.Tx, c *models.Comment) error { 17 + result, err := tx.Exec( 18 + `insert into comments ( 19 + did, 20 + rkey, 21 + subject_at, 22 + reply_to, 23 + body, 24 + pull_submission_id, 25 + created 26 + ) 27 + values (?, ?, ?, ?, ?, ?, ?) 28 + on conflict(did, rkey) do update set 29 + subject_at = excluded.subject_at, 30 + reply_to = excluded.reply_to, 31 + body = excluded.body, 32 + edited = case 33 + when 34 + comments.subject_at != excluded.subject_at 35 + or comments.body != excluded.body 36 + or comments.reply_to != excluded.reply_to 37 + then ? 38 + else comments.edited 39 + end`, 40 + c.Did, 41 + c.Rkey, 42 + c.Subject, 43 + c.ReplyTo, 44 + c.Body, 45 + c.PullSubmissionId, 46 + c.Created.Format(time.RFC3339), 47 + time.Now().Format(time.RFC3339), 48 + ) 49 + if err != nil { 50 + return err 51 + } 52 + 53 + c.Id, err = result.LastInsertId() 54 + if err != nil { 55 + return err 56 + } 57 + 58 + if err := putReferences(tx, c.AtUri(), c.References); err != nil { 59 + return fmt.Errorf("put reference_links: %w", err) 60 + } 61 + 62 + return nil 63 + } 64 + 65 + func DeleteComments(e Execer, filters ...filter) error { 66 + var conditions []string 67 + var args []any 68 + for _, filter := range filters { 69 + conditions = append(conditions, filter.Condition()) 70 + args = append(args, filter.Arg()...) 71 + } 72 + 73 + whereClause := "" 74 + if conditions != nil { 75 + whereClause = " where " + strings.Join(conditions, " and ") 76 + } 77 + 78 + query := fmt.Sprintf(`update comments set body = "", deleted = strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', 'now') %s`, whereClause) 79 + 80 + _, err := e.Exec(query, args...) 81 + return err 82 + } 83 + 84 + func GetComments(e Execer, filters ...filter) ([]models.Comment, error) { 85 + commentMap := make(map[string]*models.Comment) 86 + 87 + var conditions []string 88 + var args []any 89 + for _, filter := range filters { 90 + conditions = append(conditions, filter.Condition()) 91 + args = append(args, filter.Arg()...) 92 + } 93 + 94 + whereClause := "" 95 + if conditions != nil { 96 + whereClause = " where " + strings.Join(conditions, " and ") 97 + } 98 + 99 + query := fmt.Sprintf(` 100 + select 101 + id, 102 + did, 103 + rkey, 104 + subject_at, 105 + reply_to, 106 + body, 107 + pull_submission_id, 108 + created, 109 + edited, 110 + deleted 111 + from 112 + comments 113 + %s 114 + `, whereClause) 115 + 116 + rows, err := e.Query(query, args...) 117 + if err != nil { 118 + return nil, err 119 + } 120 + 121 + for rows.Next() { 122 + var comment models.Comment 123 + var created string 124 + var rkey, edited, deleted, replyTo sql.Null[string] 125 + err := rows.Scan( 126 + &comment.Id, 127 + &comment.Did, 128 + &rkey, 129 + &comment.Subject, 130 + &replyTo, 131 + &comment.Body, 132 + &comment.PullSubmissionId, 133 + &created, 134 + &edited, 135 + &deleted, 136 + ) 137 + if err != nil { 138 + return nil, err 139 + } 140 + 141 + // this is a remnant from old times, newer comments always have rkey 142 + if rkey.Valid { 143 + comment.Rkey = rkey.V 144 + } 145 + 146 + if t, err := time.Parse(time.RFC3339, created); err == nil { 147 + comment.Created = t 148 + } 149 + 150 + if edited.Valid { 151 + if t, err := time.Parse(time.RFC3339, edited.V); err == nil { 152 + comment.Edited = &t 153 + } 154 + } 155 + 156 + if deleted.Valid { 157 + if t, err := time.Parse(time.RFC3339, deleted.V); err == nil { 158 + comment.Deleted = &t 159 + } 160 + } 161 + 162 + if replyTo.Valid { 163 + rt := syntax.ATURI(replyTo.V) 164 + comment.ReplyTo = &rt 165 + } 166 + 167 + atUri := comment.AtUri().String() 168 + commentMap[atUri] = &comment 169 + } 170 + 171 + if err := rows.Err(); err != nil { 172 + return nil, err 173 + } 174 + 175 + // collect references from each comments 176 + commentAts := slices.Collect(maps.Keys(commentMap)) 177 + allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts)) 178 + if err != nil { 179 + return nil, fmt.Errorf("failed to query reference_links: %w", err) 180 + } 181 + for commentAt, references := range allReferencs { 182 + if comment, ok := commentMap[commentAt.String()]; ok { 183 + comment.References = references 184 + } 185 + } 186 + 187 + var comments []models.Comment 188 + for _, c := range commentMap { 189 + comments = append(comments, *c) 190 + } 191 + 192 + sort.Slice(comments, func(i, j int) bool { 193 + return comments[i].Created.After(comments[j].Created) 194 + }) 195 + 196 + return comments, nil 197 + }
+32
appview/db/db.go
··· 1174 1174 return err 1175 1175 }) 1176 1176 1177 + // not migrating existing comments here 1178 + // all legacy comments will be dropped 1179 + runMigration(conn, logger, "add-comments-table", func(tx *sql.Tx) error { 1180 + _, err := tx.Exec(` 1181 + drop table comments; 1182 + 1183 + create table comments ( 1184 + -- identifiers 1185 + id integer primary key autoincrement, 1186 + did text not null, 1187 + rkey text not null, 1188 + at_uri text generated always as ('at://' || did || '/' || 'sh.tangled.comment' || '/' || rkey) stored, 1189 + 1190 + -- at identifiers 1191 + subject_at text not null, 1192 + reply_to text, -- at_uri of parent comment 1193 + 1194 + pull_submission_id integer, -- dirty fix until we atprotate the pull-rounds 1195 + 1196 + -- content 1197 + body text not null, 1198 + created text not null default (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), 1199 + edited text, 1200 + deleted text, 1201 + 1202 + -- constraints 1203 + unique(did, rkey) 1204 + ); 1205 + `) 1206 + return err 1207 + }) 1208 + 1177 1209 return &DB{ 1178 1210 db, 1179 1211 logger,
+6 -121
appview/db/pulls.go
··· 446 446 return nil, err 447 447 } 448 448 449 - // Get comments for all submissions using GetPullComments 449 + // Get comments for all submissions using GetComments 450 450 submissionIds := slices.Collect(maps.Keys(submissionMap)) 451 - comments, err := GetPullComments(e, FilterIn("submission_id", submissionIds)) 451 + comments, err := GetComments(e, FilterIn("pull_submission_id", submissionIds)) 452 452 if err != nil { 453 453 return nil, fmt.Errorf("failed to get pull comments: %w", err) 454 454 } 455 455 for _, comment := range comments { 456 - if submission, ok := submissionMap[comment.SubmissionId]; ok { 457 - submission.Comments = append(submission.Comments, comment) 456 + if comment.PullSubmissionId != nil { 457 + if submission, ok := submissionMap[*comment.PullSubmissionId]; ok { 458 + submission.Comments = append(submission.Comments, comment) 459 + } 458 460 } 459 461 } 460 462 ··· 474 476 return m, nil 475 477 } 476 478 477 - func GetPullComments(e Execer, filters ...filter) ([]models.PullComment, error) { 478 - var conditions []string 479 - var args []any 480 - for _, filter := range filters { 481 - conditions = append(conditions, filter.Condition()) 482 - args = append(args, filter.Arg()...) 483 - } 484 - 485 - whereClause := "" 486 - if conditions != nil { 487 - whereClause = " where " + strings.Join(conditions, " and ") 488 - } 489 - 490 - query := fmt.Sprintf(` 491 - select 492 - id, 493 - pull_id, 494 - submission_id, 495 - repo_at, 496 - owner_did, 497 - comment_at, 498 - body, 499 - created 500 - from 501 - pull_comments 502 - %s 503 - order by 504 - created asc 505 - `, whereClause) 506 - 507 - rows, err := e.Query(query, args...) 508 - if err != nil { 509 - return nil, err 510 - } 511 - defer rows.Close() 512 - 513 - commentMap := make(map[string]*models.PullComment) 514 - for rows.Next() { 515 - var comment models.PullComment 516 - var createdAt string 517 - err := rows.Scan( 518 - &comment.ID, 519 - &comment.PullId, 520 - &comment.SubmissionId, 521 - &comment.RepoAt, 522 - &comment.OwnerDid, 523 - &comment.CommentAt, 524 - &comment.Body, 525 - &createdAt, 526 - ) 527 - if err != nil { 528 - return nil, err 529 - } 530 - 531 - if t, err := time.Parse(time.RFC3339, createdAt); err == nil { 532 - comment.Created = t 533 - } 534 - 535 - atUri := comment.AtUri().String() 536 - commentMap[atUri] = &comment 537 - } 538 - 539 - if err := rows.Err(); err != nil { 540 - return nil, err 541 - } 542 - 543 - // collect references for each comments 544 - commentAts := slices.Collect(maps.Keys(commentMap)) 545 - allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts)) 546 - if err != nil { 547 - return nil, fmt.Errorf("failed to query reference_links: %w", err) 548 - } 549 - for commentAt, references := range allReferencs { 550 - if comment, ok := commentMap[commentAt.String()]; ok { 551 - comment.References = references 552 - } 553 - } 554 - 555 - var comments []models.PullComment 556 - for _, c := range commentMap { 557 - comments = append(comments, *c) 558 - } 559 - 560 - sort.Slice(comments, func(i, j int) bool { 561 - return comments[i].Created.Before(comments[j].Created) 562 - }) 563 - 564 - return comments, nil 565 - } 566 - 567 479 // timeframe here is directly passed into the sql query filter, and any 568 480 // timeframe in the past should be negative; e.g.: "-3 months" 569 481 func GetPullsByOwnerDid(e Execer, did, timeframe string) ([]models.Pull, error) { ··· 640 552 return pulls, nil 641 553 } 642 554 643 - func NewPullComment(tx *sql.Tx, comment *models.PullComment) (int64, error) { 644 - query := `insert into pull_comments (owner_did, repo_at, submission_id, comment_at, pull_id, body) values (?, ?, ?, ?, ?, ?)` 645 - res, err := tx.Exec( 646 - query, 647 - comment.OwnerDid, 648 - comment.RepoAt, 649 - comment.SubmissionId, 650 - comment.CommentAt, 651 - comment.PullId, 652 - comment.Body, 653 - ) 654 - if err != nil { 655 - return 0, err 656 - } 657 - 658 - i, err := res.LastInsertId() 659 - if err != nil { 660 - return 0, err 661 - } 662 - 663 - if err := putReferences(tx, comment.AtUri(), comment.References); err != nil { 664 - return 0, fmt.Errorf("put reference_links: %w", err) 665 - } 666 - 667 - return i, nil 668 - } 669 - 670 555 func SetPullState(e Execer, repoAt syntax.ATURI, pullId int, pullState models.PullState) error { 671 556 _, err := e.Exec( 672 557 `update pulls set state = ? where repo_at = ? and pull_id = ? and (state <> ? or state <> ?)`,
+7 -8
appview/db/reference.go
··· 123 123 values %s 124 124 ) 125 125 select 126 - p.owner_did, p.rkey, 127 - c.comment_at 126 + p.owner_did, p.rkey, c.at_uri 128 127 from input inp 129 128 join repos r 130 129 on r.did = inp.owner_did ··· 132 131 join pulls p 133 132 on p.repo_at = r.at_uri 134 133 and p.pull_id = inp.pull_id 135 - left join pull_comments c 134 + left join comments c 136 135 on inp.comment_id is not null 137 - and c.repo_at = r.at_uri and c.pull_id = p.pull_id 136 + and c.subject_at = ('at://' || p.owner_did || '/' || 'sh.tangled.repo.pull' || '/' || p.rkey) 138 137 and c.id = inp.comment_id 139 138 `, 140 139 strings.Join(vals, ","), ··· 292 291 return nil, fmt.Errorf("get pull backlinks: %w", err) 293 292 } 294 293 backlinks = append(backlinks, ls...) 295 - ls, err = getPullCommentBacklinks(e, backlinksMap[tangled.RepoPullCommentNSID]) 294 + ls, err = getPullCommentBacklinks(e, backlinksMap[tangled.CommentNSID]) 296 295 if err != nil { 297 296 return nil, fmt.Errorf("get pull_comment backlinks: %w", err) 298 297 } ··· 427 426 if len(aturis) == 0 { 428 427 return nil, nil 429 428 } 430 - filter := FilterIn("c.comment_at", aturis) 429 + filter := FilterIn("c.at_uri", aturis) 431 430 rows, err := e.Query( 432 431 fmt.Sprintf( 433 432 `select r.did, r.name, p.pull_id, c.id, p.title, p.state 434 433 from repos r 435 434 join pulls p 436 435 on r.at_uri = p.repo_at 437 - join pull_comments c 438 - on r.at_uri = c.repo_at and p.pull_id = c.pull_id 436 + join comments c 437 + on ('at://' || p.owner_did || '/' || 'sh.tangled.repo.pull' || '/' || p.rkey) = c.subject_at 439 438 where %s`, 440 439 filter.Condition(), 441 440 ),
+117
appview/models/comment.go
··· 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 138 RoundNumber int 139 139 Patch string 140 140 Combined string 141 - Comments []PullComment 141 + Comments []Comment 142 142 SourceRev string // include the rev that was used to create this submission: only for branch/fork PRs 143 143 144 144 // meta 145 145 Created time.Time 146 146 } 147 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 - // } 191 - 192 148 func (p *Pull) LastRoundNumber() int { 193 149 return len(p.Submissions) - 1 194 150 } ··· 289 245 addParticipant(s.PullAt.Authority().String()) 290 246 291 247 for _, c := range s.Comments { 292 - addParticipant(c.OwnerDid) 248 + addParticipant(c.Did.String()) 293 249 } 294 250 295 251 return participants
+11 -6
appview/notify/db/db.go
··· 248 248 ) 249 249 } 250 250 251 - func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { 252 - pull, err := db.GetPull(n.db, 253 - syntax.ATURI(comment.RepoAt), 254 - comment.PullId, 251 + func (n *databaseNotifier) NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { 252 + pulls, err := db.GetPulls(n.db, 253 + db.FilterEq("owner_did", comment.Subject.Authority()), 254 + db.FilterEq("rkey", comment.Subject.RecordKey()), 255 255 ) 256 256 if err != nil { 257 257 log.Printf("NewPullComment: failed to get pulls: %v", err) 258 258 return 259 259 } 260 + if len(pulls) == 0 { 261 + log.Printf("NewPullComment: no pull found for %s", comment.Subject) 262 + return 263 + } 264 + pull := pulls[0] 260 265 261 - repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", comment.RepoAt)) 266 + repo, err := db.GetRepo(n.db, db.FilterEq("at_uri", pull.RepoAt)) 262 267 if err != nil { 263 268 log.Printf("NewPullComment: failed to get repos: %v", err) 264 269 return ··· 273 278 recipients = append(recipients, syntax.DID(p)) 274 279 } 275 280 276 - actorDid := syntax.DID(comment.OwnerDid) 281 + actorDid := comment.Did 277 282 eventType := models.NotificationTypePullCommented 278 283 entityType := "pull" 279 284 entityId := pull.AtUri().String()
+1 -1
appview/notify/merged_notifier.go
··· 82 82 m.fanout("NewPull", ctx, pull) 83 83 } 84 84 85 - func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { 85 + func (m *mergedNotifier) NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { 86 86 m.fanout("NewPullComment", ctx, comment, mentions) 87 87 } 88 88
+2 -2
appview/notify/notifier.go
··· 22 22 DeleteFollow(ctx context.Context, follow *models.Follow) 23 23 24 24 NewPull(ctx context.Context, pull *models.Pull) 25 - NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) 25 + NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) 26 26 NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) 27 27 28 28 UpdateProfile(ctx context.Context, profile *models.Profile) ··· 52 52 func (m *BaseNotifier) DeleteFollow(ctx context.Context, follow *models.Follow) {} 53 53 54 54 func (m *BaseNotifier) NewPull(ctx context.Context, pull *models.Pull) {} 55 - func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.PullComment, mentions []syntax.DID) { 55 + func (m *BaseNotifier) NewPullComment(ctx context.Context, models *models.Comment, mentions []syntax.DID) { 56 56 } 57 57 func (m *BaseNotifier) NewPullState(ctx context.Context, actor syntax.DID, pull *models.Pull) {} 58 58
+3 -4
appview/notify/posthog/notifier.go
··· 86 86 } 87 87 } 88 88 89 - func (n *posthogNotifier) NewPullComment(ctx context.Context, comment *models.PullComment, mentions []syntax.DID) { 89 + func (n *posthogNotifier) NewPullComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { 90 90 err := n.client.Enqueue(posthog.Capture{ 91 - DistinctId: comment.OwnerDid, 91 + DistinctId: comment.Did.String(), 92 92 Event: "new_pull_comment", 93 93 Properties: posthog.Properties{ 94 - "repo_at": comment.RepoAt, 95 - "pull_id": comment.PullId, 94 + "pull_at": comment.Subject, 96 95 "mentions": mentions, 97 96 }, 98 97 })
+3 -3
appview/pages/templates/repo/pulls/pull.html
··· 165 165 166 166 <div class="md:pl-[3.5rem] flex flex-col gap-2 mt-2 relative"> 167 167 {{ range $cidx, $c := .Comments }} 168 - <div id="comment-{{$c.ID}}" class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full"> 168 + <div id="comment-{{$c.Id}}" class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full"> 169 169 {{ if gt $cidx 0 }} 170 170 <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div> 171 171 {{ end }} 172 172 <div class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1"> 173 - {{ template "user/fragments/picHandleLink" $c.OwnerDid }} 173 + {{ template "user/fragments/picHandleLink" $c.Did.String }} 174 174 <span class="before:content-['路']"></span> 175 - <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="#comment-{{.ID}}">{{ template "repo/fragments/time" $c.Created }}</a> 175 + <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="#comment-{{.Id}}">{{ template "repo/fragments/time" $c.Created }}</a> 176 176 </div> 177 177 <div class="prose dark:prose-invert"> 178 178 {{ $c.Body | markdown }}
+1 -1
appview/pulls/opengraph.go
··· 276 276 } 277 277 278 278 // Get comment count from database 279 - comments, err := db.GetPullComments(s.db, db.FilterEq("pull_id", pull.ID)) 279 + comments, err := db.GetComments(s.db, db.FilterEq("subject_at", pull.AtUri())) 280 280 if err != nil { 281 281 log.Printf("failed to get pull comments: %v", err) 282 282 }
+24 -23
appview/pulls/pulls.go
··· 740 740 } 741 741 defer tx.Rollback() 742 742 743 - createdAt := time.Now().Format(time.RFC3339) 743 + comment := models.Comment{ 744 + Did: syntax.DID(user.Did), 745 + Rkey: tid.TID(), 746 + Subject: pull.AtUri(), 747 + ReplyTo: nil, 748 + Body: body, 749 + Created: time.Now(), 750 + Mentions: mentions, 751 + References: references, 752 + PullSubmissionId: &pull.Submissions[roundNumber].ID, 753 + } 754 + if err = comment.Validate(); err != nil { 755 + log.Println("failed to validate comment", err) 756 + s.pages.Notice(w, "pull-comment", "Failed to create comment.") 757 + return 758 + } 759 + record := comment.AsRecord() 744 760 745 761 client, err := s.oauth.AuthorizedClient(r) 746 762 if err != nil { ··· 748 764 s.pages.Notice(w, "pull-comment", "Failed to create comment.") 749 765 return 750 766 } 751 - atResp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 752 - Collection: tangled.RepoPullCommentNSID, 767 + _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 768 + Collection: tangled.CommentNSID, 753 769 Repo: user.Did, 754 - Rkey: tid.TID(), 770 + Rkey: comment.Rkey, 755 771 Record: &lexutil.LexiconTypeDecoder{ 756 - Val: &tangled.RepoPullComment{ 757 - Pull: pull.AtUri().String(), 758 - Body: body, 759 - CreatedAt: createdAt, 760 - }, 772 + Val: &record, 761 773 }, 762 774 }) 763 775 if err != nil { ··· 766 778 return 767 779 } 768 780 769 - comment := &models.PullComment{ 770 - OwnerDid: user.Did, 771 - RepoAt: f.RepoAt().String(), 772 - PullId: pull.PullId, 773 - Body: body, 774 - CommentAt: atResp.Uri, 775 - SubmissionId: pull.Submissions[roundNumber].ID, 776 - Mentions: mentions, 777 - References: references, 778 - } 779 - 780 781 // Create the pull comment in the database with the commentAt field 781 - commentId, err := db.NewPullComment(tx, comment) 782 + err = db.PutComment(tx, &comment) 782 783 if err != nil { 783 784 log.Println("failed to create pull comment", err) 784 785 s.pages.Notice(w, "pull-comment", "Failed to create comment.") ··· 792 793 return 793 794 } 794 795 795 - s.notifier.NewPullComment(r.Context(), comment, mentions) 796 + s.notifier.NewPullComment(r.Context(), &comment, mentions) 796 797 797 798 ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f) 798 - s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", ownerSlashRepo, pull.PullId, commentId)) 799 + s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", ownerSlashRepo, pull.PullId, comment.Id)) 799 800 return 800 801 } 801 802 }

History

8 rounds 4 comments
sign up or login to add to the discussion
1 commit
expand
appview: replace PullComment to Comment
2/3 timeout, 1/3 success
expand
merge conflicts detected
expand
  • appview/notify/db/db.go:260
  • appview/notify/merged_notifier.go:81
  • appview/notify/notifier.go:22
  • appview/pulls/opengraph.go:277
expand 0 comments
1 commit
expand
appview: replace PullComment to Comment
2/3 failed, 1/3 success
expand
expand 0 comments
1 commit
expand
appview: replace PullComment to Comment
3/3 success
expand
expand 0 comments
1 commit
expand
appview: replace PullComment to Comment
3/3 success
expand
expand 1 comment

here, the sort order is reversed, it should be .Before.

1 commit
expand
appview: replace PullComment to Comment
1/3 failed, 2/3 success
expand
expand 0 comments
1 commit
expand
appview: replace PullComment to Comment
1/3 failed, 2/3 success
expand
expand 0 comments
1 commit
expand
appview: replace PullComment to Comment
3/3 success
expand
expand 3 comments

here will this delete all comments made on tangled thus far? don't think this is the right approach if so.

I should've been more precise about my expression. Existing comments won't be dropped as they are stored in issue_comments and pull_comments table (I'm just dropping legacy table with same name there), but yeah this PR itself doesn't include the backward compatibility layer yet so old comments won't be rendered.

Honestly this PR hasn't been updated since you two suggested to just ingest old records. I'll push more commits on top of this stack.

As a side note: I'd suggest to not publish the new sh.tangled.comment lexicon yet.

This unified comment record can be used for PR review comments and it might make us to modify the schema again. I think it would be safest to publish this when PR redesign discussion is finished.

boltless.me submitted #0
1 commit
expand
appview: replace PullComment to Comment
3/3 success
expand
expand 0 comments