let currentPage = 1; const perPage = 12; localStorage.clear(); function InitializeLocalStorage() { if (!localStorage.getItem('config')) { localStorage.setItem('config', JSON.stringify({ servers: [{ "https://getfigleaf.com": {} }] })); InitializeServerStatus(); } } function InitializeServerStatus() { const config = JSON.parse(localStorage.getItem('config')); config.servers.forEach(serverObj => { const server = Object.keys(serverObj)[0]; fetch(`/api/status`, { method: "POST", body: JSON.stringify({ server: server }), headers: { "Content-Type": "application/json", }, }) .then(response => response.json()) .then(status => { serverObj[server] = status; localStorage.setItem('config', JSON.stringify(config)); }) .catch(err => { serverObj[server] = { online: false }; localStorage.setItem('config', JSON.stringify(config)); }); }); } async function loadVideos() { const config = JSON.parse(localStorage.getItem('config')); const response = await fetch('/api/videos', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ channel: config.channel, sort: "latest", query: "", page: currentPage, perPage: perPage }) }); const videos = await response.json(); renderVideos(videos); currentPage++; } function renderVideos(videos) { const grid = document.getElementById('video-grid'); videos.forEach(v => { const card = document.createElement('div'); card.className = 'video-card'; card.innerHTML = ` ${v.title}

${v.title}

${v.channel} • ${v.duration}s

`; card.onclick = () => openPlayer(v.url); grid.appendChild(card); }); } function openPlayer(videoUrl) { const modal = document.getElementById('video-modal'); const player = document.getElementById('player'); // Using GET for the video tag src as it's the standard for streaming player.src = `/api/stream?url=${encodeURIComponent(videoUrl)}`; modal.style.display = 'block'; } function closePlayer() { const modal = document.getElementById('video-modal'); const player = document.getElementById('player'); player.pause(); player.src = ""; modal.style.display = 'none'; } // UI Helpers function toggleDrawer(id) { document.querySelectorAll('.drawer').forEach(d => d.classList.remove('open')); document.getElementById(`drawer-${id}`).classList.add('open'); document.getElementById('overlay').style.display = 'block'; } function closeDrawers() { document.querySelectorAll('.drawer').forEach(d => d.classList.remove('open')); document.getElementById('overlay').style.display = 'none'; } // Infinite Scroll Observer const observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting) loadVideos(); }, { threshold: 1.0 }); observer.observe(document.getElementById('sentinel')); // Init InitializeLocalStorage(); loadVideos();