mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-12 07:12:58 +02:00
handle radio metadata in discord rpc / fullscreen player (#1649)
This commit is contained in:
@@ -6,6 +6,10 @@ import { generatePath, Link } from 'react-router';
|
||||
import styles from './full-screen-player-image.module.css';
|
||||
|
||||
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
||||
import {
|
||||
useIsRadioActive,
|
||||
useRadioPlayer,
|
||||
} from '/@/renderer/features/radio/hooks/use-radio-player';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useNativeAspectRatio, usePlayerData, usePlayerSong } from '/@/renderer/store';
|
||||
import { Badge } from '/@/shared/components/badge/badge';
|
||||
@@ -45,8 +49,9 @@ const MotionImage = motion.img;
|
||||
|
||||
const ImageWithPlaceholder = ({
|
||||
className,
|
||||
placeholderIcon = 'itemAlbum',
|
||||
...props
|
||||
}: HTMLMotionProps<'img'> & { placeholder?: string }) => {
|
||||
}: HTMLMotionProps<'img'> & { placeholder?: string; placeholderIcon?: 'itemAlbum' | 'radio' }) => {
|
||||
const nativeAspectRatio = useNativeAspectRatio();
|
||||
|
||||
if (!props.src) {
|
||||
@@ -59,7 +64,7 @@ const ImageWithPlaceholder = ({
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Icon color="muted" icon="itemAlbum" size="25%" />
|
||||
<Icon color="muted" icon={placeholderIcon} size="25%" />
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
@@ -79,9 +84,14 @@ const ImageWithPlaceholder = ({
|
||||
export const FullScreenPlayerImage = () => {
|
||||
const mainImageRef = useRef<HTMLImageElement | null>(null);
|
||||
|
||||
const isRadioActive = useIsRadioActive();
|
||||
const { isPlaying: isRadioPlaying, metadata: radioMetadata, stationName } = useRadioPlayer();
|
||||
|
||||
const currentSong = usePlayerSong();
|
||||
const { nextSong } = usePlayerData();
|
||||
|
||||
const isPlayingRadio = isRadioActive && isRadioPlaying;
|
||||
|
||||
const currentImageUrl = useItemImageUrl({
|
||||
id: currentSong?.imageId || undefined,
|
||||
itemType: LibraryItem.SONG,
|
||||
@@ -111,8 +121,11 @@ export const FullScreenPlayerImage = () => {
|
||||
imageStateRef.current = imageState;
|
||||
}, [imageState]);
|
||||
|
||||
// Update images when song or size changes
|
||||
// Update images when song or size changes (skip when playing radio - no album art)
|
||||
useEffect(() => {
|
||||
if (isPlayingRadio) {
|
||||
return;
|
||||
}
|
||||
if (currentSong?._uniqueId === previousSongRef.current) {
|
||||
return;
|
||||
}
|
||||
@@ -126,7 +139,14 @@ export const FullScreenPlayerImage = () => {
|
||||
});
|
||||
|
||||
previousSongRef.current = currentSong?._uniqueId;
|
||||
}, [currentSong?._uniqueId, currentImageUrl, nextSong?._uniqueId, nextImageUrl, setImageState]);
|
||||
}, [
|
||||
isPlayingRadio,
|
||||
currentSong?._uniqueId,
|
||||
currentImageUrl,
|
||||
nextSong?._uniqueId,
|
||||
nextImageUrl,
|
||||
setImageState,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
@@ -138,7 +158,7 @@ export const FullScreenPlayerImage = () => {
|
||||
>
|
||||
<div className={styles.imageContainer} ref={mainImageRef}>
|
||||
<AnimatePresence initial={false} mode="sync">
|
||||
{imageState.current === 0 && (
|
||||
{!isPlayingRadio && imageState.current === 0 && (
|
||||
<ImageWithPlaceholder
|
||||
animate="open"
|
||||
className="full-screen-player-image"
|
||||
@@ -153,7 +173,7 @@ export const FullScreenPlayerImage = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{imageState.current === 1 && (
|
||||
{!isPlayingRadio && imageState.current === 1 && (
|
||||
<ImageWithPlaceholder
|
||||
animate="open"
|
||||
className="full-screen-player-image"
|
||||
@@ -167,57 +187,85 @@ export const FullScreenPlayerImage = () => {
|
||||
variants={imageVariants}
|
||||
/>
|
||||
)}
|
||||
|
||||
{isPlayingRadio && (
|
||||
<ImageWithPlaceholder
|
||||
animate="open"
|
||||
className="full-screen-player-image"
|
||||
custom={{ isOpen: true }}
|
||||
draggable={false}
|
||||
exit="closed"
|
||||
initial="closed"
|
||||
key="radio"
|
||||
placeholder="var(--theme-colors-foreground-muted)"
|
||||
placeholderIcon="radio"
|
||||
src=""
|
||||
variants={imageVariants}
|
||||
/>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
<Stack className={styles.metadataContainer} gap="md" maw="100%">
|
||||
<Text fw={900} lh="1.2" overflow="hidden" size="4xl" w="100%">
|
||||
{currentSong?.name}
|
||||
</Text>
|
||||
<Text
|
||||
component={Link}
|
||||
isLink
|
||||
overflow="hidden"
|
||||
size="xl"
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||
albumId: currentSong?.albumId || '',
|
||||
})}
|
||||
w="100%"
|
||||
>
|
||||
{currentSong?.album}
|
||||
{isPlayingRadio
|
||||
? radioMetadata?.title || stationName || 'Radio'
|
||||
: currentSong?.name}
|
||||
</Text>
|
||||
{isPlayingRadio ? (
|
||||
<Text overflow="hidden" size="xl" w="100%">
|
||||
{stationName || 'Radio'}
|
||||
</Text>
|
||||
) : (
|
||||
<Text
|
||||
component={Link}
|
||||
isLink
|
||||
overflow="hidden"
|
||||
size="xl"
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||
albumId: currentSong?.albumId || '',
|
||||
})}
|
||||
w="100%"
|
||||
>
|
||||
{currentSong?.album}
|
||||
</Text>
|
||||
)}
|
||||
<Text key="fs-artists">
|
||||
{currentSong?.artists?.map((artist, index) => (
|
||||
<Fragment key={`fs-artist-${artist.id}`}>
|
||||
{index > 0 && (
|
||||
<Text
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
padding: '0 0.5rem',
|
||||
}}
|
||||
>
|
||||
•
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
component={Link}
|
||||
isLink
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
albumArtistId: artist.id,
|
||||
})}
|
||||
>
|
||||
{artist.name}
|
||||
</Text>
|
||||
</Fragment>
|
||||
))}
|
||||
{isPlayingRadio
|
||||
? radioMetadata?.artist || stationName || 'Radio'
|
||||
: currentSong?.artists?.map((artist, index) => (
|
||||
<Fragment key={`fs-artist-${artist.id}`}>
|
||||
{index > 0 && (
|
||||
<Text
|
||||
style={{
|
||||
display: 'inline-block',
|
||||
padding: '0 0.5rem',
|
||||
}}
|
||||
>
|
||||
•
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
component={Link}
|
||||
isLink
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
albumArtistId: artist.id,
|
||||
})}
|
||||
>
|
||||
{artist.name}
|
||||
</Text>
|
||||
</Fragment>
|
||||
))}
|
||||
</Text>
|
||||
<Group justify="center" mt="sm">
|
||||
{currentSong?.container && (
|
||||
<Badge variant="transparent">{currentSong?.container}</Badge>
|
||||
)}
|
||||
{currentSong?.releaseYear && (
|
||||
<Badge variant="transparent">{currentSong?.releaseYear}</Badge>
|
||||
)}
|
||||
</Group>
|
||||
{!isPlayingRadio && (
|
||||
<Group justify="center" mt="sm">
|
||||
{currentSong?.container && (
|
||||
<Badge variant="transparent">{currentSong?.container}</Badge>
|
||||
)}
|
||||
{currentSong?.releaseYear && (
|
||||
<Badge variant="transparent">{currentSong?.releaseYear}</Badge>
|
||||
)}
|
||||
</Group>
|
||||
)}
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user