Skip to content

Static Navigators, Playlist Mutation Enhancements, Cut Down on Hooks#1160

Merged
anultravioletaurora merged 61 commits into
mainfrom
maintenance/move-to-static-navigators
May 9, 2026
Merged

Static Navigators, Playlist Mutation Enhancements, Cut Down on Hooks#1160
anultravioletaurora merged 61 commits into
mainfrom
maintenance/move-to-static-navigators

Conversation

@anultravioletaurora
Copy link
Copy Markdown
Member

@anultravioletaurora anultravioletaurora commented May 2, 2026

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:

  • Refactored playlist mutation logic into 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 introduced ensurePlaylistLibraryQueryData for consistent data fetching. [1] [2] [3] [4] [5] [6]

Navigation and component prop simplification:

  • Simplified navigation handling in artist-related components by using the useNavigation hook instead of passing navigation props, and removed unnecessary navigation prop requirements from context components. [1] [2] [3] [4]

App initialization and service registration:

  • Moved initialization of the track player and download manager from App.tsx to index.js to ensure they are registered before the app mounts, improving reliability of media features. [1] [2] [3] [4] [5]

UI/UX improvements:

  • Updated CarPlay and Discover tab labels for artist and album suggestions to more user-friendly phrases ("Artists for You", "More from the Vault"). [1] [2]

Test updates for track URL resolution:

  • Adjusted player queue tests to reflect that track URL resolution is now handled natively via onTracksNeedUpdate, removing direct calls to updateTrackMediaInfo in these scenarios. [1] [2] [3] [4]

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/*, adds ensurePlaylistLibraryQueryData, and updates cache update behavior for playlist lists/tracks.
  • Moves early service initialization (Nitro player + downloads) into index.js and 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

  • GenreSelectionScreen and YearSelectionScreen are 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.

Comment thread src/constants/query-client.ts
Comment thread src/api/mutations/playlist/index.ts Outdated
Comment thread src/api/mutations/playlist/index.ts
Comment thread src/components/Player/components/song-info.tsx
Comment thread src/components/Player/components/song-info.tsx
Comment thread src/screens/Settings/sign-out-modal.tsx
Comment thread src/screens/Library/index.tsx Outdated
Comment thread src/screens/GenreSelection/index.tsx Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 103 out of 110 changed files in this pull request and generated 11 comments.

Comment thread src/services/player.ts
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 thread src/services/player.ts
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 thread src/screens/Library/index.ts Outdated
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
}
@anultravioletaurora anultravioletaurora merged commit 611b636 into main May 9, 2026
6 checks passed
@anultravioletaurora anultravioletaurora deleted the maintenance/move-to-static-navigators branch May 9, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants