diff --git a/maestro-tests/musicplayer.yaml b/maestro-tests/musicplayer.yaml
index 5860cea6..2cc989ea 100644
--- a/maestro-tests/musicplayer.yaml
+++ b/maestro-tests/musicplayer.yaml
@@ -34,10 +34,6 @@ appId: com.jellify
- tapOn:
id: "play-button-test-id"
-# check if the pause button is visible
-- assertVisible:
- id: "pause-button-test-id"
-
# check if the queue button is visible
- assertVisible:
id: 'queue-button-test-id'
diff --git a/package.json b/package.json
index 698c4e16..eb3a41fb 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
"@react-navigation/native-stack": "^7.3.21",
"@sentry/react-native": "^6.17.0",
"@shopify/flash-list": "^2.0.0-rc.11",
- "@tamagui/config": "^1.132.1",
+ "@tamagui/config": "^1.132.6",
"@tanstack/query-sync-storage-persister": "^5.83.0",
"@tanstack/react-query": "^5.83.0",
"@tanstack/react-query-persist-client": "^5.83.0",
@@ -87,7 +87,7 @@
"react-native-uuid": "^2.0.3",
"react-native-vector-icons": "^10.2.0",
"ruby": "^0.6.1",
- "tamagui": "^1.132.1"
+ "tamagui": "^1.132.6"
},
"devDependencies": {
"@babel/core": "^7.28.0",
diff --git a/src/components/Artists/component.tsx b/src/components/Artists/component.tsx
index d58f269c..7ab7ffe7 100644
--- a/src/components/Artists/component.tsx
+++ b/src/components/Artists/component.tsx
@@ -11,6 +11,7 @@ import { FlashList } from '@shopify/flash-list'
import { useLibraryContext } from '../../providers/Library'
import { sleepify } from '../../utils/sleep'
import { AZScroller } from '../Global/components/alphabetical-selector'
+import { useMutation } from '@tanstack/react-query'
export default function Artists({
artists,
@@ -50,18 +51,19 @@ export default function Artists({
!artistPageParams.current.includes(letter)) &&
hasNextPage
)
-
- await sleepify(250)
- sectionListRef.current?.scrollToIndex({
- index:
- (artistsRef.current?.indexOf(letter) ?? 0) > -1
- ? artistsRef.current!.indexOf(letter)
- : 0,
- viewPosition: 0.1,
- animated: true,
- })
}
+ const { mutate: alphabetSelectorMutate, isPending: isAlphabetSelectorPending } = useMutation({
+ mutationFn: (letter: string) => alphabeticalSelectorCallback(letter),
+ onSuccess: (data, letter) => {
+ sectionListRef.current?.scrollToIndex({
+ index: artistsRef.current!.indexOf(letter),
+ viewPosition: 0.1,
+ animated: true,
+ })
+ },
+ })
+
useEffect(() => {
artistsRef.current = artists ?? []
}, [artists])
@@ -89,21 +91,28 @@ export default function Artists({
ItemSeparatorComponent={() => }
estimatedItemSize={itemHeight}
data={artists}
- refreshControl={}
+ refreshControl={
+
+ }
renderItem={({ index, item: artist }) =>
typeof artist === 'string' ? (
-
-
- {artist.toUpperCase()}
-
-
+ // 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 === artists!.length ||
+ typeof artists![index + 1] !== 'object' ? null : (
+
+
+ {artist.toUpperCase()}
+
+
+ )
) : typeof artist === 'number' ? null : typeof artist === 'object' ? (
- {showAlphabeticalSelector && (
-
- )}
+ {showAlphabeticalSelector && }
)
}
diff --git a/src/components/Context/components/multiple-artists.tsx b/src/components/Context/components/multiple-artists.tsx
new file mode 100644
index 00000000..b5c4e659
--- /dev/null
+++ b/src/components/Context/components/multiple-artists.tsx
@@ -0,0 +1,38 @@
+import { ScrollView, View } from 'tamagui'
+import { MultipleArtistsProps } from '../../types'
+import ItemRow from '../../Global/components/item-row'
+import { useEffect } from 'react'
+
+export default function MultipleArtists({
+ navigation,
+ route,
+}: MultipleArtistsProps): React.JSX.Element {
+ return (
+
+ {route.params.artists.map((artist) => {
+ return (
+ {
+ navigation.goBack()
+ navigation.goBack()
+ navigation.navigate('Tabs', {
+ screen: 'Library',
+ params: {
+ screen: 'Artist',
+ params: {
+ artist: artist,
+ },
+ },
+ })
+ }}
+ />
+ )
+ })}
+
+ )
+}
diff --git a/src/components/Global/components/item-row.tsx b/src/components/Global/components/item-row.tsx
index ac82b25a..de36b10c 100644
--- a/src/components/Global/components/item-row.tsx
+++ b/src/components/Global/components/item-row.tsx
@@ -28,10 +28,14 @@ export default function ItemRow({
item,
queueName,
navigation,
+ onPress,
+ circular,
}: {
item: BaseItemDto
queueName: string
navigation: NativeStackNavigationProp
+ onPress?: () => void
+ circular?: boolean
}): React.JSX.Element {
const { useStartPlayback } = usePlayerContext()
const { useLoadNewQueue } = useQueueContext()
@@ -77,6 +81,11 @@ export default function ItemRow({
})
}}
onPress={() => {
+ if (onPress) {
+ onPress()
+ return
+ }
+
switch (item.Type) {
case 'MusicArtist': {
navigation.navigate('Artist', {
@@ -101,7 +110,7 @@ export default function ItemRow({
item={item}
height={'$12'}
width={'$12'}
- circular={item.Type === 'MusicArtist'}
+ circular={item.Type === 'MusicArtist' || circular}
/>
diff --git a/src/components/Player/components/song-info.tsx b/src/components/Player/components/song-info.tsx
index a355e45e..dbe3ce91 100644
--- a/src/components/Player/components/song-info.tsx
+++ b/src/components/Player/components/song-info.tsx
@@ -62,16 +62,22 @@ export default function SongInfo({
color={'$color'}
onPress={() => {
if (nowPlaying!.item.ArtistItems) {
- navigation.goBack() // Dismiss player modal
- navigation.navigate('Tabs', {
- screen: 'Library',
- params: {
- screen: 'Artist',
+ if (nowPlaying!.item.ArtistItems!.length > 1) {
+ navigation.navigate('MultipleArtists', {
+ artists: nowPlaying!.item.ArtistItems!,
+ })
+ } else {
+ navigation.goBack() // Dismiss player modal
+ navigation.navigate('Tabs', {
+ screen: 'Library',
params: {
- artist: nowPlaying!.item.ArtistItems![0],
+ screen: 'Artist',
+ params: {
+ artist: nowPlaying!.item.ArtistItems![0],
+ },
},
- },
- })
+ })
+ }
}
}}
>
diff --git a/src/components/types.d.ts b/src/components/types.d.ts
index 9615ed83..4ef4dc18 100644
--- a/src/components/types.d.ts
+++ b/src/components/types.d.ts
@@ -87,6 +87,10 @@ export type StackParamList = {
Player: undefined
Queue: undefined
+ MultipleArtists: {
+ artists: BaseItemDto[]
+ }
+
Artist: {
artist: BaseItemDto
}
@@ -126,6 +130,7 @@ export type LibrarySelectionProps = NativeStackScreenProps
export type PlayerProps = NativeStackScreenProps
+export type MultipleArtistsProps = NativeStackScreenProps
export type ProvidedHomeProps = NativeStackScreenProps
export type AddPlaylistProps = NativeStackScreenProps
diff --git a/src/screens/Context/multiple-artists.tsx b/src/screens/Context/multiple-artists.tsx
new file mode 100644
index 00000000..eb1c7b12
--- /dev/null
+++ b/src/screens/Context/multiple-artists.tsx
@@ -0,0 +1,6 @@
+import { MultipleArtistsProps } from '../../components/types'
+import MultipleArtists from '../../components/Context/components/multiple-artists'
+
+export default function MultipleArtistsSheet(props: MultipleArtistsProps): React.JSX.Element {
+ return
+}
diff --git a/src/screens/Player/index.tsx b/src/screens/Player/index.tsx
index 02e469ba..0862cafa 100644
--- a/src/screens/Player/index.tsx
+++ b/src/screens/Player/index.tsx
@@ -4,6 +4,7 @@ import PlayerScreen from '../../components/Player'
import Queue from '../../components/Player/queue'
import DetailsScreen from '../Detail'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
+import MultipleArtistsSheet from '../Context/multiple-artists'
export const PlayerStack = createNativeStackNavigator()
@@ -34,6 +35,21 @@ export default function Player(): React.JSX.Element {
headerTitle: '',
}}
/>
+
+
+
+
)
}
diff --git a/src/screens/index.tsx b/src/screens/index.tsx
index e95fa8fa..03367002 100644
--- a/src/screens/index.tsx
+++ b/src/screens/index.tsx
@@ -37,6 +37,7 @@ export default function Root(): React.JSX.Element {
options={{
headerShown: false,
presentation: 'modal',
+ sheetAllowedDetents: Platform.OS === 'ios' ? 'fitToContents' : [1.0],
}}
/>
(