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.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();