mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 02:46:16 -08:00
Two dashboard additions, both async after first paint so the page renders
exactly as fast as before:
Trending rail ("Trending this week", dashboardRails.tmdbTrending toggle,
default on, rendered only when TMDB is opted in AND the Electron DB
worker is available):
- TmdbTrendingService fetches /trending/{movie,tv}/week (one request
each, cached one day per language in tmdb_metadata under
trending:week), merges by popularity; exposed via the enrichment
facade (getTrendingWeek)
- DashboardTrendingService matches the titles against imported Xtream
playlists with ONE batched DB_MATCH_TITLES request, applying the same
two-tier + year-compatibility rule as actor pages; matched cards show
the playlist name and navigate straight to the detail view, unmatched
cards open the global search prefilled (?q=)
- The load fires only after the dashboard's own recent/favorites data
is in (never competes for the worker at startup) and once per session
- DashboardRailCard gained optional queryParams for the search links
Hero enrichment:
- DashboardHeroTmdbService patches the hero with a TMDB backdrop (only
when the item has none), a rating badge and up to two genre chips —
via the enrichment facade, so previously opened items resolve from
the SQLite cache without network; memoized per title per session,
staleness-guarded against hero changes in flight
- Series heroes show the tracked "S{n}·E{n}" badge from the playback
position; the watch-progress bar no longer applies to live heroes
Settings: new dashboardRails.tmdbTrending toggle in Settings > Dashboard.
i18n: 3 new keys translated into all 17 locales via tools/i18n patches.
Tests: dashboard-trending.service.spec.ts (gating, matching, year guard,
single-flight); settings fixtures updated. Docs updated
(tmdb-metadata-enrichment.md Dashboard Integration section, CLAUDE.md).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
183 lines
6.4 KiB
HTML
183 lines
6.4 KiB
HTML
<section
|
|
class="settings-group"
|
|
[class.settings-group--active]="activeSection() === 'dashboard'"
|
|
id="dashboard"
|
|
[formGroup]="form()"
|
|
>
|
|
<header class="settings-group__header">
|
|
<div class="settings-group__header-icon">
|
|
<mat-icon>dashboard</mat-icon>
|
|
</div>
|
|
<div class="settings-group__header-text">
|
|
<h3>{{ 'SETTINGS.DASHBOARD' | translate }}</h3>
|
|
<p>{{ 'SETTINGS.DASHBOARD_SUBTITLE' | translate }}</p>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{ 'SETTINGS.SHOW_DASHBOARD' | translate }}</h4>
|
|
<p>
|
|
{{ 'SETTINGS.SHOW_DASHBOARD_DESCRIPTION' | translate }}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="showDashboard"
|
|
data-test-id="toggle-show-dashboard"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div formGroupName="dashboardRails">
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{ 'SETTINGS.DASHBOARD_HERO' | translate }}</h4>
|
|
<p>
|
|
{{ 'SETTINGS.DASHBOARD_HERO_DESCRIPTION' | translate }}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="hero"
|
|
data-test-id="toggle-dashboard-hero"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{ 'SETTINGS.DASHBOARD_RAIL_CONTINUE' | translate }}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_CONTINUE_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="continueWatching"
|
|
data-test-id="toggle-dashboard-rail-continue-watching"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{
|
|
'SETTINGS.DASHBOARD_RAIL_LIVE_FAVORITES' | translate
|
|
}}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_LIVE_FAVORITES_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="liveFavorites"
|
|
data-test-id="toggle-dashboard-rail-live-favorites"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{
|
|
'SETTINGS.DASHBOARD_RAIL_RECENT_LIVE' | translate
|
|
}}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_RECENT_LIVE_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="recentlyWatchedLive"
|
|
data-test-id="toggle-dashboard-rail-recently-watched-live"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{
|
|
'SETTINGS.DASHBOARD_RAIL_FAVORITE_VOD' | translate
|
|
}}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_FAVORITE_VOD_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="favoriteMoviesAndSeries"
|
|
data-test-id="toggle-dashboard-rail-favorite-movies-and-series"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{ 'SETTINGS.DASHBOARD_RAIL_SOURCES' | translate }}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_SOURCES_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="recentSources"
|
|
data-test-id="toggle-dashboard-rail-recent-sources"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{
|
|
'SETTINGS.DASHBOARD_RAIL_XTREAM_ADDED' | translate
|
|
}}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_XTREAM_ADDED_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="xtreamRecentlyAdded"
|
|
data-test-id="toggle-dashboard-rail-xtream-recently-added"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="setting-item">
|
|
<div class="setting-item__meta">
|
|
<h4>{{ 'SETTINGS.DASHBOARD_RAIL_TMDB_TRENDING' | translate }}</h4>
|
|
<p>
|
|
{{
|
|
'SETTINGS.DASHBOARD_RAIL_TMDB_TRENDING_DESCRIPTION'
|
|
| translate
|
|
}}
|
|
</p>
|
|
</div>
|
|
<div class="setting-item__control setting-item__toggle">
|
|
<mat-checkbox
|
|
formControlName="tmdbTrending"
|
|
data-test-id="toggle-dashboard-rail-tmdb-trending"
|
|
></mat-checkbox>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|