// Vidgas — main App const { useState, useEffect } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "theme": "cinema", "accent": "#ff3d3d", "density": "regular", "fontStyle": "modern" }/*EDITMODE-END*/; // Read initial route from URL: ?v= opens the player for that video function getInitialRoute() { try { const params = new URLSearchParams(window.location.search); const v = params.get('v'); if (v) return { name: 'player', id: v }; } catch (e) {} return { name: 'library' }; } function syncUrl(route) { try { const url = new URL(window.location.href); if (route.name === 'player' && route.id) { url.searchParams.set('v', route.id); } else { url.searchParams.delete('v'); } window.history.replaceState({}, '', url.toString()); } catch (e) {} } function App() { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); const [route, setRoute] = useState(getInitialRoute()); const [menuOpen, setMenuOpen] = useState(false); const data = window.VIDGAS_DATA; // Keep URL in sync with route so player links are shareable useEffect(() => { syncUrl(route); }, [route]); // Apply theme to body useEffect(() => { document.body.className = ''; document.body.classList.add('theme-' + (t.theme || 'cinema')); document.documentElement.style.setProperty('--accent', t.accent); // derive accent variants document.documentElement.style.setProperty('--accent-glow', hexToRgba(t.accent, 0.35)); if (t.fontStyle === 'editorial') { document.documentElement.style.setProperty('--font-display', "'Instrument Serif', 'Cormorant Garamond', serif"); } else if (t.fontStyle === 'mono') { document.documentElement.style.setProperty('--font-display', "'Geist Mono', ui-monospace, monospace"); } else { document.documentElement.style.setProperty('--font-display', "'Geist', 'Bricolage Grotesque', system-ui, sans-serif"); } }, [t.theme, t.accent, t.fontStyle]); // Scroll to top on route change useEffect(() => { window.scrollTo({ top: 0, behavior: 'instant' }); }, [route]); const navigate = (r) => { setRoute(r); setMenuOpen(false); }; let screen; if (route.name === 'library') screen = ; else if (route.name === 'player') screen = ; else if (route.name === 'upload') screen = ; else if (route.name === 'collections') screen = ; else if (route.name === 'search') screen = ; else screen = ; return (
setMenuOpen(o => !o)} route={route} /> {screen}
setTweak('theme', v)} /> setTweak('fontStyle', v)} /> setTweak('accent', v)} /> navigate({ name: 'library' })} /> navigate({ name: 'player', id: 'v01' })} /> navigate({ name: 'upload' })} /> navigate({ name: 'collections' })} /> navigate({ name: 'search' })} />
); } function hexToRgba(hex, a) { const h = hex.replace('#', ''); const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16); const r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255; return `rgba(${r},${g},${b},${a})`; } ReactDOM.createRoot(document.getElementById('root')).render();