Files
AtreidesAssetsFree/client/ui/splash.js
T

97 lines
3.7 KiB
JavaScript
Raw Normal View History

2026-10-29 11:57:29 +01:00
// Generated, do not edit. sha256:a433ae61cf1d51dd5a396f13922a2aaa329bfea96e00b35d9456a671a84c5e04
import { CONFIG } from '../../shared/config.js';
import { t } from '../i18n/index.js';
const bootT0 = performance.now();
(function splashGateFallback() {
const html = document.documentElement;
if (html.dataset.splash === 'on') return;
try {
const KEY = 'splash_last_shown';
const d = new Date();
const today = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
const force = location.search.includes('splash') || location.hash.includes('splash');
if (force || localStorage.getItem(KEY) !== today) {
console.warn('[splash] boot-gate.js draaide niet (niet geladen of oude index.html uit de cache?); vangnet in ui/splash.js toont de splash.');
localStorage.setItem(KEY, today);
html.dataset.splash = 'on';
}
} catch { html.dataset.splash = 'on'; }
})();
let typeTimer = 0;
const reducedMotion = () => window.matchMedia('(prefers-reduced-motion: reduce)').matches;
function fadeOut(splash) {
splash.style.transitionDuration = `${CONFIG.SPLASH.FADE_MS}ms`;
splash.classList.add('is-done');
setTimeout(() => reset(splash), CONFIG.SPLASH.FADE_MS + 50);
}
function reset(splash) {
clearTimeout(typeTimer);
delete document.documentElement.dataset.splash;
splash.classList.remove('is-done', 'is-manual', 'is-typed');
splash.style.transitionDuration = '';
const out = splash.querySelector('.splash-quote-text');
if (out) out.textContent = '';
}
export function finishSplash() {
const splash = document.getElementById('splash');
if (!splash || document.documentElement.dataset.splash !== 'on') return;
const wait = Math.max(0, CONFIG.SPLASH.MIN_MS - (performance.now() - bootT0));
setTimeout(() => fadeOut(splash), wait);
}
function showManualSplash() {
const splash = document.getElementById('splash');
if (!splash || document.documentElement.dataset.splash === 'on') return;
splash.classList.add('is-manual');
document.documentElement.dataset.splash = 'on';
const out = splash.querySelector('.splash-quote-text');
if (!out) console.warn('[splash] Citaat-element ontbreekt (oude index.html uit de cache?); één keer hard verversen.');
const text = t('splash.quote');
const done = () => splash.classList.add('is-typed');
if (!out) {
} else if (reducedMotion()) {
out.textContent = text;
done();
} else {
let i = 0;
const step = () => {
out.textContent = text.slice(0, ++i);
if (i >= text.length) return done();
const pause = CONFIG.SPLASH.QUOTE_CHAR_MS
+ (text[i - 1] === ' ' ? CONFIG.SPLASH.QUOTE_WORD_PAUSE_MS : 0);
typeTimer = setTimeout(step, pause);
};
typeTimer = setTimeout(step, CONFIG.SPLASH.QUOTE_START_MS);
}
const ctl = new AbortController();
const close = () => { ctl.abort(); fadeOut(splash); };
splash.addEventListener('click', close, { signal: ctl.signal });
window.addEventListener('keydown', (e) => { if (e.key === 'Escape') close(); }, { signal: ctl.signal });
}
export function splashMarkHtml() {
return `<div class="splash-mini" aria-hidden="true">
<div class="splash-band">
<div class="splash-wing splash-wing--l"><span></span><span></span><span></span></div>
<div class="splash-logo"></div>
<div class="splash-wing splash-wing--r"><span></span><span></span><span></span></div>
</div>
<div class="splash-title">${t('app.name')}</div>
</div>`;
}
export function initSplashReplay() {
for (const el of document.querySelectorAll('.sidebar-logo, .mobile-topbar-logo')) {
el.title = t('splash.logoHint');
el.addEventListener('click', showManualSplash);
}
}