async function load(){
let data;
try {
const r = await fetch('/api/streams', { cache: 'no-store' });
if (!r.ok) throw new Error('api '+r.status);
data = await r.json();
} catch (e) {
console.warn('streams api error:', e);
// UI freundlich degradieren
document.getElementById('list').innerHTML =
'
';
return;
}
const q = (document.getElementById('filter').value||'').toLowerCase();
const list = document.getElementById('list');
list.innerHTML = '';
data.items.filter(it => !q || it.name.toLowerCase().includes(q)).forEach(it => {
const a = document.createElement('a');
a.href = '/' + encodeURIComponent(it.name);
a.className = 'card';
a.innerHTML = `
${it.name}
Zuschauer: ${it.viewers}
${it.live ? 'LIVE' : 'Offline'}
`;
list.appendChild(a);
});
}
document.getElementById('filter').addEventListener('input', load);
document.getElementById('reload').addEventListener('click', load);
load();
setInterval(load, 3000);