From f78f4892b8da31174187bf16a613b8178f916d81 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sat, 20 Nov 2021 02:41:58 -0800 Subject: [PATCH] Add genres, musicfolder --- src/api/controller.ts | 6 ++- src/api/jellyfinApi.ts | 39 ++++++++++++++++++- src/components/library/AlbumList.tsx | 8 +++- src/components/library/GenreList.tsx | 7 +++- src/components/player/NowPlayingMiniView.tsx | 6 ++- src/components/player/NowPlayingView.tsx | 6 ++- .../settings/ConfigPanels/ServerConfig.tsx | 2 +- 7 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/api/controller.ts b/src/api/controller.ts index 228b5d0..16acc63 100644 --- a/src/api/controller.ts +++ b/src/api/controller.ts @@ -47,6 +47,8 @@ import { unstar as jfUnstar, batchStar as jfBatchStar, batchUnstar as jfBatchUnstar, + getGenres as jfGetGenres, + getMusicFolders as jfGetMusicFolders, } from './jellyfinApi'; import { APIEndpoints, ServerType } from '../types'; @@ -75,11 +77,11 @@ const endpoints = [ { id: 'createPlaylist', endpoint: { subsonic: createPlaylist, jellyfin: undefined } }, { id: 'updatePlaylist', endpoint: { subsonic: updatePlaylist, jellyfin: undefined } }, { id: 'clearPlaylist', endpoint: { subsonic: clearPlaylist, jellyfin: undefined } }, - { id: 'getGenres', endpoint: { subsonic: getGenres, jellyfin: undefined } }, + { id: 'getGenres', endpoint: { subsonic: getGenres, jellyfin: jfGetGenres } }, { id: 'getSearch', endpoint: { subsonic: getSearch, jellyfin: undefined } }, { id: 'scrobble', endpoint: { subsonic: scrobble, jellyfin: undefined } }, { id: 'getIndexes', endpoint: { subsonic: getIndexes, jellyfin: undefined } }, - { id: 'getMusicFolders', endpoint: { subsonic: getMusicFolders, jellyfin: undefined } }, + { id: 'getMusicFolders', endpoint: { subsonic: getMusicFolders, jellyfin: jfGetMusicFolders } }, { id: 'getMusicDirectory', endpoint: { subsonic: getMusicDirectory, jellyfin: undefined } }, { id: 'getMusicDirectorySongs', endpoint: { subsonic: getMusicDirectorySongs, jellyfin: undefined } }, { id: 'getDownloadUrl', endpoint: { subsonic: getDownloadUrl, jellyfin: jfGetDownloadUrl } }, diff --git a/src/api/jellyfinApi.ts b/src/api/jellyfinApi.ts index 42033dd..d5683be 100644 --- a/src/api/jellyfinApi.ts +++ b/src/api/jellyfinApi.ts @@ -176,6 +176,28 @@ const normalizePlaylist = (item: any) => { }; }; +const normalizeGenre = (item: any) => { + return { + id: item.Id, + title: item.Name, + songCount: undefined, + albumCount: undefined, + type: Item.Genre, + uniqueId: nanoid(), + }; +}; + +const normalizeFolder = (item: any) => { + return { + id: item.Id, + title: item.Name, + isDir: true, + image: getCoverArtUrl(item, 350), + type: Item.Folder, + uniqueId: nanoid(), + }; +}; + export const getPlaylist = async (options: { id: string }) => { const { data } = await jellyfinApi.get(`/Items`, { params: { @@ -251,8 +273,9 @@ export const getAlbums = async (options: { fields: 'Genres, DateCreated, ChildCount', includeItemTypes: 'MusicAlbum', recursive: true, - sortBy: sortType!.replacement, - sortOrder: sortType!.sortOrder, + sortBy: sortType ? sortType!.replacement : 'SortName', + sortOrder: sortType ? sortType!.sortOrder : 'Ascending', + genres: !sortType ? options.type : undefined, }, }); @@ -413,3 +436,15 @@ export const batchUnstar = async (options: { ids: string[] }) => { return res; }; + +export const getGenres = async (options: { musicFolderId: string }) => { + const { data } = await jellyfinApi.get(`/genres`, { + params: { parentId: options.musicFolderId }, + }); + return (data.Items || []).map((entry: any) => normalizeGenre(entry)); +}; + +export const getMusicFolders = async () => { + const { data } = await jellyfinApi.get(`/users/${auth.username}/items`); + return (data.Items || []).map((entry: any) => normalizeFolder(entry)); +}; diff --git a/src/components/library/AlbumList.tsx b/src/components/library/AlbumList.tsx index 4f4dc73..c69f199 100644 --- a/src/components/library/AlbumList.tsx +++ b/src/components/library/AlbumList.tsx @@ -98,11 +98,15 @@ const AlbumList = () => { } ); const { data: genres }: any = useQuery(['genreList'], async () => { - const res = await apiController({ serverType: config.serverType, endpoint: 'getGenres' }); + const res = await apiController({ + serverType: config.serverType, + endpoint: 'getGenres', + args: { musicFolderId: musicFolder }, + }); return res.map((genre: any) => { if (genre.albumCount !== 0) { return { - label: `${genre.title} (${genre.albumCount})`, + label: `${genre.title} ${genre.albumCount ? `(${genre.albumCount})` : ''}`, value: genre.title, role: 'Genre', }; diff --git a/src/components/library/GenreList.tsx b/src/components/library/GenreList.tsx index a7c4094..2600d98 100644 --- a/src/components/library/GenreList.tsx +++ b/src/components/library/GenreList.tsx @@ -23,8 +23,13 @@ const GenreList = () => { const config = useAppSelector((state) => state.config); const album = useAppSelector((state) => state.album); const misc = useAppSelector((state) => state.misc); + const folder = useAppSelector((state) => state.folder); const { isLoading, isError, data: genres, error }: any = useQuery(['genrePageList'], async () => { - const res = await apiController({ serverType: config.serverType, endpoint: 'getGenres' }); + const res = await apiController({ + serverType: config.serverType, + endpoint: 'getGenres', + args: { musicFolderId: folder.musicFolder }, + }); return _.orderBy(res, 'songCount', 'desc'); }); const filteredData = useSearchQuery(misc.searchQuery, genres, ['title']); diff --git a/src/components/player/NowPlayingMiniView.tsx b/src/components/player/NowPlayingMiniView.tsx index 9d3096b..398c928 100644 --- a/src/components/player/NowPlayingMiniView.tsx +++ b/src/components/player/NowPlayingMiniView.tsx @@ -79,7 +79,11 @@ const NowPlayingMiniView = () => { const [musicFolder, setMusicFolder] = useState(folder.musicFolder); const { isLoading: isLoadingGenres, data: genres }: any = useQuery(['genreList'], async () => { - const res = await apiController({ serverType: config.serverType, endpoint: 'getGenres' }); + const res = await apiController({ + serverType: config.serverType, + endpoint: 'getGenres', + args: { musicFolderId: musicFolder }, + }); const genresOrderedBySongCount = _.orderBy(res, 'songCount', 'desc'); return genresOrderedBySongCount.map((genre: any) => { return { diff --git a/src/components/player/NowPlayingView.tsx b/src/components/player/NowPlayingView.tsx index e0fa9d3..14aca00 100644 --- a/src/components/player/NowPlayingView.tsx +++ b/src/components/player/NowPlayingView.tsx @@ -96,7 +96,11 @@ const NowPlayingView = () => { ]); const { data: genres }: any = useQuery(['genreList'], async () => { - const res = await apiController({ serverType: config.serverType, endpoint: 'getGenres' }); + const res = await apiController({ + serverType: config.serverType, + endpoint: 'getGenres', + args: { musicFolderId: musicFolder }, + }); const genresOrderedBySongCount = _.orderBy(res, 'songCount', 'desc'); return genresOrderedBySongCount.map((genre: any) => { return { diff --git a/src/components/settings/ConfigPanels/ServerConfig.tsx b/src/components/settings/ConfigPanels/ServerConfig.tsx index a41d96f..b220c60 100644 --- a/src/components/settings/ConfigPanels/ServerConfig.tsx +++ b/src/components/settings/ConfigPanels/ServerConfig.tsx @@ -32,7 +32,7 @@ const ServerConfig = () => { data={isLoading ? [] : musicFolders} defaultValue={folder.musicFolder} valueKey="id" - labelKey="name" + labelKey="title" onChange={(e: any) => { settings.setSync('musicFolder.id', e); dispatch(setMusicFolder(e));