feat: show episode info on download and history cards
- Add includeEpisode:true to Sonarr queue and history API requests in both the poller and historyFetcher - Add extractEpisode() / gatherEpisodes() helpers in dashboard.js and history.js to build a sorted, deduplicated episodes array covering all records matching a download title (handles multi- episode packs and series packs) - Replace episodeInfo: sonarrMatch with episodes: gatherEpisodes() across all 8 assignment sites in dashboard.js - Add episodes field to /api/history/recent response items - Frontend: formatEpisodeInfo() renders S01E05 for single episodes or 'Multiple episodes' with hover tooltip listing all for packs - CSS: .episode-info and .multi-episode tooltip styles - ARCHITECTURE.md: update polling table and download/history schemas
This commit is contained in:
@@ -290,6 +290,30 @@ function hideLoginError() {
|
||||
errorDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
// Build an episode-info element for series downloads/history.
|
||||
// Single episode: "S01E05 — Episode Title"
|
||||
// Multiple episodes: "Multiple episodes" with tooltip listing them all.
|
||||
// Returns null if no episode data.
|
||||
function formatEpisodeInfo(episodes) {
|
||||
if (!episodes || episodes.length === 0) return null;
|
||||
const el = document.createElement('p');
|
||||
el.className = 'episode-info';
|
||||
if (episodes.length === 1) {
|
||||
const ep = episodes[0];
|
||||
const code = 'S' + String(ep.season).padStart(2, '0') + 'E' + String(ep.episode).padStart(2, '0');
|
||||
el.textContent = ep.title ? code + ' \u2014 ' + ep.title : code;
|
||||
} else {
|
||||
el.textContent = 'Multiple episodes';
|
||||
el.classList.add('multi-episode');
|
||||
const lines = episodes.map(ep => {
|
||||
const code = 'S' + String(ep.season).padStart(2, '0') + 'E' + String(ep.episode).padStart(2, '0');
|
||||
return ep.title ? code + ' \u2014 ' + ep.title : code;
|
||||
});
|
||||
el.setAttribute('data-tooltip', lines.join('\n'));
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
// fetchUserDownloads is kept for the showAll toggle re-connection case
|
||||
// but the primary data path is now via SSE (startSSE / EventSource).
|
||||
|
||||
@@ -478,6 +502,8 @@ function createDownloadCard(download) {
|
||||
series.textContent = `Series: ${download.seriesName}`;
|
||||
}
|
||||
infoDiv.appendChild(series);
|
||||
const epEl = formatEpisodeInfo(download.episodes);
|
||||
if (epEl) infoDiv.appendChild(epEl);
|
||||
}
|
||||
|
||||
if (download.movieName) {
|
||||
@@ -982,6 +1008,8 @@ function createHistoryCard(item) {
|
||||
p.textContent = 'Series: ' + item.seriesName;
|
||||
}
|
||||
info.appendChild(p);
|
||||
const epEl = formatEpisodeInfo(item.episodes);
|
||||
if (epEl) info.appendChild(epEl);
|
||||
}
|
||||
if (item.movieName) {
|
||||
const p = document.createElement('p');
|
||||
|
||||
Reference in New Issue
Block a user