feat(tv): Serie als gesehen markieren - Button im Header
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
764da40447
commit
406ba57a2d
2 changed files with 82 additions and 0 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,15 @@
|
|||
<span class="watchlist-icon">{% if in_watchlist %}♥{% else %}♡{% endif %}</span>
|
||||
<span class="watchlist-text">{{ t('series.watchlist') }}</span>
|
||||
</button>
|
||||
<!-- Serie als gesehen markieren -->
|
||||
<button class="tv-mark-series-btn"
|
||||
id="btn-mark-series"
|
||||
data-focusable
|
||||
data-series-id="{{ series.id }}"
|
||||
onclick="markSeriesWatched(this)">
|
||||
<span class="mark-series-icon">✓</span>
|
||||
<span class="mark-series-text">{{ t('status.mark_series') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue