Monorepo for Tangled tangled.org
2

Configure Feed

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

appview/models: move notif target URL calculation into model

the target URL for a notif was previously calculated in the template, we
now have this in models.NotificationWithEntity.

Signed-off-by: oppiliappan <me@oppi.li>

author
oppiliappan
date (Jun 15, 2026, 2:01 PM +0100) commit 412352d6 parent d4011490 change-id yrzxrplt
+34 -17
+33
appview/models/notifications.go
··· 1 1 package models 2 2 3 3 import ( 4 + "context" 5 + "fmt" 4 6 "time" 5 7 6 8 "github.com/bluesky-social/indigo/atproto/syntax" 9 + "tangled.org/core/idresolver" 7 10 ) 8 11 9 12 type NotificationType string ··· 106 109 Repo *Repo 107 110 Issue *Issue 108 111 Pull *Pull 112 + } 113 + 114 + // URL returns the navigable path for the notification, resolving DIDs to 115 + // handles via the provided resolver. 116 + func (n *NotificationWithEntity) URL(res *idresolver.Resolver) string { 117 + resolve := func(did string) string { 118 + if id, err := res.ResolveIdent(context.Background(), did); err == nil && !id.Handle.IsInvalidHandle() { 119 + return id.Handle.String() 120 + } 121 + return did 122 + } 123 + 124 + switch n.Type { 125 + case NotificationTypeFollowed: 126 + return "/" + resolve(n.ActorDid) 127 + } 128 + if n.Repo == nil { 129 + return "" 130 + } 131 + repoHandle := resolve(n.Repo.Did) 132 + slug := n.Repo.Slug() 133 + switch { 134 + case n.Issue != nil: 135 + return fmt.Sprintf("/%s/%s/issues/%d", repoHandle, slug, n.Issue.IssueId) 136 + case n.Pull != nil: 137 + return fmt.Sprintf("/%s/%s/pulls/%d", repoHandle, slug, n.Pull.PullId) 138 + default: 139 + // repo_starred and other repo-level types 140 + return fmt.Sprintf("/%s/%s", repoHandle, slug) 141 + } 109 142 } 110 143 111 144 type NotificationPreferences struct {
+1 -17
appview/pages/templates/notifications/fragments/item.html
··· 1 1 {{define "notifications/fragments/item"}} 2 - <a href="{{ template "notificationUrl" . }}" 2 + <a href="{{ .URL resolver }}" 3 3 onclick="if(!event.target.closest('button'))navigator.sendBeacon('/notifications/{{ .ID }}/read')" 4 4 class="block no-underline hover:no-underline group"> 5 5 <div ··· 133 133 <div class="row-start-2 col-start-2 text-sm text-gray-700 dark:text-gray-300 truncate">{{ .Pull.Title }}</div> 134 134 {{ end }} 135 135 {{ end }} 136 - 137 - {{ define "notificationUrl" }} 138 - {{ $url := "" }} 139 - {{ if eq .Type "repo_starred" }} 140 - {{$url = printf "/%s/%s" (resolve .Repo.Did) .Repo.Slug}} 141 - {{ else if .Issue }} 142 - {{$url = printf "/%s/%s/issues/%d" (resolve .Repo.Did) .Repo.Slug .Issue.IssueId}} 143 - {{ else if .Pull }} 144 - {{$url = printf "/%s/%s/pulls/%d" (resolve .Repo.Did) .Repo.Slug .Pull.PullId}} 145 - {{ else if eq .Type "followed" }} 146 - {{$url = printf "/%s" (resolve .ActorDid)}} 147 - {{ else }} 148 - {{ end }} 149 - 150 - {{ $url }} 151 - {{ end }}