From a90d2f322e15031a860eef1331e4b0fa7b8a72aa Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Sat, 28 Oct 2023 22:10:46 +0300 Subject: [PATCH] Add music view --- .../components/library/ItemsView.tsx | 42 +++++---- .../experimental/routes/asyncRoutes/user.ts | 3 +- .../experimental/routes/legacyRoutes/user.ts | 6 -- src/apps/experimental/routes/music/index.tsx | 94 +++++++++++++++++++ src/types/listOptions.ts | 49 ++++++++++ 5 files changed, 171 insertions(+), 23 deletions(-) create mode 100644 src/apps/experimental/routes/music/index.tsx create mode 100644 src/types/listOptions.ts diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index 5dffd1a66d..2770bf84f5 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -26,6 +26,7 @@ import { CollectionType } from 'types/collectionType'; import { LibraryTab } from 'types/libraryTab'; import { CardOptions } from 'types/cardOptions'; +import { ListOptions } from 'types/listOptions'; interface ItemsViewProps { viewType: LibraryTab; @@ -77,12 +78,33 @@ const ItemsView: FC = ({ ); const { data: item } = useGetItem(parentId); + const getListOptions = useCallback(() => { + const listOptions: ListOptions = { + items: itemsResult?.Items ?? [], + context: collectionType + }; + + if (viewType === LibraryTab.Songs) { + listOptions.showParentTitle = true; + listOptions.action = 'playallfromhere'; + listOptions.smallIcon = true; + listOptions.artist = true; + listOptions.addToListButton = true; + } else if (viewType === LibraryTab.Albums) { + listOptions.sortBy = libraryViewSettings.SortBy; + listOptions.addToListButton = true; + } else if (viewType === LibraryTab.Episodes) { + listOptions.showParentTitle = true; + } + + return listOptions; + }, [itemsResult?.Items, collectionType, viewType, libraryViewSettings.SortBy]); + const getCardOptions = useCallback(() => { let shape; let preferThumb; let preferDisc; let preferLogo; - let lines = libraryViewSettings.ShowTitle ? 2 : 0; if (libraryViewSettings.ImageType === ImageType.Banner) { shape = 'banner'; @@ -122,12 +144,9 @@ const ItemsView: FC = ({ ) { cardOptions.showParentTitle = libraryViewSettings.ShowTitle; } else if (viewType === LibraryTab.Artists) { - cardOptions.showYear = false; - lines = 1; + cardOptions.lines = 1; } - cardOptions.lines = lines; - return cardOptions; }, [ libraryViewSettings.ShowTitle, @@ -142,10 +161,7 @@ const ItemsView: FC = ({ let html = ''; if (libraryViewSettings.ViewMode === ViewMode.ListView) { - html = listview.getListViewHtml({ - items: itemsResult?.Items ?? [], - context: collectionType - }); + html = listview.getListViewHtml(getListOptions()); } else { html = cardBuilder.getCardsHtml( itemsResult?.Items ?? [], @@ -161,13 +177,7 @@ const ItemsView: FC = ({ } return html; - }, [ - libraryViewSettings.ViewMode, - itemsResult?.Items, - collectionType, - getCardOptions, - noItemsMessage - ]); + }, [libraryViewSettings.ViewMode, itemsResult?.Items, getListOptions, getCardOptions, noItemsMessage]); const totalRecordCount = itemsResult?.TotalRecordCount ?? 0; const items = itemsResult?.Items ?? []; diff --git a/src/apps/experimental/routes/asyncRoutes/user.ts b/src/apps/experimental/routes/asyncRoutes/user.ts index eb30c49b63..4e865dd7b5 100644 --- a/src/apps/experimental/routes/asyncRoutes/user.ts +++ b/src/apps/experimental/routes/asyncRoutes/user.ts @@ -6,5 +6,6 @@ export const ASYNC_USER_ROUTES: AsyncRoute[] = [ { path: 'userprofile.html', page: 'user/userprofile' }, { path: 'home.html', page: 'home', type: AsyncRouteType.Experimental }, { path: 'movies.html', page: 'movies', type: AsyncRouteType.Experimental }, - { path: 'tv.html', page: 'shows', type: AsyncRouteType.Experimental } + { path: 'tv.html', page: 'shows', type: AsyncRouteType.Experimental }, + { path: 'music.html', page: 'music', type: AsyncRouteType.Experimental } ]; diff --git a/src/apps/experimental/routes/legacyRoutes/user.ts b/src/apps/experimental/routes/legacyRoutes/user.ts index b17e62a155..4e28280084 100644 --- a/src/apps/experimental/routes/legacyRoutes/user.ts +++ b/src/apps/experimental/routes/legacyRoutes/user.ts @@ -19,12 +19,6 @@ export const LEGACY_USER_ROUTES: LegacyRoute[] = [ controller: 'livetv/livetvsuggested', view: 'livetv.html' } - }, { - path: 'music.html', - pageProps: { - controller: 'music/musicrecommended', - view: 'music/music.html' - } }, { path: 'mypreferencesmenu.html', pageProps: { diff --git a/src/apps/experimental/routes/music/index.tsx b/src/apps/experimental/routes/music/index.tsx new file mode 100644 index 0000000000..6ab42749b7 --- /dev/null +++ b/src/apps/experimental/routes/music/index.tsx @@ -0,0 +1,94 @@ +import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; +import React, { FC } from 'react'; +import useCurrentTab from 'hooks/useCurrentTab'; +import Page from 'components/Page'; +import PageTabContent from '../../components/library/PageTabContent'; +import { LibraryTab } from 'types/libraryTab'; +import { CollectionType } from 'types/collectionType'; +import { LibraryTabContent, LibraryTabMapping } from 'types/libraryTabContent'; +import { SectionsView } from 'types/suggestionsSections'; + +const albumArtistsTabContent: LibraryTabContent = { + viewType: LibraryTab.AlbumArtists, + collectionType: CollectionType.Music, + isBtnSortEnabled: false +}; + +const albumsTabContent: LibraryTabContent = { + viewType: LibraryTab.Albums, + collectionType: CollectionType.Music, + isBtnPlayAllEnabled: true, + isBtnShuffleEnabled: true, + itemType: [BaseItemKind.MusicAlbum] +}; + +const artistsTabContent: LibraryTabContent = { + viewType: LibraryTab.Artists, + collectionType: CollectionType.Music, + isBtnSortEnabled: false +}; + +const playlistsTabContent: LibraryTabContent = { + viewType: LibraryTab.Playlists, + isBtnFilterEnabled: false, + isBtnGridListEnabled: false, + isBtnSortEnabled: false, + isAlphabetPickerEnabled: false, + itemType: [BaseItemKind.Playlist] +}; + +const songsTabContent: LibraryTabContent = { + viewType: LibraryTab.Songs, + isBtnGridListEnabled: false, + isAlphabetPickerEnabled: false, + itemType: [BaseItemKind.Audio] +}; + +const suggestionsTabContent: LibraryTabContent = { + viewType: LibraryTab.Suggestions, + collectionType: CollectionType.Music, + sectionsType: { + suggestionSectionsView: [ + SectionsView.LatestMusic, + SectionsView.FrequentlyPlayedMusic, + SectionsView.RecentlyPlayedMusic + ] + } +}; + +const genresTabContent: LibraryTabContent = { + viewType: LibraryTab.Genres, + collectionType: CollectionType.Music, + itemType: [BaseItemKind.MusicAlbum] +}; + +const musicTabMapping: LibraryTabMapping = { + 0: albumsTabContent, + 1: suggestionsTabContent, + 2: albumArtistsTabContent, + 3: artistsTabContent, + 4: playlistsTabContent, + 5: songsTabContent, + 6: genresTabContent +}; + +const Music: FC = () => { + const { searchParamsParentId, currentTabIndex } = useCurrentTab(); + const currentTab = musicTabMapping[currentTabIndex]; + + return ( + + + + ); +}; + +export default Music; diff --git a/src/types/listOptions.ts b/src/types/listOptions.ts new file mode 100644 index 0000000000..ad943e35b5 --- /dev/null +++ b/src/types/listOptions.ts @@ -0,0 +1,49 @@ +import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; +import { ItemSortBy } from '@jellyfin/sdk/lib/models/api/item-sort-by'; +import { CollectionType } from './collectionType'; + +export interface ListOptions { + items?: BaseItemDto[] | null; + index?: string; + showIndex?: boolean; + action?: string | null; + imageSize?: string; + enableOverview?: boolean; + enableSideMediaInfo?: boolean; + playlistId?: string | null; + collectionId?: string | null; + context?: CollectionType; + parentId?: string | null; + border?: boolean; + highlight?: boolean; + dragHandle?: boolean; + showIndexNumberLeft?: boolean; + mediaInfo?: boolean; + recordButton?: boolean; + image?: boolean; + imageSource?: string; + defaultCardImageIcon?: string; + disableIndicators?: boolean; + imagePlayButton?: boolean; + showProgramDateTime?: boolean; + showProgramTime?: boolean; + showChannel?: boolean; + showParentTitle?: boolean; + showIndexNumber?: boolean; + parentTitleWithTitle?: boolean; + artist?: boolean; + includeParentInfoInTitle?: boolean; + addToListButton?: boolean; + infoButton?: boolean; + enableUserDataButtons?: boolean; + moreButton?: boolean; + rightButtons?: { + icon: string; + title: string; + id: string; + }[]; + enablePlayedButton?: boolean; + enableRatingButton?: boolean; + smallIcon?: boolean; + sortBy?: ItemSortBy; +}