diff --git a/docs/footer.tsx b/docs/footer.tsx index d2385732..eb0b08af 100644 --- a/docs/footer.tsx +++ b/docs/footer.tsx @@ -1,6 +1,110 @@ +import { useEffect, useRef } from 'react'; +import { useLocation } from 'react-router'; + +const UTTERANCES_CONFIG = { + repo: 'xmtp/docs-xmtp-org', + issueTerm: 'pathname', + label: 'comment-docs', +} as const; + +// Detect current Vocs theme +function getVocsTheme(): 'github-dark' | 'github-light' { + // Check localStorage + try { + const stored = localStorage.getItem('vocs.theme'); + if (stored === 'dark') return 'github-dark'; + if (stored === 'light') return 'github-light'; + } catch {} + + // Check data-theme attribute + const theme = document.documentElement.getAttribute('data-theme'); + if (theme === 'dark') return 'github-dark'; + if (theme === 'light') return 'github-light'; + + // Check dark class + if (document.documentElement.classList.contains('dark')) { + return 'github-dark'; + } + + // Fallback to system preference + return window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'github-dark' + : 'github-light'; +} + +function Utterances() { + const commentBox = useRef(null); + const location = useLocation(); + + useEffect(() => { + if (!commentBox.current || location.pathname === '/') return; + + // Clear container and inject Utterances script + commentBox.current.innerHTML = ''; + + const script = document.createElement('script'); + script.src = 'https://utteranc.es/client.js'; + script.setAttribute('repo', UTTERANCES_CONFIG.repo); + script.setAttribute('issue-term', UTTERANCES_CONFIG.issueTerm); + script.setAttribute('label', UTTERANCES_CONFIG.label); + script.setAttribute('theme', getVocsTheme()); + script.setAttribute('crossorigin', 'anonymous'); + script.async = true; + + commentBox.current.appendChild(script); + + // Sync theme changes with Utterances iframe (debounced) + let timeoutId: ReturnType; + const observer = new MutationObserver(() => { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + const iframe = document.querySelector('.utterances-frame'); + iframe?.contentWindow?.postMessage( + { type: 'set-theme', theme: getVocsTheme() }, + 'https://utteranc.es' + ); + }, 100); + }); + + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ['class', 'data-theme'], + }); + + return () => { + observer.disconnect(); + clearTimeout(timeoutId); + }; + }, [location.pathname]); + + if (location.pathname === '/') return null; + + return ( +
+
+

+ Building with XMTP and have a question about this documentation? Leave a comment. +

+
+
+ ); +} + export default function Footer() { return (
+