48 lines
2.4 KiB
JavaScript
48 lines
2.4 KiB
JavaScript
const menu = document.getElementById('docs-menu');
|
|
const mobile = matchMedia('(max-width:720px)');
|
|
const setMenu = () => { menu.open = !mobile.matches; };
|
|
setMenu();
|
|
mobile.addEventListener('change', setMenu);
|
|
const search = document.getElementById('doc-search');
|
|
const folders = [...menu.querySelectorAll('.nav-folder')];
|
|
let beforeSearch = null;
|
|
const normalize = value => value.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
search.addEventListener('input', () => {
|
|
const query = normalize(search.value.trim());
|
|
if (query && !beforeSearch) beforeSearch = new Map(folders.map(folder => [folder, folder.open]));
|
|
let count = 0;
|
|
for (const item of document.querySelectorAll('[data-search]')) {
|
|
item.hidden = !normalize(item.dataset.search).includes(query);
|
|
if (!item.hidden) count++;
|
|
}
|
|
for (const folder of folders) {
|
|
const matches = [...folder.querySelectorAll('[data-search]')].some(item => !item.hidden);
|
|
folder.parentElement.hidden = !matches;
|
|
if (query) folder.open = matches;
|
|
else if (beforeSearch) folder.open = beforeSearch.get(folder);
|
|
}
|
|
if (!query) beforeSearch = null;
|
|
for (const group of menu.querySelectorAll('section')) group.hidden = ![...group.querySelectorAll('[data-search]')].some(item => !item.hidden);
|
|
const result = document.getElementById('search-result');
|
|
result.hidden = !query;
|
|
result.textContent = count ? `${count} passende Themen` : 'Keine passenden Themen gefunden.';
|
|
});
|
|
async function syncStatus() {
|
|
const label = document.getElementById('sync-status');
|
|
try {
|
|
const response = await fetch('/docs-status.json', { cache:'no-store', credentials:'omit', signal:AbortSignal.timeout(8000) });
|
|
if (!response.ok) throw new Error();
|
|
const status = await response.json();
|
|
const date = new Date(status.lastSuccess);
|
|
if (!Number.isFinite(date.valueOf())) throw new Error();
|
|
const stale = !status.ok || Date.now() - date.valueOf() > 15 * 60 * 1000;
|
|
label.classList.toggle('warning', stale);
|
|
label.textContent = `${stale ? 'Git-Abgleich verzögert. Letzter erfolgreicher Abgleich' : 'Git zuletzt geprüft'}: ${date.toLocaleString('de-CH')}${status.drafts ? ' · neue Anleitungen noch nicht in Git veröffentlicht' : ''}.`;
|
|
} catch {
|
|
label.classList.add('warning');
|
|
label.textContent = 'Der aktuelle Git-Abgleichstatus ist nicht erreichbar. Quellstand dieser Seite siehe unten.';
|
|
}
|
|
}
|
|
syncStatus();
|
|
setInterval(() => { if (!document.hidden) syncStatus(); }, 60000);
|