mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +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');
|
||||
|
||||
// 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 (!hasArtistMatches && artists.length > 0) {
|
||||
return (
|
||||
<Text component="span" {...rootTextProps}>
|
||||
{artists.map((artist, index) => (
|
||||
<Fragment key={artist.id}>
|
||||
<Fragment key={artist.id || `artist-${index}`}>
|
||||
{index > 0 && ', '}
|
||||
<Text
|
||||
component={Link}
|
||||
fw={600}
|
||||
isLink
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
albumArtistId: artist.id,
|
||||
})}
|
||||
{...linkProps}
|
||||
>
|
||||
{artist.name}
|
||||
</Text>
|
||||
{artist.id ? (
|
||||
<Text
|
||||
component={Link}
|
||||
fw={600}
|
||||
isLink
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
albumArtistId: artist.id,
|
||||
})}
|
||||
{...linkProps}
|
||||
>
|
||||
{artist.name}
|
||||
</Text>
|
||||
) : (
|
||||
<Text fw={600} {...linkProps}>
|
||||
{artist.name}
|
||||
</Text>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
</Text>
|
||||
@@ -137,21 +151,56 @@ export const JoinedArtists = ({
|
||||
}
|
||||
|
||||
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 (
|
||||
<Text
|
||||
component={Link}
|
||||
fw={600}
|
||||
isLink
|
||||
key={`${artist.id}-${index}`}
|
||||
to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
albumArtistId: artist.id,
|
||||
})}
|
||||
{...linkProps}
|
||||
>
|
||||
<Text fw={600} key={`${artist.name}-${index}`} {...linkProps}>
|
||||
{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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -106,6 +106,33 @@ const getPlaylistImageId = (item: z.infer<typeof jfType._response.playlist>): nu
|
||||
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 = (
|
||||
item: z.infer<typeof jfType._response.song>,
|
||||
server: null | ServerListItem,
|
||||
@@ -143,6 +170,11 @@ const normalizeSong = (
|
||||
console.warn('Jellyfin song retrieved with no media sources', item);
|
||||
}
|
||||
|
||||
const participants = getPeople(item);
|
||||
|
||||
const artists = getArtists(item, participants);
|
||||
|
||||
console.log('artists', artists);
|
||||
return {
|
||||
_itemType: LibraryItem.SONG,
|
||||
_serverId: server?.id || '',
|
||||
@@ -159,16 +191,7 @@ const normalizeSong = (
|
||||
})),
|
||||
albumId: item.AlbumId || `dummy/${item.Id}`,
|
||||
artistName: item?.ArtistItems?.map((entry) => entry.Name).join(', ') || '',
|
||||
artists: (item?.ArtistItems?.length ? item.ArtistItems : item.AlbumArtists)?.map(
|
||||
(entry) => ({
|
||||
id: entry.Id,
|
||||
imageId: null,
|
||||
imageUrl: null,
|
||||
name: entry.Name,
|
||||
userFavorite: false,
|
||||
userRating: null,
|
||||
}),
|
||||
),
|
||||
artists,
|
||||
bitDepth: null,
|
||||
bitRate,
|
||||
bpm: null,
|
||||
@@ -210,7 +233,7 @@ const normalizeSong = (
|
||||
mbzRecordingId: null,
|
||||
mbzTrackId: item.ProviderIds?.MusicBrainzTrack || null,
|
||||
name: item.Name,
|
||||
participants: getPeople(item),
|
||||
participants,
|
||||
path: replacePathPrefix(path || '', pathReplace, pathReplaceWith),
|
||||
peak: null,
|
||||
playCount: (item.UserData && item.UserData.PlayCount) || 0,
|
||||
|
||||
@@ -57,12 +57,13 @@ const getArtists = (
|
||||
) => {
|
||||
let albumArtists: RelatedArtist[] | undefined;
|
||||
let artists: RelatedArtist[] | undefined;
|
||||
let remixers: RelatedArtist[] | undefined;
|
||||
let participants: null | Record<string, RelatedArtist[]> = null;
|
||||
|
||||
if (item.participants) {
|
||||
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) => ({
|
||||
id: item.id,
|
||||
imageId: null,
|
||||
@@ -74,6 +75,8 @@ const getArtists = (
|
||||
|
||||
if (role === 'albumartist') {
|
||||
albumArtists = roleList;
|
||||
} else if (role === 'remixer') {
|
||||
remixers = roleList;
|
||||
} else {
|
||||
artists = roleList;
|
||||
}
|
||||
@@ -121,7 +124,7 @@ const getArtists = (
|
||||
];
|
||||
}
|
||||
|
||||
if (artists === undefined) {
|
||||
if (artists === undefined && remixers === undefined) {
|
||||
artists = [
|
||||
{
|
||||
id: item.artistId,
|
||||
@@ -134,7 +137,7 @@ const getArtists = (
|
||||
];
|
||||
}
|
||||
|
||||
return { albumArtists, artists, participants };
|
||||
return { albumArtists, artists: [...(artists || []), ...(remixers || [])], participants };
|
||||
};
|
||||
|
||||
const normalizeSong = (
|
||||
|
||||
@@ -21,26 +21,39 @@ const getArtistList = (
|
||||
artists?: typeof ssType._response.song._type.artists,
|
||||
artistId?: number | string,
|
||||
artistName?: string,
|
||||
participants?: null | Record<string, RelatedArtist[]>,
|
||||
) => {
|
||||
return artists
|
||||
? artists.map((item) => ({
|
||||
id: item.id.toString(),
|
||||
imageId: null,
|
||||
imageUrl: null,
|
||||
name: item.name,
|
||||
userFavorite: false,
|
||||
userRating: null,
|
||||
}))
|
||||
: [
|
||||
{
|
||||
id: artistId?.toString() || '',
|
||||
imageId: null,
|
||||
imageUrl: null,
|
||||
name: artistName || '',
|
||||
userFavorite: false,
|
||||
userRating: null,
|
||||
},
|
||||
];
|
||||
if (!artists && !participants) {
|
||||
return [
|
||||
{
|
||||
id: artistId?.toString() || '',
|
||||
imageId: null,
|
||||
imageUrl: null,
|
||||
name: artistName || '',
|
||||
userFavorite: false,
|
||||
userRating: null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const result: RelatedArtist[] = [];
|
||||
|
||||
artists?.forEach((item) => {
|
||||
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 = (
|
||||
@@ -121,6 +134,8 @@ const normalizeSong = (
|
||||
pathReplace?: string,
|
||||
pathReplaceWith?: string,
|
||||
): Song => {
|
||||
const participants = getParticipants(item);
|
||||
|
||||
return {
|
||||
_itemType: LibraryItem.SONG,
|
||||
_serverId: server?.id || 'unknown',
|
||||
@@ -130,7 +145,7 @@ const normalizeSong = (
|
||||
albumArtists: getArtistList(item.albumArtists, item.artistId, item.artist),
|
||||
albumId: item.albumId?.toString() || '',
|
||||
artistName: item.artist || '',
|
||||
artists: getArtistList(item.artists, item.artistId, item.artist),
|
||||
artists: getArtistList(item.artists, item.artistId, item.artist, participants),
|
||||
bitDepth: item.bitDepth || null,
|
||||
bitRate: item.bitRate || 0,
|
||||
bpm: item.bpm || null,
|
||||
@@ -164,7 +179,7 @@ const normalizeSong = (
|
||||
mbzRecordingId: item.musicBrainzId || null,
|
||||
mbzTrackId: null,
|
||||
name: item.title,
|
||||
participants: getParticipants(item),
|
||||
participants,
|
||||
path: replacePathPrefix(item.path || '', pathReplace, pathReplaceWith),
|
||||
peak:
|
||||
item.replayGain && (item.replayGain.albumPeak || item.replayGain.trackPeak)
|
||||
|
||||
Reference in New Issue
Block a user