Ionosphere.tv
3
fork

Configure Feed

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

feat: derive concept sidebar from document facets

When the API concepts array is empty (old annotation system removed),
extract unique concept-ref entities from the document facets instead.
Concepts appear in the sidebar sorted alphabetically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+23 -2
+23 -2
apps/ionosphere/src/app/talks/[rkey]/TalkContent.tsx
··· 58 58 return doc?.facets?.length > 0 ? doc : null; 59 59 }, [talk.document]); 60 60 61 + // Derive concepts from document facets (concept-ref entities) 62 + const docConcepts = useMemo(() => { 63 + if (!document) return []; 64 + const seen = new Map<string, { name: string; uri: string; rkey: string }>(); 65 + for (const f of document.facets) { 66 + for (const feat of f.features) { 67 + if (feat.$type === "tv.ionosphere.facet#concept-ref" && feat.conceptUri) { 68 + if (!seen.has(feat.conceptUri)) { 69 + const rkey = feat.conceptUri.split("/").pop() || ""; 70 + seen.set(feat.conceptUri, { 71 + name: feat.conceptName || feat.label || rkey, 72 + uri: feat.conceptUri, 73 + rkey, 74 + }); 75 + } 76 + } 77 + } 78 + } 79 + return [...seen.values()].sort((a, b) => a.name.localeCompare(b.name)); 80 + }, [document]); 81 + 61 82 const videoContainerRef = useRef<HTMLDivElement>(null); 62 83 const [videoWidth, setVideoWidth] = useState<number | null>(null); 63 84 ··· 194 215 195 216 {/* Right sidebar — concepts + cross-refs (hidden on mobile, scrollable on desktop) */} 196 217 <aside className="hidden lg:flex lg:flex-col lg:w-56 xl:w-64 shrink-0 border-l border-neutral-800 overflow-y-auto p-4 gap-5"> 197 - {concepts.length > 0 && ( 218 + {(concepts.length > 0 || docConcepts.length > 0) && ( 198 219 <section> 199 220 <h2 className="text-xs font-semibold text-neutral-500 uppercase tracking-wide mb-2">Concepts</h2> 200 221 <div className="flex flex-wrap gap-1.5"> 201 - {concepts.map((c: any) => ( 222 + {(concepts.length > 0 ? concepts : docConcepts).map((c: any) => ( 202 223 <a 203 224 key={c.rkey} 204 225 href={`/concepts/${c.rkey}`}