mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-20 19:04:23 +02:00
refactor grid columns internally into album artist sections to handle null cases
This commit is contained in:
@@ -159,15 +159,17 @@ const AlbumArtistActionButtons = ({
|
||||
|
||||
interface AlbumArtistMetadataGenresProps {
|
||||
genres?: Array<{ id: string; name: string }>;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
const AlbumArtistMetadataGenres = ({ genres }: AlbumArtistMetadataGenresProps) => {
|
||||
const AlbumArtistMetadataGenres = ({ genres, order }: AlbumArtistMetadataGenresProps) => {
|
||||
const { t } = useTranslation();
|
||||
const genrePath = useGenreRoute();
|
||||
|
||||
if (!genres || genres.length === 0) return null;
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<Stack gap="xs">
|
||||
<Text fw={600} isNoSelect size="sm" tt="uppercase">
|
||||
{t('entity.genre', {
|
||||
@@ -196,16 +198,19 @@ const AlbumArtistMetadataGenres = ({ genres }: AlbumArtistMetadataGenresProps) =
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
interface AlbumArtistMetadataBiographyProps {
|
||||
artistName?: string;
|
||||
order?: number;
|
||||
routeId: string;
|
||||
}
|
||||
|
||||
const AlbumArtistMetadataBiography = ({
|
||||
artistName,
|
||||
order,
|
||||
routeId,
|
||||
}: AlbumArtistMetadataBiographyProps) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -234,6 +239,7 @@ const AlbumArtistMetadataBiography = ({
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<section style={{ maxWidth: '1280px' }}>
|
||||
<TextTitle fw={700} order={3}>
|
||||
{t('page.albumArtistDetail.about', {
|
||||
@@ -246,6 +252,7 @@ const AlbumArtistMetadataBiography = ({
|
||||
<Skeleton enableAnimation height="1rem" width="60%" />
|
||||
</Stack>
|
||||
</section>
|
||||
</Grid.Col>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -254,6 +261,7 @@ const AlbumArtistMetadataBiography = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<section style={{ maxWidth: '1280px' }}>
|
||||
<TextTitle fw={700} order={3}>
|
||||
{t('page.albumArtistDetail.about', {
|
||||
@@ -264,6 +272,7 @@ const AlbumArtistMetadataBiography = ({
|
||||
<Text dangerouslySetInnerHTML={{ __html: sanitizedBiography }} />
|
||||
</Spoiler>
|
||||
</section>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -302,11 +311,13 @@ const SongTableListContainer = ({
|
||||
|
||||
interface AlbumArtistMetadataTopSongsProps {
|
||||
detailQuery: ReturnType<typeof useSuspenseQuery<AlbumArtistDetailResponse>>;
|
||||
order?: number;
|
||||
routeId: string;
|
||||
}
|
||||
|
||||
const AlbumArtistMetadataTopSongsContent = ({
|
||||
detailQuery,
|
||||
order,
|
||||
routeId,
|
||||
}: AlbumArtistMetadataTopSongsProps) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -395,10 +406,12 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
const isLoading = topSongsQuery.isLoading || !topSongsQuery.data;
|
||||
|
||||
if (!isLoading && !tableConfig) return null;
|
||||
if (!isLoading && songs.length === 0) return null;
|
||||
|
||||
const currentSongId = currentSong?.id;
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<section>
|
||||
<Stack gap="md">
|
||||
<div className={styles.albumSectionTitle}>
|
||||
@@ -475,7 +488,9 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
flex={1}
|
||||
leftSection={<Icon icon="search" />}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
placeholder={t('common.search', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
radius="xl"
|
||||
rightSection={
|
||||
searchTerm ? (
|
||||
@@ -564,11 +579,13 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
) : null}
|
||||
</Stack>
|
||||
</section>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
const AlbumArtistMetadataTopSongs = ({
|
||||
detailQuery,
|
||||
order,
|
||||
routeId,
|
||||
}: AlbumArtistMetadataTopSongsProps) => {
|
||||
const server = useCurrentServer();
|
||||
@@ -581,17 +598,25 @@ const AlbumArtistMetadataTopSongs = ({
|
||||
return (
|
||||
<Suspense fallback={null}>
|
||||
{canStartQuery ? (
|
||||
<AlbumArtistMetadataTopSongsContent detailQuery={detailQuery} routeId={routeId} />
|
||||
<AlbumArtistMetadataTopSongsContent
|
||||
detailQuery={detailQuery}
|
||||
order={order}
|
||||
routeId={routeId}
|
||||
/>
|
||||
) : null}
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
interface AlbumArtistMetadataFavoriteSongsProps {
|
||||
order?: number;
|
||||
routeId: string;
|
||||
}
|
||||
|
||||
const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavoriteSongsProps) => {
|
||||
const AlbumArtistMetadataFavoriteSongs = ({
|
||||
order,
|
||||
routeId,
|
||||
}: AlbumArtistMetadataFavoriteSongsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 300);
|
||||
@@ -671,10 +696,12 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
const isLoading = favoriteSongsQuery.isLoading || !favoriteSongsQuery.data;
|
||||
|
||||
if (!isLoading && !tableConfig) return null;
|
||||
if (!isLoading && songs.length === 0) return null;
|
||||
|
||||
const currentSongId = currentSong?.id;
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<section>
|
||||
<Stack gap="md">
|
||||
<div className={styles.albumSectionTitle}>
|
||||
@@ -691,9 +718,12 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
<Button
|
||||
component={Link}
|
||||
size="compact-md"
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_FAVORITE_SONGS, {
|
||||
to={generatePath(
|
||||
AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_FAVORITE_SONGS,
|
||||
{
|
||||
albumArtistId: routeId,
|
||||
})}
|
||||
},
|
||||
)}
|
||||
uppercase
|
||||
variant="subtle"
|
||||
>
|
||||
@@ -751,7 +781,9 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
flex={1}
|
||||
leftSection={<Icon icon="search" />}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
placeholder={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
placeholder={t('common.search', {
|
||||
postProcess: 'sentenceCase',
|
||||
})}
|
||||
radius="xl"
|
||||
rightSection={
|
||||
searchTerm ? (
|
||||
@@ -819,6 +851,7 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
) : null}
|
||||
</Stack>
|
||||
</section>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -828,6 +861,7 @@ interface AlbumArtistMetadataExternalLinksProps {
|
||||
lastFM: boolean;
|
||||
mbzId?: null | string;
|
||||
musicBrainz: boolean;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
const AlbumArtistMetadataExternalLinks = ({
|
||||
@@ -836,12 +870,14 @@ const AlbumArtistMetadataExternalLinks = ({
|
||||
lastFM,
|
||||
mbzId,
|
||||
musicBrainz,
|
||||
order,
|
||||
}: AlbumArtistMetadataExternalLinksProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!externalLinks || (!lastFM && !musicBrainz)) return null;
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<Stack gap="xs">
|
||||
<Text fw={600} isNoSelect size="sm" tt="uppercase">
|
||||
{t('common.externalLinks', {
|
||||
@@ -885,14 +921,19 @@ const AlbumArtistMetadataExternalLinks = ({
|
||||
) : null}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
interface AlbumArtistMetadataSimilarArtistsProps {
|
||||
order?: number;
|
||||
routeId: string;
|
||||
}
|
||||
|
||||
const AlbumArtistMetadataSimilarArtists = ({ routeId }: AlbumArtistMetadataSimilarArtistsProps) => {
|
||||
const AlbumArtistMetadataSimilarArtists = ({
|
||||
order,
|
||||
routeId,
|
||||
}: AlbumArtistMetadataSimilarArtistsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const server = useCurrentServer();
|
||||
const serverId = useCurrentServerId();
|
||||
@@ -957,6 +998,7 @@ const AlbumArtistMetadataSimilarArtists = ({ routeId }: AlbumArtistMetadataSimil
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<AlbumArtistGridCarousel
|
||||
data={similarArtists}
|
||||
excludeIds={[routeId]}
|
||||
@@ -964,6 +1006,7 @@ const AlbumArtistMetadataSimilarArtists = ({ routeId }: AlbumArtistMetadataSimil
|
||||
rowCount={1}
|
||||
title={carouselTitle}
|
||||
/>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1022,7 +1065,6 @@ export const AlbumArtistDetailContent = ({
|
||||
[routeId, detailQuery.data?.name],
|
||||
);
|
||||
|
||||
const showGenres = detailQuery.data?.genres ? detailQuery.data.genres.length !== 0 : false;
|
||||
const mbzId = detailQuery.data?.mbz;
|
||||
|
||||
const handleArtistRadio = useCallback(async () => {
|
||||
@@ -1061,50 +1103,46 @@ export const AlbumArtistDetailContent = ({
|
||||
onArtistRadio={handleArtistRadio}
|
||||
/>
|
||||
<Grid gutter="2xl">
|
||||
{showGenres && (
|
||||
<Grid.Col order={genresOrder} span={12}>
|
||||
<AlbumArtistMetadataGenres genres={detailQuery.data?.genres} />
|
||||
</Grid.Col>
|
||||
)}
|
||||
<AlbumArtistMetadataGenres
|
||||
genres={detailQuery.data?.genres}
|
||||
order={genresOrder}
|
||||
/>
|
||||
{externalLinks && (lastFM || musicBrainz) && (
|
||||
<Grid.Col order={externalLinksOrder} span={12}>
|
||||
<AlbumArtistMetadataExternalLinks
|
||||
artistName={detailQuery.data?.name}
|
||||
externalLinks={externalLinks}
|
||||
lastFM={lastFM}
|
||||
mbzId={mbzId}
|
||||
musicBrainz={musicBrainz}
|
||||
order={externalLinksOrder}
|
||||
/>
|
||||
</Grid.Col>
|
||||
)}
|
||||
{enabledItem.biography && (
|
||||
<Grid.Col order={itemOrder.biography} span={12}>
|
||||
<AlbumArtistMetadataBiography
|
||||
artistName={detailQuery.data?.name}
|
||||
order={itemOrder.biography}
|
||||
routeId={routeId}
|
||||
/>
|
||||
</Grid.Col>
|
||||
)}
|
||||
<Grid.Col order={itemOrder.recentAlbums} span={12}>
|
||||
<ArtistAlbums albumsQuery={albumsQuery} />
|
||||
</Grid.Col>
|
||||
<ArtistAlbums albumsQuery={albumsQuery} order={itemOrder.recentAlbums} />
|
||||
{enabledItem.similarArtists && (
|
||||
<Grid.Col order={itemOrder.similarArtists} span={12}>
|
||||
<AlbumArtistMetadataSimilarArtists routeId={routeId} />
|
||||
</Grid.Col>
|
||||
<AlbumArtistMetadataSimilarArtists
|
||||
order={itemOrder.similarArtists}
|
||||
routeId={routeId}
|
||||
/>
|
||||
)}
|
||||
{enabledItem.topSongs && (
|
||||
<Grid.Col order={itemOrder.topSongs} span={12}>
|
||||
<AlbumArtistMetadataTopSongs
|
||||
detailQuery={detailQuery}
|
||||
order={itemOrder.topSongs}
|
||||
routeId={routeId}
|
||||
/>
|
||||
</Grid.Col>
|
||||
)}
|
||||
{enabledItem.favoriteSongs && (
|
||||
<Grid.Col order={itemOrder.favoriteSongs} span={12}>
|
||||
<AlbumArtistMetadataFavoriteSongs routeId={routeId} />
|
||||
</Grid.Col>
|
||||
<AlbumArtistMetadataFavoriteSongs
|
||||
order={itemOrder.favoriteSongs}
|
||||
routeId={routeId}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</div>
|
||||
@@ -1427,9 +1465,10 @@ const releaseTypeToEnumMap: Record<string, ArtistReleaseTypeItem> = {
|
||||
|
||||
interface ArtistAlbumsProps {
|
||||
albumsQuery: UseSuspenseQueryResult<AlbumListResponse, Error>;
|
||||
order?: number;
|
||||
}
|
||||
|
||||
const ArtistAlbums = ({ albumsQuery }: ArtistAlbumsProps) => {
|
||||
const ArtistAlbums = ({ albumsQuery, order }: ArtistAlbumsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const artistReleaseTypeItems = useArtistReleaseTypeItems();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
@@ -1674,6 +1713,7 @@ const ArtistAlbums = ({ albumsQuery }: ArtistAlbumsProps) => {
|
||||
]);
|
||||
|
||||
return (
|
||||
<Grid.Col order={order} span={12}>
|
||||
<Stack gap="md">
|
||||
<Group gap="sm" w="100%">
|
||||
<TextInput
|
||||
@@ -1710,7 +1750,9 @@ const ArtistAlbums = ({ albumsQuery }: ArtistAlbumsProps) => {
|
||||
sortBy={sortBy}
|
||||
/>
|
||||
<ListSortOrderToggleButtonControlled
|
||||
setSortOrder={(value) => setAlbumArtistDetailSort(sortBy, value as SortOrder)}
|
||||
setSortOrder={(value) =>
|
||||
setAlbumArtistDetailSort(sortBy, value as SortOrder)
|
||||
}
|
||||
sortOrder={sortOrder}
|
||||
/>
|
||||
<GroupingTypeSelector />
|
||||
@@ -1736,6 +1778,7 @@ const ArtistAlbums = ({ albumsQuery }: ArtistAlbumsProps) => {
|
||||
</div>
|
||||
)}
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user