Route Wolfskin setup and recovery through its own profile picker #63
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/tv-skip-stock-setup"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Outcome
When Wolfskin screens is enabled, the stock Wholphin server and user selectors no longer render. Household setup, profile choice and failed-login recovery stay in Wolfskin. The rollback switch still exposes both original selectors.
Root cause
MainContentrenderedSwitchServerContent/SwitchUserContentbefore the signed-inWolfskinApphook. The stock user selector also callsSwitchUserViewModel.init→ServerRepository.switchServerOrUser, clearing the remembered server and user merely by visiting the screen. That can send the next start back to server selection.The fork has a compiled Conductarr URL, but no compiled Jellyfin URL. Setup therefore recovers the supplied/current/recent server, then the most recently used Room server, before offering the approved one-time URL field on an unconfigured install. No new endpoint is hardcoded.
Change
MainContent, gated by the existing rollout preference. Navigation destination types remain compatible with upstream.requireLogin; expired saved tokens open real credential entry. Failed selection/public-profile reads expose Wolfskin retry/sign-in actions. Retry reruns household startup server/profile recovery through an explicit controller callback and publishesLoadingbefore its result.docker/README.md.Every stock-selector entry path inspected
RestoredSession.None→ServerList)RestoredSession.ServerOnly→UserList)AppContent)MainActivityViewModel.appStartexception fallback →ServerListUserList(current.server)orServerList; valid intent target without a current user →ServerListIntentServicesession restoration.NavDraweruser-avatar switch →UserList(server)SwitchUserViewModel.init.switchServerOrUsercleared preferencesUserList; stock user's switch-server action →ServerListVerification
12 tests passed; zero failures, errors or skipped tests. Only the three added
WolfskinSetup*classes ran:WolfskinSetupTest: 8 controller/auth regressions with real Room and remembered-server preferences; endpoint/user preservation, expired-token renewal, PIN/require-login gates, first-run discovery, public-profile failure, late-identity/rollback protection, andUnavailable → Loading → Picker/Unavailableretry transitions.WolfskinSetupNavigationTest: 3 actualMainContentsurface scenarios covering cold start, legacy sign-out state, drawer switch, intent failure, unconfigured first run, and the unreachable-household frame without either stock selector.WolfskinSetupRollbackTest: 1 Hilt-backed test rendering both real stock selectors with Wolfskin disabled.Executed through the serialized Gradle wrapper, using a task-local debug keystore:
The brittle full-
MainContentnative retry-click driver was replaced with controller-level transition coverage, as directed; it is not skipped or time-padded. Exactly one native 1920×1080 same-data unreachable-household frame remains, reviewed against the existing token-backed palette, typography and layout. Proof and final XML are retained at/root/.treehouse/firstmate-7bab20/2/firstmate/data/tv-skip-stock-setup/proof/.No full test suite, APK/Opt build, install, ADB, TV launch or TV screenshot was performed. Full merged-candidate/Opt validation remains the integration gate. Home rows, hero motion and existing Home Back handling are untouched. Base is
fm/tv-round2; no merge requested or performed.Implementation and verification were AI-assisted.
Review (Opus, behaviour + safety): PASS, no blocking findings
Reviewed head:
a5b5e9201741693b4d4f922ae9e6d945b9ff58ce. Statusesreview/code-claudeandreview/safety-opusare set to success on this SHA.Safety checks, all passed
MainContent), and the new interceptor runs before it inside everyNavEntry. Every route into server or user selection (app-start exception, intent errors, saved-session restore, drawer, stock add/switch) lands in Wolfskin setup. The rollout switch is read from SharedPreferences before it is used, so a cold start never acts on the default. With the switch off, both stock selectors render unchanged.requireLogin(or no saved token) cannot reachchangeUserwithout the PIN or real credentials. Expired token → credential entry. A failed login leaves the current user, the remembered server/user and the shared Jellyfin client untouched. No password or token is stored or logged. The password field is masked.current === expected). Outages, 5xx and 403 are ignored. A 401 only opens the picker and clears nothing, so there is no sign-out or picker↔Home loop.switchServerOrUseror any other clearing path. The one-time URL field appears only when Room holds no server at all, and it saves a server only after discovery verifies it, same checks as upstream.Non-blocking notes
JellyfinServer.lastUsedis never written, so the fallback takes the first Room row, not the most recently used server. That is fine with one server. With several saved servers it can open on the wrong one, and setup has no way to switch server. Suggest choosing by the newest userlastUsed. The README wording is inaccurate.pickerLaunchbecomes false. A later Back then shows the shell nav and the "not built in this slice" placeholder inside setup. It is recoverable and exposes no data. After the Home PR (#59) merges, Back on the launch picker sendsShellAction.Exit, which setup ignores, so Back never exits from setup.existingUseronly when the authenticated user id matches.retry()reloads withload(null), ignoring theUserList(server)destination.git merge-treeexit 0). The only conflict is between #58 and #59 (DiscoverScreen.kt), which does not involve this PR. Semantic overlap with #59 is in note 2.Full report:
firstmate/data/review-63-auth/report.md.Pull request closed