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>
Workspace Dashboard Feature
This library owns the workspace dashboard rails UI. The dashboard is a read-only surface over existing playlist, recent, favorites, EPG, and Xtream catalog data; it should not introduce Electron IPC, SQLite schema, or route contracts on its own.
Dashboard Surfaces
The dashboard renders a surface only when the matching setting is enabled. Data rails also require the underlying data slice to have at least one item.
heroshows the large top banner for the most recent global item. When that item is a live TV channel, the hero looks up the current XMLTV programme and displays the programme title, time range, and EPG progress bar when data is available.continueWatchingshows recent movies and series fromDashboardDataService.globalRecentVodItems()using cover cards with playback progress when a saved resume position is available.liveFavoritesshows favorited live TV channels fromDashboardDataService.globalFavoriteLiveItems()using the channel layout with EPG title, time range, and progress when XMLTV data is available.recentlyWatchedLiveshows recently watched live TV channels fromDashboardDataService.globalRecentLiveItems()using the same channel layout.favoriteMoviesAndSeriesshows favorited movies and series fromDashboardDataService.globalFavoriteItems(), excluding live favorites, using cover cards.recentSourcesshows recently used playlist/source entries.xtreamRecentlyAddedshows recently added Xtream catalog items.
Settings
Per-surface visibility lives on Settings.dashboardRails as a
DashboardRailsSettings object. Every surface defaults to enabled. Stored
settings are deep-merged with DEFAULT_DASHBOARD_RAILS_SETTINGS by
SettingsStore, so existing users and older partial settings keep newly added
surfaces visible unless they explicitly turn them off.
The global showDashboard flag remains a top-level Settings property because
workspace startup and route guards already depend on that contract. The Settings
UI groups showDashboard and the per-surface checkboxes in the Dashboard
section. When showDashboard is off, the per-surface checkboxes are disabled
because the dashboard route itself is hidden.
Navigation
Rail cards use the navigation state provided by DashboardDataService for the
underlying item. Rail "See all" links may also pass router state:
- live rails open the relevant collection on Live TV.
- cover rails for movies/series open Global Recent or Global Favorites on Movies when movie items are present, otherwise on Series.
This keeps the global collection pages from defaulting to Live TV when a dashboard rail is clearly about movies or series.