(() => { const root = document.querySelector('[data-history]'); if (!root) return; const filters = Array.from(root.querySelectorAll('[data-history-filter]')); const groups = Array.from(root.querySelectorAll('[data-history-group]')); const items = Array.from(root.querySelectorAll('[data-history-item]')); const empty = root.querySelector('[data-history-empty]'); const clear = root.querySelector('[data-history-clear]'); let activeKind = 'all'; async function postJSON(url, body) { if (window.HttpRequest && typeof window.HttpRequest.post === 'function') { return window.HttpRequest.post(url, body || {}); } const response = await fetch(url, { method: 'POST', credentials: 'same-origin', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(body || {}), }); return response.json(); } function update() { root.dataset.activeKind = activeKind; items.forEach(item => { item.hidden = item.dataset.removed === 'true' || (activeKind !== 'all' && item.dataset.kind !== activeKind); }); groups.forEach(group => { group.hidden = !Array.from(group.querySelectorAll('[data-history-item]')).some(item => !item.hidden && getComputedStyle(item).display !== 'none' ); }); const hasVisible = groups.some(group => !group.hidden); if (empty) empty.hidden = hasVisible; if (clear) { clear.hidden = items.length === 0 || items.every(item => item.dataset.removed === 'true'); clear.disabled = clear.hidden; } filters.forEach(filter => { const selected = filter.dataset.historyFilter === activeKind; filter.classList.toggle('is-active', selected); filter.setAttribute('aria-pressed', String(selected)); }); } filters.forEach(filter => filter.addEventListener('click', () => { activeKind = filter.dataset.historyFilter; update(); })); root.querySelectorAll('[data-history-remove]').forEach(button => button.addEventListener('click', async (event) => { event.preventDefault(); event.stopPropagation(); if (button.disabled) return; const item = button.closest('[data-history-item]'); if (!item) return; const id = Number(item.dataset.id); const kind = item.dataset.kind || 'short'; if (!id) { item.dataset.removed = 'true'; update(); return; } button.disabled = true; try { let result; if (kind === 'series') { result = await postJSON('/api/video/history/delete', {videoId: id}); } else { result = await postJSON('/api/playlet/history/delete', {playletId: id}); } if (!result || Number(result.code) !== 200) { throw new Error((result && (result.tip || result.msg)) || '删除失败'); } item.dataset.removed = 'true'; update(); } catch (error) { window.alert(error.message || '删除失败,请稍后重试'); button.disabled = false; } })); if (clear) { clear.addEventListener('click', async () => { if (clear.disabled) return; if (!window.confirm('确定清空全部观看历史?')) return; clear.disabled = true; try { const [playletResult, videoResult] = await Promise.all([ postJSON('/api/playlet/history/clear', {}), postJSON('/api/video/history/clear', {}), ]); const playletOk = playletResult && Number(playletResult.code) === 200; const videoOk = videoResult && Number(videoResult.code) === 200; if (!playletOk && !videoOk) { throw new Error( (videoResult && (videoResult.tip || videoResult.msg)) || (playletResult && (playletResult.tip || playletResult.msg)) || '清空失败' ); } items.forEach(item => { item.dataset.removed = 'true'; }); update(); window.location.reload(); } catch (error) { window.alert(error.message || '清空失败,请稍后重试'); clear.disabled = false; } }); } window.addEventListener('resize', update); update(); })();