// desidium-app.jsx — assembles the site, owns language / scroll / tweaks const { useState: useStateApp, useEffect: useEffectApp } = React; const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "accent": "#c8643c", "motion": true, "columns": 3, "defaultLang": "en" }/*EDITMODE-END*/; function App() { const [t, setTweak] = useTweaks(TWEAK_DEFAULTS); const [lang, setLangState] = useStateApp(() => { if (window.desidiumWp && window.desidiumWp.lang) return window.desidiumWp.lang; try { return localStorage.getItem("desidium-lang") || TWEAK_DEFAULTS.defaultLang; } catch (e) { return TWEAK_DEFAULTS.defaultLang; } }); const setLang = (l) => { if (window.desidiumWp && window.desidiumWp.pllActive && window.desidiumWp.languages) { const target = window.desidiumWp.languages.find((x) => x.slug === l); if (target && target.url) { window.location.href = target.url; return; } } setLangState(l); try { localStorage.setItem("desidium-lang", l); } catch (e) {} }; useEffectApp(() => { document.documentElement.lang = lang; }, [lang]); const [scrolled, setScrolled] = useStateApp(false); const [menu, setMenu] = useStateApp(false); const [route, setRoute] = useStateApp(() => { try { const params = new URLSearchParams(window.location.search); if (params.get("view") === "join") return "join"; } catch (e) {} return "home"; }); // 'home' | model.id const [pendingScroll, setPendingScroll] = useStateApp(() => { const hash = window.location.hash; return hash && hash !== "#top" ? hash : null; }); useEffectApp(() => { const onScroll = () => setScrolled(window.scrollY > 40); onScroll(); window.addEventListener("scroll", onScroll, { passive: true }); return () => window.removeEventListener("scroll", onScroll); }, []); // after returning home, run any pending scroll-to-section useEffectApp(() => { if (route === "home" && pendingScroll) { const target = pendingScroll; requestAnimationFrame(() => { const el = document.querySelector(target); if (el) { const y = el.getBoundingClientRect().top + window.scrollY - 8; window.scrollTo({ top: y, behavior: "smooth" }); } setPendingScroll(null); }); } }, [route, pendingScroll]); const go = (href) => { if (href === "route:journal" && window.desidiumWp && window.desidiumWp.blogUrl) { window.location.href = window.desidiumWp.blogUrl; return; } setMenu(false); if (href.indexOf("route:") === 0) { setRoute(href.slice(6)); window.scrollTo({ top: 0, behavior: "auto" }); return; } if (route !== "home") { setRoute("home"); if (href === "#top") { window.scrollTo({ top: 0, behavior: "auto" }); } else { setPendingScroll(href); } return; } if (href === "#top") { window.scrollTo({ top: 0, behavior: "smooth" }); return; } const el = document.querySelector(href); if (el) { const y = el.getBoundingClientRect().top + window.scrollY - 8; window.scrollTo({ top: y, behavior: "smooth" }); } }; const openModel = (mdl) => { setMenu(false); setRoute(mdl.id); }; const goContact = () => go("#contact"); const goPost = (id) => { setMenu(false); setRoute("post:" + id); }; const goAuthor = (id) => { setMenu(false); setRoute("author:" + id); }; const goJournal = () => { setMenu(false); setRoute("journal"); window.scrollTo({ top: 0, behavior: "auto" }); }; const motion = !!t.motion; const cols = Number(t.columns) || 3; useEffectApp(() => { document.documentElement.style.setProperty("--terra", t.accent); }, [t.accent]); const navItems = [["roster","#roster"],["studio","#studio"],["cases","#cases"],["journal","route:journal"],["contact","#contact"],["join","route:join"]]; const isPost = route.indexOf("post:") === 0; const isAuthor = route.indexOf("author:") === 0; const isModel = !isPost && !isAuthor && route !== "home" && route !== "join" && route !== "journal"; return (
); } ReactDOM.createRoot(document.getElementById("root")).render();