(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.

fix share urls

+40 -20
+15 -13
web/src/components/modals/ShareMenu.tsx
··· 99 99 const did = uriParts[2]; 100 100 const collection = uriParts[3] ?? ""; 101 101 102 - if (uri.includes("network.cosmik.card")) 103 - return `${origin}/at/${did}/${rkey}`; 102 + const marginSegment = collection.startsWith("at.margin.note") 103 + ? "note" 104 + : collection.startsWith("at.margin.highlight") 105 + ? "highlight" 106 + : collection.startsWith("at.margin.bookmark") 107 + ? "bookmark" 108 + : collection.startsWith("at.margin.annotation") 109 + ? "annotation" 110 + : null; 104 111 105 - if (handle) { 106 - const segment = collection.includes("at.margin.note") 107 - ? "note" 108 - : collection.includes("at.margin.highlight") 109 - ? "highlight" 110 - : collection.includes("at.margin.bookmark") 111 - ? "bookmark" 112 - : collection.includes("at.margin.annotation") 113 - ? "annotation" 114 - : (type?.toLowerCase() ?? "note"); 115 - return `${origin}/${handle}/${segment}/${rkey}`; 112 + if (marginSegment && handle) { 113 + return `${origin}/${handle}/${marginSegment}/${rkey}`; 114 + } 115 + 116 + if (did && collection && rkey) { 117 + return `${origin}/at/${did}/${collection}/${rkey}`; 116 118 } 117 119 118 120 return `${origin}/at/${did}/${rkey}`;
+2
web/src/pages/[...appPath].astro
··· 20 20 uri = decodeURIComponent(segments[1]); 21 21 } else if (segments.length === 3 && segments[0] === 'at') { 22 22 uri = `at://${segments[1]}/at.margin.note/${segments[2]}`; 23 + } else if (segments.length === 4 && segments[0] === 'at') { 24 + uri = `at://${segments[1]}/${segments[2]}/${segments[3]}`; 23 25 } else if (segments.length === 3) { 24 26 const [handle, type, rkey] = segments; 25 27 const contentTypes = ['note', 'annotation', 'highlight', 'bookmark', 'collection'];
+13
web/src/views/AppShell.tsx
··· 99 99 return <AnnotationDetail did={did} rkey={rkey} />; 100 100 } 101 101 102 + function AtCollectionAnnotationRoute() { 103 + const { did, collection, rkey } = useParams<{ 104 + did: string; 105 + collection: string; 106 + rkey: string; 107 + }>(); 108 + return <AnnotationDetail did={did} collection={collection} rkey={rkey} />; 109 + } 110 + 102 111 function UriAnnotationRoute() { 103 112 const { uri } = useParams<{ uri: string }>(); 104 113 return <AnnotationDetail uri={uri ? decodeURIComponent(uri) : undefined} />; ··· 292 301 element={<UriAnnotationRoute />} 293 302 /> 294 303 <Route path="/at/:did/:rkey" element={<AtAnnotationRoute />} /> 304 + <Route 305 + path="/at/:did/:collection/:rkey" 306 + element={<AtCollectionAnnotationRoute />} 307 + /> 295 308 <Route path="/url/*" element={<UrlRoute />} /> 296 309 <Route path="/:handle/url/*" element={<UserUrlRoute />} /> 297 310 <Route path="/profile/:did" element={<ProfileRoute />} />
+10 -7
web/src/views/content/AnnotationDetail.tsx
··· 29 29 type?: string; 30 30 uri?: string; 31 31 did?: string; 32 + collection?: string; 32 33 initialAnnotation?: AnnotationItem | null; 33 34 initialReplies?: AnnotationItem[]; 34 35 resolvedUri?: string; ··· 40 41 type, 41 42 uri, 42 43 did, 44 + collection, 43 45 initialAnnotation, 44 46 initialReplies, 45 47 resolvedUri, ··· 76 78 } 77 79 78 80 if (handle && rkey) { 79 - let collection = "at.margin.note"; 80 - if (type === "annotation") collection = "at.margin.annotation"; 81 - if (type === "highlight") collection = "at.margin.highlight"; 82 - if (type === "bookmark") collection = "at.margin.bookmark"; 81 + let resolvedCollection = "at.margin.note"; 82 + if (type === "annotation") resolvedCollection = "at.margin.annotation"; 83 + if (type === "highlight") resolvedCollection = "at.margin.highlight"; 84 + if (type === "bookmark") resolvedCollection = "at.margin.bookmark"; 83 85 84 86 try { 85 87 const resolvedDid = await resolveHandle(handle); 86 88 if (resolvedDid) { 87 - setTargetUri(`at://${resolvedDid}/${collection}/${rkey}`); 89 + setTargetUri(`at://${resolvedDid}/${resolvedCollection}/${rkey}`); 88 90 } else { 89 91 throw new Error("Could not resolve handle"); 90 92 } ··· 97 99 setLoading(false); 98 100 } 99 101 } else if (did && rkey) { 100 - setTargetUri(`at://${did}/at.margin.note/${rkey}`); 102 + const resolvedCollection = collection || "at.margin.note"; 103 + setTargetUri(`at://${did}/${resolvedCollection}/${rkey}`); 101 104 } 102 105 } 103 106 resolve(); 104 - }, [uri, did, rkey, handle, type, resolvedUri, t]); 107 + }, [uri, did, rkey, handle, type, collection, resolvedUri, t]); 105 108 106 109 const refreshReplies = async () => { 107 110 if (!targetUri) return;