From 6e2cc56e2c889dc95e0c130b12d4306bed366c39 Mon Sep 17 00:00:00 2001 From: 4gray Date: Sat, 4 Jul 2026 18:49:37 +0200 Subject: [PATCH] fix(ui): app-prefix detail template directive selectors, build fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit detailTags/detailMeta/detailActions → appDetailTags/appDetailMeta/ appDetailActions per @angular-eslint/directive-selector; type the Escape host listener as Event; drop a redundant ?? in season tabs. Co-Authored-By: Claude Fable 5 --- CLAUDE.md | 2 +- docs/architecture/embedded-inline-playback.md | 4 ++-- .../stalker-series-view.component.html | 6 +++--- .../lib/serial-details/serial-details.component.html | 6 +++--- .../lib/vod-details/vod-details-route.component.html | 10 +++++----- .../lib/portal-detail-shell/content-about.component.ts | 2 +- .../portal-detail-shell/detail-template.directives.ts | 6 +++--- .../portal-detail-shell.component.spec.ts | 6 +++--- .../portal-detail-shell.component.ts | 2 +- .../lib/season-container/season-tabs.component.html | 2 +- .../src/lib/vod-details/vod-details.component.html | 6 +++--- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2419bb1f6..323e433f2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -622,7 +622,7 @@ This project uses modern Angular signal-based APIs and patterns. **ALWAYS** use - Xtream and Stalker detail pages use the shared `PortalDetailShellComponent` (`libs/ui/components/src/lib/portal-detail-shell/`) with two states: **Browse** (hero with poster/metadata/actions, episodes below) and **Watch** (hero collapses with a ~300ms morph, the inline player takes the full content width, metadata moves to an About block below the episodes) - Watch state derives from `inlinePlayback() !== null` only; external MPV/VLC playback keeps the browse layout. Esc and the now-playing back button close the inline player back to browse without route navigation -- Hosts pass hero chips/meta/actions as `*detailTags`/`*detailMeta`/`*detailActions` templates; the shell stamps them into both the hero and the About block +- Hosts pass hero chips/meta/actions as `*appDetailTags`/`*appDetailMeta`/`*appDetailActions` templates; the shell stamps them into both the hero and the About block - Seasons are tabs (`SeasonTabsComponent`, dropdown beyond 6 seasons) with auto-selection (playing episode's season → resume season → first) that fires the same `seasonSelected` lazy-load/enrichment hooks as manual clicks; grid/list episode view toggle persists to localStorage; season descriptions come from `get_series_info` (Xtream) or TMDB (Stalker) - See `docs/architecture/embedded-inline-playback.md` ("Two-State Detail Layout") diff --git a/docs/architecture/embedded-inline-playback.md b/docs/architecture/embedded-inline-playback.md index 88ef2a9d8..394dc7eff 100644 --- a/docs/architecture/embedded-inline-playback.md +++ b/docs/architecture/embedded-inline-playback.md @@ -101,8 +101,8 @@ which owns the page scroll container and two layout states: Contracts: -- Hosts provide hero chips/meta/actions as `*detailTags` / `*detailMeta` / - `*detailActions` templates; the shell stamps them into the hero and again +- Hosts provide hero chips/meta/actions as `*appDetailTags` / `*appDetailMeta` / + `*appDetailActions` templates; the shell stamps them into the hero and again into the About block. Degradation stays "missing → not rendered". - The shell never wraps the `[detail-player]` slot in a conditional; the host's `@if (inlinePlayback())` is the only creator/destroyer of the diff --git a/libs/portal/stalker/feature/src/lib/stalker-series-view/stalker-series-view.component.html b/libs/portal/stalker/feature/src/lib/stalker-series-view/stalker-series-view.component.html index e87d4dc4e..0499a4959 100644 --- a/libs/portal/stalker/feature/src/lib/stalker-series-view/stalker-series-view.component.html +++ b/libs/portal/stalker/feature/src/lib/stalker-series-view/stalker-series-view.component.html @@ -9,7 +9,7 @@ (closePlayerRequested)="closeInlinePlayer()" > - + @if (serial.info.releasedate) { {{ serial.info.releasedate }} } @@ -29,7 +29,7 @@ - + @if (serial.info.actors || serial.info.tmdb_cast?.length) {
{{ 'XTREAM.ACTORS' | translate }} @@ -89,7 +89,7 @@ - + @if (quickStartAction(); as action) { @if (playbackActive()) { diff --git a/libs/ui/components/src/lib/portal-detail-shell/portal-detail-shell.component.ts b/libs/ui/components/src/lib/portal-detail-shell/portal-detail-shell.component.ts index b46cd10d9..6f841052c 100644 --- a/libs/ui/components/src/lib/portal-detail-shell/portal-detail-shell.component.ts +++ b/libs/ui/components/src/lib/portal-detail-shell/portal-detail-shell.component.ts @@ -76,7 +76,7 @@ export class PortalDetailShellComponent { }); } - onEscape(event: KeyboardEvent): void { + onEscape(event: Event): void { if (!this.playbackActive()) return; if (event.defaultPrevented) return; // Browser fullscreen owns Escape (exits fullscreen first). diff --git a/libs/ui/components/src/lib/season-container/season-tabs.component.html b/libs/ui/components/src/lib/season-container/season-tabs.component.html index 18ef7e62f..3f23870b4 100644 --- a/libs/ui/components/src/lib/season-container/season-tabs.component.html +++ b/libs/ui/components/src/lib/season-container/season-tabs.component.html @@ -30,7 +30,7 @@ }} - {{ episodeCounts()[seasonKey] ?? 0 }} + {{ episodeCounts()[seasonKey] }} @if (isSeasonCompleted(seasonKey)) { check diff --git a/libs/ui/playback/src/lib/vod-details/vod-details.component.html b/libs/ui/playback/src/lib/vod-details/vod-details.component.html index faa9e99f7..2ca437221 100644 --- a/libs/ui/playback/src/lib/vod-details/vod-details.component.html +++ b/libs/ui/playback/src/lib/vod-details/vod-details.component.html @@ -10,7 +10,7 @@ (closePlayerRequested)="closeInlinePlayback()" > - + @if (meta.year) { {{ meta.year }} } @@ -31,7 +31,7 @@ - + @if (meta.actors || meta.tmdbCast?.length) {
{{ 'XTREAM.ACTORS' | translate }} @@ -90,7 +90,7 @@ - + @if (hasPlaybackPosition()) {