Monorepo for Tangled tangled.org
859
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview: link issue/pull comment notifications to anchor #340

Store comment_id on notifications and use it to deep-link to the specific comment via #comment- on the issue/pull page. Add scroll-margin and a target highlight so the linked comment is visible and emphasized.

Signed-off-by: eti eti@eti.tf

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:xu5apv6kmu5jp7g5hwdnej42/sh.tangled.repo.pull/3ml7exebrg322
+53 -17
Diff #0
+5
appview/db/db.go
··· 1475 1475 return err 1476 1476 }) 1477 1477 1478 + orm.RunMigration(conn, logger, "add-comment-id-to-notifications", func(tx *sql.Tx) error { 1479 + _, err := tx.Exec(`alter table notifications add column comment_id integer;`) 1480 + return err 1481 + }) 1482 + 1478 1483 return &DB{ 1479 1484 db, 1480 1485 logger,
+7 -5
appview/db/notifications.go
··· 16 16 17 17 func CreateNotification(e Execer, notification *models.Notification) error { 18 18 query := ` 19 - INSERT INTO notifications (recipient_did, actor_did, type, entity_type, entity_id, read, repo_id, issue_id, pull_id) 20 - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) 19 + INSERT INTO notifications (recipient_did, actor_did, type, entity_type, entity_id, read, repo_id, issue_id, pull_id, comment_id) 20 + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 21 21 ` 22 22 23 23 result, err := e.Exec(query, ··· 30 30 notification.RepoId, 31 31 notification.IssueId, 32 32 notification.PullId, 33 + notification.CommentId, 33 34 ) 34 35 if err != nil { 35 36 return fmt.Errorf("failed to create notification: %w", err) ··· 68 69 } 69 70 70 71 query := fmt.Sprintf(` 71 - select id, recipient_did, actor_did, type, entity_type, entity_id, read, created, repo_id, issue_id, pull_id 72 + select id, recipient_did, actor_did, type, entity_type, entity_id, read, created, repo_id, issue_id, pull_id, comment_id 72 73 from notifications 73 74 %s 74 75 order by created desc ··· 98 99 &n.RepoId, 99 100 &n.IssueId, 100 101 &n.PullId, 102 + &n.CommentId, 101 103 ) 102 104 if err != nil { 103 105 return nil, fmt.Errorf("failed to scan notification: %w", err) ··· 134 136 query := fmt.Sprintf(` 135 137 select 136 138 n.id, n.recipient_did, n.actor_did, n.type, n.entity_type, n.entity_id, 137 - n.read, n.created, n.repo_id, n.issue_id, n.pull_id, 139 + n.read, n.created, n.repo_id, n.issue_id, n.pull_id, n.comment_id, 138 140 r.id as r_id, r.did as r_did, r.name as r_name, r.description as r_description, r.website as r_website, r.topics as r_topics, 139 141 i.id as i_id, i.did as i_did, i.issue_id as i_issue_id, i.title as i_title, i.open as i_open, 140 142 p.id as p_id, p.owner_did as p_owner_did, p.pull_id as p_pull_id, p.title as p_title, p.state as p_state ··· 176 178 177 179 err := rows.Scan( 178 180 &n.ID, &n.RecipientDid, &n.ActorDid, &typeStr, &n.EntityType, &n.EntityId, 179 - &n.Read, &createdStr, &n.RepoId, &n.IssueId, &n.PullId, 181 + &n.Read, &createdStr, &n.RepoId, &n.IssueId, &n.PullId, &n.CommentId, 180 182 &rId, &rDid, &rName, &rDescription, &rWebsite, &rTopicStr, 181 183 &iId, &iDid, &iIssueId, &iTitle, &iOpen, 182 184 &pId, &pOwnerDid, &pPullId, &pTitle, &pState,
+4 -3
appview/models/notifications.go
··· 34 34 Created time.Time 35 35 36 36 // foreign key references 37 - RepoId *int64 38 - IssueId *int64 39 - PullId *int64 37 + RepoId *int64 38 + IssueId *int64 39 + PullId *int64 40 + CommentId *int64 40 41 } 41 42 42 43 // lucide icon that represents this notification
+1 -1
appview/models/pull.go
··· 308 308 309 309 type PullComment struct { 310 310 // ids 311 - ID int 311 + ID int64 312 312 PullId int 313 313 SubmissionId int 314 314
+21 -1
appview/notify/db/db.go
··· 62 62 repoId := &repo.Id 63 63 var issueId *int64 64 64 var pullId *int64 65 + var commentId *int64 65 66 66 67 n.notifyEvent( 67 68 ctx, ··· 73 74 repoId, 74 75 issueId, 75 76 pullId, 77 + commentId, 76 78 ) 77 79 } 78 80 ··· 107 109 repoId := &issue.Repo.Id 108 110 issueId := &issue.Id 109 111 var pullId *int64 112 + var commentId *int64 110 113 111 114 n.notifyEvent( 112 115 ctx, ··· 118 121 repoId, 119 122 issueId, 120 123 pullId, 124 + commentId, 121 125 ) 122 126 n.notifyEvent( 123 127 ctx, ··· 129 133 repoId, 130 134 issueId, 131 135 pullId, 136 + commentId, 132 137 ) 133 138 } 134 139 ··· 180 185 repoId := &issue.Repo.Id 181 186 issueId := &issue.Id 182 187 var pullId *int64 188 + commentId := &comment.Id 183 189 184 190 n.notifyEvent( 185 191 ctx, ··· 191 197 repoId, 192 198 issueId, 193 199 pullId, 200 + commentId, 194 201 ) 195 202 n.notifyEvent( 196 203 ctx, ··· 202 209 repoId, 203 210 issueId, 204 211 pullId, 212 + commentId, 205 213 ) 206 214 } 207 215 ··· 218 226 eventType := models.NotificationTypeFollowed 219 227 entityType := "follow" 220 228 entityId := follow.UserDid 221 - var repoId, issueId, pullId *int64 229 + var repoId, issueId, pullId, commentId *int64 222 230 223 231 n.notifyEvent( 224 232 ctx, ··· 230 238 repoId, 231 239 issueId, 232 240 pullId, 241 + commentId, 233 242 ) 234 243 } 235 244 ··· 267 276 var issueId *int64 268 277 p := int64(pull.ID) 269 278 pullId := &p 279 + var commentId *int64 270 280 271 281 n.notifyEvent( 272 282 ctx, ··· 278 288 repoId, 279 289 issueId, 280 290 pullId, 291 + commentId, 281 292 ) 282 293 } 283 294 ··· 319 330 var issueId *int64 320 331 p := int64(pull.ID) 321 332 pullId := &p 333 + commentId := &comment.ID 322 334 323 335 n.notifyEvent( 324 336 ctx, ··· 330 342 repoId, 331 343 issueId, 332 344 pullId, 345 + commentId, 333 346 ) 334 347 n.notifyEvent( 335 348 ctx, ··· 341 354 repoId, 342 355 issueId, 343 356 pullId, 357 + commentId, 344 358 ) 345 359 } 346 360 ··· 394 408 repoId := &issue.Repo.Id 395 409 issueId := &issue.Id 396 410 var pullId *int64 411 + var commentId *int64 397 412 var eventType models.NotificationType 398 413 399 414 if issue.Open { ··· 412 427 repoId, 413 428 issueId, 414 429 pullId, 430 + commentId, 415 431 ) 416 432 } 417 433 ··· 460 476 } 461 477 p := int64(pull.ID) 462 478 pullId := &p 479 + var commentId *int64 463 480 464 481 n.notifyEvent( 465 482 ctx, ··· 471 488 repoId, 472 489 issueId, 473 490 pullId, 491 + commentId, 474 492 ) 475 493 } 476 494 ··· 484 502 repoId *int64, 485 503 issueId *int64, 486 504 pullId *int64, 505 + commentId *int64, 487 506 ) { 488 507 l := log.FromContext(ctx) 489 508 ··· 533 552 RepoId: repoId, 534 553 IssueId: issueId, 535 554 PullId: pullId, 555 + CommentId: commentId, 536 556 } 537 557 538 558 if err := db.CreateNotification(tx, notif); err != nil {
+10 -2
appview/pages/templates/notifications/fragments/item.html
··· 78 78 {{ if eq .Type "repo_starred" }} 79 79 {{$url = printf "/%s/%s" (resolve .Repo.Did) .Repo.Name}} 80 80 {{ else if .Issue }} 81 - {{$url = printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId}} 81 + {{ if .CommentId }} 82 + {{$url = printf "/%s/%s/issues/%d#comment-%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId (deref .CommentId)}} 83 + {{ else }} 84 + {{$url = printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Name .Issue.IssueId}} 85 + {{ end }} 82 86 {{ else if .Pull }} 83 - {{$url = printf "/%s/%s/pulls/%d" (resolve .Repo.Did) .Repo.Name .Pull.PullId}} 87 + {{ if .CommentId }} 88 + {{$url = printf "/%s/%s/pulls/%d#comment-%d" (resolve .Repo.Did) .Repo.Name .Pull.PullId (deref .CommentId)}} 89 + {{ else }} 90 + {{$url = printf "/%s/%s/pulls/%d" (resolve .Repo.Did) .Repo.Name .Pull.PullId}} 91 + {{ end }} 84 92 {{ else if eq .Type "followed" }} 85 93 {{$url = printf "/%s" (resolve .ActorDid)}} 86 94 {{ else }}
+2 -2
appview/pages/templates/repo/issues/fragments/commentList.html
··· 42 42 {{ end }} 43 43 44 44 {{ define "topLevelComment" }} 45 - <div class="rounded px-6 py-4 bg-white dark:bg-gray-800 flex gap-2 "> 45 + <div id="comment-{{ .Comment.Id }}" class="rounded px-6 py-4 bg-white dark:bg-gray-800 flex gap-2 group/comment md:scroll-mt-52"> 46 46 <div class="flex-shrink-0"> 47 47 {{ template "user/fragments/picLink" (list .Comment.Did "size-8 mr-1" .VouchRelationship) }} 48 48 </div> ··· 54 54 {{ end }} 55 55 56 56 {{ define "replyComment" }} 57 - <div class="py-4 pr-4 w-full mx-auto overflow-hidden flex gap-2 "> 57 + <div id="comment-{{ .Comment.Id }}" class="py-4 pr-4 w-full mx-auto overflow-hidden flex gap-2 group/comment md:scroll-mt-52"> 58 58 <div class="flex-shrink-0"> 59 59 {{ template "user/fragments/picLink" (list .Comment.Did "size-8 mr-1" .VouchRelationship) }} 60 60 </div>
+2 -3
appview/pages/templates/repo/issues/fragments/issueCommentHeader.html
··· 1 1 {{ define "repo/issues/fragments/issueCommentHeader" }} 2 - <div class="flex flex-wrap items-center gap-2 text-sm text-gray-500 dark:text-gray-400 "> 2 + <div class="flex flex-wrap items-center gap-2 text-sm text-gray-500 dark:text-gray-400 group-target/comment:bg-yellow-200/30 group-target/comment:dark:bg-yellow-600/30"> 3 3 {{ $handle := resolve .Comment.Did }} 4 4 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="/{{ $handle }}">{{ $handle }}</a> 5 5 {{ template "hats" $ }} ··· 22 22 23 23 {{ define "timestamp" }} 24 24 <a href="#comment-{{ .Comment.Id }}" 25 - class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-400 hover:underline no-underline" 26 - id="comment-{{ .Comment.Id }}"> 25 + class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-400 hover:underline no-underline"> 27 26 {{ if .Comment.Deleted }} 28 27 {{ template "repo/fragments/shortTimeAgo" .Comment.Deleted }} 29 28 {{ else if .Comment.Edited }}
+1
appview/pulls/comment.go
··· 127 127 return 128 128 } 129 129 130 + comment.ID = commentId 130 131 s.notifier.NewPullComment(r.Context(), comment, mentions) 131 132 132 133 ownerSlashRepo := reporesolver.GetBaseRepoPath(r, f)

History

1 round 0 comments
sign up or login to add to the discussion
eti.tf submitted #0
1 commit
expand
appview: link issue/pull comment notifications to anchor
merge conflicts detected
expand
  • appview/db/notifications.go:134
  • appview/pages/templates/notifications/fragments/item.html:78
expand 0 comments