Add album detail api

This commit is contained in:
jeffvli 2022-12-29 17:11:25 -08:00
parent dc6936b22c
commit f4ba82531c
6 changed files with 106 additions and 75 deletions

View File

@ -543,41 +543,6 @@ const getSongCoverArtUrl = (args: { baseUrl: string; item: JFSong; size: number
);
};
const normalizeAlbum = (item: JFAlbum, server: ServerListItem, imageSize?: number): Album => {
return {
albumArtists:
item.AlbumArtists?.map((entry) => ({
id: entry.Id,
name: entry.Name,
})) || [],
artists: item.ArtistItems?.map((entry) => ({ id: entry.Id, name: entry.Name })),
backdropImageUrl: null,
createdAt: item.DateCreated,
duration: item.RunTimeTicks / 10000000,
genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })),
id: item.Id,
imagePlaceholderUrl: null,
imageUrl: getAlbumCoverArtUrl({
baseUrl: server.url,
item,
size: imageSize || 300,
}),
isCompilation: null,
isFavorite: item.UserData?.IsFavorite || false,
lastPlayedAt: null,
name: item.Name,
playCount: item.UserData?.PlayCount || 0,
rating: null,
releaseDate: item.PremiereDate?.split('T')[0] || null,
releaseYear: item.ProductionYear,
serverType: ServerType.JELLYFIN,
size: null,
songCount: item?.ChildCount || null,
uniqueId: nanoid(),
updatedAt: item?.DateLastMediaAdded || item.DateCreated,
};
};
const normalizeSong = (
item: JFSong,
server: ServerListItem,
@ -627,6 +592,42 @@ const normalizeSong = (
};
};
const normalizeAlbum = (item: JFAlbum, server: ServerListItem, imageSize?: number): Album => {
return {
albumArtists:
item.AlbumArtists.map((entry) => ({
id: entry.Id,
name: entry.Name,
})) || [],
artists: item.ArtistItems?.map((entry) => ({ id: entry.Id, name: entry.Name })),
backdropImageUrl: null,
createdAt: item.DateCreated,
duration: item.RunTimeTicks / 10000000,
genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })),
id: item.Id,
imagePlaceholderUrl: null,
imageUrl: getAlbumCoverArtUrl({
baseUrl: server.url,
item,
size: imageSize || 300,
}),
isCompilation: null,
isFavorite: item.UserData?.IsFavorite || false,
lastPlayedAt: null,
name: item.Name,
playCount: item.UserData?.PlayCount || 0,
rating: null,
releaseDate: item.PremiereDate?.split('T')[0] || null,
releaseYear: item.ProductionYear,
serverType: ServerType.JELLYFIN,
size: null,
songCount: item?.ChildCount || null,
songs: item.songs?.map((song) => normalizeSong(song, server, '', imageSize)),
uniqueId: nanoid(),
updatedAt: item?.DateLastMediaAdded || item.DateCreated,
};
};
// const normalizeArtist = (item: any) => {
// return {
// album: (item.album || []).map((entry: any) => normalizeAlbum(entry)),

View File

