mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 18:33:33 +00:00
In the fullscreen player use dynamic resolution for the main image (#290)
* In the fullscreen player use dynamic resolution for the main image * Use ceil instead of round * Add types and lint --------- Co-authored-by: Jeff <42182408+jeffvli@users.noreply.github.com>
This commit is contained in:
parent
f4f73289c9
commit
c7aa5d09c9
1 changed files with 42 additions and 12 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import { Flex, Stack, Group, Center } from '@mantine/core';
|
import { Flex, Stack, Group, Center } from '@mantine/core';
|
||||||
import { useSetState } from '@mantine/hooks';
|
import { useSetState } from '@mantine/hooks';
|
||||||
import { AnimatePresence, HTMLMotionProps, motion, Variants } from 'framer-motion';
|
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 { RiAlbumFill } from 'react-icons/ri';
|
||||||
import { generatePath } from 'react-router';
|
import { generatePath } from 'react-router';
|
||||||
import { Link } from 'react-router-dom';
|
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
|
return url
|
||||||
?.replace(/&size=\d+/, '&size=500')
|
?.replace(/&size=\d+/, `&size=${imageSize}`)
|
||||||
.replace(/\?width=\d+/, '?width=500')
|
.replace(/\?width=\d+/, `?width=${imageSize}`)
|
||||||
.replace(/&height=\d+/, '&height=500');
|
.replace(/&height=\d+/, `&height=${imageSize}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ImageWithPlaceholder = ({
|
const ImageWithPlaceholder = ({
|
||||||
|
|
@ -127,6 +127,9 @@ const ImageWithPlaceholder = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FullScreenPlayerImage = () => {
|
export const FullScreenPlayerImage = () => {
|
||||||
|
const mainImageRef = useRef<HTMLImageElement | null>(null);
|
||||||
|
const [mainImageDimensions, setMainImageDimensions] = useState({ idealSize: 1 });
|
||||||
|
|
||||||
const { queue } = usePlayerData();
|
const { queue } = usePlayerData();
|
||||||
const { opacity, useImageAspectRatio } = useFullScreenPlayerStore();
|
const { opacity, useImageAspectRatio } = useFullScreenPlayerStore();
|
||||||
const currentSong = queue.current;
|
const currentSong = queue.current;
|
||||||
|
|
@ -136,13 +139,31 @@ export const FullScreenPlayerImage = () => {
|
||||||
srcLoaded: true,
|
srcLoaded: true,
|
||||||
});
|
});
|
||||||
const imageKey = `image-${background}`;
|
const imageKey = `image-${background}`;
|
||||||
|
|
||||||
const [imageState, setImageState] = useSetState({
|
const [imageState, setImageState] = useSetState({
|
||||||
bottomImage: scaleImageUrl(queue.next?.imageUrl),
|
bottomImage: scaleImageUrl(mainImageDimensions.idealSize, queue.next?.imageUrl),
|
||||||
current: 0,
|
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(() => {
|
useEffect(() => {
|
||||||
const unsubSongChange = usePlayerStore.subscribe(
|
const unsubSongChange = usePlayerStore.subscribe(
|
||||||
(state) => [state.current.song, state.actions.getPlayerData().queue],
|
(state) => [state.current.song, state.actions.getPlayerData().queue],
|
||||||
|
|
@ -150,8 +171,14 @@ export const FullScreenPlayerImage = () => {
|
||||||
const isTop = imageState.current === 0;
|
const isTop = imageState.current === 0;
|
||||||
const queue = state[1] as PlayerData['queue'];
|
const queue = state[1] as PlayerData['queue'];
|
||||||
|
|
||||||
const currentImageUrl = scaleImageUrl(queue.current?.imageUrl);
|
const currentImageUrl = scaleImageUrl(
|
||||||
const nextImageUrl = scaleImageUrl(queue.next?.imageUrl);
|
mainImageDimensions.idealSize,
|
||||||
|
queue.current?.imageUrl,
|
||||||
|
);
|
||||||
|
const nextImageUrl = scaleImageUrl(
|
||||||
|
mainImageDimensions.idealSize,
|
||||||
|
queue.next?.imageUrl,
|
||||||
|
);
|
||||||
|
|
||||||
setImageState({
|
setImageState({
|
||||||
bottomImage: isTop ? currentImageUrl : nextImageUrl,
|
bottomImage: isTop ? currentImageUrl : nextImageUrl,
|
||||||
|
|
@ -165,7 +192,7 @@ export const FullScreenPlayerImage = () => {
|
||||||
return () => {
|
return () => {
|
||||||
unsubSongChange();
|
unsubSongChange();
|
||||||
};
|
};
|
||||||
}, [imageState, queue, setImageState]);
|
}, [imageState, mainImageDimensions.idealSize, queue, setImageState]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PlayerContainer
|
<PlayerContainer
|
||||||
|
|
@ -175,7 +202,10 @@ export const FullScreenPlayerImage = () => {
|
||||||
justify="flex-start"
|
justify="flex-start"
|
||||||
p="1rem"
|
p="1rem"
|
||||||
>
|
>
|
||||||
<ImageContainer>
|
<ImageContainer
|
||||||
|
ref={mainImageRef}
|
||||||
|
onLoad={updateImageSize}
|
||||||
|
>
|
||||||
<AnimatePresence
|
<AnimatePresence
|
||||||
initial={false}
|
initial={false}
|
||||||
mode="sync"
|
mode="sync"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue