fix(m3u): keep groups hidden in Manage groups after a restart (#1894) (#1907)

* fix(m3u): keep groups hidden in Manage groups after a restart (#1894)

Electron fills the playlist store from DB_GET_APP_PLAYLIST_METAS, which
reads the metadata columns only. hiddenGroupTitles lives only in the JSON
payload, so after a restart the store had none and the groups rail showed
every group, although SQLite still held the saved selection; saving the
dialog from that state then overwrote it.

M3uWorkspaceRouteSession already reads the full playlist to publish its
channels and favorites. It now copies hiddenGroupTitles from that read into
the store (updatePlaylistMeta, persist: false) before the channels, unless
the store value changed while the read was queued behind a save.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(m3u): wait for the playlist entity before hydrating hidden groups

The startup inventory publishes playlists only after settings and EPG
reconciliation, while a restored or deep-linked playlist route waits for
the metadata read alone. The route session's full read could therefore
finish first, and updateOne dropped the hydration for the missing entity
for the whole session. The hydration now waits for the entity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(m3u): cover hidden groups when the Groups route opens before the inventory

An Electron E2E reloads the renderer on the Groups route while the startup
inventory is held (the EPG reconcile fails once and its retry is parked),
and records from document start whether a hidden group is ever rendered
visibly. It fails on the previous hydration that did not wait for the
playlist entity. A service test pins that getPlaylist reads hidden groups
from a meta update that is still being written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(m3u): type empty hidden-group arrays in the route session spec

The CI spec typecheck (apps/web/tsconfig.spec.json) rejected `[]` inferred
as never[] inside the PlaylistMeta and Playlist casts with TS2352.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-12 23:06:39 +02:00
1 parent 8508010ea5
commit b546fe0123
7 files changed
+551 -6

No files matched your search

+13
View File
@@ -633,6 +633,19 @@ channel-list-container/
- `PlaylistsService.updatePlaylistMeta()` persists `hiddenGroupTitles` into the
stored playlist payload, and M3U refresh/update flows preserve the existing
value when refreshed playlist data omits the field.
- Electron loads the playlist store from `DB_GET_APP_PLAYLIST_METAS`, which
reads columns only, so `hiddenGroupTitles` is absent from the store after a
restart. `M3uWorkspaceRouteSession` copies it from the full playlist read into
the store (`updatePlaylistMeta` with `persist: false`) before publishing the
channels, unless the store value changed while that read was queued (#1894).
A restored or deep-linked route can finish that read before the startup
inventory, which waits for settings and EPG reconciliation, publishes the
playlist; the hydration then waits for the entity, since `updateOne` drops an
update for a missing one. The startup screen keeps the router outlet hidden
until that inventory is published, and the hydration runs in the same store
update, so the rail never renders a hidden group. A save's meta write joins
the per-playlist queue that `getPlaylist()` reads through, so a reopened
route reads the saved value.
- The groups route keeps the manage action reachable even when every group is
hidden by separating "playlist has no groups" from "no visible/search-matching
groups" empty states.