@ -401,42 +401,6 @@ const getCoverArtUrl = (args: {
);
};
const normalizeAlbum = (item: NDAlbum, server: ServerListItem, imageSize?: number): Album => {
const imageUrl = getCoverArtUrl({
baseUrl: server.url,
coverArtId: item.coverArtId,
credential: server.credential,
size: imageSize || 300,
});
const imagePlaceholderUrl = imageUrl?.replace(/size=\d+/, 'size=50') || null;
return {
albumArtists: [{ id: item.albumArtistId, name: item.albumArtist }],
artists: [{ id: item.artistId, name: item.artist }],
backdropImageUrl: null,
createdAt: item.createdAt.split('T')[0],
duration: item.duration || null,
genres: item.genres,
id: item.id,
imagePlaceholderUrl,
imageUrl,
isCompilation: item.compilation,
isFavorite: item.starred,
lastPlayedAt: item.playDate ? item.playDate.split('T')[0] : null,
name: item.name,
playCount: item.playCount,
rating: item.rating,
releaseDate: new Date(item.minYear, 0, 1).toISOString(),
releaseYear: item.minYear,
serverType: ServerType.NAVIDROME,
size: item.size,
songCount: item.songCount,
uniqueId: nanoid(),
updatedAt: item.updatedAt,
};
};
const normalizeSong = (
item: NDSong,
server: ServerListItem,
@ -485,6 +449,44 @@ const normalizeSong = (
};
};
const normalizeAlbum = (item: NDAlbum, server: ServerListItem, imageSize?: number): Album => {
const imageUrl = getCoverArtUrl({
baseUrl: server.url,
coverArtId: item.coverArtId,
credential: server.credential,
size: imageSize || 300,
});
const imagePlaceholderUrl = imageUrl?.replace(/size=\d+/, 'size=50') || null;
const imageBackdropUrl = imageUrl?.replace(/size=\d+/, 'size=1000') || null;
return {
albumArtists: [{ id: item.albumArtistId, name: item.albumArtist }],
artists: [{ id: item.artistId, name: item.artist }],
backdropImageUrl: imageBackdropUrl,
createdAt: item.createdAt.split('T')[0],
duration: item.duration || null,
genres: item.genres,
id: item.id,
imagePlaceholderUrl,
imageUrl,
isCompilation: item.compilation,
isFavorite: item.starred,
lastPlayedAt: item.playDate ? item.playDate.split('T')[0] : null,
name: item.name,
playCount: item.playCount,
rating: item.rating,
releaseDate: new Date(item.minYear, 0, 1).toISOString(),
releaseYear: item.minYear,
serverType: ServerType.NAVIDROME,
size: item.size,
songCount: item.songCount,
songs: item.songs ? item.songs.map((song) => normalizeSong(song, server, '')) : undefined,
uniqueId: nanoid(),
updatedAt: item.updatedAt,
};
};
export const navidromeApi = {
authenticate,
createPlaylist,

View File

@ -45,7 +45,7 @@ export type NDAlbum = {
starred: boolean;
starredAt: string;
updatedAt: string;
};
} & { songs?: NDSong[] };
export type NDSong = {
album: string;

View File

@ -9,6 +9,8 @@ import { ndNormalize } from '/@/renderer/api/navidrome.api';
import type { NDAlbum, NDGenreList, NDSong } from '/@/renderer/api/navidrome.types';
import { SSGenreList, SSMusicFolderList } from '/@/renderer/api/subsonic.types';
import type {
Album,
RawAlbumDetailResponse,
RawAlbumListResponse,
RawGenreListResponse,
RawMusicFolderListResponse,
@ -36,6 +38,25 @@ const albumList = (data: RawAlbumListResponse | undefined, server: ServerListIte
};
};
const albumDetail = (
data: RawAlbumDetailResponse | undefined,
server: ServerListItem | null,
): Album | undefined => {
let album: Album | undefined;
switch (server?.type) {
case 'jellyfin':
album = jfNormalize.album(data as JFAlbum, server);
break;
case 'navidrome':
album = ndNormalize.album(data as NDAlbum, server);
break;
case 'subsonic':
break;
}
return album;
};
const songList = (data: RawSongListResponse | undefined, server: ServerListItem | null) => {
let songs;
switch (server?.type) {
@ -116,6 +137,7 @@ const genreList = (data: RawGenreListResponse | undefined, server: ServerListIte
};
export const normalize = {
albumDetail,
albumList,
genreList,
musicFolderList,

View File

@ -165,7 +165,7 @@ export type Album = {
songs?: Song[];
uniqueId: string;
updatedAt: string;
};
} & { songs?: Song[] };
export type Song = {
album: string;

View File

@ -2,15 +2,21 @@ import { useQuery } from '@tanstack/react-query';
import { queryKeys } from '/@/renderer/api/query-keys';
import type { QueryOptions } from '/@/renderer/lib/react-query';
import { useCurrentServer } from '../../../store/auth.store';
import type { AlbumDetailQuery } from '/@/renderer/api/types';
import type { AlbumDetailQuery, RawAlbumDetailResponse } from '/@/renderer/api/types';
import { controller } from '/@/renderer/api/controller';
import { useCallback } from 'react';
import { api } from '/@/renderer/api';
export const useAlbumDetail = (query: AlbumDetailQuery, options: QueryOptions) => {
export const useAlbumDetail = (query: AlbumDetailQuery, options?: QueryOptions) => {
const server = useCurrentServer();
return useQuery({
queryFn: ({ signal }) => controller.getAlbumDetail({ query, server, signal }),
queryKey: queryKeys.albums.detail(server?.id || '', query),
select: useCallback(
(data: RawAlbumDetailResponse | undefined) => api.normalize.albumDetail(data, server),
[server],
),
...options,
});
};