mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 09:26:14 -08:00
* feat(stalker): append portal pages on scroll and drop pagination everywhere Second and final PR of the pagination removal (plan: .plans/2026-08-09-infinite-scroll-catalog.md). Stalker VOD/series grids now feed the shared infinite-scroll contract from server-paged appends: portal pages (server-side size, typically 14) accumulate into one deduplicated paginatedContent list, page 1 replaces it for the skeleton, hasMoreContent derives from accumulated length vs total_items (portals that ignore requested page sizes still terminate), and a failed page > 1 keeps the accumulated pages on screen with a tail retry (retryContentPage reloads the same page; loadMore refuses to skip past an unresolved append error). The facade splits the resource's loading flag by page — skeleton for page one, tail spinner for appends — and keeps per-identity scroll offsets for Stalker's INLINE detail round trips; the shared view re-arms its one-shot restore when a detail opens in the same component instance. The transitional supportsInfiniteScroll flag and every paged member are deleted from PortalCatalogFacade; the shared catalog view loses the mat-paginator, the ?page= round-trip, and the paged query-param branch. The ITV all-channels grid becomes a client-side render window over the cached full list (the app's last paginator), and Stalker search pages past its first capped request via the layout's nearEnd, with a progress guard for portals that report no usable total. Validation: 1600 unit tests across 7 projects green (new: vod/series append + failed-append retry, facade loading split/loadMore guards/scroll snapshots, ITV window model, compat selector update); catalog-sorting e2e 5/5 (Stalker spec rewritten to scroll model with p>=2 network asserts and an inline-detail spot-restore round trip; one unrelated nav-timeout flake reproduced only under parallel machine load), search e2e 16/16, web stalker e2e green (all-channels grid asserts the windowed count instead of a paginator range label); lint clean; release note added and validated; stalker-portal.md, CLAUDE.md, and ui-guidelines updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(stalker): reset paging on content-type switch and never skip failed search pages Round-1 review findings on #1395: 1. Codex P1: switching /vod -> /series with the same category id ('*' on both section roots) left page > 1 in place — setSelectedContentType did not touch paging and setSelectedCategory('*') no-ops on an unchanged id — so the new type's FIRST response was treated as an append onto the old type's accumulated list. The type setter now resets the page (and no-ops entirely when the type repeats, keeping detail round-trip restores intact). 2. Greptile P1 + Codex P2: a failed search append left searchHasMore true, so the next near-end advanced to page N+1 and permanently omitted the failed page. The search now tracks searchAppendError: a failed append keeps the accumulated pages and the next near-end RETRIES the same page; a failed fresh search (page 1) clears the previous query's cards instead of rendering them under the new term (Codex P2). The page-merge/failure logic moved into applySearchPageSuccess/Failure methods: Angular resource() never re-fires on params changes in this repo's template-less jest harnesses (store-hosted resources do), so the extracted methods carry the unit coverage — accumulation + dedupe, no-total progress guard, retry-not-skip, fresh-failure clear — plus a selection spec for the type-switch page reset. portal-stalker-feature 260, portal-stalker-data-access 464, lint clean; catalog-sorting e2e 5/5 and web stalker e2e green. search.e2e shows machine-load nav-timeout flakes on unrelated M3U/live specs (a runaway third-party process pegs the host CPU); CI provides the clean independent run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(stalker): include the portal in the search paging identity Round-2 Codex P1 on #1395: Angular reuses the search route across /stalker/A/search -> /stalker/B/search, and the paging identity covered only term + filter — the page number and accumulator survived the portal change, so the next near-end fetched portal B at the OLD page number and appended it onto portal A's results while skipping B's first page. The active playlist id now joins the page-reset identity, the resource params, the stale-response guard, and the layout's near-end reset key. Regression spec: switching the active playlist on a reused route resets the page to 1 and rotates the scroll reset key. portal-stalker-feature 261, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(stalker): end paging on no-progress appends even with a reported total Round-3 Codex P2s on #1395 (same defect in both accumulators): the no-progress guard only applied when the portal reported no usable total_items. After a mid-list portal mutation, deduplication can leave the unique list permanently shorter than the claimed total — hasMore then stayed true forever and every scroll crossing kept requesting pages past the end of the data. An append that adds no unique items now ends paging in both places: the catalog clamps totalCount to the accumulated length (hasMoreContent turns false and the count badge reflects what is actually reachable), and the search requires append progress in the total-backed branch exactly like the no-total branch. Regression specs cover a duplicate page under a larger claimed total for both. portal-stalker-data-access 465, portal-stalker-feature 262, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(stalker): explicit search retry control and per-portal scroll identities Round-4 findings on #1395: 1. Greptile P1: with the results pane parked at the bottom, repeated append failures exhausted the scroll auto-fill budget while the near-end latch stayed armed — the retry path was reachable only through another nearEnd event that could never fire. The search page now renders an explicit retry control under the results whenever an append has failed (same wording as the catalog grid tail), wired to the existing retry-same-page path, so recovery never depends on producing another scroll event. 2. Codex P2: the facade's saved-scroll map survives a same-config portal switch (the vod/series route provider is reused across /stalker/A -> /stalker/B), and its identity lacked the playlist — portal A's offset could restore onto portal B's unrelated catalog. The playlist id now leads the scroll identity; regression spec covers the cross-portal non-restore and the return restore. portal-stalker-feature 263, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(stalker): restore the search results scroll after an inline detail Round-5 Codex P2 on #1395: the search layout destroys the results container while an inline detail is shown (showDetails) and recreates it at offset zero — with the new multi-page accumulation a user could load several pages, open a result far down the list, and land back at the top on close even though the accumulated results survived. SearchLayoutComponent now exposes a scroll handoff for hosts whose details replace the results (getResultsScrollTop / restoreResultsScrollTop on the container it owns), and the Stalker search captures the offset when a detail opens and restores it one-shot after the container is recreated on close. Regression specs cover the layout handoff methods and the capture/restore round trip. portal-shared-ui 90, portal-stalker-feature 264, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(stalker): clear accumulated search results for unsearchable portals Round-6 Codex P2 on #1395: the loader's early returns (deleted or malformed playlist on a reused route) predate the accumulator and returned [] without touching it — the previous portal's cards kept rendering under the new context once loading settled. Every no-portal early return now goes through resetSearchAccumulator(), which empties the accumulated list and both paging flags; the short-term path uses it too (and now also clears a stale append error). Regression spec covers the full reset. portal-stalker-feature 265, lint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>