Repository navigation
Conversation
…typed cast state, module cleanup Fixes all 36 findings of a second whole-repo refactoring review (21 backend and CI, 15 frontend). Backend - A delayed live-stream reconnect only reloads while its session is still the current one (generation check under the session lock); switching channel during the backoff used to bring the old channel back. - The macOS keychain backend runs `security` on the blocking pool, so an unlock prompt can't stall a runtime worker and `timed()` can give up. Error::KeyringLocked replaces matching on the message. - series_detail/movie_detail split into named steps (resume_point, build_seasons, watch_history, choose_movie_copy, ...); shared movie/series lookups and the episode-history filter in catalog/works.rs; details_of returns a named Details. - rebuild_works split into remap_search_matches / work_row / collect_facets with push_unique. - CastState enum instead of &'static str; on_media_status goes through a pure, tested media_transition. - SourceKind is FromSql/ToSql (unknown kinds are an error, not Xtream); ItemRef for work preferences; versions::unavailable takes Option<&Value>. - TMDB progress is App state (one lock, no separate AtomicBool); HTTP clients are shared per user agent (App::client); one user-agent constant; one TMDB_KIND SQL fragment; Error::msg takes String. - No glob imports outside test modules; cast/catalog/sources/works keep only mod declarations and re-exports, their items moved to types.rs / keys.rs leaves. - lib.rs background jobs in spawn_background_jobs; labelled assertions. Frontend - Player labels use lib/format; ROUTES covers every page; shared useSources/useSeriesDetail and queryKeys; isAiring/currentAndUpcoming; usePagedQuery, useFolds, useTimeout (timers cleared on unmount); NavRow, FoldHeader, SearchInput; WorkKind/HistoryKind; casting-aware control methods; backgroundWrite (was playerWrite) on user actions; new tests for play.ts and the player store's onEvent. CI - The four jobs share .github/actions/setup; the bundle trigger is one YAML anchor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes all 36 findings of a second whole-repo refactoring review: 21 in the Rust backend and CI, 15 in the frontend. Two of them were real bugs; the rest is mostly finishing what #12 started.
Bugs
player/mod.rs). A dropped live stream is reopened after a 0.5–2.5 s backoff on a detached thread, which used to reload the URL it captured no matter what had happened since. Switching channel during the backoff brought the old channel back. Sessions now carry a generation number, and the thread reloads only if the session is still the same one, checked under the session lock so a newloadcan't slip in between.secrets.rs). The macOS backend isasync fn, but it called the blockingstd::process::Command::output()without ever awaiting, sosecurity unlock-keychainwaiting on a prompt held a tokio worker and thetimed()wrapper could never fire. Thesecuritycalls now run on the blocking pool.Error::KeyringLockedreplaces matching on the error message.Backend
Detail pages.
series_detail(292 lines) andmovie_detail(157) are split into named steps, with tests forresume_point:series_text,watch_history,copy_tracks,latest_watch_state,build_seasons,resume_pointchoose_movie_copy,movie_resume_positionThe repeated work/item lookups (
movie_by_key,series_by_key, …) and the episode-history filter live incatalog/works.rs, anddetails_ofreturns a namedDetails.Grouping.
rebuild_works(231 lines) is split intoremap_search_matches,work_rowandcollect_facets; six copies of "push if not already there" becomepush_unique.Typed state.
CastStateenum instead of&'static str.on_media_statusgoes through a puremedia_transition, with tests including the three live reloads.SourceKindisFromSql/ToSql, so an unknown kind in the database is now an error instead of silently counting as Xtream.ItemRefinstead of(i64, String).Shared state.
Mutexplus a separateAtomicBoolintoApp, with check-and-set under one lock.App::client) instead of built on every detail, guide and sync request; playback's URL-onlyXtreamshares one idle client.Modules.
use super::*;outside test modules.cast,catalog,sourcesandworkskeep onlymoddeclarations and re-exports; their items moved totypes.rs/keys.rsleaves.Smaller.
TMDB_KINDSQL fragment (it was written out 6 times).Error::msgtakesString;versions::unavailabletakesOption<&Value>.spawn_background_jobswith a# Panicssection onrun().let _ = &cast;no-op lines are deleted, and assertion-roulette tests are labelled.Frontend
lib/format.ROUTEScovers every page.useSources/useSeriesDetailhooks and aqueryKeysmodule.isAiring/currentAndUpcoming(tested),usePagedQueryfor the three infinite lists,useFolds, andNavRow/FoldHeader/SearchInputinui.tsx.useTimeoutclears the Live preview, channel-digit, notice and flash timers on unmount, so a preview can no longer start after leaving Live TV.backgroundWrite(renamed fromplayerWrite) or a mutation with an error.controlmethods.PlayerPageis about 200 lines (was about 345), withuseNotice,useTransport,TopBarandBottomBar.WorkKind/HistoryKindreplace the retyped unions, andStartPagemoved tolib/routes.ts.lib/play.test.tsandonEventcases;Live.test.tsbecamelib/liveLists.test.ts.CI
.github/actions/setup: system packages or Homebrew tools, toolchains, the media-engine cache with the same keys as before, and rust-cache. The bundle trigger condition is written once as a YAML anchor.Visible changes
Intl), e.g. "Norwegian Bokmål".Testing
scripts/check.shpasses: fmt, clippy-D warningsplus the unsafe lint, 95 Rust tests (2 ignored), tsc, 77 vitest tests (was 65), third-party notices.scripts/headless.sh) on a debug build of this branch, with a local M3U playlist:check-macoshere is its first compile.