Live video on the AT Protocol

fall back to branding in header if we haven't gotten it yet

+60 -1
+60 -1
js/components/src/streamplace-store/branding.tsx
··· 25 25 }); 26 26 }; 27 27 28 + const PropsInHeader = [ 29 + "siteTitle", 30 + "siteDescription", 31 + "primaryColor", 32 + "accentColor", 33 + "defaultStreamer", 34 + "mainLogo", 35 + "favicon", 36 + "sidebarBg", 37 + "legalLinks", 38 + ]; 39 + 40 + function getMetaContent(key: string): BrandingAsset | null { 41 + if (typeof window === "undefined" || !window.document) return null; 42 + const meta = document.querySelector(`meta[name="internal-brand:${key}`); 43 + if (meta && meta.getAttribute("content")) { 44 + let content = meta.getAttribute("content"); 45 + if (content) return JSON.parse(content) as BrandingAsset; 46 + } 47 + 48 + return null; 49 + } 50 + 28 51 // hook to fetch broadcaster DID (unauthenticated) 29 52 export function useFetchBroadcasterDID() { 30 53 const streamplaceAgent = usePossiblyUnauthedPDSAgent(); 31 54 const store = getStreamplaceStoreFromContext(); 55 + 56 + // prefetch from meta records, if on web 57 + useEffect(() => { 58 + if (typeof window !== "undefined" && window.document) { 59 + try { 60 + const metaRecords = PropsInHeader.reduce( 61 + (acc, key) => { 62 + const meta = document.querySelector( 63 + `meta[name="internal-brand:${key}`, 64 + ); 65 + // hrmmmmmmmmmmmm 66 + if (meta && meta.getAttribute("content")) { 67 + let content = meta.getAttribute("content"); 68 + if (content) acc[key] = JSON.parse(content) as BrandingAsset; 69 + } 70 + return acc; 71 + }, 72 + {} as Record<string, BrandingAsset>, 73 + ); 74 + 75 + console.log("Found meta records for broadcaster DID:", metaRecords); 76 + // filter out all non-text values, can get on second fetch? 77 + for (const key of Object.keys(metaRecords)) { 78 + if (metaRecords[key].mimeType != "text/plain") { 79 + delete metaRecords[key]; 80 + } 81 + } 82 + } catch (e) { 83 + console.warn("Failed to parse broadcaster DID from meta tags", e); 84 + } 85 + } 86 + }, []); 32 87 33 88 return useCallback(async () => { 34 89 try { ··· 140 195 141 196 // hook to get a specific branding asset by key 142 197 export function useBrandingAsset(key: string): BrandingAsset | undefined { 143 - return useStreamplaceStore((state) => state.branding?.[key]); 198 + return ( 199 + useStreamplaceStore((state) => state.branding?.[key]) || 200 + getMetaContent(key) || 201 + undefined 202 + ); 144 203 } 145 204 146 205 // convenience hook for main logo