mirror of
https://github.com/Jellify-Music/App.git
synced 2025-12-30 23:39:51 -06:00
home screen animation and indicator improvements
This commit is contained in:
@@ -2,7 +2,7 @@ import HorizontalCardList from '../../../components/Global/components/horizontal
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import React, { useCallback } from 'react'
|
||||
import { ItemCard } from '../../../components/Global/components/item-card'
|
||||
import { H5, View, XStack } from 'tamagui'
|
||||
import { H5, XStack } from 'tamagui'
|
||||
import Icon from '../../Global/components/icon'
|
||||
import { useDisplayContext } from '../../../providers/Display/display-provider'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
@@ -11,6 +11,7 @@ import { RootStackParamList } from '../../../screens/types'
|
||||
import { useFrequentlyPlayedArtists } from '../../../api/queries/frequents'
|
||||
import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'
|
||||
import { pickFirstGenre } from '../../../utils/genre-formatting'
|
||||
import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'
|
||||
|
||||
export default function FrequentArtists(): React.JSX.Element {
|
||||
const navigation = useNavigation<NativeStackNavigationProp<HomeStackParamList>>()
|
||||
@@ -42,8 +43,15 @@ export default function FrequentArtists(): React.JSX.Element {
|
||||
[],
|
||||
)
|
||||
|
||||
return (
|
||||
<View>
|
||||
return frequentArtistsInfiniteQuery.data ? (
|
||||
<Animated.View
|
||||
entering={FadeIn}
|
||||
exiting={FadeOut}
|
||||
layout={LinearTransition.springify()}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<XStack
|
||||
alignItems='center'
|
||||
onPress={() => {
|
||||
@@ -57,9 +65,11 @@ export default function FrequentArtists(): React.JSX.Element {
|
||||
</XStack>
|
||||
|
||||
<HorizontalCardList
|
||||
data={frequentArtistsInfiniteQuery.data?.slice(0, horizontalItems) ?? []}
|
||||
data={frequentArtistsInfiniteQuery.data.slice(0, horizontalItems) ?? []}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</View>
|
||||
</Animated.View>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import { H5, View, XStack } from 'tamagui'
|
||||
import { H5, XStack } from 'tamagui'
|
||||
import HorizontalCardList from '../../../components/Global/components/horizontal-list'
|
||||
import { ItemCard } from '../../../components/Global/components/item-card'
|
||||
import { QueuingType } from '../../../enums/queuing-type'
|
||||
@@ -13,6 +13,7 @@ import { useNetworkStatus } from '../../../stores/network'
|
||||
import useStreamingDeviceProfile from '../../../stores/device-profile'
|
||||
import { useFrequentlyPlayedTracks } from '../../../api/queries/frequents'
|
||||
import { useApi } from '../../../stores'
|
||||
import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'
|
||||
|
||||
export default function FrequentlyPlayedTracks(): React.JSX.Element {
|
||||
const api = useApi()
|
||||
@@ -30,8 +31,15 @@ export default function FrequentlyPlayedTracks(): React.JSX.Element {
|
||||
const loadNewQueue = useLoadNewQueue()
|
||||
const { horizontalItems } = useDisplayContext()
|
||||
|
||||
return (
|
||||
<View>
|
||||
return tracksInfiniteQuery.data ? (
|
||||
<Animated.View
|
||||
entering={FadeIn}
|
||||
exiting={FadeOut}
|
||||
layout={LinearTransition.springify()}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<XStack
|
||||
alignItems='center'
|
||||
onPress={() => {
|
||||
@@ -46,8 +54,8 @@ export default function FrequentlyPlayedTracks(): React.JSX.Element {
|
||||
|
||||
<HorizontalCardList
|
||||
data={
|
||||
(tracksInfiniteQuery.data?.length ?? 0 > horizontalItems)
|
||||
? tracksInfiniteQuery.data?.slice(0, horizontalItems)
|
||||
tracksInfiniteQuery.data.length > horizontalItems
|
||||
? tracksInfiniteQuery.data.slice(0, horizontalItems)
|
||||
: tracksInfiniteQuery.data
|
||||
}
|
||||
renderItem={({ item: track, index }) => (
|
||||
@@ -81,6 +89,8 @@ export default function FrequentlyPlayedTracks(): React.JSX.Element {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
</Animated.View>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import HomeStackParamList from '../../../screens/Home/types'
|
||||
import { useRecentArtists } from '../../../api/queries/recents'
|
||||
import { pickFirstGenre } from '../../../utils/genre-formatting'
|
||||
import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models/base-item-dto'
|
||||
import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'
|
||||
|
||||
export default function RecentArtists(): React.JSX.Element {
|
||||
const recentArtistsInfiniteQuery = useRecentArtists()
|
||||
@@ -50,17 +51,26 @@ export default function RecentArtists(): React.JSX.Element {
|
||||
[navigation, rootNavigation],
|
||||
)
|
||||
|
||||
return (
|
||||
<View>
|
||||
return recentArtistsInfiniteQuery.data ? (
|
||||
<Animated.View
|
||||
entering={FadeIn}
|
||||
exiting={FadeOut}
|
||||
layout={LinearTransition.springify()}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<XStack alignItems='center' onPress={handleHeaderPress}>
|
||||
<H5 marginLeft={'$2'}>Recent Artists</H5>
|
||||
<Icon name='arrow-right' />
|
||||
</XStack>
|
||||
|
||||
<HorizontalCardList
|
||||
data={recentArtistsInfiniteQuery.data?.slice(0, horizontalItems) ?? []}
|
||||
data={recentArtistsInfiniteQuery.data.slice(0, horizontalItems)}
|
||||
renderItem={renderItem}
|
||||
/>
|
||||
</View>
|
||||
</Animated.View>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import { H5, View, XStack } from 'tamagui'
|
||||
import React from 'react'
|
||||
import { H5, XStack } from 'tamagui'
|
||||
import { ItemCard } from '../../Global/components/item-card'
|
||||
import { RootStackParamList } from '../../../screens/types'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
@@ -13,8 +13,8 @@ import HomeStackParamList from '../../../screens/Home/types'
|
||||
import { useNetworkStatus } from '../../../stores/network'
|
||||
import useStreamingDeviceProfile from '../../../stores/device-profile'
|
||||
import { useRecentlyPlayedTracks } from '../../../api/queries/recents'
|
||||
import { useCurrentTrack } from '../../../stores/player/queue'
|
||||
import { useApi } from '../../../stores'
|
||||
import Animated, { FadeIn, FadeOut, LinearTransition } from 'react-native-reanimated'
|
||||
|
||||
export default function RecentlyPlayed(): React.JSX.Element {
|
||||
const api = useApi()
|
||||
@@ -23,8 +23,6 @@ export default function RecentlyPlayed(): React.JSX.Element {
|
||||
|
||||
const deviceProfile = useStreamingDeviceProfile()
|
||||
|
||||
const nowPlaying = useCurrentTrack()
|
||||
|
||||
const navigation = useNavigation<NativeStackNavigationProp<HomeStackParamList>>()
|
||||
const rootNavigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>()
|
||||
|
||||
@@ -33,60 +31,68 @@ export default function RecentlyPlayed(): React.JSX.Element {
|
||||
const tracksInfiniteQuery = useRecentlyPlayedTracks()
|
||||
|
||||
const { horizontalItems } = useDisplayContext()
|
||||
return useMemo(() => {
|
||||
return (
|
||||
<View>
|
||||
<XStack
|
||||
alignItems='center'
|
||||
onPress={() => {
|
||||
navigation.navigate('RecentTracks', {
|
||||
tracksInfiniteQuery,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<H5 marginLeft={'$2'}>Play it again</H5>
|
||||
<Icon name='arrow-right' />
|
||||
</XStack>
|
||||
|
||||
<HorizontalCardList
|
||||
data={
|
||||
(tracksInfiniteQuery.data?.length ?? 0 > horizontalItems)
|
||||
? tracksInfiniteQuery.data?.slice(0, horizontalItems)
|
||||
: tracksInfiniteQuery.data
|
||||
}
|
||||
renderItem={({ index, item: recentlyPlayedTrack }) => (
|
||||
<ItemCard
|
||||
size={'$11'}
|
||||
caption={recentlyPlayedTrack.Name}
|
||||
subCaption={`${recentlyPlayedTrack.Artists?.join(', ')}`}
|
||||
squared
|
||||
testId={`recently-played-${index}`}
|
||||
item={recentlyPlayedTrack}
|
||||
onPress={() => {
|
||||
loadNewQueue({
|
||||
api,
|
||||
deviceProfile,
|
||||
networkStatus,
|
||||
track: recentlyPlayedTrack,
|
||||
index: index,
|
||||
tracklist: tracksInfiniteQuery.data ?? [recentlyPlayedTrack],
|
||||
queue: 'Recently Played',
|
||||
queuingType: QueuingType.FromSelection,
|
||||
startPlayback: true,
|
||||
})
|
||||
}}
|
||||
onLongPress={() => {
|
||||
rootNavigation.navigate('Context', {
|
||||
item: recentlyPlayedTrack,
|
||||
navigation,
|
||||
})
|
||||
}}
|
||||
marginHorizontal={'$1'}
|
||||
captionAlign='left'
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}, [tracksInfiniteQuery.data, nowPlaying])
|
||||
return tracksInfiniteQuery.data ? (
|
||||
<Animated.View
|
||||
entering={FadeIn}
|
||||
exiting={FadeOut}
|
||||
layout={LinearTransition.springify()}
|
||||
style={{
|
||||
flex: 1,
|
||||
}}
|
||||
>
|
||||
<XStack
|
||||
alignItems='center'
|
||||
onPress={() => {
|
||||
navigation.navigate('RecentTracks', {
|
||||
tracksInfiniteQuery,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<H5 marginLeft={'$2'}>Play it again</H5>
|
||||
<Icon name='arrow-right' />
|
||||
</XStack>
|
||||
|
||||
<HorizontalCardList
|
||||
data={
|
||||
(tracksInfiniteQuery.data.length ?? 0 > horizontalItems)
|
||||
? tracksInfiniteQuery.data.slice(0, horizontalItems)
|
||||
: tracksInfiniteQuery.data
|
||||
}
|
||||
renderItem={({ index, item: recentlyPlayedTrack }) => (
|
||||
<ItemCard
|
||||
size={'$11'}
|
||||
caption={recentlyPlayedTrack.Name}
|
||||
subCaption={`${recentlyPlayedTrack.Artists?.join(', ')}`}
|
||||
squared
|
||||
testId={`recently-played-${index}`}
|
||||
item={recentlyPlayedTrack}
|
||||
onPress={() => {
|
||||
loadNewQueue({
|
||||
api,
|
||||
deviceProfile,
|
||||
networkStatus,
|
||||
track: recentlyPlayedTrack,
|
||||
index: index,
|
||||
tracklist: tracksInfiniteQuery.data ?? [recentlyPlayedTrack],
|
||||
queue: 'Recently Played',
|
||||
queuingType: QueuingType.FromSelection,
|
||||
startPlayback: true,
|
||||
})
|
||||
}}
|
||||
onLongPress={() => {
|
||||
rootNavigation.navigate('Context', {
|
||||
item: recentlyPlayedTrack,
|
||||
navigation,
|
||||
})
|
||||
}}
|
||||
marginHorizontal={'$1'}
|
||||
captionAlign='left'
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Animated.View>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import FrequentlyPlayedTracks from './helpers/frequent-tracks'
|
||||
import { usePreventRemove } from '@react-navigation/native'
|
||||
import useHomeQueries from '../../api/mutations/home'
|
||||
import { usePerformanceMonitor } from '../../hooks/use-performance-monitor'
|
||||
import { useIsRestoring } from '@tanstack/react-query'
|
||||
import { useRecentlyPlayedTracks } from '../../api/queries/recents'
|
||||
|
||||
const COMPONENT_NAME = 'Home'
|
||||
|
||||
@@ -17,18 +19,21 @@ export function Home(): React.JSX.Element {
|
||||
|
||||
usePerformanceMonitor(COMPONENT_NAME, 5)
|
||||
|
||||
const { isPending: refreshing, mutate: refresh } = useHomeQueries()
|
||||
const { isPending: refreshing, mutateAsync: refresh } = useHomeQueries()
|
||||
|
||||
const { isPending: loadingInitialData } = useRecentlyPlayedTracks()
|
||||
|
||||
const isRestoring = useIsRestoring()
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
contentInsetAdjustmentBehavior='automatic'
|
||||
contentContainerStyle={{
|
||||
marginVertical: getToken('$4'),
|
||||
marginHorizontal: getToken('$2'),
|
||||
}}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={refreshing}
|
||||
refreshing={refreshing || isRestoring || loadingInitialData}
|
||||
onRefresh={refresh}
|
||||
tintColor={theme.primary.val}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user