From 406ba57a2d914c9445cfb4d58301f05b14a1cb7a Mon Sep 17 00:00:00 2001 From: data Date: Mon, 16 Mar 2026 11:28:10 +0100 Subject: [PATCH] feat(tv): Serie als gesehen markieren - Button im Header Co-Authored-By: Claude Opus 4.6 --- video-konverter/app/static/tv/css/tv.css | 25 ++++++++ .../app/templates/tv/series_detail.html | 57 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/video-konverter/app/static/tv/css/tv.css b/video-konverter/app/static/tv/css/tv.css index 0b94c1c..83ff31f 100644 --- a/video-konverter/app/static/tv/css/tv.css +++ b/video-konverter/app/static/tv/css/tv.css @@ -1814,6 +1814,31 @@ textarea.input-editing { font-size: 0.75rem; } +/* Serie als gesehen markieren - Button */ +.tv-mark-series-btn { + display: inline-flex; + align-items: center; + gap: 0.4rem; + padding: 0.5rem 1rem; + background: transparent; + border: 1px solid var(--border); + color: var(--text); + border-radius: var(--radius); + cursor: pointer; + font-size: 0.9rem; + transition: background 0.2s, border-color 0.2s; +} +.tv-mark-series-btn:hover, +.tv-mark-series-btn:focus { + background: var(--bg-hover); + border-color: var(--accent); +} +.tv-mark-series-btn.active { + background: var(--accent); + color: #000; + border-color: var(--accent); +} + /* --- Episode Card-Grid (Phase 5, Plex-Style) --- */ .tv-episode-grid { display: grid; diff --git a/video-konverter/app/templates/tv/series_detail.html b/video-konverter/app/templates/tv/series_detail.html index a10711c..6236be9 100644 --- a/video-konverter/app/templates/tv/series_detail.html +++ b/video-konverter/app/templates/tv/series_detail.html @@ -63,6 +63,15 @@ {% if in_watchlist %}♥{% else %}♡{% endif %} {{ t('series.watchlist') }} + + @@ -254,6 +263,54 @@ function toggleWatched(videoId, btn) { .catch(() => {}); } +function markSeriesWatched(btn) { + // Alle ungesehenen Episoden aus ALLEN Staffeln sammeln + const allCards = document.querySelectorAll('.tv-episode-tile:not(.tv-ep-seen)'); + const ids = []; + allCards.forEach(function(card) { + var vid = card.dataset.videoId; + if (vid) ids.push(parseInt(vid)); + }); + if (ids.length === 0) return; + + // Batch-Request an API (gleiche Methode wie markSeasonWatched) + Promise.all(ids.map(function(id) { + return fetch('/tv/api/watch-progress', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ video_id: id, position_sec: 100, duration_sec: 100 }), + }); + })).then(function() { + // Alle Episoden-Cards als gesehen markieren + document.querySelectorAll('.tv-episode-tile').forEach(function(card) { + card.classList.add('tv-ep-seen'); + var markBtn = card.querySelector('.tv-ep-tile-mark'); + if (markBtn) markBtn.classList.add('active'); + var thumb = card.querySelector('.tv-ep-thumb'); + if (thumb && !thumb.querySelector('.tv-ep-watched')) { + var check = document.createElement('div'); + check.className = 'tv-ep-watched'; + check.innerHTML = '✓'; + thumb.appendChild(check); + } + }); + // Alle Staffel-Tabs als komplett markieren + document.querySelectorAll('.tv-tab').forEach(function(tab) { + if (!tab.classList.contains('tv-tab-complete')) { + tab.classList.add('tv-tab-complete'); + if (!tab.querySelector('.tv-tab-check')) { + var check = document.createElement('span'); + check.className = 'tv-tab-check'; + check.innerHTML = ' ✓'; + tab.appendChild(check); + } + } + }); + // Button-Zustand aendern + btn.classList.add('active'); + }).catch(function() {}); +} + function markSeasonWatched(seriesId, seasonNum) { const season = document.getElementById('season-' + seasonNum); if (!season) return;