diff --git a/public/upload.html b/public/upload.html index 3990ede..f9e44e5 100644 --- a/public/upload.html +++ b/public/upload.html @@ -225,28 +225,97 @@ async function applyBranding() { } catch {} } -async function init() { - await applyBranding(); - const r = await fetch(`/u/${token}/info`); - if (!r.ok) { - document.querySelector('.card').innerHTML = - '
Bitte wende dich an deinen Ansprechpartner für einen neuen Link.
'; - return; - } - const data = await r.json(); +function applyInfo(data) { window._uploadInfo = data; document.getElementById('title').textContent = `Upload für ${data.name}`; if (data.expired) { - info.innerHTML = `⚠ Link ist abgelaufen — Uploads sind weiterhin möglich, der Datei-Browser ist deaktiviert.`; + info.innerHTML = `⚠ Link ist abgelaufen — Uploads sind weiterhin möglich, der Datei-Browser ist deaktiviert.`; } else if (data.expires_at) { info.innerHTML = `⏳ gültig bis ${new Date(data.expires_at).toLocaleString()}`; } else { info.textContent = 'Lade Dateien oder ganze Ordner hoch — die Ordnerstruktur bleibt erhalten.'; } + // Browser visibility synced to expiry + const browser = document.querySelector('.browser'); + if (browser) browser.style.display = data.expired ? 'none' : ''; +} + +function showLinkGone(reason) { + stopPolling(); + document.querySelector('.card').innerHTML = + `${reason}
`; +} + +async function init() { + await applyBranding(); + const r = await fetch(`/u/${token}/info`); + if (!r.ok) { + showLinkGone('Bitte wende dich an deinen Ansprechpartner für einen neuen Link.'); + return; + } + const data = await r.json(); + applyInfo(data); if (data.has_password) gate.style.display = 'block'; else { main.style.display = 'block'; loadFiles(); } + startPolling(); } +// --- Auto-refresh --- +const POLL_INTERVAL_MS = 20000; +let pollTimer = null; +let pollBusy = false; +let lastInfoSig = ''; +let lastFilesSig = ''; + +async function pollState() { + if (pollBusy) return; + pollBusy = true; + try { + const r = await fetch(`/u/${token}/info`); + if (r.status === 404) { + showLinkGone('Der Upload-Link wurde deaktiviert oder gelöscht.'); + return; + } + if (!r.ok) return; + const data = await r.json(); + const sig = JSON.stringify(data); + if (sig !== lastInfoSig) { + lastInfoSig = sig; + applyInfo(data); + // Newly expired or unexpired → reload list + if (!data.expired && main.style.display !== 'none') loadFiles(); + } + if (!data.expired && main.style.display !== 'none') await refreshFilesIfChanged(); + } catch {} + finally { pollBusy = false; } +} + +async function refreshFilesIfChanged() { + try { + const url = `/u/${token}/files${currentDir ? '?dir=' + encodeURIComponent(currentDir) : ''}`; + const r = await fetch(url, { headers: authHeaders() }); + if (r.status === 410) { applyInfo({ ...(window._uploadInfo || {}), expired: true }); return; } + if (!r.ok) return; + const data = await r.json(); + const sig = JSON.stringify(data); + if (sig === lastFilesSig) return; + lastFilesSig = sig; + renderFiles(data); + } catch {} +} + +function startPolling() { + if (pollTimer) return; + pollTimer = setInterval(pollState, POLL_INTERVAL_MS); +} +function stopPolling() { + if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } +} +document.addEventListener('visibilitychange', () => { + if (document.hidden) stopPolling(); + else if (window._uploadInfo) startPolling(); +}); + function authHeaders() { return password ? { 'X-Upload-Password': password } : {}; } @@ -269,31 +338,16 @@ function renderCrumbs() { cr.innerHTML = html; } -async function loadFiles() { +function renderFiles(data) { const browser = document.getElementById('fileBrowser'); const count = document.getElementById('fileCount'); - // Browser komplett ausblenden wenn Link abgelaufen ist - if (window._uploadInfo && window._uploadInfo.expired) { - document.querySelector('.browser').style.display = 'none'; + const entries = (data && data.entries) || []; + count.textContent = entries.length ? `(${entries.length})` : ''; + if (!entries.length) { + browser.innerHTML = '