mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-10 14:22:46 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e7830afc86 |
@@ -143,6 +143,7 @@
|
||||
"resetToDefault": "Reset to default",
|
||||
"restartRequired": "Restart required",
|
||||
"right": "Right",
|
||||
"role": "Role",
|
||||
"sampleRate": "Sample rate",
|
||||
"save": "Save",
|
||||
"saveAndReplace": "Save and replace",
|
||||
|
||||
@@ -428,16 +428,18 @@ export const NavidromeController: InternalControllerEndpoint = {
|
||||
? query.artistIds
|
||||
: query.artistIds?.[0];
|
||||
|
||||
const key = query.role ? `role_${query.role}_id` : 'artist_id';
|
||||
|
||||
const res = await ndApiClient(apiClientProps).getAlbumList({
|
||||
query: {
|
||||
_end: query.startIndex + (query.limit || 0),
|
||||
_order: sortOrderMap.navidrome[query.sortOrder],
|
||||
_sort: albumListSortMap.navidrome[query.sortBy],
|
||||
_start: query.startIndex,
|
||||
artist_id: artistIds,
|
||||
compilation: query.compilation,
|
||||
genre_id: genres,
|
||||
has_rating: query.hasRating,
|
||||
[key]: artistIds,
|
||||
library_id: getLibraryId(query.musicFolderId),
|
||||
name: query.searchTerm,
|
||||
recently_played: query.isRecentlyPlayed,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
UseQueryResult,
|
||||
useSuspenseQuery,
|
||||
UseSuspenseQueryResult,
|
||||
} from '@tanstack/react-query';
|
||||
@@ -1061,6 +1062,7 @@ const AlbumArtistMetadataSimilarArtists = ({
|
||||
mbz: null,
|
||||
name: relatedArtist.name,
|
||||
playCount: null,
|
||||
roles: null,
|
||||
similarArtists: null,
|
||||
songCount: null,
|
||||
userFavorite: relatedArtist.userFavorite,
|
||||
@@ -1101,13 +1103,17 @@ const AlbumArtistMetadataSimilarArtists = ({
|
||||
};
|
||||
|
||||
interface AlbumArtistDetailContentProps {
|
||||
albumsQuery: UseSuspenseQueryResult<AlbumListResponse, Error>;
|
||||
albumsQuery: UseQueryResult<AlbumListResponse, Error>;
|
||||
detailQuery: UseSuspenseQueryResult<AlbumArtistDetailResponse, Error>;
|
||||
role: null | string;
|
||||
setRole: (role: null | string) => void;
|
||||
}
|
||||
|
||||
export const AlbumArtistDetailContent = ({
|
||||
albumsQuery,
|
||||
detailQuery,
|
||||
role,
|
||||
setRole,
|
||||
}: AlbumArtistDetailContentProps) => {
|
||||
const artistItems = useArtistItems();
|
||||
const artistRadioCount = useArtistRadioCount();
|
||||
@@ -1220,7 +1226,13 @@ export const AlbumArtistDetailContent = ({
|
||||
routeId={routeId}
|
||||
/>
|
||||
)}
|
||||
<ArtistAlbums albumsQuery={albumsQuery} order={itemOrder.recentAlbums} />
|
||||
<ArtistAlbums
|
||||
albumsQuery={albumsQuery}
|
||||
order={itemOrder.recentAlbums}
|
||||
role={role}
|
||||
roles={detailQuery.data?.roles}
|
||||
setRole={setRole}
|
||||
/>
|
||||
{enabledItem.similarArtists && (
|
||||
<AlbumArtistMetadataSimilarArtists
|
||||
order={itemOrder.similarArtists}
|
||||
@@ -1420,13 +1432,17 @@ const AlbumSection = memo(function AlbumSection({
|
||||
});
|
||||
|
||||
import { useArtistAlbumsGrouped } from '/@/renderer/features/artists/hooks/use-artist-albums-grouped';
|
||||
import { Select } from '/@/shared/components/select/select';
|
||||
|
||||
interface ArtistAlbumsProps {
|
||||
albumsQuery: UseSuspenseQueryResult<AlbumListResponse, Error>;
|
||||
albumsQuery: UseQueryResult<AlbumListResponse, Error>;
|
||||
order?: number;
|
||||
role: null | string;
|
||||
roles?: null | string[];
|
||||
setRole: (role: null | string) => void;
|
||||
}
|
||||
|
||||
const ArtistAlbums = ({ albumsQuery, order }: ArtistAlbumsProps) => {
|
||||
const ArtistAlbums = ({ albumsQuery, order, role, roles, setRole }: ArtistAlbumsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 300);
|
||||
@@ -1521,6 +1537,17 @@ const ArtistAlbums = ({ albumsQuery, order }: ArtistAlbumsProps) => {
|
||||
}}
|
||||
value={searchTerm}
|
||||
/>
|
||||
{roles?.length && (
|
||||
<Select
|
||||
aria-label="role"
|
||||
clearable
|
||||
data={roles}
|
||||
onChange={setRole}
|
||||
placeholder={t('common.role')}
|
||||
value={role}
|
||||
w={200}
|
||||
/>
|
||||
)}
|
||||
<ListSortByDropdownControlled
|
||||
filters={CLIENT_SIDE_ALBUM_FILTERS}
|
||||
itemType={LibraryItem.ALBUM}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useSuspenseQuery, UseSuspenseQueryResult } from '@tanstack/react-query';
|
||||
import { UseQueryResult, useSuspenseQuery } from '@tanstack/react-query';
|
||||
import { forwardRef, Fragment, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router';
|
||||
@@ -38,7 +38,7 @@ import { ServerFeature } from '/@/shared/types/features-types';
|
||||
import { Play } from '/@/shared/types/types';
|
||||
|
||||
interface AlbumArtistDetailHeaderProps {
|
||||
albumsQuery: UseSuspenseQueryResult<AlbumListResponse, Error>;
|
||||
albumsQuery: UseQueryResult<AlbumListResponse, Error>;
|
||||
}
|
||||
|
||||
function ArtistImageUploadOverlay({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useSuspenseQueries } from '@tanstack/react-query';
|
||||
import { Suspense, useRef } from 'react';
|
||||
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
|
||||
import { Suspense, useRef, useState } from 'react';
|
||||
import { useParams } from 'react-router';
|
||||
|
||||
import { useItemImageUrl } from '/@/renderer/components/item-image/item-image';
|
||||
@@ -34,22 +34,24 @@ const AlbumArtistDetailRouteContent = () => {
|
||||
};
|
||||
|
||||
const routeId = (artistId || albumArtistId) as string;
|
||||
const [role, setRole] = useState<null | string>(null);
|
||||
|
||||
const [detailQuery, albumsQuery] = useSuspenseQueries({
|
||||
queries: [
|
||||
artistsQueries.albumArtistDetail({ query: { id: routeId }, serverId: server?.id }),
|
||||
albumQueries.list({
|
||||
query: {
|
||||
artistIds: [routeId],
|
||||
limit: -1,
|
||||
sortBy: AlbumListSort.RELEASE_DATE,
|
||||
sortOrder: SortOrder.DESC,
|
||||
startIndex: 0,
|
||||
},
|
||||
serverId,
|
||||
}),
|
||||
],
|
||||
});
|
||||
const detailQuery = useSuspenseQuery(
|
||||
artistsQueries.albumArtistDetail({ query: { id: routeId }, serverId: server?.id }),
|
||||
);
|
||||
const albumsQuery = useQuery(
|
||||
albumQueries.list({
|
||||
query: {
|
||||
artistIds: [routeId],
|
||||
limit: -1,
|
||||
role: role || undefined,
|
||||
sortBy: AlbumListSort.RELEASE_DATE,
|
||||
sortOrder: SortOrder.DESC,
|
||||
startIndex: 0,
|
||||
},
|
||||
serverId,
|
||||
}),
|
||||
);
|
||||
|
||||
const imageUrl = useItemImageUrl({
|
||||
id: detailQuery.data?.imageId || undefined,
|
||||
@@ -117,7 +119,12 @@ const AlbumArtistDetailRouteContent = () => {
|
||||
albumsQuery={albumsQuery}
|
||||
ref={headerRef as React.Ref<HTMLDivElement>}
|
||||
/>
|
||||
<AlbumArtistDetailContent albumsQuery={albumsQuery} detailQuery={detailQuery} />
|
||||
<AlbumArtistDetailContent
|
||||
albumsQuery={albumsQuery}
|
||||
detailQuery={detailQuery}
|
||||
role={role}
|
||||
setRole={setRole}
|
||||
/>
|
||||
</LibraryContainer>
|
||||
</NativeScrollArea>
|
||||
</AnimatedPage>
|
||||
|
||||
@@ -395,6 +395,7 @@ const normalizeAlbumArtist = (
|
||||
mbz: item.ProviderIds?.MusicBrainzArtist || null,
|
||||
name: item.Name,
|
||||
playCount: item.UserData?.PlayCount || 0,
|
||||
roles: null,
|
||||
similarArtists,
|
||||
songCount: item.SongCount ?? null,
|
||||
uploadedImage: item.ImageTags?.Primary ?? undefined,
|
||||
|
||||
@@ -410,10 +410,12 @@ const normalizeAlbumArtist = (
|
||||
|
||||
if (item.stats) {
|
||||
albumCount = Math.max(
|
||||
item.stats.maincredit?.albumCount ?? 0,
|
||||
item.stats.albumartist?.albumCount ?? 0,
|
||||
item.stats.artist?.albumCount ?? 0,
|
||||
);
|
||||
songCount = Math.max(
|
||||
item.stats.maincredit?.songCount ?? 0,
|
||||
item.stats.albumartist?.songCount ?? 0,
|
||||
item.stats.artist?.songCount ?? 0,
|
||||
);
|
||||
@@ -453,6 +455,8 @@ const normalizeAlbumArtist = (
|
||||
mbz: item.mbzArtistId || null,
|
||||
name: item.name,
|
||||
playCount: item.playCount || 0,
|
||||
// filter out specifically maincredit. This is not filterable properly
|
||||
roles: item.stats ? Object.keys(item.stats).filter((key) => key !== 'maincredit') : null,
|
||||
similarArtists:
|
||||
item.similarArtists?.map((artist) => ({
|
||||
id: artist.id,
|
||||
|
||||
@@ -274,6 +274,7 @@ const normalizeAlbumArtist = (
|
||||
mbz: null,
|
||||
name: item.name,
|
||||
playCount: null,
|
||||
roles: null,
|
||||
similarArtists:
|
||||
item.similarArtists?.map((artist) => ({
|
||||
id: artist.id,
|
||||
|
||||
@@ -223,6 +223,7 @@ export type AlbumArtist = {
|
||||
mbz: null | string;
|
||||
name: string;
|
||||
playCount: null | number;
|
||||
roles: null | string[];
|
||||
similarArtists: null | RelatedArtist[];
|
||||
songCount: null | number;
|
||||
uploadedImage?: string;
|
||||
@@ -500,6 +501,7 @@ export interface AlbumListQuery extends AlbumListNavidromeQuery, BaseQuery<Album
|
||||
maxYear?: number;
|
||||
minYear?: number;
|
||||
musicFolderId?: string | string[];
|
||||
role?: string;
|
||||
searchTerm?: string;
|
||||
startIndex: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user