add popover on tracks?

This commit is contained in:
Violet Caulfield
2025-01-17 08:07:54 -06:00
parent ef4da53945
commit b954f6e34e
2 changed files with 133 additions and 92 deletions

View File

@@ -1,5 +1,5 @@
import { usePlayerContext } from "@/player/provider";
import React from "react";
import React, { useState } from "react";
import { Separator, Spacer, View, XStack, YStack } from "tamagui";
import { Text } from "../helpers/text";
import { RunTimeTicks } from "../helpers/time-codes";
@@ -11,6 +11,7 @@ import { useApiClientContext } from "@/components/jellyfin-api-provider";
import { queryConfig } from "@/api/queries/query.config";
import { useSafeAreaFrame } from "react-native-safe-area-context";
import Icon from "../helpers/icon";
import Popover from "../helpers/popover";
interface TrackProps {
track: BaseItemDto;
@@ -44,104 +45,118 @@ export default function Track({
const isPlaying = nowPlaying?.item.Id === track.Id;
const [popoverOpen, setPopoverOpen] = useState<boolean>(false);
return (
<View>
<Separator />
<XStack
alignContent="center"
flex={1}
onLongPress={() => {
if (onLongPress) {
onLongPress();
} else {
}
}}
onPress={() => {
if (onPress) {
onPress();
} else {
usePlayNewQueue.mutate({
track,
index,
tracklist,
queueName: queueName ? queueName : track.Album ? track.Album! : "Queue"
});
}
}}
paddingVertical={"$2"}
marginHorizontal={"$1"}
>
<XStack
alignContent="center"
justifyContent="center"
flex={1}
minHeight={showArtwork ? width / 9 : "unset"}
>
{ showArtwork ? (
<CachedImage
source={getImageApi(apiClient!)
.getItemImageUrlById(
track.AlbumId ?? "",
ImageType.Primary,
{ ...queryConfig.images }
)
<Popover
open={popoverOpen}
anchor={(
<XStack
alignContent="center"
flex={1}
onLongPress={() => {
setPopoverOpen(true)
if (onLongPress) {
onLongPress();
} else {
}
imageStyle={{
position: "relative",
width: width / 9,
height: width / 9,
borderRadius: 2,
}}
/>
) : (
<Text color={isPlaying ? Colors.Primary : Colors.White}>
{ track.IndexNumber?.toString() ?? "" }
</Text>
)}
</XStack>
<YStack alignContent="center" justifyContent="flex-start" flex={6}>
<Text
bold
color={isPlaying ? Colors.Primary : Colors.White}
lineBreakStrategyIOS="standard"
numberOfLines={1}
}}
onPress={() => {
if (onPress) {
onPress();
} else {
usePlayNewQueue.mutate({
track,
index,
tracklist,
queueName: queueName ? queueName : track.Album ? track.Album! : "Queue"
});
}
}}
paddingVertical={"$2"}
marginHorizontal={"$1"}
>
{ track.Name ?? "Untitled Track" }
</Text>
{ (showArtwork || (track.ArtistCount ?? 0 > 1)) && (
<Text lineBreakStrategyIOS="standard" numberOfLines={1}>{ track.Artists?.join(", ") ?? "" }</Text>
)}
</YStack>
<XStack
alignItems="center"
justifyContent="space-between"
alignContent="center"
flex={1}
>
<YStack
alignContent="center"
justifyContent="center"
>
{ track.UserData?.IsFavorite ? (
<Icon small name="heart" color={Colors.Primary} />
) : (
<Spacer />
<XStack
alignContent="center"
justifyContent="center"
flex={1}
minHeight={showArtwork ? width / 9 : "unset"}
>
{ showArtwork ? (
<CachedImage
source={getImageApi(apiClient!)
.getItemImageUrlById(
track.AlbumId ?? "",
ImageType.Primary,
{ ...queryConfig.images }
)
}
imageStyle={{
position: "relative",
width: width / 9,
height: width / 9,
borderRadius: 2,
}}
/>
) : (
<Text color={isPlaying ? Colors.Primary : Colors.White}>
{ track.IndexNumber?.toString() ?? "" }
</Text>
)}
</YStack>
</XStack>
<YStack
alignContent="center"
justifyContent="center"
>
<RunTimeTicks>{ track.RunTimeTicks }</RunTimeTicks>
</YStack>
</XStack>
</XStack>
<YStack alignContent="center" justifyContent="flex-start" flex={6}>
<Text
bold
color={isPlaying ? Colors.Primary : Colors.White}
lineBreakStrategyIOS="standard"
numberOfLines={1}
>
{ track.Name ?? "Untitled Track" }
</Text>
{ (showArtwork || (track.ArtistCount ?? 0 > 1)) && (
<Text lineBreakStrategyIOS="standard" numberOfLines={1}>{ track.Artists?.join(", ") ?? "" }</Text>
)}
</YStack>
<XStack
alignItems="center"
justifyContent="space-between"
alignContent="center"
flex={1}
>
<YStack
alignContent="center"
justifyContent="center"
>
{ track.UserData?.IsFavorite ? (
<Icon small name="heart" color={Colors.Primary} />
) : (
<Spacer />
)}
</YStack>
<YStack
alignContent="center"
justifyContent="center"
>
<RunTimeTicks>{ track.RunTimeTicks }</RunTimeTicks>
</YStack>
</XStack>
</XStack>
)}>
<View>
</View>
</Popover>
</View>
)
}

View File

@@ -0,0 +1,26 @@
import React from "react"
import { Popover as TamaguiPopover, View } from "tamagui"
interface PopoverProps {
children: React.ReactNode;
anchor: React.ReactNode;
open: boolean
}
export default function Popover(props: PopoverProps) : React.JSX.Element {
return (
<TamaguiPopover open={props.open}>
<TamaguiPopover.Anchor asChild>
{ props.anchor }
</TamaguiPopover.Anchor>
<TamaguiPopover.Content>
<TamaguiPopover.Arrow />
<TamaguiPopover.Close />
<View>
{ props.children }
</View>
</TamaguiPopover.Content>
</TamaguiPopover>
)
}