Static Navigators, Playlist Mutation Enhancements, Cut Down on Hooks#1160
Merged
Conversation
remove top level useEffect from App.tsx fix player context navigation
rework playlist screens, move their hooks to the api folder
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors navigation to React Navigation’s static navigator configuration while consolidating playlist mutation logic into dedicated hooks/utilities and standardizing user feedback patterns (haptics → react-native-pulsar presets) across several screens/components.
Changes:
- Migrates multiple navigators (Root/Tabs/Library/Discover/Settings) to static configuration and simplifies navigation prop passing by relying more on
useNavigation/ refs. - Refactors playlist mutations into
src/api/mutations/playlist/*, addsensurePlaylistLibraryQueryData, and updates cache update behavior for playlist lists/tracks. - Moves early service initialization (Nitro player + downloads) into
index.jsand updates various UI strings/labels.
Reviewed changes
Copilot reviewed 45 out of 47 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/logging/enums.ts | Adds a dedicated logging context for Nitro player configuration. |
| src/services/player.ts | Renames/updates player registration to configure Nitro TrackPlayer with logging on failure. |
| src/services/downloads.ts | Replaces hardcoded download manager constants with config-driven values. |
| src/screens/YearSelection/index.tsx | Switches to useNavigation, updates feedback to Pulsar presets, and adjusts route typing. |
| src/screens/types.d.ts | Moves several library-related sheet routes/types out of the root stack types. |
| src/screens/Tabs/tab-bar.tsx | Adjusts tab bar theming merge logic to update descriptor options. |
| src/screens/Tabs/index.tsx | Converts Tabs to a static navigator definition and updates nested stacks used per tab. |
| src/screens/SortOptions/index.tsx | Updates props typing import location after navigation refactor. |
| src/screens/Settings/types.d.ts | Prunes Settings stack param list to the routes actually hosted by Settings stack. |
| src/screens/Settings/sign-out-modal.tsx | Converts to useNavigation rather than receiving navigation via props. |
| src/screens/Settings/index.tsx | Converts Settings stack to static navigator configuration. |
| src/screens/Login/server-library.tsx | Simplifies navigation into Tabs after login/library selection. |
| src/screens/Library/types.ts | Relocates Library-related sheet routes/types into Library stack param list. |
| src/screens/Library/index.tsx | Converts Library stack to static config and adds library-scoped sheets/routes (Filters/Sort/Genre/Year/DeletePlaylist). |
| src/screens/Library/delete-playlist.tsx | Switches delete flow to shared mutation hook and useNavigation. |
| src/screens/Library/add-playlist.tsx | Switches add flow to shared mutation hook and updates pending UI. |
| src/screens/index.tsx | Migrates root navigation to static navigation via createStaticNavigation and centralized theme application. |
| src/screens/GenreSelection/index.tsx | Switches to useNavigation and partially migrates feedback to Pulsar presets. |
| src/screens/Filters/index.tsx | Simplifies wrapper to stop passing navigation down into Filters component. |
| src/screens/Discover/index.tsx | Converts Discover stack to static config and updates some titles. |
| src/screens/Context/index.tsx | Stops passing navigation prop to ItemContext screen component. |
| src/screens/Artist/index.tsx | Simplifies Artist screen to render overview tab directly. |
| src/screens/Album/index.tsx | Removes unused navigation prop from Album screen wrapper. |
| src/hooks/player/functions/shuffle.ts | Updates queue reference label for library shuffle. |
| src/hooks/player/functions/queue.ts | Replaces haptics with Pulsar presets; optimizes lookahead media info update. |
| src/constants/query-client.ts | Centralizes retry attempts via config constant. |
| src/configs/query.config.ts | Introduces MAX_RETRY_ATTEMPTS. |
| src/configs/download.config.ts | Adjusts max concurrent downloads constant. |
| src/components/SortOptions/index.tsx | Replaces haptic feedback with Pulsar presets. |
| src/components/Playlist/index.tsx | Switches to shared update-playlist hook and removes explicit navigation prop passing. |
| src/components/Player/components/song-info.tsx | Refactors navigation actions from player to album/artist/context to use navigation hooks + actions. |
| src/components/Library/tab-bar.tsx | Replaces haptics with Pulsar presets and routes Filters/Sort to Library stack. |
| src/components/Library/component.tsx | Converts library top tabs to static config and uses navigation theme colors. |
| src/components/Filters/index.tsx | Removes navigation prop and uses library stack navigation + Pulsar presets. |
| src/components/Discover/helpers/suggested-artists.tsx | Updates suggested artists header copy. |
| src/components/Context/index.tsx | Removes required navigation prop from Context component’s props. |
| src/components/Context/components/remove-from-playlist-row.tsx | Updates playlist mutation import path. |
| src/components/Context/components/delete-playlist-row.tsx | Cleans up imports while keeping DeletePlaylist push behavior. |
| src/components/CarPlay/Discover.tsx | Updates CarPlay Discover menu text for artists/albums suggestions. |
| src/components/Artist/OverviewTab.tsx | Uses useNavigation rather than receiving navigation via props. |
| src/components/Artist/index.tsx | Removes now-unnecessary ArtistNavigation wrapper component. |
| src/components/AddToPlaylist/index.tsx | Updates playlist mutation import path. |
| src/api/queries/libraries/index.ts | Adds ensurePlaylistLibraryQueryData() helper for mutations/cache updates. |
| src/api/mutations/playlist/utils/playlists.ts | Moves playlist mutation utilities and changes createPlaylist to return new playlist id. |
| src/api/mutations/playlist/index.ts | Adds playlist mutation hooks (add/delete/update) with cache updates and feedback handling. |
| index.js | Runs Nitro player registration and download manager configuration before app mounts. |
| App.tsx | Removes late initialization of player/download services and removes NavigationContainer wrapper (now provided by Root static navigation). |
Comments suppressed due to low confidence (1)
src/screens/index.tsx:20
GenreSelectionScreenandYearSelectionScreenare imported but no longer referenced in the RootStack static config. Remove these unused imports to avoid TS/eslint noUnusedLocals failures.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
screens folder organization
…move-to-static-navigators
…move-to-static-navigators
also bump some deps as long as we're doing a release with this branch
Comment on lines
+7
to
+13
| export async function configureNitroPlayer(config: Partial<PlayerConfig>) { | ||
| try { | ||
| await TrackPlayer.configure(config) | ||
| } catch (error) { | ||
| captureError(error, LoggingContext.NitroPlayer, 'Failed to reconfigure TrackPlayer') | ||
| } | ||
| } |
Comment on lines
+15
to
20
| export default function registerNitroPlayer() { | ||
| const lookaheadCount = usePlayerSettingsStore.getState().lookahead | ||
|
|
||
| configureNitroPlayer({ | ||
| lookaheadCount, | ||
| }) |
Comment on lines
+44
to
+51
| lookahead: DEFAULT_PLAYER_LOOKAHEAD, | ||
| setLookahead: async (lookahead) => { | ||
| await configureNitroPlayer({ | ||
| lookaheadCount: lookahead, | ||
| }) | ||
|
|
||
| set({ lookahead }) | ||
| }, |
Comment on lines
+50
to
+58
| useAnimatedReaction( | ||
| () => lookaheadSharedValue, | ||
| (prepared) => { | ||
| const rounded = Math.round(prepared.value) | ||
| if (rounded !== lookahead) { | ||
| runOnJS(handleLookaheadChange)(rounded) | ||
| } | ||
| }, | ||
| ) |
Comment on lines
+18
to
+20
| import Slider from '@jellify-music/react-native-reanimated-slider' | ||
| import Animated, { useAnimatedReaction, useSharedValue } from 'react-native-reanimated' | ||
| import { runOnJS } from 'react-native-worklets' |
Comment on lines
46
to
59
| const handleArtistPress = () => { | ||
| if (item?.ArtistItems) { | ||
| if (item.ArtistItems.length > 1) { | ||
| navigationRef.dispatch( | ||
| CommonActions.navigate('MultipleArtistsSheet', { | ||
| artists: item.ArtistItems, | ||
| }), | ||
| ) | ||
| playerStackNavigation.navigate('MultipleArtistsSheet', { | ||
| artists: item.ArtistItems, | ||
| }) | ||
| } else { | ||
| navigationRef.goBack() // Dismiss player modal | ||
| playerStackNavigation.pop() | ||
| navigationRef.dispatch( | ||
| CommonActions.navigate('Artist', { artist: item.ArtistItems[0] }), | ||
| StackActions.push('Artist', { | ||
| artist: item.ArtistItems[0], | ||
| }), | ||
| ) | ||
| } |
Comment on lines
+24
to
+33
| // Post updated capabilities to the server whenever the device profile changes | ||
| const api = getApi() | ||
| if (api && api.accessToken !== '') { | ||
| getSessionApi(api).postFullCapabilities({ | ||
| clientCapabilitiesDto: { | ||
| IconUrl: MONOCHROME_ICON_URL, | ||
| DeviceProfile: data, | ||
| }, | ||
| }) | ||
| } |
Comment on lines
+39
to
+49
| onRehydrateStorage: ({ deviceProfile }) => { | ||
| // Post capabilities on app start to ensure the server has the latest profile | ||
| const api = getApi() | ||
| if (api && api.accessToken !== '') { | ||
| getSessionApi(api).postFullCapabilities({ | ||
| clientCapabilitiesDto: { | ||
| IconUrl: MONOCHROME_ICON_URL, | ||
| DeviceProfile: deviceProfile, | ||
| }, | ||
| }) | ||
| } |
Comment on lines
+1
to
+10
| import { PlaylistScreen } from '../Playlist' | ||
| import AddPlaylist from './add-playlist' | ||
| import ArtistScreen from '../Artist' | ||
| import { createNativeStackNavigator } from '@react-navigation/native-stack' | ||
| import AlbumScreen from '../Album' | ||
| import LibraryStackParamList from './types' | ||
| import InstantMix from '../../components/InstantMix/component' | ||
| import { getItemName } from '../../utils/formatting/item-names' | ||
| import TracksScreen from '../Tracks' | ||
| import { bottomSheetPresentation } from '../../utils/navigating/form-sheet' |
Comment on lines
9
to
13
| AddPlaylist: undefined | ||
| Filters: undefined | ||
| DeletePlaylist: { | ||
| playlist: BaseItemDto | ||
| onDelete: () => void | ||
| } |
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.
This pull request refactors playlist mutation logic, improves navigation consistency, and updates several UI labels. The playlist mutation code is modularized and enhanced for better state management and user feedback. Navigation props are streamlined in artist-related components, and some UI text is clarified for a more user-friendly experience. Additionally, initialization logic for media services is moved to the app entry point, and tests are updated to reflect changes in track URL resolution.
Playlist mutation refactor and improvements:
src/api/mutations/playlist/, separating utility functions and hooks for creating, updating, and deleting playlists, and ensuring UI state updates and user feedback with toasts and haptics. Also added cache updates for playlist creation/deletion and introducedensurePlaylistLibraryQueryDatafor consistent data fetching. [1] [2] [3] [4] [5] [6]Navigation and component prop simplification:
useNavigationhook instead of passing navigation props, and removed unnecessary navigation prop requirements from context components. [1] [2] [3] [4]App initialization and service registration:
App.tsxtoindex.jsto ensure they are registered before the app mounts, improving reliability of media features. [1] [2] [3] [4] [5]UI/UX improvements:
Test updates for track URL resolution:
onTracksNeedUpdate, removing direct calls toupdateTrackMediaInfoin these scenarios. [1] [2] [3] [4]