Files
feishin/src/renderer/components/item-image/item-image.tsx
T
2025-12-28 02:43:31 -08:00

112 lines
3.1 KiB
TypeScript

import { memo, useMemo } from 'react';
import z from 'zod';
import { api } from '/@/renderer/api';
import {
GeneralSettingsSchema,
useAuthStore,
useCurrentServerId,
useSettingsStore,
} from '/@/renderer/store';
import { BaseImage, ImageProps } from '/@/shared/components/image/image';
import { LibraryItem } from '/@/shared/types/domain-types';
const getUnloaderIcon = (itemType: LibraryItem) => {
switch (itemType) {
case LibraryItem.ALBUM:
return 'emptyAlbumImage';
case LibraryItem.ALBUM_ARTIST:
return 'emptyArtistImage';
case LibraryItem.ARTIST:
return 'emptyArtistImage';
case LibraryItem.GENRE:
return 'emptyGenreImage';
case LibraryItem.PLAYLIST:
return 'emptyPlaylistImage';
case LibraryItem.SONG:
return 'emptySongImage';
default:
return 'emptyImage';
}
};
const BaseItemImage = (
props: Omit<ImageProps, 'src'> & {
id?: null | string;
itemType: LibraryItem;
src?: null | string;
},
) => {
const { src, ...rest } = props;
const imageUrl = useItemImageUrl({
id: props.id,
imageUrl: src,
itemType: props.itemType,
size: 300,
});
return <BaseImage src={imageUrl} unloaderIcon={getUnloaderIcon(props.itemType)} {...rest} />;
};
export const ItemImage = memo(BaseItemImage);
interface UseItemImageUrlProps {
id?: string;
imageUrl?: null | string;
itemType: LibraryItem;
serverId?: string;
size?: number;
type?: keyof z.infer<typeof GeneralSettingsSchema>['imageRes'];
}
export const useItemImageUrl = (args: UseItemImageUrlProps) => {
const { id, imageUrl, itemType, size, type } = args;
const serverId = useCurrentServerId();
const imageRes = useSettingsStore((store) => store.general.imageRes);
const sizeByType: number | undefined = type ? imageRes[type] : undefined;
return useMemo(() => {
if (imageUrl) {
return imageUrl;
}
if (!id) {
return undefined;
}
return (
api.controller.getImageUrl({
apiClientProps: { serverId: args.serverId || serverId },
query: { id, itemType, size: size ?? sizeByType },
}) || undefined
);
}, [args.serverId, id, imageUrl, itemType, serverId, size, sizeByType]);
};
export function getItemImageUrl(args: UseItemImageUrlProps) {
const { id, imageUrl, itemType, size, type } = args;
const authStore = useAuthStore.getState();
const currentServerId = authStore.currentServer?.id;
const serverId = (args.serverId || currentServerId) as string;
const imageRes = useSettingsStore.getState().general.imageRes;
const sizeByType: number | undefined = type ? imageRes[type] : undefined;
if (imageUrl) {
return imageUrl;
}
if (!id) {
return undefined;
}
return (
api.controller.getImageUrl({
apiClientProps: { serverId },
query: { id, itemType, size: size ?? sizeByType },
}) || undefined
);
}