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

Configure Feed

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

add repair-on-read for missing annotation cids

scanash00 6d019a50 ae1828a5

+90 -12
+86
backend/internal/api/handler.go
··· 619 619 } 620 620 621 621 if annotation, err := h.db.GetAnnotationByURI(uri); err == nil { 622 + if annotation.CID == nil || *annotation.CID == "" { 623 + parts := parseATURI(uri) 624 + if len(parts) >= 3 { 625 + did := parts[0] 626 + collection := parts[1] 627 + rkey := parts[2] 628 + 629 + session, err := h.refresher.GetSessionWithAutoRefresh(r) 630 + if err == nil { 631 + _ = h.refresher.ExecuteWithAutoRefresh(r, session, func(client *xrpc.Client, _ string) error { 632 + record, getErr := client.GetRecord(r.Context(), did, collection, rkey) 633 + if getErr == nil { 634 + h.db.UpdateAnnotation(uri, *annotation.BodyValue, *annotation.TagsJSON, record.CID) 635 + cid := record.CID 636 + annotation.CID = &cid 637 + } 638 + return nil 639 + }) 640 + } 641 + } 642 + } 643 + 622 644 if enriched, _ := hydrateAnnotations(h.db, []db.Annotation{*annotation}, h.getViewerDID(r)); len(enriched) > 0 { 623 645 serveResponse(enriched[0], "http://www.w3.org/ns/anno.jsonld") 624 646 return ··· 626 648 } 627 649 628 650 if highlight, err := h.db.GetHighlightByURI(uri); err == nil { 651 + if highlight.CID == nil || *highlight.CID == "" { 652 + parts := parseATURI(uri) 653 + if len(parts) >= 3 { 654 + did := parts[0] 655 + collection := parts[1] 656 + rkey := parts[2] 657 + 658 + session, err := h.refresher.GetSessionWithAutoRefresh(r) 659 + if err == nil { 660 + _ = h.refresher.ExecuteWithAutoRefresh(r, session, func(client *xrpc.Client, _ string) error { 661 + record, getErr := client.GetRecord(r.Context(), did, collection, rkey) 662 + if getErr == nil { 663 + tagsJSON := "" 664 + if highlight.TagsJSON != nil { 665 + tagsJSON = *highlight.TagsJSON 666 + } 667 + color := "" 668 + if highlight.Color != nil { 669 + color = *highlight.Color 670 + } 671 + h.db.UpdateHighlight(uri, color, tagsJSON, record.CID) 672 + cid := record.CID 673 + highlight.CID = &cid 674 + } 675 + return nil 676 + }) 677 + } 678 + } 679 + } 680 + 629 681 if enriched, _ := hydrateHighlights(h.db, []db.Highlight{*highlight}, h.getViewerDID(r)); len(enriched) > 0 { 630 682 serveResponse(enriched[0], "http://www.w3.org/ns/anno.jsonld") 631 683 return ··· 670 722 } 671 723 672 724 if bookmark, err := h.db.GetBookmarkByURI(uri); err == nil { 725 + if bookmark.CID == nil || *bookmark.CID == "" { 726 + parts := parseATURI(uri) 727 + if len(parts) >= 3 { 728 + did := parts[0] 729 + collection := parts[1] 730 + rkey := parts[2] 731 + 732 + session, err := h.refresher.GetSessionWithAutoRefresh(r) 733 + if err == nil { 734 + _ = h.refresher.ExecuteWithAutoRefresh(r, session, func(client *xrpc.Client, _ string) error { 735 + record, getErr := client.GetRecord(r.Context(), did, collection, rkey) 736 + if getErr == nil { 737 + tagsJSON := "" 738 + if bookmark.TagsJSON != nil { 739 + tagsJSON = *bookmark.TagsJSON 740 + } 741 + title := "" 742 + if bookmark.Title != nil { 743 + title = *bookmark.Title 744 + } 745 + desc := "" 746 + if bookmark.Description != nil { 747 + desc = *bookmark.Description 748 + } 749 + h.db.UpdateBookmark(uri, title, desc, tagsJSON, record.CID) 750 + cid := record.CID 751 + bookmark.CID = &cid 752 + } 753 + return nil 754 + }) 755 + } 756 + } 757 + } 758 + 673 759 if enriched, _ := hydrateBookmarks(h.db, []db.Bookmark{*bookmark}, h.getViewerDID(r)); len(enriched) > 0 { 674 760 serveResponse(enriched[0], "http://www.w3.org/ns/anno.jsonld") 675 761 return
-2
web/src/api/client.js
··· 501 501 export async function deleteAPIKey(id) { 502 502 return request(`${API_BASE}/keys/${id}`, { method: "DELETE" }); 503 503 } 504 - 505 -
+2 -2
web/src/components/AnnotationCard.jsx
··· 382 382 {data.tags.map((tag, i) => ( 383 383 <Link 384 384 key={i} 385 - to={`/?tag=${encodeURIComponent(tag)}`} 385 + to={`/home?tag=${encodeURIComponent(tag)}`} 386 386 className="annotation-tag" 387 387 > 388 388 #{tag} ··· 637 637 {data.tags.map((tag, i) => ( 638 638 <Link 639 639 key={i} 640 - to={`/?tag=${encodeURIComponent(tag)}`} 640 + to={`/home?tag=${encodeURIComponent(tag)}`} 641 641 className="annotation-tag" 642 642 > 643 643 #{tag}
+2 -8
web/src/pages/Login.jsx
··· 247 247 )} 248 248 </div> 249 249 250 - 251 - 252 250 {error && <p className="login-error">{error}</p>} 253 251 254 252 <button 255 253 type="submit" 256 254 className="btn btn-primary login-submit" 257 - disabled={ 258 - loading || !handle.trim() 259 - } 255 + disabled={loading || !handle.trim()} 260 256 > 261 - {loading 262 - ? "Connecting..." 263 - : "Continue"} 257 + {loading ? "Connecting..." : "Continue"} 264 258 </button> 265 259 266 260 <p className="login-legal">