Add configuration for player image aspect ratio (#138)
This commit is contained in:
parent
eeefe9d9dc
commit
72099cb1fe
3 changed files with 40 additions and 8 deletions
|
@ -10,16 +10,21 @@ import { QueueSong } from '/@/renderer/api/types';
|
||||||
import { Badge, Text, TextTitle } from '/@/renderer/components';
|
import { Badge, Text, TextTitle } from '/@/renderer/components';
|
||||||
import { useFastAverageColor } from '/@/renderer/hooks';
|
import { useFastAverageColor } from '/@/renderer/hooks';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { PlayerData, usePlayerData, usePlayerStore } from '/@/renderer/store';
|
import {
|
||||||
|
PlayerData,
|
||||||
|
useFullScreenPlayerStore,
|
||||||
|
usePlayerData,
|
||||||
|
usePlayerStore,
|
||||||
|
} from '/@/renderer/store';
|
||||||
|
|
||||||
const Image = styled(motion.img)`
|
const Image = styled(motion.img)<{ $useAspectRatio: boolean }>`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: ${({ $useAspectRatio }) => ($useAspectRatio ? 'contain' : 'cover')}};
|
||||||
object-position: 50% 50%;
|
object-position: 50% 50%;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 40%);
|
filter: drop-shadow(0 0 5px rgba(0, 0, 0, 40%)) drop-shadow(0 0 5px rgba(0, 0, 0, 40%));
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ImageContainer = styled(motion.div)`
|
const ImageContainer = styled(motion.div)`
|
||||||
|
@ -83,7 +88,10 @@ const scaleImageUrl = (url?: string | null) => {
|
||||||
.replace(/&height=\d+/, '&height=500');
|
.replace(/&height=\d+/, '&height=500');
|
||||||
};
|
};
|
||||||
|
|
||||||
const ImageWithPlaceholder = ({ ...props }: HTMLMotionProps<'img'>) => {
|
const ImageWithPlaceholder = ({
|
||||||
|
useAspectRatio,
|
||||||
|
...props
|
||||||
|
}: HTMLMotionProps<'img'> & { useAspectRatio: boolean }) => {
|
||||||
if (!props.src) {
|
if (!props.src) {
|
||||||
return (
|
return (
|
||||||
<Center
|
<Center
|
||||||
|
@ -102,11 +110,17 @@ const ImageWithPlaceholder = ({ ...props }: HTMLMotionProps<'img'>) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Image {...props} />;
|
return (
|
||||||
|
<Image
|
||||||
|
$useAspectRatio={useAspectRatio}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FullScreenPlayerImage = () => {
|
export const FullScreenPlayerImage = () => {
|
||||||
const { queue } = usePlayerData();
|
const { queue } = usePlayerData();
|
||||||
|
const useImageAspectRatio = useFullScreenPlayerStore((state) => state.useImageAspectRatio);
|
||||||
const currentSong = queue.current;
|
const currentSong = queue.current;
|
||||||
const background = useFastAverageColor(queue.current?.imageUrl, true, 'dominant');
|
const background = useFastAverageColor(queue.current?.imageUrl, true, 'dominant');
|
||||||
const imageKey = `image-${background}`;
|
const imageKey = `image-${background}`;
|
||||||
|
@ -165,6 +179,7 @@ export const FullScreenPlayerImage = () => {
|
||||||
initial="closed"
|
initial="closed"
|
||||||
placeholder="var(--placeholder-bg)"
|
placeholder="var(--placeholder-bg)"
|
||||||
src={imageState.topImage || ''}
|
src={imageState.topImage || ''}
|
||||||
|
useAspectRatio={useImageAspectRatio}
|
||||||
variants={imageVariants}
|
variants={imageVariants}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -180,6 +195,7 @@ export const FullScreenPlayerImage = () => {
|
||||||
initial="closed"
|
initial="closed"
|
||||||
placeholder="var(--placeholder-bg)"
|
placeholder="var(--placeholder-bg)"
|
||||||
src={imageState.bottomImage || ''}
|
src={imageState.bottomImage || ''}
|
||||||
|
useAspectRatio={useImageAspectRatio}
|
||||||
variants={imageVariants}
|
variants={imageVariants}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -59,7 +59,7 @@ const BackgroundImageOverlay = styled.div`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Controls = () => {
|
const Controls = () => {
|
||||||
const { dynamicBackground, expanded } = useFullScreenPlayerStore();
|
const { dynamicBackground, expanded, useImageAspectRatio } = useFullScreenPlayerStore();
|
||||||
const { setStore } = useFullScreenPlayerStoreActions();
|
const { setStore } = useFullScreenPlayerStoreActions();
|
||||||
|
|
||||||
const handleToggleFullScreenPlayer = () => {
|
const handleToggleFullScreenPlayer = () => {
|
||||||
|
@ -112,6 +112,19 @@ const Controls = () => {
|
||||||
/>
|
/>
|
||||||
</Option.Control>
|
</Option.Control>
|
||||||
</Option>
|
</Option>
|
||||||
|
<Option>
|
||||||
|
<Option.Label>Use image aspect ratio</Option.Label>
|
||||||
|
<Option.Control>
|
||||||
|
<Switch
|
||||||
|
defaultChecked={useImageAspectRatio}
|
||||||
|
onChange={(e) =>
|
||||||
|
setStore({
|
||||||
|
useImageAspectRatio: e.target.checked,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Option.Control>
|
||||||
|
</Option>
|
||||||
<TableConfigDropdown type="fullScreen" />
|
<TableConfigDropdown type="fullScreen" />
|
||||||
</Popover.Dropdown>
|
</Popover.Dropdown>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|
|
@ -7,6 +7,7 @@ interface FullScreenPlayerState {
|
||||||
activeTab: string | 'queue' | 'related' | 'lyrics';
|
activeTab: string | 'queue' | 'related' | 'lyrics';
|
||||||
dynamicBackground?: boolean;
|
dynamicBackground?: boolean;
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
|
useImageAspectRatio: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FullScreenPlayerSlice extends FullScreenPlayerState {
|
export interface FullScreenPlayerSlice extends FullScreenPlayerState {
|
||||||
|
@ -25,7 +26,9 @@ export const useFullScreenPlayerStore = create<FullScreenPlayerSlice>()(
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
activeTab: 'queue',
|
activeTab: 'queue',
|
||||||
|
dynamicBackground: true,
|
||||||
expanded: false,
|
expanded: false,
|
||||||
|
useImageAspectRatio: false,
|
||||||
})),
|
})),
|
||||||
{ name: 'store_full_screen_player' },
|
{ name: 'store_full_screen_player' },
|
||||||
),
|
),
|
||||||
|
@ -34,7 +37,7 @@ export const useFullScreenPlayerStore = create<FullScreenPlayerSlice>()(
|
||||||
return merge(currentState, persistedState);
|
return merge(currentState, persistedState);
|
||||||
},
|
},
|
||||||
name: 'store_full_screen_player',
|
name: 'store_full_screen_player',
|
||||||
version: 1,
|
version: 2,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Reference in a new issue