mirror of
https://github.com/Jellify-Music/App.git
synced 2026-02-18 00:38:31 -06:00
git blame violet (#536)
Fix react native upgrade issues restore similar artists to a given artist and albums featuring a given artist
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="28"
|
||||
tools:ignore="GoogleAppIndexingWarning"/>
|
||||
</manifest>
|
||||
@@ -13,6 +13,7 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme"
|
||||
android:usesCleartextTraffic="${usesCleartextTraffic}"
|
||||
android:supportsRtl="true">
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.car.application"
|
||||
|
||||
@@ -41,10 +41,7 @@ export function Album(): React.JSX.Element {
|
||||
|
||||
const { api } = useJellifyContext()
|
||||
const { addToDownloadQueue, pendingDownloads } = useNetworkContext()
|
||||
const [networkStatus] = useNetworkStatus()
|
||||
const streamingDeviceProfile = useStreamingDeviceProfile()
|
||||
const downloadingDeviceProfile = useDownloadingDeviceProfile()
|
||||
const { mutate: loadNewQueue } = useLoadNewQueue()
|
||||
|
||||
const downloadAlbum = (item: BaseItemDto[]) => {
|
||||
if (!api) return
|
||||
@@ -54,29 +51,6 @@ export function Album(): React.JSX.Element {
|
||||
addToDownloadQueue(jellifyTracks)
|
||||
}
|
||||
|
||||
const playAlbum = useCallback(
|
||||
(shuffled: boolean = false) => {
|
||||
if (!discs || discs.length === 0) return
|
||||
|
||||
const allTracks = discs.flatMap((disc) => disc.data) ?? []
|
||||
if (allTracks.length === 0) return
|
||||
|
||||
loadNewQueue({
|
||||
api,
|
||||
networkStatus,
|
||||
deviceProfile: streamingDeviceProfile,
|
||||
track: allTracks[0],
|
||||
index: 0,
|
||||
tracklist: allTracks,
|
||||
queue: album,
|
||||
queuingType: QueuingType.FromSelection,
|
||||
shuffled,
|
||||
startPlayback: true,
|
||||
})
|
||||
},
|
||||
[discs, loadNewQueue],
|
||||
)
|
||||
|
||||
const sections = useMemo(
|
||||
() =>
|
||||
(Array.isArray(discs) ? discs : []).map(({ title, data }) => ({
|
||||
@@ -123,7 +97,7 @@ export function Album(): React.JSX.Element {
|
||||
</XStack>
|
||||
) : null
|
||||
}}
|
||||
ListHeaderComponent={() => AlbumTrackListHeader(album, playAlbum, navigation)}
|
||||
ListHeaderComponent={AlbumTrackListHeader}
|
||||
renderItem={({ item: track, index }) => (
|
||||
<Track
|
||||
navigation={navigation}
|
||||
@@ -133,7 +107,7 @@ export function Album(): React.JSX.Element {
|
||||
queue={album}
|
||||
/>
|
||||
)}
|
||||
ListFooterComponent={() => AlbumTrackListFooter(album)}
|
||||
ListFooterComponent={AlbumTrackListFooter}
|
||||
ListEmptyComponent={() => (
|
||||
<YStack>
|
||||
{isPending ? (
|
||||
@@ -154,13 +128,43 @@ export function Album(): React.JSX.Element {
|
||||
* @param playAlbum The function to call to play the album
|
||||
* @returns A React component
|
||||
*/
|
||||
function AlbumTrackListHeader(
|
||||
album: BaseItemDto,
|
||||
playAlbum: (shuffled?: boolean) => void,
|
||||
navigation: Pick<NativeStackNavigationProp<BaseStackParamList>, 'navigate' | 'dispatch'>,
|
||||
): React.JSX.Element {
|
||||
function AlbumTrackListHeader(): React.JSX.Element {
|
||||
const { api } = useJellifyContext()
|
||||
|
||||
const { width } = useSafeAreaFrame()
|
||||
|
||||
const [networkStatus] = useNetworkStatus()
|
||||
const streamingDeviceProfile = useStreamingDeviceProfile()
|
||||
|
||||
const { mutate: loadNewQueue } = useLoadNewQueue()
|
||||
|
||||
const { album, discs } = useAlbumContext()
|
||||
|
||||
const navigation = useNavigation<NativeStackNavigationProp<BaseStackParamList>>()
|
||||
|
||||
const playAlbum = useCallback(
|
||||
(shuffled: boolean = false) => {
|
||||
if (!discs || discs.length === 0) return
|
||||
|
||||
const allTracks = discs.flatMap((disc) => disc.data) ?? []
|
||||
if (allTracks.length === 0) return
|
||||
|
||||
loadNewQueue({
|
||||
api,
|
||||
networkStatus,
|
||||
deviceProfile: streamingDeviceProfile,
|
||||
track: allTracks[0],
|
||||
index: 0,
|
||||
tracklist: allTracks,
|
||||
queue: album,
|
||||
queuingType: QueuingType.FromSelection,
|
||||
shuffled,
|
||||
startPlayback: true,
|
||||
})
|
||||
},
|
||||
[discs, loadNewQueue],
|
||||
)
|
||||
|
||||
return (
|
||||
<YStack marginTop={'$4'} alignItems='center'>
|
||||
<XStack justifyContent='center'>
|
||||
@@ -239,7 +243,8 @@ function AlbumTrackListHeader(
|
||||
)
|
||||
}
|
||||
|
||||
function AlbumTrackListFooter(album: BaseItemDto): React.JSX.Element {
|
||||
function AlbumTrackListFooter(): React.JSX.Element {
|
||||
const { album } = useAlbumContext()
|
||||
const navigation =
|
||||
useNavigation<
|
||||
NativeStackNavigationProp<
|
||||
|
||||
@@ -7,6 +7,7 @@ import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'
|
||||
import ItemRow from '../Global/components/item-row'
|
||||
import ArtistHeader from './header'
|
||||
import { Text } from '../Global/helpers/text'
|
||||
import SimilarArtists from './similar'
|
||||
|
||||
export default function ArtistNavigation({
|
||||
navigation,
|
||||
@@ -36,6 +37,10 @@ export default function ArtistNavigation({
|
||||
title: '',
|
||||
data: albums?.filter(({ ChildCount }) => typeof ChildCount !== 'number') ?? [],
|
||||
},
|
||||
{
|
||||
title: 'Featured On',
|
||||
data: featuredOn ?? [],
|
||||
},
|
||||
]
|
||||
}, [artist, albums?.map(({ Id }) => Id)])
|
||||
|
||||
@@ -56,6 +61,7 @@ export default function ArtistNavigation({
|
||||
ListHeaderComponent={ArtistHeader}
|
||||
renderSectionHeader={renderSectionHeader}
|
||||
renderItem={({ item }) => <ItemRow item={item} navigation={navigation} />}
|
||||
ListFooterComponent={SimilarArtists}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,57 +4,54 @@ import { BaseStackParamList } from '../../screens/types'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { Text } from '../Global/helpers/text'
|
||||
import { useArtistContext } from '../../providers/Artist'
|
||||
import Animated, { useAnimatedScrollHandler } from 'react-native-reanimated'
|
||||
import { ActivityIndicator } from 'react-native'
|
||||
import navigationRef from '../../../navigation'
|
||||
import HorizontalCardList from '../Global/components/horizontal-list'
|
||||
import { H6, YStack } from 'tamagui'
|
||||
|
||||
export default function SimilarArtists(): React.JSX.Element {
|
||||
const navigation = useNavigation<NativeStackNavigationProp<BaseStackParamList>>()
|
||||
const { similarArtists, fetchingSimilarArtists, scroll } = useArtistContext()
|
||||
const scrollHandler = useAnimatedScrollHandler({
|
||||
onScroll: (event) => {
|
||||
'worklet'
|
||||
scroll.value = event.contentOffset.y
|
||||
},
|
||||
})
|
||||
const { artist, similarArtists, fetchingSimilarArtists } = useArtistContext()
|
||||
|
||||
return (
|
||||
<Animated.FlatList
|
||||
contentContainerStyle={{
|
||||
flexGrow: 1,
|
||||
justifyContent: 'flex-start',
|
||||
alignSelf: 'center',
|
||||
}}
|
||||
data={similarArtists}
|
||||
numColumns={2}
|
||||
renderItem={({ item: artist }) => (
|
||||
<ItemCard
|
||||
caption={artist.Name ?? 'Unknown Artist'}
|
||||
size={'$14'}
|
||||
item={artist}
|
||||
onPress={() => {
|
||||
navigation.push('Artist', {
|
||||
artist,
|
||||
})
|
||||
}}
|
||||
onLongPress={() => {
|
||||
navigationRef.navigate('Context', {
|
||||
item: artist,
|
||||
navigation,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
ListEmptyComponent={
|
||||
fetchingSimilarArtists ? (
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<Text justify={'center'} textAlign='center'>
|
||||
No similar artists
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
onScroll={scrollHandler}
|
||||
removeClippedSubviews
|
||||
/>
|
||||
<YStack flex={1}>
|
||||
<Text
|
||||
padding={'$3'}
|
||||
fontSize={'$6'}
|
||||
bold
|
||||
>{`Similar to ${artist.Name ?? 'Unknown Artist'}`}</Text>
|
||||
|
||||
<HorizontalCardList
|
||||
data={similarArtists}
|
||||
renderItem={({ item: artist }) => (
|
||||
<ItemCard
|
||||
caption={artist.Name ?? 'Unknown Artist'}
|
||||
size={'$8'}
|
||||
item={artist}
|
||||
onPress={() => {
|
||||
navigation.push('Artist', {
|
||||
artist,
|
||||
})
|
||||
}}
|
||||
onLongPress={() => {
|
||||
navigationRef.navigate('Context', {
|
||||
item: artist,
|
||||
navigation,
|
||||
})
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
ListEmptyComponent={
|
||||
fetchingSimilarArtists ? (
|
||||
<ActivityIndicator />
|
||||
) : (
|
||||
<Text justify={'center'} textAlign='center'>
|
||||
No similar artists
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
removeClippedSubviews
|
||||
/>
|
||||
</YStack>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ interface HorizontalCardListProps extends FlashListProps<BaseItemDto> {}
|
||||
export default function HorizontalCardList({
|
||||
data,
|
||||
renderItem,
|
||||
...props
|
||||
}: HorizontalCardListProps): React.JSX.Element {
|
||||
return (
|
||||
<FlashList
|
||||
@@ -23,6 +24,7 @@ export default function HorizontalCardList({
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ export default function LibraryScreen({
|
||||
options={{
|
||||
tabBarIcon: ({ focused, color }) => (
|
||||
<Icon
|
||||
name='music-box-multiple'
|
||||
name={`music-box-multiple${!focused ? '-outline' : ''}`}
|
||||
color={focused ? '$primary' : '$neutral'}
|
||||
small
|
||||
/>
|
||||
|
||||
@@ -7,9 +7,8 @@ import { QueryKeys } from '../../enums/query-keys'
|
||||
import { fetchSearchResults } from '../../api/queries/search'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { FlatList } from 'react-native'
|
||||
import { H3 } from '../Global/helpers/text'
|
||||
import { fetchSearchSuggestions } from '../../api/queries/suggestions'
|
||||
import { getToken, Separator, Spinner, YStack } from 'tamagui'
|
||||
import { getToken, H3, Separator, Spinner, YStack } from 'tamagui'
|
||||
import Suggestions from './suggestions'
|
||||
import { isEmpty } from 'lodash'
|
||||
import HorizontalCardList from '../Global/components/horizontal-list'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ItemRow from '../Global/components/item-row'
|
||||
import { H3, Text } from '../Global/helpers/text'
|
||||
import { Separator, YStack } from 'tamagui'
|
||||
import { Text } from '../Global/helpers/text'
|
||||
import { H3, Separator, YStack } from 'tamagui'
|
||||
import { ItemCard } from '../Global/components/item-card'
|
||||
import HorizontalCardList from '../Global/components/horizontal-list'
|
||||
import { FlashList } from '@shopify/flash-list'
|
||||
|
||||
@@ -39,7 +39,7 @@ export default function Settings(): React.JSX.Element {
|
||||
title: 'App',
|
||||
tabBarIcon: ({ focused, color }) => (
|
||||
<Icon
|
||||
name='jellyfish-outline'
|
||||
name={`jellyfish${!focused ? '-outline' : ''}`}
|
||||
color={focused ? '$primary' : '$borderColor'}
|
||||
small
|
||||
/>
|
||||
@@ -97,7 +97,7 @@ export default function Settings(): React.JSX.Element {
|
||||
options={{
|
||||
tabBarIcon: ({ focused, color }) => (
|
||||
<Icon
|
||||
name='information'
|
||||
name={`information${!focused ? '-outline' : ''}`}
|
||||
color={focused ? '$primary' : '$borderColor'}
|
||||
small
|
||||
/>
|
||||
|
||||
@@ -19,7 +19,7 @@ export function Discover(): React.JSX.Element {
|
||||
|
||||
return (
|
||||
<DiscoverProvider>
|
||||
<DiscoverStack.Navigator initialRouteName='Discover' screenOptions={{}}>
|
||||
<DiscoverStack.Navigator initialRouteName='Discover'>
|
||||
<DiscoverStack.Screen
|
||||
name='Discover'
|
||||
component={Index}
|
||||
|
||||
@@ -3,15 +3,13 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
||||
import { PlaylistScreen } from '../Playlist'
|
||||
import { Home as HomeComponent } from '../../components/Home'
|
||||
import { ArtistScreen } from '../Artist'
|
||||
import { useTheme, XStack } from 'tamagui'
|
||||
import { useTheme } from 'tamagui'
|
||||
import HomeArtistsScreen from './artists'
|
||||
import HomeTracksScreen from './tracks'
|
||||
import AlbumScreen from '../Album'
|
||||
import HomeStackParamList from './types'
|
||||
import InstantMix from '../../components/InstantMix/component'
|
||||
import { getItemName } from '../../utils/text'
|
||||
import FavoriteButton from '../../components/Global/components/favorite-button'
|
||||
import InstantMixButton from '../../components/Global/components/instant-mix-button'
|
||||
|
||||
const HomeStack = createNativeStackNavigator<HomeStackParamList>()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user