fix(web): stop season-tile flooding in channel builder and collections (#180)
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 5m8s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m16s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped

Part of the #180 library picker fixes (SPA side).

Channel builder: TelevisionSeason is removed from the library grid fan-out, so a
multi-season show renders as one tile instead of one tile per season. Show tiles
gain a "Seasons" drill-in affordance (both grid and compact layouts) that opens a
dialog listing that show's seasons (via the new GET /api/library/browse?parentId=
&mediaType=TelevisionSeason), each with title, artwork and an Add button that
drops the specific season into the lineup.

Collections add-items dialog: the default search fan-out now excludes seasons,
and a media-kind filter row (All / Movies / Shows / Seasons / Artists,
default = All-without-seasons) keeps seasons reachable when explicitly selected.

Client: getLibraryBrowseItems gains an optional parentId param. Tests cover the
param mapping, the builder no longer requesting TelevisionSeason, and the
collections dialog default-excluding vs explicitly-including seasons.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 21:42:18 +02:00
co-authored by Claude Fable 5
parent 54b18e73cd
commit d05e442605
7 changed files with 432 additions and 26 deletions
+80
View File
@@ -2432,6 +2432,57 @@
animation: ctv-pop 260ms cubic-bezier(0.16, 1, 0.3, 1);
}
/* Seasons drill-in affordance on show tiles (issue #180) */
.ctv-builder-seasons-btn {
position: absolute;
left: 6px;
bottom: 6px;
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
border-radius: var(--radius-sm);
border: 1px solid var(--border-hairline);
background: color-mix(in srgb, var(--surface-card) 82%, transparent);
color: var(--text-primary);
font: var(--weight-medium) var(--text-2xs) / 1 var(--font-sans);
cursor: pointer;
backdrop-filter: blur(2px);
}
.ctv-builder-seasons-btn:hover {
border-color: color-mix(in srgb, var(--action-primary) 45%, transparent);
color: var(--action-primary);
}
.ctv-builder-seasons-list {
display: flex;
flex-direction: column;
gap: 6px;
max-height: 420px;
overflow-y: auto;
}
.ctv-builder-seasons-row {
display: flex;
align-items: center;
gap: var(--space-5, 10px);
padding: 6px 8px;
border-radius: var(--radius-sm);
background: var(--surface-card);
border: 1px solid var(--border-hairline);
}
.ctv-builder-seasons-row-title {
flex: 1;
min-width: 0;
font: var(--weight-medium) var(--text-xs) / 1.15 var(--font-sans);
color: var(--text-primary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@keyframes ctv-pop {
from {
transform: scale(0.2);
@@ -3658,6 +3709,35 @@
color: var(--text-disabled);
}
/* Media-kind filter chips in the add-items dialog (issue #180) */
.ctv-collections-picker-filters {
margin-top: 10px;
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.ctv-collections-picker-filter {
padding: 4px 12px;
border-radius: var(--radius-pill, 999px);
border: 1px solid var(--border-hairline);
background: var(--surface-card);
color: var(--text-secondary);
font: var(--weight-medium) var(--text-2xs) / 1 var(--font-sans);
cursor: pointer;
}
.ctv-collections-picker-filter:hover {
color: var(--text-primary);
border-color: color-mix(in srgb, var(--action-primary) 35%, transparent);
}
.ctv-collections-picker-filter-active {
background: color-mix(in srgb, var(--action-primary) 14%, transparent);
border-color: color-mix(in srgb, var(--action-primary) 45%, transparent);
color: var(--action-primary);
}
.ctv-collections-picker-results {
margin-top: 10px;
display: flex;