From 0cdf333ae8a7db5aff21d9c554fd429bd70348f4 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Mon, 08 Dec 2025 15:06:33 +0000 Subject: [PATCH] appview: replace `IssueComment` to `Comment` Signed-off-by: Seongmin Lee --- appview/ingester.go | 21 +++++++++++++++------ appview/db/issues.go | 192 ++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ appview/db/reference.go | 37 +++++++++++++------------------------ appview/issues/issues.go | 74 ++++++++++++++++++++++++++++++++++++++------------------------------------ appview/models/issue.go | 97 ++++++++----------------------------------------------------------------------------------------- appview/notify/merged_notifier.go | 2 +- appview/notify/notifier.go | 4 ++-- appview/pages/pages.go | 8 ++++---- appview/validator/issue.go | 27 --------------------------- appview/notify/db/db.go | 8 ++++---- appview/notify/posthog/notifier.go | 6 +++--- appview/pages/templates/repo/issues/fragments/commentList.html | 4 ++-- appview/pages/templates/repo/issues/fragments/issueCommentHeader.html | 4 ++-- 13 file(s) changed, 98 insertion(s)(+), 386 deletion(s)(-) diff --git a/appview/ingester.go b/appview/ingester.go --- a/appview/ingester.go +++ b/appview/ingester.go @@ -891,7 +891,7 @@ } switch e.Commit.Operation { - case jmodels.CommitOperationCreate, jmodels.CommitOperationUpdate: + case jmodels.CommitOperationUpdate: raw := json.RawMessage(e.Commit.Record) record := tangled.RepoIssueComment{} err = json.Unmarshal(raw, &record) @@ -899,12 +899,20 @@ return fmt.Errorf("invalid record: %w", err) } - comment, err := models.IssueCommentFromRecord(did, rkey, record) + // convert 'sh.tangled.repo.issue.comment' to 'sh.tangled.comment' + comment, err := models.CommentFromRecord(syntax.DID(did), syntax.RecordKey(rkey), tangled.Comment{ + Body: record.Body, + CreatedAt: record.CreatedAt, + Mentions: record.Mentions, + References: record.References, + ReplyTo: record.ReplyTo, + Subject: record.Issue, + }) if err != nil { return fmt.Errorf("failed to parse comment from record: %w", err) } - if err := i.Validator.ValidateIssueComment(comment); err != nil { + if err := comment.Validate(); err != nil { return fmt.Errorf("failed to validate comment: %w", err) } @@ -914,17 +922,18 @@ } defer tx.Rollback() - _, err = db.AddIssueComment(tx, *comment) + err = db.PutComment(tx, comment) if err != nil { - return fmt.Errorf("failed to create issue comment: %w", err) + return fmt.Errorf("failed to create comment: %w", err) } return tx.Commit() case jmodels.CommitOperationDelete: - if err := db.DeleteIssueComments( + if err := db.DeleteComments( ddb, orm.FilterEq("did", did), + orm.FilterEq("collection", e.Commit.Collection), orm.FilterEq("rkey", rkey), ); err != nil { return fmt.Errorf("failed to delete issue comment record: %w", err) diff --git a/appview/db/issues.go b/appview/db/issues.go --- a/appview/db/issues.go +++ b/appview/db/issues.go @@ -100,7 +100,7 @@ } func GetIssuesPaginated(e Execer, page pagination.Page, filters ...orm.Filter) ([]models.Issue, error) { - issueMap := make(map[string]*models.Issue) // at-uri -> issue + issueMap := make(map[syntax.ATURI]*models.Issue) // at-uri -> issue var conditions []string var args []any @@ -196,8 +196,7 @@ } } - atUri := issue.AtUri().String() - issueMap[atUri] = &issue + issueMap[issue.AtUri()] = &issue } // collect reverse repos @@ -229,12 +228,12 @@ // collect comments issueAts := slices.Collect(maps.Keys(issueMap)) - comments, err := GetIssueComments(e, orm.FilterIn("issue_at", issueAts)) + comments, err := GetComments(e, orm.FilterIn("subject_at", issueAts)) if err != nil { return nil, fmt.Errorf("failed to query comments: %w", err) } for i := range comments { - issueAt := comments[i].IssueAt + issueAt := comments[i].Subject if issue, ok := issueMap[issueAt]; ok { issue.Comments = append(issue.Comments, comments[i]) } @@ -246,7 +245,7 @@ return nil, fmt.Errorf("failed to query labels: %w", err) } for issueAt, labels := range allLabels { - if issue, ok := issueMap[issueAt.String()]; ok { + if issue, ok := issueMap[issueAt]; ok { issue.Labels = labels } } @@ -257,7 +256,7 @@ return nil, fmt.Errorf("failed to query reference_links: %w", err) } for issueAt, references := range allReferencs { - if issue, ok := issueMap[issueAt.String()]; ok { + if issue, ok := issueMap[issueAt]; ok { issue.References = references } } @@ -293,185 +292,6 @@ func GetIssues(e Execer, filters ...orm.Filter) ([]models.Issue, error) { return GetIssuesPaginated(e, pagination.Page{}, filters...) -} - -func AddIssueComment(tx *sql.Tx, c models.IssueComment) (int64, error) { - result, err := tx.Exec( - `insert into issue_comments ( - did, - rkey, - issue_at, - body, - reply_to, - created, - edited - ) - values (?, ?, ?, ?, ?, ?, null) - on conflict(did, rkey) do update set - issue_at = excluded.issue_at, - body = excluded.body, - edited = case - when - issue_comments.issue_at != excluded.issue_at - or issue_comments.body != excluded.body - or issue_comments.reply_to != excluded.reply_to - then ? - else issue_comments.edited - end`, - c.Did, - c.Rkey, - c.IssueAt, - c.Body, - c.ReplyTo, - c.Created.Format(time.RFC3339), - time.Now().Format(time.RFC3339), - ) - if err != nil { - return 0, err - } - - id, err := result.LastInsertId() - if err != nil { - return 0, err - } - - if err := putReferences(tx, c.AtUri(), c.References); err != nil { - return 0, fmt.Errorf("put reference_links: %w", err) - } - - return id, nil -} - -func DeleteIssueComments(e Execer, filters ...orm.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 issue_comments set body = "", deleted = strftime('%%Y-%%m-%%dT%%H:%%M:%%SZ', 'now') %s`, whereClause) - - _, err := e.Exec(query, args...) - return err -} - -func GetIssueComments(e Execer, filters ...orm.Filter) ([]models.IssueComment, error) { - commentMap := make(map[string]*models.IssueComment) - - 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, - issue_at, - reply_to, - body, - created, - edited, - deleted - from - issue_comments - %s - `, whereClause) - - rows, err := e.Query(query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var comment models.IssueComment - var created string - var rkey, edited, deleted, replyTo sql.Null[string] - err := rows.Scan( - &comment.Id, - &comment.Did, - &rkey, - &comment.IssueAt, - &replyTo, - &comment.Body, - &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 { - comment.ReplyTo = &replyTo.V - } - - 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, orm.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.IssueComment - 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 } func DeleteIssues(tx *sql.Tx, did, rkey string) error { diff --git a/appview/db/reference.go b/appview/db/reference.go --- a/appview/db/reference.go +++ b/appview/db/reference.go @@ -11,7 +11,7 @@ "tangled.org/core/orm" ) -// ValidateReferenceLinks resolves refLinks to Issue/PR/IssueComment/PullComment ATURIs. +// ValidateReferenceLinks resolves refLinks to Issue/PR/Comment ATURIs. // It will ignore missing refLinks. func ValidateReferenceLinks(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATURI, error) { var ( @@ -53,8 +53,7 @@ values %s ) select - i.did, i.rkey, - c.did, c.rkey + i.at_uri, c.at_uri from input inp join repos r on r.did = inp.owner_did @@ -62,9 +61,9 @@ join issues i on i.repo_at = r.at_uri and i.issue_id = inp.issue_id - left join issue_comments c + left join comments c on inp.comment_id is not null - and c.issue_at = i.at_uri + and c.subject_at = i.at_uri and c.id = inp.comment_id `, strings.Join(vals, ","), @@ -79,26 +78,16 @@ for rows.Next() { // Scan rows - var issueOwner, issueRkey string - var commentOwner, commentRkey sql.NullString + var issueUri string + var commentUri sql.NullString var uri syntax.ATURI - if err := rows.Scan(&issueOwner, &issueRkey, &commentOwner, &commentRkey); err != nil { + if err := rows.Scan(&issueUri, &commentUri); err != nil { return nil, err } - if commentOwner.Valid && commentRkey.Valid { - uri = syntax.ATURI(fmt.Sprintf( - "at://%s/%s/%s", - commentOwner.String, - tangled.RepoIssueCommentNSID, - commentRkey.String, - )) + if commentUri.Valid { + uri = syntax.ATURI(commentUri.String) } else { - uri = syntax.ATURI(fmt.Sprintf( - "at://%s/%s/%s", - issueOwner, - tangled.RepoIssueNSID, - issueRkey, - )) + uri = syntax.ATURI(issueUri) } uris = append(uris, uri) } @@ -282,7 +271,7 @@ return nil, fmt.Errorf("get issue backlinks: %w", err) } backlinks = append(backlinks, ls...) - ls, err = getIssueCommentBacklinks(e, backlinksMap[tangled.RepoIssueCommentNSID]) + ls, err = getIssueCommentBacklinks(e, backlinksMap[tangled.CommentNSID]) if err != nil { return nil, fmt.Errorf("get issue_comment backlinks: %w", err) } @@ -351,9 +340,9 @@ rows, err := e.Query( fmt.Sprintf( `select r.did, r.name, i.issue_id, c.id, i.title, i.open - from issue_comments c + from comments c join issues i - on i.at_uri = c.issue_at + on i.at_uri = c.subject_at join repos r on r.at_uri = i.repo_at where %s`, diff --git a/appview/issues/issues.go b/appview/issues/issues.go --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -402,34 +402,39 @@ body := r.FormValue("body") if body == "" { - rp.pages.Notice(w, "issue", "Body is required") + rp.pages.Notice(w, "issue-comment", "Body is required") return } - replyToUri := r.FormValue("reply-to") - var replyTo *string - if replyToUri != "" { - replyTo = &replyToUri + var replyTo *syntax.ATURI + replyToRaw := r.FormValue("reply-to") + if replyToRaw != "" { + aturi, err := syntax.ParseATURI(replyToRaw) + if err != nil { + rp.pages.Notice(w, "issue-comment", "reply-to should be valid AT-URI") + return + } + replyTo = &aturi } mentions, references := rp.mentionsResolver.Resolve(r.Context(), body) - comment := models.IssueComment{ - Did: user.Active.Did, + comment := models.Comment{ + Did: syntax.DID(user.Active.Did), + Collection: tangled.CommentNSID, Rkey: tid.TID(), - IssueAt: issue.AtUri().String(), + Subject: issue.AtUri(), ReplyTo: replyTo, Body: body, Created: time.Now(), Mentions: mentions, References: references, } - if err = rp.validator.ValidateIssueComment(&comment); err != nil { + if err = comment.Validate(); err != nil { l.Error("failed to validate comment", "err", err) rp.pages.Notice(w, "issue-comment", "Failed to create comment.") return } - record := comment.AsRecord() client, err := rp.oauth.AuthorizedClient(r) if err != nil { @@ -440,11 +445,11 @@ // create a record first resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ - Collection: tangled.RepoIssueCommentNSID, - Repo: comment.Did, + Collection: comment.Collection.String(), + Repo: comment.Did.String(), Rkey: comment.Rkey, Record: &lexutil.LexiconTypeDecoder{ - Val: &record, + Val: comment.AsRecord(), }, }) if err != nil { @@ -467,7 +472,7 @@ } defer tx.Rollback() - commentId, err := db.AddIssueComment(tx, comment) + err = db.PutComment(tx, &comment) if err != nil { l.Error("failed to create comment", "err", err) rp.pages.Notice(w, "issue-comment", "Failed to create comment.") @@ -483,13 +488,10 @@ // reset atUri to make rollback a no-op atUri = "" - // notify about the new comment - comment.Id = commentId - rp.notifier.NewIssueComment(r.Context(), &comment, mentions) ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f) - rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d#comment-%d", ownerSlashRepo, issue.IssueId, commentId)) + rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d#comment-%d", ownerSlashRepo, issue.IssueId, comment.Id)) } func (rp *Issues) IssueComment(w http.ResponseWriter, r *http.Request) { @@ -504,7 +506,7 @@ } commentId := chi.URLParam(r, "commentId") - comments, err := db.GetIssueComments( + comments, err := db.GetComments( rp.db, orm.FilterEq("id", commentId), ) @@ -540,7 +542,7 @@ } commentId := chi.URLParam(r, "commentId") - comments, err := db.GetIssueComments( + comments, err := db.GetComments( rp.db, orm.FilterEq("id", commentId), ) @@ -556,7 +558,7 @@ } comment := comments[0] - if comment.Did != user.Active.Did { + if comment.Did.String() != user.Active.Did { l.Error("unauthorized comment edit", "expectedDid", comment.Did, "gotDid", user.Active.Did) http.Error(w, "you are not the author of this comment", http.StatusUnauthorized) return @@ -586,8 +588,6 @@ newComment.Edited = &now newComment.Mentions, newComment.References = rp.mentionsResolver.Resolve(r.Context(), newBody) - record := newComment.AsRecord() - tx, err := rp.db.Begin() if err != nil { l.Error("failed to start transaction", "err", err) @@ -596,7 +596,7 @@ } defer tx.Rollback() - _, err = db.AddIssueComment(tx, newComment) + err = db.PutComment(tx, &newComment) if err != nil { l.Error("failed to perferom update-description query", "err", err) rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") @@ -606,21 +606,23 @@ // rkey is optional, it was introduced later if newComment.Rkey != "" { + // TODO: update correct comment + // update the record on pds - ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Active.Did, comment.Rkey) + ex, err := comatproto.RepoGetRecord(r.Context(), client, "", newComment.Collection.String(), newComment.Did.String(), newComment.Rkey) if err != nil { l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey) - rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.") + rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update comment, no record found on PDS.") return } _, err = comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ - Collection: tangled.RepoIssueCommentNSID, - Repo: user.Active.Did, + Collection: newComment.Collection.String(), + Repo: newComment.Did.String(), Rkey: newComment.Rkey, SwapRecord: ex.Cid, Record: &lexutil.LexiconTypeDecoder{ - Val: &record, + Val: newComment.AsRecord(), }, }) if err != nil { @@ -650,7 +652,7 @@ } commentId := chi.URLParam(r, "commentId") - comments, err := db.GetIssueComments( + comments, err := db.GetComments( rp.db, orm.FilterEq("id", commentId), ) @@ -686,7 +688,7 @@ } commentId := chi.URLParam(r, "commentId") - comments, err := db.GetIssueComments( + comments, err := db.GetComments( rp.db, orm.FilterEq("id", commentId), ) @@ -722,7 +724,7 @@ } commentId := chi.URLParam(r, "commentId") - comments, err := db.GetIssueComments( + comments, err := db.GetComments( rp.db, orm.FilterEq("id", commentId), ) @@ -738,7 +740,7 @@ } comment := comments[0] - if comment.Did != user.Active.Did { + if comment.Did.String() != user.Active.Did { l.Error("unauthorized action", "expectedDid", comment.Did, "gotDid", user.Active.Did) http.Error(w, "you are not the author of this comment", http.StatusUnauthorized) return @@ -751,7 +753,7 @@ // optimistic deletion deleted := time.Now() - err = db.DeleteIssueComments(rp.db, orm.FilterEq("id", comment.Id)) + err = db.DeleteComments(rp.db, orm.FilterEq("id", comment.Id)) if err != nil { l.Error("failed to delete comment", "err", err) rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "failed to delete comment") @@ -767,8 +769,8 @@ return } _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{ - Collection: tangled.RepoIssueCommentNSID, - Repo: user.Active.Did, + Collection: comment.Collection.String(), + Repo: comment.Did.String(), Rkey: comment.Rkey, }) if err != nil { diff --git a/appview/models/issue.go b/appview/models/issue.go --- a/appview/models/issue.go +++ b/appview/models/issue.go @@ -26,7 +26,7 @@ // optionally, populate this when querying for reverse mappings // like comment counts, parent repo etc. - Comments []IssueComment + Comments []Comment Labels LabelState Repo *Repo } @@ -62,8 +62,8 @@ } type CommentListItem struct { - Self *IssueComment - Replies []*IssueComment + Self *Comment + Replies []*Comment } func (it *CommentListItem) Participants() []syntax.DID { @@ -88,13 +88,13 @@ func (i *Issue) CommentList() []CommentListItem { // Create a map to quickly find comments by their aturi - toplevel := make(map[string]*CommentListItem) - var replies []*IssueComment + toplevel := make(map[syntax.ATURI]*CommentListItem) + var replies []*Comment // collect top level comments into the map for _, comment := range i.Comments { if comment.IsTopLevel() { - toplevel[comment.AtUri().String()] = &CommentListItem{ + toplevel[comment.AtUri()] = &CommentListItem{ Self: &comment, } } else { @@ -115,7 +115,7 @@ } // sort everything - sortFunc := func(a, b *IssueComment) bool { + sortFunc := func(a, b *Comment) bool { return a.Created.Before(b.Created) } sort.Slice(listing, func(i, j int) bool { @@ -144,7 +144,7 @@ addParticipant(i.Did) for _, c := range i.Comments { - addParticipant(c.Did) + addParticipant(c.Did.String()) } return participants @@ -170,85 +170,4 @@ Body: body, Open: true, // new issues are open by default } -} - -type IssueComment struct { - Id int64 - Did string - Rkey string - IssueAt string - ReplyTo *string - Body string - Created time.Time - Edited *time.Time - Deleted *time.Time - Mentions []syntax.DID - References []syntax.ATURI -} - -func (i *IssueComment) AtUri() syntax.ATURI { - return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", i.Did, tangled.RepoIssueCommentNSID, i.Rkey)) -} - -func (i *IssueComment) AsRecord() tangled.RepoIssueComment { - mentions := make([]string, len(i.Mentions)) - for i, did := range i.Mentions { - mentions[i] = string(did) - } - references := make([]string, len(i.References)) - for i, uri := range i.References { - references[i] = string(uri) - } - return tangled.RepoIssueComment{ - Body: i.Body, - Issue: i.IssueAt, - CreatedAt: i.Created.Format(time.RFC3339), - ReplyTo: i.ReplyTo, - Mentions: mentions, - References: references, - } -} - -func (i *IssueComment) IsTopLevel() bool { - return i.ReplyTo == nil -} - -func (i *IssueComment) IsReply() bool { - return i.ReplyTo != nil -} - -func IssueCommentFromRecord(did, rkey string, record tangled.RepoIssueComment) (*IssueComment, error) { - created, err := time.Parse(time.RFC3339, record.CreatedAt) - if err != nil { - created = time.Now() - } - - ownerDid := did - - if _, err = syntax.ParseATURI(record.Issue); 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) - } - - comment := IssueComment{ - Did: ownerDid, - Rkey: rkey, - Body: record.Body, - IssueAt: record.Issue, - ReplyTo: record.ReplyTo, - Created: created, - Mentions: mentions, - References: references, - } - - return &comment, nil } diff --git a/appview/notify/merged_notifier.go b/appview/notify/merged_notifier.go --- a/appview/notify/merged_notifier.go +++ b/appview/notify/merged_notifier.go @@ -57,7 +57,7 @@ m.fanout("NewIssue", ctx, issue, mentions) } -func (m *mergedNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) { +func (m *mergedNotifier) NewIssueComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { m.fanout("NewIssueComment", ctx, comment, mentions) } diff --git a/appview/notify/notifier.go b/appview/notify/notifier.go --- a/appview/notify/notifier.go +++ b/appview/notify/notifier.go @@ -14,7 +14,7 @@ DeleteStar(ctx context.Context, star *models.Star) NewIssue(ctx context.Context, issue *models.Issue, mentions []syntax.DID) - NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) + NewIssueComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) NewIssueState(ctx context.Context, actor syntax.DID, issue *models.Issue) DeleteIssue(ctx context.Context, issue *models.Issue) @@ -43,7 +43,7 @@ func (m *BaseNotifier) DeleteStar(ctx context.Context, star *models.Star) {} func (m *BaseNotifier) NewIssue(ctx context.Context, issue *models.Issue, mentions []syntax.DID) {} -func (m *BaseNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) { +func (m *BaseNotifier) NewIssueComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { } func (m *BaseNotifier) NewIssueState(ctx context.Context, actor syntax.DID, issue *models.Issue) {} func (m *BaseNotifier) DeleteIssue(ctx context.Context, issue *models.Issue) {} diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -1004,7 +1004,7 @@ LoggedInUser *oauth.MultiAccountUser RepoInfo repoinfo.RepoInfo Issue *models.Issue - Comment *models.IssueComment + Comment *models.Comment } func (p *Pages) EditIssueCommentFragment(w io.Writer, params EditIssueCommentParams) error { @@ -1015,7 +1015,7 @@ LoggedInUser *oauth.MultiAccountUser RepoInfo repoinfo.RepoInfo Issue *models.Issue - Comment *models.IssueComment + Comment *models.Comment } func (p *Pages) ReplyIssueCommentPlaceholderFragment(w io.Writer, params ReplyIssueCommentPlaceholderParams) error { @@ -1026,7 +1026,7 @@ LoggedInUser *oauth.MultiAccountUser RepoInfo repoinfo.RepoInfo Issue *models.Issue - Comment *models.IssueComment + Comment *models.Comment } func (p *Pages) ReplyIssueCommentFragment(w io.Writer, params ReplyIssueCommentParams) error { @@ -1037,7 +1037,7 @@ LoggedInUser *oauth.MultiAccountUser RepoInfo repoinfo.RepoInfo Issue *models.Issue - Comment *models.IssueComment + Comment *models.Comment } func (p *Pages) IssueCommentBodyFragment(w io.Writer, params IssueCommentBodyParams) error { diff --git a/appview/validator/issue.go b/appview/validator/issue.go --- a/appview/validator/issue.go +++ b/appview/validator/issue.go @@ -4,35 +4,8 @@ "fmt" "strings" - "tangled.org/core/appview/db" "tangled.org/core/appview/models" - "tangled.org/core/orm" ) - -func (v *Validator) ValidateIssueComment(comment *models.IssueComment) error { - // if comments have parents, only ingest ones that are 1 level deep - if comment.ReplyTo != nil { - parents, err := db.GetIssueComments(v.db, orm.FilterEq("at_uri", *comment.ReplyTo)) - if err != nil { - return fmt.Errorf("failed to fetch parent comment: %w", err) - } - if len(parents) != 1 { - return fmt.Errorf("incorrect number of parent comments returned: %d", len(parents)) - } - - // depth check - parent := parents[0] - if parent.ReplyTo != nil { - return fmt.Errorf("incorrect depth, this comment is replying at depth >1") - } - } - - if sb := strings.TrimSpace(v.sanitizer.SanitizeDefault(comment.Body)); sb == "" { - return fmt.Errorf("body is empty after HTML sanitization") - } - - return nil -} func (v *Validator) ValidateIssue(issue *models.Issue) error { if issue.Title == "" { diff --git a/appview/notify/db/db.go b/appview/notify/db/db.go --- a/appview/notify/db/db.go +++ b/appview/notify/db/db.go @@ -122,14 +122,14 @@ ) } -func (n *databaseNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) { - issues, err := db.GetIssues(n.db, orm.FilterEq("at_uri", comment.IssueAt)) +func (n *databaseNotifier) NewIssueComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { + issues, err := db.GetIssues(n.db, orm.FilterEq("at_uri", comment.Subject)) if err != nil { log.Printf("NewIssueComment: failed to get issues: %v", err) return } if len(issues) == 0 { - log.Printf("NewIssueComment: no issue found for %s", comment.IssueAt) + log.Printf("NewIssueComment: no issue found for %s", comment.Subject) return } issue := issues[0] @@ -147,7 +147,7 @@ // find the parent thread, and add all DIDs from here to the recipient list for _, t := range issue.CommentList() { - if t.Self.AtUri().String() == parentAtUri { + if t.Self.AtUri() == parentAtUri { for _, p := range t.Participants() { recipients.Insert(p) } diff --git a/appview/notify/posthog/notifier.go b/appview/notify/posthog/notifier.go --- a/appview/notify/posthog/notifier.go +++ b/appview/notify/posthog/notifier.go @@ -179,12 +179,12 @@ } } -func (n *posthogNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) { +func (n *posthogNotifier) NewIssueComment(ctx context.Context, comment *models.Comment, mentions []syntax.DID) { err := n.client.Enqueue(posthog.Capture{ - DistinctId: comment.Did, + DistinctId: comment.Did.String(), Event: "new_issue_comment", Properties: posthog.Properties{ - "issue_at": comment.IssueAt, + "issue_at": comment.Subject, "mentions": mentions, }, }) diff --git a/appview/pages/templates/repo/issues/fragments/commentList.html b/appview/pages/templates/repo/issues/fragments/commentList.html --- a/appview/pages/templates/repo/issues/fragments/commentList.html +++ b/appview/pages/templates/repo/issues/fragments/commentList.html @@ -41,7 +41,7 @@ {{ define "topLevelComment" }}
- {{ template "user/fragments/picLink" (list .Comment.Did "size-8 mr-1") }} + {{ template "user/fragments/picLink" (list .Comment.Did.String "size-8 mr-1") }}
{{ template "repo/issues/fragments/issueCommentHeader" . }} @@ -53,7 +53,7 @@ {{ define "replyComment" }}
- {{ template "user/fragments/picLink" (list .Comment.Did "size-8 mr-1") }} + {{ template "user/fragments/picLink" (list .Comment.Did.String "size-8 mr-1") }}
{{ template "repo/issues/fragments/issueCommentHeader" . }} diff --git a/appview/pages/templates/repo/issues/fragments/issueCommentHeader.html b/appview/pages/templates/repo/issues/fragments/issueCommentHeader.html --- a/appview/pages/templates/repo/issues/fragments/issueCommentHeader.html +++ b/appview/pages/templates/repo/issues/fragments/issueCommentHeader.html @@ -1,11 +1,11 @@ {{ define "repo/issues/fragments/issueCommentHeader" }}
- {{ $handle := resolve .Comment.Did }} + {{ $handle := resolve .Comment.Did.String }} {{ $handle }} {{ template "hats" $ }} {{ template "timestamp" . }} - {{ $isCommentOwner := and .LoggedInUser (eq .LoggedInUser.Did .Comment.Did) }} + {{ $isCommentOwner := and .LoggedInUser (eq .LoggedInUser.Did .Comment.Did.String) }} {{ if and $isCommentOwner (not .Comment.Deleted) }} {{ template "editIssueComment" . }} {{ template "deleteIssueComment" . }} -- tangled.sh