Redesign settings with vertical hub navigation#1096
Merged
Conversation
Replace the horizontal tab bar in Settings with a vertical hub-and-spoke layout: profile card, six nav rows (Appearance, Gestures, Playback, Storage, Privacy & Developer, About), and a sign-out button. Each section pushes a dedicated detail screen onto the Settings stack. The Storage row routes to the existing Nitro-backed Storage screen, which now hosts the auto-download toggle and download quality radio inline at the top alongside the download manager UI. Add Play Next as a swipe action across the settings store, swipe helper, Track row, and item-row, wired to the existing playNext() in the player queue hook. Update maestro/tests/7-settings.yaml to walk the new navigation, exercise theme/preset selection, toggle each swipe chip including Play Next, verify the inline download settings, and dismiss the sign-out sheet without signing out. Add maestro/flows/flow-settings.yaml as a focused login + settings entry point. iOS login flow tweaks: dismiss the keyboard with Enter (which also submits the form) and replace the slow optional permission-dialog taps with conditional runFlow blocks gated on visibility. Reimplements PR #982 (settings redesign) and PR #1037 (Play Next) cleanly on top of Nitro Player main.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR redesigns the Settings experience from a horizontal tabbed layout to a vertical hub-and-spoke navigation, adds a configurable Play Next swipe action, and updates Maestro flows/tests to exercise the new UX and iOS login behavior.
Changes:
- Replaced Settings top tabs with a vertical settings hub that routes to dedicated detail screens (Appearance, Gestures, Playback, Storage, Privacy & Developer, About, Account).
- Added Play Next as a swipe action option across the swipe settings store and row swipe-action wiring.
- Updated Maestro login/settings flows to match the new navigation and streamline iOS interactions.
Reviewed changes
Copilot reviewed 32 out of 34 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/stores/settings/swipe.ts | Adds PlayNext to persisted swipe-action settings. |
| src/screens/Storage/index.tsx | Embeds download settings (auto-download + quality) inline in the Storage screen. |
| src/screens/Settings/types.d.ts | Updates Settings stack route types for new hub screens. |
| src/screens/Settings/privacy-developer.tsx | Adds new Privacy & Developer screen (toggles + PR OTA input). |
| src/screens/Settings/playback.tsx | Adds new Playback settings screen (quality + toggles). |
| src/screens/Settings/index.tsx | Registers new stack screens and updates Storage header title. |
| src/screens/Settings/gestures.tsx | Adds new Gestures screen for configuring swipe actions. |
| src/screens/Settings/appearance.tsx | Adds new Appearance screen (theme, preset, runtime toggle). |
| src/screens/Settings/account.tsx | Adds new Account screen (library + server info). |
| src/screens/Settings/account-details.tsx | Removes old account-details wrapper screen. |
| src/screens/Settings/about.tsx | Adds new About screen (links, OTA version, patrons). |
| src/components/Settings/utils/quality.ts | Removes old quality label helpers (no longer used). |
| src/components/Settings/types.d.ts | Removes old Settings tab list types (tab UI removed). |
| src/components/Settings/components/vertical-settings.tsx | Implements the new vertical Settings hub screen. |
| src/components/Settings/components/usage-tab.tsx | Removes old Usage tab implementation. |
| src/components/Settings/components/sign-out-button.tsx | Removes old sign-out button component (replaced by hub button). |
| src/components/Settings/components/settings-section.tsx | Adds reusable collapsible SettingsSection card component. |
| src/components/Settings/components/settings-nav-row.tsx | Adds reusable navigation row for hub routing. |
| src/components/Settings/components/settings-list-group.tsx | Removes old list-group abstraction used by tabs. |
| src/components/Settings/components/sections/index.ts | Adds barrel export for new sections components. |
| src/components/Settings/components/sections/action-chip.tsx | Adds ActionChip UI used in Gestures screen. |
| src/components/Settings/components/preferences-tab.tsx | Removes old Preferences tab implementation. |
| src/components/Settings/components/playback-tab.tsx | Removes old Playback tab implementation. |
| src/components/Settings/components/labs-tab.tsx | Removes old Labs tab implementation. |
| src/components/Settings/components/info-tab.tsx | Removes old Info tab implementation. |
| src/components/Settings/components/gestures-tab.tsx | Removes old Gestures tab implementation. |
| src/components/Settings/components/account-tab.tsx | Removes old Account tab implementation. |
| src/components/Settings/component.tsx | Swaps Settings entry component to the new VerticalSettings hub. |
| src/components/Global/helpers/swipe-actions.ts | Adds PlayNext mapping to swipe actions + handlers type. |
| src/components/Global/components/Track/index.tsx | Wires PlayNext swipe handler to queue hook using QueuingType.PlayNext. |
| src/components/Global/components/item-row.tsx | Wires PlayNext swipe handler for item rows. |
| maestro/tests/7-settings.yaml | Rewrites settings E2E to traverse the new hub and verify inline download settings + Play Next chip. |
| maestro/tests/1-login.yaml | Improves iOS login flow (Enter to submit, conditional permission handling). |
| maestro/flows/flow-settings.yaml | Adds focused flow to clear state, login, and run settings tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Member
|
This is so awesome 💜 |
This was referenced Apr 7, 2026
Address Copilot review feedback on #1096. SwitchWithLabel previously rendered a Separator + Label unconditionally, so the seven settings rows that passed label='' showed a blank trailing label and extra spacing next to the switch. Make the label prop optional and skip the separator/label entirely when it isn't supplied. Drop the empty label='' from each callsite now that it isn't required. handleSubmitPr only checked the input was non-empty before passing Number(input) to downloadPRUpdate, so 'abc' produced NaN and a bogus OTA branch name. Validate the value is a positive integer first and surface a more specific error otherwise.
The previous fix made props.label optional but still passed it to the Tamagui Label component, whose 'children' prop is typed as string. TypeScript correctly rejected string | undefined. Destructure label and use a truthy ternary so the renderable Label only sees the narrowed non-empty string.
Add waitForAnimationToEnd after every screen transition to handle React Navigation slide_from_right animations that CI disable-animations does not suppress. Exercise interactive elements that were previously only asserted as visible: toggle color scheme on Appearance (Ocean → Purple), tap streaming quality radio on Playback, toggle Developer Options switch on Privacy & Developer to reveal the conditional PR ID input, and toggle gesture chips on Gestures with screenshot verification at each mutation point. Add scrolling to Storage (download settings below StorageSummaryCard), Playback (switches below radio group), About (patron list), and Account (server info chips) to catch below-the-fold content that fails on Pixel 6 emulator dimensions. Mix pressKey: back (5 screens) with tab-bar tap (1 screen) to test both Android back navigation and tab-bar return paths. Add rapid push/pop stress test — navigate to all 6 screens and immediately back with no waits — to catch stack navigator race conditions, followed by a persistence check re-entering Appearance to verify theme selection survived. Replace fragile swipe-based sign-out dismissal with deterministic tapOn Cancel button from the formSheet modal. Source changes: add testID passthrough to SwitchWithLabel, add developer-options-switch testID, add settings-screen-storage testID to Storage root for consistent wait selectors. 25 named screenshots across hub, all detail screens, mutation states, stress test, and persistence check.
Member
|
@skalthoff was this ready yet? |
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.
Replace the horizontal tab bar in Settings with a vertical hub-and-spoke layout: profile card, six nav rows (Appearance, Gestures, Playback, Storage, Privacy & Developer, About), and a sign-out button. Each section pushes a dedicated detail screen onto the Settings stack.
The Storage row routes to the existing Nitro-backed Storage screen, which now hosts the auto-download toggle and download quality radio inline at the top alongside the download manager UI.
Add Play Next as a swipe action across the settings store, swipe helper, Track row, and item-row, wired to the existing playNext() in the player queue hook.
Update maestro/tests/7-settings.yaml to walk the new navigation, exercise theme/preset selection, toggle each swipe chip including Play Next, verify the inline download settings, and dismiss the sign-out sheet without signing out. Add maestro/flows/flow-settings.yaml as a focused login + settings entry point.
iOS login flow tweaks: dismiss the keyboard with Enter (which also submits the form) and replace the slow optional permission-dialog taps with conditional runFlow blocks gated on visibility.
Reimplements PR #982 (settings redesign) and PR #1037 (Play Next) cleanly on top of Nitro Player main.




Tag reviewers
@anultravioletaurora