diff --git a/src/renderer/features/albums/components/album-detail-header.tsx b/src/renderer/features/albums/components/album-detail-header.tsx index def95183..854d214a 100644 --- a/src/renderer/features/albums/components/album-detail-header.tsx +++ b/src/renderer/features/albums/components/album-detail-header.tsx @@ -18,8 +18,9 @@ import { AlbumDetailResponse, LibraryItem, ServerType } from '/@/shared/types/do interface AlbumDetailHeaderProps { background: { - background: string; + background?: string; blur: number; + loading: boolean; }; } diff --git a/src/renderer/features/albums/routes/album-detail-route.tsx b/src/renderer/features/albums/routes/album-detail-route.tsx index fa6dd0cf..2a6c59f9 100644 --- a/src/renderer/features/albums/routes/album-detail-route.tsx +++ b/src/renderer/features/albums/routes/album-detail-route.tsx @@ -3,7 +3,7 @@ import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/li import { useRef } from 'react'; import { useParams } from 'react-router'; -import { NativeScrollArea, Spinner } from '/@/renderer/components'; +import { NativeScrollArea } from '/@/renderer/components'; import { AlbumDetailContent } from '/@/renderer/features/albums/components/album-detail-content'; import { AlbumDetailHeader } from '/@/renderer/features/albums/components/album-detail-header'; import { useAlbumDetail } from '/@/renderer/features/albums/queries/album-detail-query'; @@ -23,7 +23,7 @@ const AlbumDetailRoute = () => { const { albumId } = useParams() as { albumId: string }; const server = useCurrentServer(); const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); - const { color: backgroundColor, colorId } = useFastAverageColor({ + const { background: backgroundColor, colorId } = useFastAverageColor({ id: albumId, src: detailQuery.data?.imageUrl, srcLoaded: !detailQuery.isLoading, @@ -41,10 +41,6 @@ const AlbumDetailRoute = () => { }); }; - if (!backgroundColor || colorId !== albumId) { - return ; - } - const backgroundUrl = detailQuery.data?.imageUrl || ''; const background = (albumBackground && `url(${backgroundUrl})`) || backgroundColor; @@ -70,6 +66,7 @@ const AlbumDetailRoute = () => { background={{ background, blur: (albumBackground && albumBackgroundBlur) || 0, + loading: !backgroundColor || colorId !== albumId, }} ref={headerRef} /> diff --git a/src/renderer/features/albums/routes/dummy-album-detail-route.tsx b/src/renderer/features/albums/routes/dummy-album-detail-route.tsx index 8dbd51f4..f49956f0 100644 --- a/src/renderer/features/albums/routes/dummy-album-detail-route.tsx +++ b/src/renderer/features/albums/routes/dummy-album-detail-route.tsx @@ -9,7 +9,7 @@ import { styled } from 'styled-components'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { Button, Spinner, Spoiler, Text } from '/@/renderer/components'; +import { Button, Spoiler, Text } from '/@/renderer/components'; import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu'; import { SONG_ALBUM_PAGE } from '/@/renderer/features/context-menu/context-menu-items'; import { usePlayQueueAdd } from '/@/renderer/features/player'; @@ -55,7 +55,7 @@ const DummyAlbumDetailRoute = () => { queryKey, }); - const { color: background, colorId } = useFastAverageColor({ + const { background, colorId } = useFastAverageColor({ id: albumId, src: detailQuery.data?.imageUrl, srcLoaded: !detailQuery.isLoading, @@ -114,10 +114,6 @@ const DummyAlbumDetailRoute = () => { }); }; - if (!background || colorId !== albumId) { - return ; - } - const metadataItems = [ { id: 'releaseYear', @@ -138,6 +134,7 @@ const DummyAlbumDetailRoute = () => { background={background} imageUrl={detailQuery?.data?.imageUrl} item={{ route: AppRoute.LIBRARY_SONGS, type: LibraryItem.SONG }} + loading={!background || colorId !== albumId} title={detailQuery?.data?.name || ''} > diff --git a/src/renderer/features/artists/components/album-artist-detail-header.tsx b/src/renderer/features/artists/components/album-artist-detail-header.tsx index b9f3b25e..ba512247 100644 --- a/src/renderer/features/artists/components/album-artist-detail-header.tsx +++ b/src/renderer/features/artists/components/album-artist-detail-header.tsx @@ -12,11 +12,12 @@ import { formatDurationString } from '/@/renderer/utils'; import { LibraryItem, ServerType } from '/@/shared/types/domain-types'; interface AlbumArtistDetailHeaderProps { - background: string; + background?: string; + loading: boolean; } export const AlbumArtistDetailHeader = forwardRef( - ({ background }: AlbumArtistDetailHeaderProps, ref: Ref) => { + ({ background, loading }: AlbumArtistDetailHeaderProps, ref: Ref) => { const { albumArtistId, artistId } = useParams() as { albumArtistId?: string; artistId?: string; @@ -76,6 +77,7 @@ export const AlbumArtistDetailHeader = forwardRef( background={background} imageUrl={detailQuery?.data?.imageUrl} item={{ route: AppRoute.LIBRARY_ALBUM_ARTISTS, type: LibraryItem.ALBUM_ARTIST }} + loading={loading} ref={ref} title={detailQuery?.data?.name || ''} > diff --git a/src/renderer/features/artists/routes/album-artist-detail-route.tsx b/src/renderer/features/artists/routes/album-artist-detail-route.tsx index e1ee5792..31389e9f 100644 --- a/src/renderer/features/artists/routes/album-artist-detail-route.tsx +++ b/src/renderer/features/artists/routes/album-artist-detail-route.tsx @@ -1,7 +1,7 @@ import { useRef } from 'react'; import { useParams } from 'react-router'; -import { NativeScrollArea, Spinner } from '/@/renderer/components'; +import { NativeScrollArea } from '/@/renderer/components'; import { AlbumArtistDetailContent } from '/@/renderer/features/artists/components/album-artist-detail-content'; import { AlbumArtistDetailHeader } from '/@/renderer/features/artists/components/album-artist-detail-header'; import { useAlbumArtistDetail } from '/@/renderer/features/artists/queries/album-artist-detail-query'; @@ -30,7 +30,7 @@ const AlbumArtistDetailRoute = () => { query: { id: routeId }, serverId: server?.id, }); - const { color: background, colorId } = useFastAverageColor({ + const { background, colorId } = useFastAverageColor({ id: routeId, src: detailQuery.data?.imageUrl, srcLoaded: !detailQuery.isLoading, @@ -46,10 +46,6 @@ const AlbumArtistDetailRoute = () => { }); }; - if (!background || colorId !== routeId) { - return ; - } - return ( { > 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 d0b6eacf..5cd685b5 100644 --- a/src/renderer/features/player/components/full-screen-player-image.tsx +++ b/src/renderer/features/player/components/full-screen-player-image.tsx @@ -132,7 +132,7 @@ export const FullScreenPlayerImage = () => { const { queue } = usePlayerData(); const { useImageAspectRatio } = useFullScreenPlayerStore(); const currentSong = queue.current; - const { color: background } = useFastAverageColor({ + const { background } = useFastAverageColor({ algorithm: 'dominant', src: queue.current?.imageUrl, srcLoaded: true, diff --git a/src/renderer/features/player/components/full-screen-player.tsx b/src/renderer/features/player/components/full-screen-player.tsx index 94db7c00..af73f630 100644 --- a/src/renderer/features/player/components/full-screen-player.tsx +++ b/src/renderer/features/player/components/full-screen-player.tsx @@ -472,7 +472,7 @@ export const FullScreenPlayer = () => { }, [location, setStore]); const currentSong = useCurrentSong(); - const { color: background } = useFastAverageColor({ + const { background } = useFastAverageColor({ algorithm: 'dominant', src: currentSong?.imageUrl, srcLoaded: true, diff --git a/src/renderer/features/shared/components/library-header.tsx b/src/renderer/features/shared/components/library-header.tsx index 1e7bf878..132191e6 100644 --- a/src/renderer/features/shared/components/library-header.tsx +++ b/src/renderer/features/shared/components/library-header.tsx @@ -14,18 +14,19 @@ import { useGeneralSettings } from '/@/renderer/store'; import { LibraryItem } from '/@/shared/types/domain-types'; interface LibraryHeaderProps { - background: string; + background?: string; blur?: number; children?: ReactNode; imagePlaceholderUrl?: null | string; imageUrl?: null | string; item: { route: string; type: LibraryItem }; + loading?: boolean; title: string; } export const LibraryHeader = forwardRef( ( - { background, blur, children, imageUrl, item, title }: LibraryHeaderProps, + { background, blur, children, imageUrl, item, loading, title }: LibraryHeaderProps, ref: Ref, ) => { const { t } = useTranslation(); @@ -106,38 +107,41 @@ export const LibraryHeader = forwardRef( style={{ cursor: 'pointer' }} tabIndex={0} > - {imageUrl && !isImageError ? ( - - ) : ( - - )} - - - - - - {itemTypeString()} - - - - - {title} - - {children} + {!loading && + (imageUrl && !isImageError ? ( + + ) : ( + + ))} + {title && ( + + + + + {itemTypeString()} + + + + + {title} + + {children} + + )} ); }, diff --git a/src/renderer/hooks/use-fast-average-color.tsx b/src/renderer/hooks/use-fast-average-color.tsx index 8f360189..7b850cb4 100644 --- a/src/renderer/hooks/use-fast-average-color.tsx +++ b/src/renderer/hooks/use-fast-average-color.tsx @@ -10,7 +10,7 @@ export const useFastAverageColor = (args: { const { algorithm, id, src, srcLoaded } = args; const idRef = useRef(id); - const [color, setColor] = useState(undefined); + const [background, setBackground] = useState(undefined); useEffect(() => { const fac = new FastAverageColor(); @@ -27,16 +27,16 @@ export const useFastAverageColor = (args: { }) .then((color) => { idRef.current = id; - return setColor(color.rgb); + return setBackground(color.rgb); }) .catch((e) => { console.log('Error fetching average color', e); idRef.current = id; - return setColor('rgba(0, 0, 0, 0)'); + return setBackground('rgba(0, 0, 0, 0)'); }); } else if (srcLoaded) { idRef.current = id; - return setColor('var(--placeholder-bg)'); + return setBackground('var(--placeholder-bg)'); } return () => { @@ -44,5 +44,5 @@ export const useFastAverageColor = (args: { }; }, [algorithm, srcLoaded, src, id]); - return { color, colorId: idRef.current }; + return { background, colorId: idRef.current }; };