Files
iptvnator/docs
4grayandClaude Opus 5 e3fc3c8802 refactor(portals): extract the destructive Xtream refresh into one flow
`PlaylistRefreshActionService.refreshXtream()` and
`RecentPlaylistsComponent.refreshXtreamPlaylist()` were two independent ~60-line
implementations of the same sequence: confirm, reset the connectivity guard,
delete the cached catalog while collecting playback positions and stamping the
update date, park the restore state, dispatch the meta update, navigate to
re-import. That duplication is what let the guard reset land in one of them and
look landed in both, which the previous commit had to fix separately.

`XtreamRefreshFlowService` now owns the sequence once. The two entry points
differ only in how they report progress — the header action drives one global
preparation signal, the sources page drives per-row busy indicators shared with
deletion — so that part is injected as an `XtreamRefreshProgressReporter`. Its
optional `waitForVisibleProgress` hook keeps the action's paint delay without
imposing it on the sources page, which never had one. A reporter cannot reach
the guard reset, so a third entry point gets it for free.

The sources page now awaits `router.navigate` before clearing its busy row,
matching the action service; it previously cleared the row while navigation was
still in flight.

Both guard-reset regression tests still fail on their own when the reset is
removed from the shared flow. The new spec pins the reporter contract:
re-entry after confirmation, busy-before-reset ordering, progress forwarding
under one run, abort vs error, and a reporter without the optional paint hook.
The sources spec's abort test counted a fixed number of microtasks to reach the
delete; the shared flow adds one await to that path, so it now waits on a
deterministic signal instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 08:25:21 +02:00
..