add utility to wait for detail bg color before page render

This commit is contained in:
jeffvli
2025-12-14 16:35:38 -08:00
parent f92754c2ac
commit 08a8f7f500
3 changed files with 59 additions and 4 deletions
@@ -14,7 +14,7 @@ import {
import { LibraryContainer } from '/@/renderer/features/shared/components/library-container';
import { LibraryHeaderBar } from '/@/renderer/features/shared/components/library-header-bar';
import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary';
import { useFastAverageColor } from '/@/renderer/hooks';
import { useFastAverageColor, useWaitForColorCalculation } from '/@/renderer/hooks';
import { useCurrentServer, useGeneralSettings } from '/@/renderer/store';
import { LibraryItem } from '/@/shared/types/domain-types';
@@ -34,7 +34,7 @@ const AlbumDetailRoute = () => {
staleTime: 0,
});
const { background: backgroundColor } = useFastAverageColor({
const { background: backgroundColor, isLoading: isColorLoading } = useFastAverageColor({
id: albumId,
src: detailQuery.data?.imageUrl,
srcLoaded: !detailQuery.isLoading,
@@ -44,6 +44,17 @@ const AlbumDetailRoute = () => {
const showBlurredImage = albumBackground;
const { isReady } = useWaitForColorCalculation({
hasImage: !!detailQuery.data?.imageUrl,
isLoading: isColorLoading,
routeId: albumId,
showBlurredImage,
});
if (!isReady) {
return null;
}
return (
<AnimatedPage key={`album-detail-${albumId}`}>
<NativeScrollArea
@@ -14,7 +14,7 @@ import {
import { LibraryContainer } from '/@/renderer/features/shared/components/library-container';
import { LibraryHeaderBar } from '/@/renderer/features/shared/components/library-header-bar';
import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary';
import { useFastAverageColor } from '/@/renderer/hooks';
import { useFastAverageColor, useWaitForColorCalculation } from '/@/renderer/hooks';
import { useCurrentServer, useGeneralSettings } from '/@/renderer/store';
import { LibraryItem } from '/@/shared/types/domain-types';
@@ -39,7 +39,7 @@ const AlbumArtistDetailRoute = () => {
staleTime: 0,
});
const { background: backgroundColor } = useFastAverageColor({
const { background: backgroundColor, isLoading: isColorLoading } = useFastAverageColor({
id: artistId,
src: detailQuery.data?.imageUrl,
srcLoaded: !detailQuery.isLoading,
@@ -49,6 +49,17 @@ const AlbumArtistDetailRoute = () => {
const showBlurredImage = artistBackground;
const { isReady } = useWaitForColorCalculation({
hasImage: !!detailQuery.data?.imageUrl,
isLoading: isColorLoading,
routeId,
showBlurredImage,
});
if (!isReady) {
return null;
}
return (
<AnimatedPage key={`album-artist-detail-${routeId}`}>
<NativeScrollArea
@@ -155,3 +155,36 @@ export const useFastAverageColor = (args: {
isLoading,
};
};
export const useWaitForColorCalculation = (args: {
hasImage: boolean;
isLoading: boolean;
routeId: string;
showBlurredImage: boolean;
timeoutMs?: number;
}) => {
const { hasImage, isLoading, routeId, showBlurredImage, timeoutMs = 1000 } = args;
const [timeoutReached, setTimeoutReached] = useState(false);
const shouldWaitForColor = hasImage && !showBlurredImage;
useEffect(() => {
setTimeoutReached(false);
if (!shouldWaitForColor) {
return;
}
const timeoutId = setTimeout(() => {
setTimeoutReached(true);
}, timeoutMs);
return () => {
clearTimeout(timeoutId);
};
}, [shouldWaitForColor, routeId, timeoutMs]);
const isReady = !shouldWaitForColor || !isLoading || timeoutReached;
return { isReady };
};