mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-09 20:29:36 +02:00
add remixer to song artist (#1400)
This commit is contained in:
@@ -96,24 +96,38 @@ export const JoinedArtists = ({
|
|||||||
|
|
||||||
const hasArtistMatches = parts.some((part) => typeof part !== 'string');
|
const hasArtistMatches = parts.some((part) => typeof part !== 'string');
|
||||||
|
|
||||||
|
// Find artists that were matched
|
||||||
|
const matchedArtistIds = new Set(nonOverlappingMatches.map((match) => match.artist.id));
|
||||||
|
|
||||||
|
// Find artists that are not present in the artist name
|
||||||
|
const unmatchedArtists = artists.filter(
|
||||||
|
(artist) => artist.name && !matchedArtistIds.has(artist.id),
|
||||||
|
);
|
||||||
|
|
||||||
// If no matches found and there are album artists, return the album artists
|
// If no matches found and there are album artists, return the album artists
|
||||||
if (!hasArtistMatches && artists.length > 0) {
|
if (!hasArtistMatches && artists.length > 0) {
|
||||||
return (
|
return (
|
||||||
<Text component="span" {...rootTextProps}>
|
<Text component="span" {...rootTextProps}>
|
||||||
{artists.map((artist, index) => (
|
{artists.map((artist, index) => (
|
||||||
<Fragment key={artist.id}>
|
<Fragment key={artist.id || `artist-${index}`}>
|
||||||
{index > 0 && ', '}
|
{index > 0 && ', '}
|
||||||
<Text
|
{artist.id ? (
|
||||||
component={Link}
|
<Text
|
||||||
fw={600}
|
component={Link}
|
||||||
isLink
|
fw={600}
|
||||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
isLink
|
||||||
albumArtistId: artist.id,
|
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||||
})}
|
albumArtistId: artist.id,
|
||||||
{...linkProps}
|
})}
|
||||||
>
|
{...linkProps}
|
||||||
{artist.name}
|
>
|
||||||
</Text>
|
{artist.name}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Text fw={600} {...linkProps}>
|
||||||
|
{artist.name}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -137,21 +151,56 @@ export const JoinedArtists = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { artist, text } = part;
|
const { artist, text } = part;
|
||||||
|
|
||||||
|
if (artist.id) {
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
component={Link}
|
||||||
|
fw={600}
|
||||||
|
isLink
|
||||||
|
key={`${artist.id}-${index}`}
|
||||||
|
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||||
|
albumArtistId: artist.id,
|
||||||
|
})}
|
||||||
|
{...linkProps}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text fw={600} key={`${artist.name}-${index}`} {...linkProps}>
|
||||||
component={Link}
|
|
||||||
fw={600}
|
|
||||||
isLink
|
|
||||||
key={`${artist.id}-${index}`}
|
|
||||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
|
||||||
albumArtistId: artist.id,
|
|
||||||
})}
|
|
||||||
{...linkProps}
|
|
||||||
>
|
|
||||||
{text}
|
{text}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
{unmatchedArtists.length > 0 && (
|
||||||
|
<>
|
||||||
|
{', '}
|
||||||
|
{unmatchedArtists.map((artist, index) => (
|
||||||
|
<Fragment key={artist.id}>
|
||||||
|
{index > 0 && ', '}
|
||||||
|
{artist.id ? (
|
||||||
|
<Text
|
||||||
|
component={Link}
|
||||||
|
fw={600}
|
||||||
|
isLink
|
||||||
|
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||||
|
albumArtistId: artist.id,
|
||||||
|
})}
|
||||||
|
{...linkProps}
|
||||||
|
>
|
||||||
|
{artist.name}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Text component="span" isMuted>
|
||||||
|
{artist.name}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -106,6 +106,33 @@ const getPlaylistImageId = (item: z.infer<typeof jfType._response.playlist>): nu
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getArtists = (
|
||||||
|
item: z.infer<typeof jfType._response.song>,
|
||||||
|
participants?: null | Record<string, RelatedArtist[]>,
|
||||||
|
): RelatedArtist[] => {
|
||||||
|
if (!item?.ArtistItems?.length && !item.AlbumArtists && !participants) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: RelatedArtist[] = [];
|
||||||
|
|
||||||
|
(item?.ArtistItems?.length ? item.ArtistItems : item.AlbumArtists)?.forEach((entry) => {
|
||||||
|
result.push({
|
||||||
|
id: entry.Id,
|
||||||
|
imageId: null,
|
||||||
|
imageUrl: null,
|
||||||
|
name: entry.Name,
|
||||||
|
userFavorite: false,
|
||||||
|
userRating: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (participants?.['Remixer']) {
|
||||||
|
result.push(...participants['Remixer']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
const normalizeSong = (
|
const normalizeSong = (
|
||||||
item: z.infer<typeof jfType._response.song>,
|
item: z.infer<typeof jfType._response.song>,
|
||||||
server: null | ServerListItem,
|
server: null | ServerListItem,
|
||||||
@@ -143,6 +170,11 @@ const normalizeSong = (
|
|||||||
console.warn('Jellyfin song retrieved with no media sources', item);
|
console.warn('Jellyfin song retrieved with no media sources', item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const participants = getPeople(item);
|
||||||
|
|
||||||
|
const artists = getArtists(item, participants);
|
||||||
|
|
||||||
|
console.log('artists', artists);
|
||||||
return {
|
return {
|
||||||
_itemType: LibraryItem.SONG,
|
_itemType: LibraryItem.SONG,
|
||||||
_serverId: server?.id || '',
|
_serverId: server?.id || '',
|
||||||
@@ -159,16 +191,7 @@ const normalizeSong = (
|
|||||||
})),
|
})),
|
||||||
albumId: item.AlbumId || `dummy/${item.Id}`,
|
albumId: item.AlbumId || `dummy/${item.Id}`,
|
||||||
artistName: item?.ArtistItems?.map((entry) => entry.Name).join(', ') || '',
|
artistName: item?.ArtistItems?.map((entry) => entry.Name).join(', ') || '',
|
||||||
artists: (item?.ArtistItems?.length ? item.ArtistItems : item.AlbumArtists)?.map(
|
artists,
|
||||||
(entry) => ({
|
|
||||||
id: entry.Id,
|
|
||||||
imageId: null,
|
|
||||||
imageUrl: null,
|
|
||||||
name: entry.Name,
|
|
||||||
userFavorite: false,
|
|
||||||
userRating: null,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
bitDepth: null,
|
bitDepth: null,
|
||||||
bitRate,
|
bitRate,
|
||||||
bpm: null,
|
bpm: null,
|
||||||
@@ -210,7 +233,7 @@ const normalizeSong = (
|
|||||||
mbzRecordingId: null,
|
mbzRecordingId: null,
|
||||||
mbzTrackId: item.ProviderIds?.MusicBrainzTrack || null,
|
mbzTrackId: item.ProviderIds?.MusicBrainzTrack || null,
|
||||||
name: item.Name,
|
name: item.Name,
|
||||||
participants: getPeople(item),
|
participants,
|
||||||
path: replacePathPrefix(path || '', pathReplace, pathReplaceWith),
|
path: replacePathPrefix(path || '', pathReplace, pathReplaceWith),
|
||||||
peak: null,
|
peak: null,
|
||||||
playCount: (item.UserData && item.UserData.PlayCount) || 0,
|
playCount: (item.UserData && item.UserData.PlayCount) || 0,
|
||||||
|
|||||||
@@ -57,12 +57,13 @@ const getArtists = (
|
|||||||
) => {
|
) => {
|
||||||
let albumArtists: RelatedArtist[] | undefined;
|
let albumArtists: RelatedArtist[] | undefined;
|
||||||
let artists: RelatedArtist[] | undefined;
|
let artists: RelatedArtist[] | undefined;
|
||||||
|
let remixers: RelatedArtist[] | undefined;
|
||||||
let participants: null | Record<string, RelatedArtist[]> = null;
|
let participants: null | Record<string, RelatedArtist[]> = null;
|
||||||
|
|
||||||
if (item.participants) {
|
if (item.participants) {
|
||||||
participants = {};
|
participants = {};
|
||||||
for (const [role, list] of Object.entries(item.participants)) {
|
for (const [role, list] of Object.entries(item.participants)) {
|
||||||
if (role === 'albumartist' || role === 'artist') {
|
if (role === 'albumartist' || role === 'artist' || role === 'remixer') {
|
||||||
const roleList = list.map((item) => ({
|
const roleList = list.map((item) => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
imageId: null,
|
imageId: null,
|
||||||
@@ -74,6 +75,8 @@ const getArtists = (
|
|||||||
|
|
||||||
if (role === 'albumartist') {
|
if (role === 'albumartist') {
|
||||||
albumArtists = roleList;
|
albumArtists = roleList;
|
||||||
|
} else if (role === 'remixer') {
|
||||||
|
remixers = roleList;
|
||||||
} else {
|
} else {
|
||||||
artists = roleList;
|
artists = roleList;
|
||||||
}
|
}
|
||||||
@@ -121,7 +124,7 @@ const getArtists = (
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (artists === undefined) {
|
if (artists === undefined && remixers === undefined) {
|
||||||
artists = [
|
artists = [
|
||||||
{
|
{
|
||||||
id: item.artistId,
|
id: item.artistId,
|
||||||
@@ -134,7 +137,7 @@ const getArtists = (
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return { albumArtists, artists, participants };
|
return { albumArtists, artists: [...(artists || []), ...(remixers || [])], participants };
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizeSong = (
|
const normalizeSong = (
|
||||||
|
|||||||
@@ -21,26 +21,39 @@ const getArtistList = (
|
|||||||
artists?: typeof ssType._response.song._type.artists,
|
artists?: typeof ssType._response.song._type.artists,
|
||||||
artistId?: number | string,
|
artistId?: number | string,
|
||||||
artistName?: string,
|
artistName?: string,
|
||||||
|
participants?: null | Record<string, RelatedArtist[]>,
|
||||||
) => {
|
) => {
|
||||||
return artists
|
if (!artists && !participants) {
|
||||||
? artists.map((item) => ({
|
return [
|
||||||
id: item.id.toString(),
|
{
|
||||||
imageId: null,
|
id: artistId?.toString() || '',
|
||||||
imageUrl: null,
|
imageId: null,
|
||||||
name: item.name,
|
imageUrl: null,
|
||||||
userFavorite: false,
|
name: artistName || '',
|
||||||
userRating: null,
|
userFavorite: false,
|
||||||
}))
|
userRating: null,
|
||||||
: [
|
},
|
||||||
{
|
];
|
||||||
id: artistId?.toString() || '',
|
}
|
||||||
imageId: null,
|
|
||||||
imageUrl: null,
|
const result: RelatedArtist[] = [];
|
||||||
name: artistName || '',
|
|
||||||
userFavorite: false,
|
artists?.forEach((item) => {
|
||||||
userRating: null,
|
result.push({
|
||||||
},
|
id: item.id.toString(),
|
||||||
];
|
imageId: null,
|
||||||
|
imageUrl: null,
|
||||||
|
name: item.name,
|
||||||
|
userFavorite: false,
|
||||||
|
userRating: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (participants?.['remixer']) {
|
||||||
|
result.push(...participants['remixer']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getParticipants = (
|
const getParticipants = (
|
||||||
@@ -121,6 +134,8 @@ const normalizeSong = (
|
|||||||
pathReplace?: string,
|
pathReplace?: string,
|
||||||
pathReplaceWith?: string,
|
pathReplaceWith?: string,
|
||||||
): Song => {
|
): Song => {
|
||||||
|
const participants = getParticipants(item);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_itemType: LibraryItem.SONG,
|
_itemType: LibraryItem.SONG,
|
||||||
_serverId: server?.id || 'unknown',
|
_serverId: server?.id || 'unknown',
|
||||||
@@ -130,7 +145,7 @@ const normalizeSong = (
|
|||||||
albumArtists: getArtistList(item.albumArtists, item.artistId, item.artist),
|
albumArtists: getArtistList(item.albumArtists, item.artistId, item.artist),
|
||||||
albumId: item.albumId?.toString() || '',
|
albumId: item.albumId?.toString() || '',
|
||||||
artistName: item.artist || '',
|
artistName: item.artist || '',
|
||||||
artists: getArtistList(item.artists, item.artistId, item.artist),
|
artists: getArtistList(item.artists, item.artistId, item.artist, participants),
|
||||||
bitDepth: item.bitDepth || null,
|
bitDepth: item.bitDepth || null,
|
||||||
bitRate: item.bitRate || 0,
|
bitRate: item.bitRate || 0,
|
||||||
bpm: item.bpm || null,
|
bpm: item.bpm || null,
|
||||||
@@ -164,7 +179,7 @@ const normalizeSong = (
|
|||||||
mbzRecordingId: item.musicBrainzId || null,
|
mbzRecordingId: item.musicBrainzId || null,
|
||||||
mbzTrackId: null,
|
mbzTrackId: null,
|
||||||
name: item.title,
|
name: item.title,
|
||||||
participants: getParticipants(item),
|
participants,
|
||||||
path: replacePathPrefix(item.path || '', pathReplace, pathReplaceWith),
|
path: replacePathPrefix(item.path || '', pathReplace, pathReplaceWith),
|
||||||
peak:
|
peak:
|
||||||
item.replayGain && (item.replayGain.albumPeak || item.replayGain.trackPeak)
|
item.replayGain && (item.replayGain.albumPeak || item.replayGain.trackPeak)
|
||||||
|
|||||||
Reference in New Issue
Block a user