import { closeAllModals, openModal } from '@mantine/modals'; import { forwardRef, ReactNode, Ref, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router'; import styles from './library-header.module.css'; import { WidePlayButton, WideShuffleButton, } from '/@/renderer/features/shared/components/play-button'; import { useIsMutatingCreateFavorite } from '/@/renderer/features/shared/mutations/create-favorite-mutation'; import { useIsMutatingDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-favorite-mutation'; import { useIsMutatingRating } from '/@/renderer/features/shared/mutations/set-rating-mutation'; import { ActionIcon } from '/@/shared/components/action-icon/action-icon'; import { Center } from '/@/shared/components/center/center'; import { Group } from '/@/shared/components/group/group'; import { Image } from '/@/shared/components/image/image'; import { Rating } from '/@/shared/components/rating/rating'; import { Text } from '/@/shared/components/text/text'; import { LibraryItem } from '/@/shared/types/domain-types'; interface LibraryHeaderProps { children?: ReactNode; imagePlaceholderUrl?: null | string; imageUrl?: null | string; item: { route: string; type: LibraryItem }; loading?: boolean; title: string; } export const LibraryHeader = forwardRef( ({ children, imageUrl, item, title }: LibraryHeaderProps, ref: Ref) => { const { t } = useTranslation(); const [isImageError, setIsImageError] = useState(false); const onImageError = () => { setIsImageError(true); }; const itemTypeString = () => { switch (item.type) { case LibraryItem.ALBUM: return t('entity.album', { count: 1 }); case LibraryItem.ALBUM_ARTIST: return t('entity.albumArtist', { count: 1 }); case LibraryItem.ARTIST: return t('entity.artist', { count: 1 }); case LibraryItem.PLAYLIST: return t('entity.playlist', { count: 1 }); case LibraryItem.SONG: return t('entity.track', { count: 1 }); default: return t('common.unknown'); } }; const openImage = useCallback(() => { if (imageUrl && !isImageError) { const fullSized = imageUrl.replace(/&?(size|width|height)=\d+/, ''); openModal({ children: (
closeAllModals()} style={{ cursor: 'pointer', height: 'calc(100vh - 80px)', width: '100%', }} > cover
), fullScreen: true, }); } }, [imageUrl, isImageError]); return (
openImage()} onKeyDown={(event) => [' ', 'Enter', 'Spacebar'].includes(event.key) && openImage() } role="button" style={{ cursor: 'pointer' }} tabIndex={0} > {!isImageError && ( cover )}
{title && (
{itemTypeString()}

{title}

{children}
)}
); }, ); interface LibraryHeaderMenuProps { favorite?: boolean; onFavorite?: (e: React.MouseEvent) => void; onMore?: (e: React.MouseEvent) => void; onPlay?: (e: React.MouseEvent) => void; onRating?: (rating: number) => void; onShuffle?: (e: React.MouseEvent) => void; rating?: number; } export const LibraryHeaderMenu = ({ favorite, onFavorite, onMore, onPlay, onRating, onShuffle, rating, }: LibraryHeaderMenuProps) => { const isMutatingRating = useIsMutatingRating(); const isMutatingCreateFavorite = useIsMutatingCreateFavorite(); const isMutatingDeleteFavorite = useIsMutatingDeleteFavorite(); return (
{onPlay && } {onShuffle && } {onRating && ( )} {onFavorite && ( )} {onMore && ( )}
); };