diff --git a/src/renderer/features/player/components/full-screen-player-image.tsx b/src/renderer/features/player/components/full-screen-player-image.tsx index 77bd98b7b..535764a7b 100644 --- a/src/renderer/features/player/components/full-screen-player-image.tsx +++ b/src/renderer/features/player/components/full-screen-player-image.tsx @@ -1,7 +1,7 @@ import { Flex, Stack, Group, Center } from '@mantine/core'; import { useSetState } from '@mantine/hooks'; import { AnimatePresence, HTMLMotionProps, motion, Variants } from 'framer-motion'; -import { useEffect } from 'react'; +import { useEffect, useRef, useLayoutEffect, useState, useCallback } from 'react'; import { RiAlbumFill } from 'react-icons/ri'; import { generatePath } from 'react-router'; import { Link } from 'react-router-dom'; @@ -89,11 +89,11 @@ const imageVariants: Variants = { }, }; -const scaleImageUrl = (url?: string | null) => { +const scaleImageUrl = (imageSize: number, url?: string | null) => { return url - ?.replace(/&size=\d+/, '&size=500') - .replace(/\?width=\d+/, '?width=500') - .replace(/&height=\d+/, '&height=500'); + ?.replace(/&size=\d+/, `&size=${imageSize}`) + .replace(/\?width=\d+/, `?width=${imageSize}`) + .replace(/&height=\d+/, `&height=${imageSize}`); }; const ImageWithPlaceholder = ({ @@ -127,6 +127,9 @@ const ImageWithPlaceholder = ({ }; export const FullScreenPlayerImage = () => { + const mainImageRef = useRef(null); + const [mainImageDimensions, setMainImageDimensions] = useState({ idealSize: 1 }); + const { queue } = usePlayerData(); const { opacity, useImageAspectRatio } = useFullScreenPlayerStore(); const currentSong = queue.current; @@ -136,13 +139,31 @@ export const FullScreenPlayerImage = () => { srcLoaded: true, }); const imageKey = `image-${background}`; - const [imageState, setImageState] = useSetState({ - bottomImage: scaleImageUrl(queue.next?.imageUrl), + bottomImage: scaleImageUrl(mainImageDimensions.idealSize, queue.next?.imageUrl), current: 0, - topImage: scaleImageUrl(queue.current?.imageUrl), + topImage: scaleImageUrl(mainImageDimensions.idealSize, queue.current?.imageUrl), }); + const updateImageSize = useCallback(() => { + if (mainImageRef.current) { + setMainImageDimensions({ + idealSize: + Math.ceil((mainImageRef.current as HTMLDivElement).offsetHeight / 100) * 100, + }); + + setImageState({ + bottomImage: scaleImageUrl(mainImageDimensions.idealSize, queue.next?.imageUrl), + current: 0, + topImage: scaleImageUrl(mainImageDimensions.idealSize, queue.current?.imageUrl), + }); + } + }, [mainImageDimensions.idealSize, queue, setImageState]); + + useLayoutEffect(() => { + updateImageSize(); + }, [updateImageSize]); + useEffect(() => { const unsubSongChange = usePlayerStore.subscribe( (state) => [state.current.song, state.actions.getPlayerData().queue], @@ -150,8 +171,14 @@ export const FullScreenPlayerImage = () => { const isTop = imageState.current === 0; const queue = state[1] as PlayerData['queue']; - const currentImageUrl = scaleImageUrl(queue.current?.imageUrl); - const nextImageUrl = scaleImageUrl(queue.next?.imageUrl); + const currentImageUrl = scaleImageUrl( + mainImageDimensions.idealSize, + queue.current?.imageUrl, + ); + const nextImageUrl = scaleImageUrl( + mainImageDimensions.idealSize, + queue.next?.imageUrl, + ); setImageState({ bottomImage: isTop ? currentImageUrl : nextImageUrl, @@ -165,7 +192,7 @@ export const FullScreenPlayerImage = () => { return () => { unsubSongChange(); }; - }, [imageState, queue, setImageState]); + }, [imageState, mainImageDimensions.idealSize, queue, setImageState]); return ( { justify="flex-start" p="1rem" > - +