(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
99
fork

Configure Feed

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

fix notifications linking to the wrong thing again...

scanash00 1247426a 14adba53

+50 -15
+1 -1
backend/internal/api/handler.go
··· 515 515 return 516 516 } 517 517 518 - enriched, err := hydrateNotifications(notifications) 518 + enriched, err := hydrateNotifications(h.db, notifications) 519 519 if err != nil { 520 520 log.Printf("Failed to hydrate notifications: %v\n", err) 521 521 }
+40 -8
backend/internal/api/hydration.go
··· 118 118 } 119 119 120 120 type APINotification struct { 121 - ID int `json:"id"` 122 - Recipient Author `json:"recipient"` 123 - Actor Author `json:"actor"` 124 - Type string `json:"type"` 125 - SubjectURI string `json:"subjectUri"` 126 - CreatedAt time.Time `json:"createdAt"` 127 - ReadAt *time.Time `json:"readAt,omitempty"` 121 + ID int `json:"id"` 122 + Recipient Author `json:"recipient"` 123 + Actor Author `json:"actor"` 124 + Type string `json:"type"` 125 + SubjectURI string `json:"subjectUri"` 126 + Subject interface{} `json:"subject,omitempty"` 127 + CreatedAt time.Time `json:"createdAt"` 128 + ReadAt *time.Time `json:"readAt,omitempty"` 128 129 } 129 130 130 131 func hydrateAnnotations(annotations []db.Annotation) ([]APIAnnotation, error) { ··· 498 499 return result, nil 499 500 } 500 501 501 - func hydrateNotifications(notifications []db.Notification) ([]APINotification, error) { 502 + func hydrateNotifications(database *db.DB, notifications []db.Notification) ([]APINotification, error) { 502 503 if len(notifications) == 0 { 503 504 return []APINotification{}, nil 504 505 } ··· 518 519 519 520 profiles := fetchProfilesForDIDs(dids) 520 521 522 + replyURIs := make([]string, 0) 523 + for _, n := range notifications { 524 + if n.Type == "reply" { 525 + replyURIs = append(replyURIs, n.SubjectURI) 526 + } 527 + } 528 + 529 + replyMap := make(map[string]APIReply) 530 + if len(replyURIs) > 0 { 531 + var replies []db.Reply 532 + for _, uri := range replyURIs { 533 + r, err := database.GetReplyByURI(uri) 534 + if err == nil { 535 + replies = append(replies, *r) 536 + } 537 + } 538 + 539 + hydratedReplies, _ := hydrateReplies(replies) 540 + for _, r := range hydratedReplies { 541 + replyMap[r.ID] = r 542 + } 543 + } 544 + 521 545 result := make([]APINotification, len(notifications)) 522 546 for i, n := range notifications { 547 + var subject interface{} 548 + if n.Type == "reply" { 549 + if val, ok := replyMap[n.SubjectURI]; ok { 550 + subject = val 551 + } 552 + } 553 + 523 554 result[i] = APINotification{ 524 555 ID: n.ID, 525 556 Recipient: profiles[n.RecipientDID], 526 557 Actor: profiles[n.ActorDID], 527 558 Type: n.Type, 528 559 SubjectURI: n.SubjectURI, 560 + Subject: subject, 529 561 CreatedAt: n.CreatedAt, 530 562 ReadAt: n.ReadAt, 531 563 }
+9 -6
web/src/pages/Notifications.jsx
··· 4 4 import { getNotifications, markNotificationsRead } from "../api/client"; 5 5 import { BellIcon, HeartIcon, ReplyIcon } from "../components/Icons"; 6 6 7 - function getContentRoute(subjectUri) { 8 - if (!subjectUri) return "/"; 9 - if (subjectUri.includes("at.margin.bookmark")) { 7 + function getNotificationRoute(n) { 8 + if (n.type === "reply" && n.subject?.inReplyTo) { 9 + return `/annotation/${encodeURIComponent(n.subject.inReplyTo)}`; 10 + } 11 + if (!n.subjectUri) return "/"; 12 + if (n.subjectUri.includes("at.margin.bookmark")) { 10 13 return `/bookmarks`; 11 14 } 12 - if (subjectUri.includes("at.margin.highlight")) { 15 + if (n.subjectUri.includes("at.margin.highlight")) { 13 16 return `/highlights`; 14 17 } 15 - return `/annotation/${encodeURIComponent(subjectUri)}`; 18 + return `/annotation/${encodeURIComponent(n.subjectUri)}`; 16 19 } 17 20 18 21 export default function Notifications() { ··· 163 166 {notifications.map((n, i) => ( 164 167 <Link 165 168 key={n.id || i} 166 - to={getContentRoute(n.subjectUri)} 169 + to={getNotificationRoute(n)} 167 170 className="notification-item card" 168 171 style={{ alignItems: "center" }} 169 172 >