From b15ec8b095928fdb38d34942eae9da69a9b4693f Mon Sep 17 00:00:00 2001 From: Violet Caulfield <42452695+anultravioletaurora@users.noreply.github.com> Date: Sun, 3 Aug 2025 18:57:57 -0500 Subject: [PATCH] Queue Provider Optimizations, Alphabetical Selector Optimizations, Artist Pagination Improvements (#467) * make now playing change faster when loading a new queue * queue provider optimizations * Improvements to the alphabetical selector handling in the artists page. * Improvements to artists pagination - fetching more artists at a given time --- jest/contextual/QueueProvider.test.tsx | 13 +- jest/contextual/Shuffle.test.tsx | 27 ++- package.json | 14 +- src/api/queries/artist.ts | 24 +-- src/components/Album/index.tsx | 4 +- src/components/Artist/tab-bar.tsx | 4 +- src/components/Artists/component.tsx | 110 +++++++---- .../Detail/helpers/TrackOptions.tsx | 4 +- src/components/Global/components/image.tsx | 8 +- src/components/Global/components/item-row.tsx | 4 +- src/components/Global/components/track.tsx | 5 +- .../Home/helpers/frequent-tracks.tsx | 4 +- .../Home/helpers/recently-played.tsx | 4 +- .../Library/components/artists-tab.tsx | 3 +- src/components/Player/components/controls.tsx | 11 +- src/components/Player/components/header.tsx | 4 +- src/components/Player/mini-player.tsx | 5 +- src/components/Player/queue.tsx | 23 ++- src/components/Playlist/components/header.tsx | 4 +- .../Settings/components/labs-tab.tsx | 4 +- src/components/types.d.ts | 3 + src/enums/query-keys.ts | 21 ++ src/providers/CarPlay/index.tsx | 6 +- src/providers/Library/index.tsx | 80 ++++---- src/providers/Player/README.md | 2 +- src/providers/Player/index.tsx | 43 +++-- src/providers/Player/queue.tsx | 181 +++++++++++------- src/screens/Settings/sign-out-modal.tsx | 4 +- yarn.lock | 61 +++--- 29 files changed, 417 insertions(+), 263 deletions(-) diff --git a/jest/contextual/QueueProvider.test.tsx b/jest/contextual/QueueProvider.test.tsx index 9ddbac2b..44cf3f33 100644 --- a/jest/contextual/QueueProvider.test.tsx +++ b/jest/contextual/QueueProvider.test.tsx @@ -5,14 +5,23 @@ import { Event } from 'react-native-track-player' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { Button, Text } from 'react-native' -import { QueueProvider, useQueueContext } from '../../src/providers/Player/queue' +import { + QueueProvider, + useCurrentIndexContext, + usePreviousContext, + useSetPlayQueueContext, + useSkipContext, +} from '../../src/providers/Player/queue' import { eventHandler } from '../setup/rntp' import JellifyTrack from '../../src/types/JellifyTrack' const queryClient = new QueryClient() const QueueConsumer = () => { - const { currentIndex, useSkip, usePrevious, playQueue, setPlayQueue } = useQueueContext() + const currentIndex = useCurrentIndexContext() + const useSkip = useSkipContext() + const usePrevious = usePreviousContext() + const setPlayQueue = useSetPlayQueueContext() const tracklist: JellifyTrack[] = [ { diff --git a/jest/contextual/Shuffle.test.tsx b/jest/contextual/Shuffle.test.tsx index 0cccd766..5da55322 100644 --- a/jest/contextual/Shuffle.test.tsx +++ b/jest/contextual/Shuffle.test.tsx @@ -5,7 +5,16 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { Button, Text } from 'react-native' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models' -import { QueueProvider, useQueueContext } from '../../src/providers/Player/queue' +import { + QueueProvider, + usePlayQueueContext, + useCurrentIndexContext, + useSetPlayQueueContext, + useSetCurrentIndexContext, + useShuffledContext, + useSetUnshuffledQueueContext, + useUnshuffledQueueContext, +} from '../../src/providers/Player/queue' import { PlayerProvider, usePlayerContext } from '../../src/providers/Player' import JellifyTrack from '../../src/types/JellifyTrack' import { QueuingType } from '../../src/enums/queuing-type' @@ -82,15 +91,13 @@ const createMockTracks = (count: number): JellifyTrack[] => { } const TestComponent = () => { - const { - playQueue, - setPlayQueue, - currentIndex, - setCurrentIndex, - shuffled, - unshuffledQueue, - setUnshuffledQueue, - } = useQueueContext() + const playQueue = usePlayQueueContext() + const setPlayQueue = useSetPlayQueueContext() + const currentIndex = useCurrentIndexContext() + const setCurrentIndex = useSetCurrentIndexContext() + const shuffled = useShuffledContext() + const unshuffledQueue = useUnshuffledQueueContext() + const setUnshuffledQueue = useSetUnshuffledQueueContext() const { useToggleShuffle, shuffled: playerShuffled } = usePlayerContext() const testTracks = createMockTracks(5) diff --git a/package.json b/package.json index 633a6815..4291ad03 100644 --- a/package.json +++ b/package.json @@ -39,10 +39,10 @@ "@react-native-community/netinfo": "^11.4.1", "@react-native-masked-view/masked-view": "^0.3.2", "@react-native-picker/picker": "^2.11.1", - "@react-navigation/bottom-tabs": "^7.4.4", - "@react-navigation/material-top-tabs": "^7.3.4", - "@react-navigation/native": "^7.1.16", - "@react-navigation/native-stack": "^7.3.23", + "@react-navigation/bottom-tabs": "^7.4.5", + "@react-navigation/material-top-tabs": "^7.3.5", + "@react-navigation/native": "^7.1.17", + "@react-navigation/native-stack": "^7.3.24", "@sentry/react-native": "^6.17.0", "@shopify/flash-list": "^2.0.1", "@tamagui/config": "^1.132.15", @@ -89,7 +89,9 @@ "react-native-uuid": "^2.0.3", "react-native-vector-icons": "^10.2.0", "ruby": "^0.6.1", - "tamagui": "^1.132.15" + "scheduler": "^0.26.0", + "tamagui": "^1.132.15", + "use-context-selector": "^2.0.0" }, "devDependencies": { "@babel/core": "^7.28.0", @@ -137,4 +139,4 @@ "node": ">=18" }, "packageManager": "yarn@1.22.22" -} \ No newline at end of file +} diff --git a/src/api/queries/artist.ts b/src/api/queries/artist.ts index c5fe555f..3c798813 100644 --- a/src/api/queries/artist.ts +++ b/src/api/queries/artist.ts @@ -3,43 +3,45 @@ import { Api } from '@jellyfin/sdk/lib/api' import { BaseItemDto, BaseItemKind, + ItemFields, ItemSortBy, SortOrder, } from '@jellyfin/sdk/lib/generated-client/models' import { getArtistsApi, getItemsApi } from '@jellyfin/sdk/lib/utils/api' import { JellifyUser } from '../../types/JellifyUser' import QueryConfig from './query.config' -import { alphabet } from '../../providers/Library' + export function fetchArtists( api: Api | undefined, user: JellifyUser | undefined, library: JellifyLibrary | undefined, - page: string | number, + page: number, isFavorite: boolean | undefined, sortBy: ItemSortBy[] = [ItemSortBy.SortName], sortOrder: SortOrder[] = [SortOrder.Ascending], -): Promise<{ title: string | number; data: BaseItemDto[] }> { +): Promise { console.debug('Fetching artists', page) return new Promise((resolve, reject) => { if (!api) return reject('No API instance provided') + if (!user) return reject('No user provided') + if (!library) return reject('Library has not been set') getArtistsApi(api) .getAlbumArtists({ - parentId: library?.musicLibraryId, - userId: user?.id, + parentId: library.musicLibraryId, + userId: user.id, enableUserData: true, sortBy: sortBy, sortOrder: sortOrder, - startIndex: typeof page === 'number' ? page * QueryConfig.limits.library : 0, + startIndex: page * QueryConfig.limits.library, + limit: QueryConfig.limits.library, isFavorite: isFavorite, - nameStartsWith: typeof page === 'string' && page !== alphabet[0] ? page : undefined, - nameLessThan: typeof page === 'string' && page === alphabet[0] ? 'A' : undefined, + fields: [ItemFields.SortName], }) .then((response) => { - return response.data.Items - ? resolve({ title: page, data: response.data.Items }) - : resolve({ title: page, data: [] }) + console.debug('Artists Response received') + return response.data.Items ? resolve(response.data.Items) : resolve([]) }) .catch((error) => { reject(error) diff --git a/src/components/Album/index.tsx b/src/components/Album/index.tsx index b3ed0ffc..257d70eb 100644 --- a/src/components/Album/index.tsx +++ b/src/components/Album/index.tsx @@ -17,7 +17,7 @@ import Icon from '../Global/components/icon' import { mapDtoToTrack } from '../../utils/mappings' import { useNetworkContext } from '../../providers/Network' import { useSettingsContext } from '../../providers/Settings' -import { useQueueContext } from '../../providers/Player/queue' +import { useLoadQueueContext } from '../../providers/Player/queue' import { QueuingType } from '../../enums/queuing-type' import { useAlbumContext } from '../../providers/Album' @@ -41,7 +41,7 @@ export function Album({ navigation }: AlbumProps): React.JSX.Element { failedDownloads, } = useNetworkContext() const { downloadQuality, streamingQuality } = useSettingsContext() - const { useLoadNewQueue } = useQueueContext() + const useLoadNewQueue = useLoadQueueContext() const downloadAlbum = (item: BaseItemDto[]) => { if (!api || !sessionId) return diff --git a/src/components/Artist/tab-bar.tsx b/src/components/Artist/tab-bar.tsx index 6dc57ca5..3eac4411 100644 --- a/src/components/Artist/tab-bar.tsx +++ b/src/components/Artist/tab-bar.tsx @@ -14,7 +14,7 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { StackParamList } from '../types' import React from 'react' import Icon from '../Global/components/icon' -import { useQueueContext } from '../../providers/Player/queue' +import { useLoadQueueContext } from '../../providers/Player/queue' import { QueuingType } from '../../enums/queuing-type' import { fetchAlbumDiscs } from '../../api/queries/item' @@ -24,7 +24,7 @@ export default function ArtistTabBar( ) { const { api } = useJellifyContext() const { artist, scroll, albums } = useArtistContext() - const { useLoadNewQueue } = useQueueContext() + const useLoadNewQueue = useLoadQueueContext() const { width } = useSafeAreaFrame() diff --git a/src/components/Artists/component.tsx b/src/components/Artists/component.tsx index 87445282..e9c9c017 100644 --- a/src/components/Artists/component.tsx +++ b/src/components/Artists/component.tsx @@ -1,62 +1,96 @@ import React, { useEffect, useRef } from 'react' -import { getToken, getTokenValue, Separator, useTheme, XStack, YStack } from 'tamagui' +import { getToken, Separator, useTheme, XStack, YStack, Spinner } from 'tamagui' import { Text } from '../Global/helpers/text' -import { RefreshControl } from 'react-native' +import { ActivityIndicator, RefreshControl } from 'react-native' import { ArtistsProps } from '../types' import ItemRow from '../Global/components/item-row' -import { useLibraryContext, useLibrarySortAndFilterContext } from '../../providers/Library' +import { useLibrarySortAndFilterContext } from '../../providers/Library' import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models/base-item-dto' import { FlashList, FlashListRef } from '@shopify/flash-list' import { AZScroller } from '../Global/components/alphabetical-selector' import { useMutation } from '@tanstack/react-query' +import { isString } from 'lodash' +/** + * @param artistsInfiniteQuery - The infinite query for artists + * @param navigation - The navigation object + * @param showAlphabeticalSelector - Whether to show the alphabetical selector + * @param artistPageParams - The page params for the artists - which are the A-Z letters that have been seen + * @returns The Artists component + */ export default function Artists({ artistsInfiniteQuery, navigation, showAlphabeticalSelector, + artistPageParams, }: ArtistsProps): React.JSX.Element { - const { artistPageParams } = useLibraryContext() const theme = useTheme() const { isFavorites } = useLibrarySortAndFilterContext() + const artists = artistsInfiniteQuery.data ?? [] const sectionListRef = useRef>(null) - const itemHeight = getToken('$6') + const pendingLetterRef = useRef(null) const MemoizedItem = React.memo(ItemRow) - const artistsRef = useRef<(string | number | BaseItemDto)[]>(artistsInfiniteQuery.data ?? []) - const alphabeticalSelectorCallback = async (letter: string) => { console.debug(`Alphabetical Selector Callback: ${letter}`) - do { - if (artistPageParams.current.includes(letter)) break - await artistsInfiniteQuery.fetchNextPage({ cancelRefetch: true }) - } while ( - !artistsRef.current.includes(letter) && - artistsInfiniteQuery.hasNextPage && - (!artistsInfiniteQuery.isFetchNextPageError || artistsInfiniteQuery.isFetchingNextPage) - ) + while ( + !artistPageParams!.current.has(letter.toUpperCase()) && + artistsInfiniteQuery.hasNextPage + ) { + if (!artistsInfiniteQuery.isPending) { + await artistsInfiniteQuery.fetchNextPage() + } + } + console.debug(`Alphabetical Selector Callback: ${letter} complete`) } const { mutate: alphabetSelectorMutate, isPending: isAlphabetSelectorPending } = useMutation({ mutationFn: (letter: string) => alphabeticalSelectorCallback(letter), onSuccess: (data, letter) => { - setTimeout(() => { - sectionListRef.current?.scrollToIndex({ - index: artistsRef.current!.indexOf(letter), - viewPosition: 0.1, - animated: true, - }) - }, 500) + pendingLetterRef.current = letter.toUpperCase() }, }) + // Effect for handling the pending alphabet selector letter useEffect(() => { - artistsRef.current = artistsInfiniteQuery.data ?? [] - console.debug(`artists: ${JSON.stringify(artistsInfiniteQuery.data)}`) - }, [artistsInfiniteQuery.data]) + if (isString(pendingLetterRef.current) && artistsInfiniteQuery.data) { + const upperLetters = artists + .filter((item): item is string => typeof item === 'string') + .map((letter) => letter.toUpperCase()) + .sort() + + const index = upperLetters.findIndex((letter) => letter >= pendingLetterRef.current!) + + if (index !== -1) { + const letterToScroll = upperLetters[index] + const scrollIndex = artists.indexOf(letterToScroll) + if (scrollIndex !== -1) { + sectionListRef.current?.scrollToIndex({ + index: scrollIndex, + viewPosition: 0.1, + animated: true, + }) + } + } else { + // fallback: scroll to last section + const lastLetter = upperLetters[upperLetters.length - 1] + const scrollIndex = artists.indexOf(lastLetter) + if (scrollIndex !== -1) { + sectionListRef.current?.scrollToIndex({ + index: scrollIndex, + viewPosition: 0.1, + animated: true, + }) + } + } + + pendingLetterRef.current = null + } + }, [pendingLetterRef.current, artistsInfiniteQuery.data]) return ( @@ -79,20 +113,20 @@ export default function Artists({ : item.Id! } ItemSeparatorComponent={() => } - data={artistsInfiniteQuery.data} + data={artists} refreshControl={ artistsInfiniteQuery.refetch()} + tintColor={theme.primary.val} /> } renderItem={({ index, item: artist }) => typeof artist === 'string' ? ( // Don't render the letter if we don't have any artists that start with it // If the index is the last index, or the next index is not an object, then don't render the letter - index - 1 === artistsInfiniteQuery.data!.length || - typeof artistsInfiniteQuery.data![index + 1] !== 'object' ? null : ( + index - 1 === artists.length || + typeof artists[index + 1] !== 'object' ? null : ( ) : null } - ListEmptyComponent={ - artistsInfiniteQuery.isPending || - artistsInfiniteQuery.isFetchingNextPage ? null : ( - - No artists - - ) - } stickyHeaderIndices={ showAlphabeticalSelector - ? artistsInfiniteQuery.data + ? artists ?.map((artist, index, artists) => typeof artist === 'string' ? index : 0, ) @@ -142,7 +168,9 @@ export default function Artists({ removeClippedSubviews /> - {showAlphabeticalSelector && } + {showAlphabeticalSelector && artistPageParams && ( + + )} ) } diff --git a/src/components/Detail/helpers/TrackOptions.tsx b/src/components/Detail/helpers/TrackOptions.tsx index 565e0dca..5cdc9867 100644 --- a/src/components/Detail/helpers/TrackOptions.tsx +++ b/src/components/Detail/helpers/TrackOptions.tsx @@ -30,7 +30,7 @@ import { fetchUserPlaylists } from '../../../api/queries/playlists' import { useJellifyContext } from '../../../providers' import { getImageApi, getItemsApi } from '@jellyfin/sdk/lib/utils/api' import { useNetworkContext } from '../../../providers/Network' -import { useQueueContext } from '../../../providers/Player/queue' +import { useAddToQueueContext } from '../../../providers/Player/queue' import Toast from 'react-native-toast-message' import FastImage from 'react-native-fast-image' import Icon from '../../../components/Global/components/icon' @@ -111,7 +111,7 @@ export default function TrackOptions({ return result }, [playlistsWithTracks.data, track.Id]) - const { useAddToQueue } = useQueueContext() + const useAddToQueue = useAddToQueueContext() const { width } = useSafeAreaFrame() diff --git a/src/components/Global/components/image.tsx b/src/components/Global/components/image.tsx index 4aa02afa..bd0b4429 100644 --- a/src/components/Global/components/image.tsx +++ b/src/components/Global/components/image.tsx @@ -3,8 +3,9 @@ import { getImageApi } from '@jellyfin/sdk/lib/utils/api' import { isUndefined } from 'lodash' import { getTokenValue, Token, useTheme } from 'tamagui' import { useJellifyContext } from '../../../providers' -import { ImageStyle, StyleProp, ViewStyle } from 'react-native' +import { ImageStyle } from 'react-native' import FastImage from 'react-native-fast-image' +import { ImageType } from '@jellyfin/sdk/lib/generated-client/models' interface ImageProps { item: BaseItemDto @@ -28,7 +29,10 @@ export default function ItemImage({ const imageUrl = api && - ((item.AlbumId && getImageApi(api).getItemImageUrlById(item.AlbumId)) || + ((item.AlbumId && + getImageApi(api).getItemImageUrlById(item.AlbumId, ImageType.Primary, { + tag: item.ImageTags?.Primary, + })) || (item.Id && getImageApi(api).getItemImageUrlById(item.Id)) || '') diff --git a/src/components/Global/components/item-row.tsx b/src/components/Global/components/item-row.tsx index 01e362c5..1a68934c 100644 --- a/src/components/Global/components/item-row.tsx +++ b/src/components/Global/components/item-row.tsx @@ -6,7 +6,7 @@ import { Text } from '../helpers/text' import Icon from './icon' import { QueuingType } from '../../../enums/queuing-type' import { RunTimeTicks } from '../helpers/time-codes' -import { useQueueContext } from '../../../providers/Player/queue' +import { useLoadQueueContext } from '../../../providers/Player/queue' import ItemImage from './image' import FavoriteIcon from './favorite-icon' import { Gesture, GestureDetector } from 'react-native-gesture-handler' @@ -36,7 +36,7 @@ export default function ItemRow({ onPress?: () => void circular?: boolean }): React.JSX.Element { - const { useLoadNewQueue } = useQueueContext() + const useLoadNewQueue = useLoadQueueContext() const gestureCallback = () => { switch (item.Type) { diff --git a/src/components/Global/components/track.tsx b/src/components/Global/components/track.tsx index 76e4841b..66b7b3e8 100644 --- a/src/components/Global/components/track.tsx +++ b/src/components/Global/components/track.tsx @@ -14,7 +14,7 @@ import FastImage from 'react-native-fast-image' import { getImageApi } from '@jellyfin/sdk/lib/utils/api' import { networkStatusTypes } from '../../../components/Network/internetConnectionWatcher' import { useNetworkContext } from '../../../providers/Network' -import { useQueueContext } from '../../../providers/Player/queue' +import { useLoadQueueContext, usePlayQueueContext } from '../../../providers/Player/queue' import { useJellifyContext } from '../../../providers' import DownloadedIcon from './downloaded-icon' @@ -53,7 +53,8 @@ export default function Track({ const theme = useTheme() const { api } = useJellifyContext() const { nowPlaying } = usePlayerContext() - const { playQueue, useLoadNewQueue } = useQueueContext() + const playQueue = usePlayQueueContext() + const useLoadNewQueue = useLoadQueueContext() const { downloadedTracks, networkStatus } = useNetworkContext() const isPlaying = nowPlaying?.item.Id === track.Id diff --git a/src/components/Home/helpers/frequent-tracks.tsx b/src/components/Home/helpers/frequent-tracks.tsx index a1664d4c..e93291d4 100644 --- a/src/components/Home/helpers/frequent-tracks.tsx +++ b/src/components/Home/helpers/frequent-tracks.tsx @@ -7,7 +7,7 @@ import { ItemCard } from '../../../components/Global/components/item-card' import { QueuingType } from '../../../enums/queuing-type' import { trigger } from 'react-native-haptic-feedback' import Icon from '../../Global/components/icon' -import { useQueueContext } from '../../../providers/Player/queue' +import { useLoadQueueContext } from '../../../providers/Player/queue' import { H4 } from '../../../components/Global/helpers/text' import { useDisplayContext } from '../../../providers/Display/display-provider' export default function FrequentlyPlayedTracks({ @@ -22,7 +22,7 @@ export default function FrequentlyPlayedTracks({ isFetchingFrequentlyPlayed, } = useHomeContext() - const { useLoadNewQueue } = useQueueContext() + const useLoadNewQueue = useLoadQueueContext() const { horizontalItems } = useDisplayContext() return ( diff --git a/src/components/Home/helpers/recently-played.tsx b/src/components/Home/helpers/recently-played.tsx index 8deae969..9b2b88e6 100644 --- a/src/components/Home/helpers/recently-played.tsx +++ b/src/components/Home/helpers/recently-played.tsx @@ -10,7 +10,7 @@ import { trigger } from 'react-native-haptic-feedback' import { QueuingType } from '../../../enums/queuing-type' import HorizontalCardList from '../../../components/Global/components/horizontal-list' import Icon from '../../Global/components/icon' -import { useQueueContext } from '../../../providers/Player/queue' +import { useLoadQueueContext } from '../../../providers/Player/queue' import { useDisplayContext } from '../../../providers/Display/display-provider' export default function RecentlyPlayed({ @@ -20,7 +20,7 @@ export default function RecentlyPlayed({ }): React.JSX.Element { const { nowPlaying } = usePlayerContext() - const { useLoadNewQueue } = useQueueContext() + const useLoadNewQueue = useLoadQueueContext() const { recentTracks, fetchNextRecentTracks, hasNextRecentTracks, isFetchingRecentTracks } = useHomeContext() diff --git a/src/components/Library/components/artists-tab.tsx b/src/components/Library/components/artists-tab.tsx index 2f885b60..3b91a11b 100644 --- a/src/components/Library/components/artists-tab.tsx +++ b/src/components/Library/components/artists-tab.tsx @@ -5,7 +5,7 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack' import { StackParamList } from '../../types' export default function ArtistsTab(): React.JSX.Element { - const { artistsInfiniteQuery } = useLibraryContext() + const { artistsInfiniteQuery, artistPageParams } = useLibraryContext() const navigation = useNavigation>() @@ -14,6 +14,7 @@ export default function ArtistsTab(): React.JSX.Element { artistsInfiniteQuery={artistsInfiniteQuery} navigation={navigation} showAlphabeticalSelector={true} + artistPageParams={artistPageParams} /> ) } diff --git a/src/components/Player/components/controls.tsx b/src/components/Player/components/controls.tsx index 7ed514ff..5e8c650c 100644 --- a/src/components/Player/components/controls.tsx +++ b/src/components/Player/components/controls.tsx @@ -3,14 +3,19 @@ import { Spacer, XStack, getToken } from 'tamagui' import PlayPauseButton from './buttons' import Icon from '../../Global/components/icon' import { usePlayerContext } from '../../../providers/Player' -import { useQueueContext } from '../../../providers/Player/queue' +import { + usePreviousContext, + useShuffledContext, + useSkipContext, +} from '../../../providers/Player/queue' import { RepeatMode } from 'react-native-track-player' export default function Controls(): React.JSX.Element { - const { usePrevious, useSkip } = useQueueContext() + const usePrevious = usePreviousContext() + const useSkip = useSkipContext() const { useToggleShuffle, useToggleRepeatMode, repeatMode } = usePlayerContext() - const { shuffled } = useQueueContext() + const shuffled = useShuffledContext() return ( { navigation.setOptions({ diff --git a/src/components/Playlist/components/header.tsx b/src/components/Playlist/components/header.tsx index e8cb7b05..2a01e1d0 100644 --- a/src/components/Playlist/components/header.tsx +++ b/src/components/Playlist/components/header.tsx @@ -16,7 +16,7 @@ import { useNetworkContext } from '../../../../src/providers/Network' import { useSettingsContext } from '../../../../src/providers/Settings' import { ActivityIndicator } from 'react-native' import { mapDtoToTrack } from '../../../utils/mappings' -import { useQueueContext } from '../../../providers/Player/queue' +import { useLoadQueueContext } from '../../../providers/Player/queue' import { QueuingType } from '../../../enums/queuing-type' export default function PlayliistTracklistHeader( @@ -148,7 +148,7 @@ function PlaylistHeaderControls({ }): React.JSX.Element { const { useDownloadMultiple, pendingDownloads } = useNetworkContext() const { downloadQuality, streamingQuality } = useSettingsContext() - const { useLoadNewQueue } = useQueueContext() + const useLoadNewQueue = useLoadQueueContext() const isDownloading = pendingDownloads.length != 0 const { sessionId, api } = useJellifyContext() diff --git a/src/components/Settings/components/labs-tab.tsx b/src/components/Settings/components/labs-tab.tsx index c2c9cc28..2f311e4e 100644 --- a/src/components/Settings/components/labs-tab.tsx +++ b/src/components/Settings/components/labs-tab.tsx @@ -19,9 +19,9 @@ export default function LabsTab(): React.JSX.Element { children: (