Add image URL generation at runtime to allow for dynamic image sizes (#1439)

* add getImageUrl to domain endpoints

* add new ItemImage component and hooks to generate image url

* add configuration for image resolution based on types
This commit is contained in:
Jeff
2025-12-23 20:18:52 -08:00
committed by GitHub
parent 96f38e597c
commit 25bfb65b6d
39 changed files with 823 additions and 670 deletions
@@ -14,6 +14,7 @@ import { useTranslation } from 'react-i18next';
import styles from './mobile-fullscreen-player.module.css';
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
import { ContextMenuController } from '/@/renderer/features/context-menu/context-menu-controller';
import { Lyrics } from '/@/renderer/features/lyrics/lyrics';
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
@@ -74,14 +75,22 @@ const BackgroundImage = memo(({ dynamicBackground, dynamicIsImage }: BackgroundI
const currentSong = usePlayerSong();
const { nextSong } = usePlayerData();
const currentImageUrl = useItemImageUrl({
id: currentSong?.id,
itemType: LibraryItem.SONG,
type: 'itemCard',
});
const nextImageUrl = useItemImageUrl({
id: nextSong?.id,
itemType: LibraryItem.SONG,
type: 'itemCard',
});
const [imageState, setImageState] = useState({
bottomImage: nextSong?.imageUrl
? nextSong.imageUrl.replace(/size=\d+/g, 'size=500')
: undefined,
bottomImage: nextImageUrl,
current: 0,
topImage: currentSong?.imageUrl
? currentSong.imageUrl.replace(/size=\d+/g, 'size=500')
: undefined,
topImage: currentImageUrl,
});
const previousSongRef = useRef<string | undefined>(currentSong?._uniqueId);
@@ -98,12 +107,6 @@ const BackgroundImage = memo(({ dynamicBackground, dynamicIsImage }: BackgroundI
}
const isTop = imageStateRef.current.current === 0;
const currentImageUrl = currentSong?.imageUrl
? currentSong.imageUrl.replace(/size=\d+/g, 'size=500')
: undefined;
const nextImageUrl = nextSong?.imageUrl
? nextSong.imageUrl.replace(/size=\d+/g, 'size=500')
: undefined;
setImageState({
bottomImage: isTop ? currentImageUrl : nextImageUrl,
@@ -112,7 +115,7 @@ const BackgroundImage = memo(({ dynamicBackground, dynamicIsImage }: BackgroundI
});
previousSongRef.current = currentSong?._uniqueId;
}, [currentSong?._uniqueId, currentSong?.imageUrl, nextSong?._uniqueId, nextSong?.imageUrl]);
}, [currentSong?._uniqueId, currentImageUrl, nextSong?._uniqueId, nextImageUrl]);
if (!dynamicBackground || !dynamicIsImage) {
return null;
@@ -299,9 +302,15 @@ interface MobilePlayerContainerProps {
const MobilePlayerContainer = memo(
({ children, dynamicBackground, dynamicIsImage }: MobilePlayerContainerProps) => {
const currentSong = usePlayerSong();
const imageUrl = useItemImageUrl({
id: currentSong?.id,
imageUrl: currentSong?.imageUrl,
itemType: LibraryItem.SONG,
type: 'itemCard',
});
const { background } = useFastAverageColor({
algorithm: 'dominant',
src: currentSong?.imageUrl,
src: imageUrl,
srcLoaded: true,
});