Add Item Context Provider

Wrap Item Context Provider around item components:
- ItemCard
- ItemRow
- Track

This is to prepopulate our query cache with data used in the Context Sheet
This commit is contained in:
Violet Caulfield
2025-08-20 16:17:11 -05:00
parent 8a191b91ab
commit f368ba77d6
6 changed files with 79 additions and 97 deletions

View File

@@ -96,6 +96,7 @@ export default function Albums({
</Text>
)
}
removeClippedSubviews
/>
)
}

View File

@@ -168,7 +168,6 @@ export default function Artists({
if (artistsInfiniteQuery.hasNextPage && !artistsInfiniteQuery.isFetching)
artistsInfiniteQuery.fetchNextPage()
}}
removeClippedSubviews
/>
{showAlphabeticalSelector && artistPageParams && (

View File

@@ -137,7 +137,7 @@ function AddToPlaylistRow({ track }: { track: BaseItemDto }): React.JSX.Element
}}
pressStyle={{ opacity: 0.5 }}
>
<Icon color='$primary' name='playlist-plus' />
<Icon small color='$primary' name='playlist-plus' />
<Text bold>Add to Playlist</Text>
</ListItem>
@@ -164,9 +164,11 @@ function AddToQueueMenuRow({ tracks }: { tracks: BaseItemDto[] }): React.JSX.Ele
}}
pressStyle={{ opacity: 0.5 }}
>
<Icon color='$primary' name='music-note-plus' />
<Icon small color='$primary' name='music-note-plus' />
<Text bold>Add to Queue</Text>
<Text bold marginLeft={'$1'}>
Add to Queue
</Text>
</ListItem>
)
}
@@ -206,7 +208,7 @@ function ViewAlbumMenuRow({ album: album, stackNavigation }: MenuRowProps): Reac
onPress={goToAlbum}
pressStyle={{ opacity: 0.5 }}
>
<ItemImage item={album} height={'$10'} width={'$10'} />
<ItemImage item={album} height={'$9'} width={'$9'} />
<TextTicker {...TextTickerConfig}>
<Text bold>{`Go to ${getItemName(album)}`}</Text>
@@ -263,7 +265,7 @@ function ViewArtistMenuRow({
onPress={() => goToArtist(artist)}
pressStyle={{ opacity: 0.5 }}
>
<ItemImage circular item={artist} height={'$10'} width={'$10'} />
<ItemImage circular item={artist} height={'$9'} width={'$9'} />
<Text bold>{`Go to ${getItemName(artist)}`}</Text>
</ListItem>

View File

@@ -72,12 +72,10 @@ export default function FavoriteContextMenuRow({ item }: { item: BaseItemDto }):
pressStyle={{ opacity: 0.5 }}
>
<Animated.View entering={FadeIn} exiting={FadeOut} key={`${item.Id}-favorite-row`}>
<XStack alignContent='center' justifyContent='flex-start' gap={'$3'}>
<Icon name={'heart-outline'} small color={'$primary'} />
<XStack alignItems='center' justifyContent='flex-start' gap={'$2'}>
<Icon small name={'heart-outline'} color={'$primary'} />
<Text marginTop={'$2'} bold>
Add to favorites
</Text>
<Text bold>Add to favorites</Text>
</XStack>
</Animated.View>
</ListItem>

View File

@@ -49,6 +49,7 @@ export default function Icon({
onPress={onPress}
onPressIn={onPressIn}
hitSlop={getTokenValue('$2.5')}
marginHorizontal={'$1'}
width={size}
height={size}
flex={flex}

View File

@@ -24,6 +24,8 @@ import navigationRef from '../../../../navigation'
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
import { BaseStackParamList } from '../../../screens/types'
import { fetchItem } from '../../../api/queries/item'
import ItemImage from './image'
import { ItemProvider } from '../../../providers/Item'
export interface TrackProps {
track: BaseItemDto
@@ -84,21 +86,6 @@ export default function Track({
[networkStatus],
)
// Memoize image source to prevent recreation
const imageSource = useMemo(
() => ({
uri:
getImageApi(api!).getItemImageUrlById(
track.AlbumId! || track.Id!,
ImageType.Primary,
{
tag: track.ImageTags?.Primary,
},
) || '',
}),
[api, track.AlbumId, track.Id, track.ImageTags?.Primary],
)
// Memoize tracklist for queue loading
const memoizedTracklist = useMemo(
() => tracklist ?? playQueue.map((track) => track.item),
@@ -188,91 +175,85 @@ export default function Track({
)
return (
<Theme name={invertedColors ? 'inverted_purple' : undefined}>
<XStack
alignContent='center'
alignItems='center'
height={showArtwork ? '$6' : '$5'}
flex={1}
testID={testID ?? undefined}
onPress={handlePress}
onLongPress={handleLongPress}
paddingVertical={'$2'}
justifyContent='center'
marginRight={'$2'}
>
<ItemProvider item={track}>
<Theme name={invertedColors ? 'inverted_purple' : undefined}>
<XStack
alignContent='center'
alignItems='center'
height={showArtwork ? '$6' : '$5'}
flex={1}
testID={testID ?? undefined}
onPress={handlePress}
onLongPress={handleLongPress}
paddingVertical={'$2'}
justifyContent='center'
marginHorizontal={showArtwork ? '$2' : '$1'}
marginRight={'$2'}
>
{showArtwork ? (
<FastImage
key={`${track.Id}-${track.AlbumId || track.Id}`}
source={imageSource}
style={{
width: getToken('$12'),
height: getToken('$12'),
borderRadius: getToken('$1'),
}}
/>
) : (
<Text
key={`${track.Id}-number`}
color={textColor}
width={getToken('$12')}
textAlign='center'
>
{indexNumber}
</Text>
)}
</XStack>
<YStack alignContent='center' justifyContent='flex-start' flex={6}>
<Text
key={`${track.Id}-name`}
bold
color={textColor}
lineBreakStrategyIOS='standard'
numberOfLines={1}
<XStack
alignContent='center'
justifyContent='center'
marginHorizontal={showArtwork ? '$2' : '$1'}
>
{trackName}
</Text>
{showArtwork ? (
<ItemImage item={track} width={'$12'} height={'$12'} />
) : (
<Text
key={`${track.Id}-number`}
color={textColor}
width={getToken('$12')}
textAlign='center'
>
{indexNumber}
</Text>
)}
</XStack>
{shouldShowArtists && (
<YStack alignContent='center' justifyContent='flex-start' flex={6}>
<Text
key={`${track.Id}-artists`}
key={`${track.Id}-name`}
bold
color={textColor}
lineBreakStrategyIOS='standard'
numberOfLines={1}
>
{artistsText}
{trackName}
</Text>
)}
</YStack>
<DownloadedIcon item={track} />
{shouldShowArtists && (
<Text
key={`${track.Id}-artists`}
lineBreakStrategyIOS='standard'
numberOfLines={1}
>
{artistsText}
</Text>
)}
</YStack>
<FavoriteIcon item={track} />
<DownloadedIcon item={track} />
<RunTimeTicks
key={`${track.Id}-runtime`}
props={{
style: {
textAlign: 'center',
flex: 1.5,
alignSelf: 'center',
},
}}
>
{track.RunTimeTicks}
</RunTimeTicks>
<FavoriteIcon item={track} />
<Icon
name={showRemove ? 'close' : 'dots-horizontal'}
flex={1}
onPress={handleIconPress}
/>
</XStack>
</Theme>
<RunTimeTicks
key={`${track.Id}-runtime`}
props={{
style: {
textAlign: 'center',
flex: 1.5,
alignSelf: 'center',
},
}}
>
{track.RunTimeTicks}
</RunTimeTicks>
<Icon
name={showRemove ? 'close' : 'dots-horizontal'}
flex={1}
onPress={handleIconPress}
/>
</XStack>
</Theme>
</ItemProvider>
)
}