diff --git a/package-lock.json b/package-lock.json index ba6955b6fa..24b7993c4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3611,9 +3611,9 @@ "dev": true }, "node_modules/@jellyfin/sdk": { - "version": "0.0.0-unstable.202307130502", - "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202307130502.tgz", - "integrity": "sha512-1+GXATaJLP5akFnUrpxYzoshLtTPZXJEdy/ozhY1g/DkULlz4LthLTaTJ2qImF0mb8Ayk7LNbh00n4ATk0JycA==", + "version": "0.0.0-unstable.202401060501", + "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202401060501.tgz", + "integrity": "sha512-6+mTkcr62rUqF8BoZS8K2h87fV/JjMYPqZ45faytqecJIv3GMo2cJTtBKR1LrmPuAdKhC+/1ic5E7bxIK+P9gA==", "peerDependencies": { "axios": "^1.3.4" } @@ -24829,9 +24829,9 @@ "dev": true }, "@jellyfin/sdk": { - "version": "0.0.0-unstable.202307130502", - "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202307130502.tgz", - "integrity": "sha512-1+GXATaJLP5akFnUrpxYzoshLtTPZXJEdy/ozhY1g/DkULlz4LthLTaTJ2qImF0mb8Ayk7LNbh00n4ATk0JycA==", + "version": "0.0.0-unstable.202401060501", + "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202401060501.tgz", + "integrity": "sha512-6+mTkcr62rUqF8BoZS8K2h87fV/JjMYPqZ45faytqecJIv3GMo2cJTtBKR1LrmPuAdKhC+/1ic5E7bxIK+P9gA==", "requires": {} }, "@jest/schemas": { diff --git a/src/apps/dashboard/routes/users/profile.tsx b/src/apps/dashboard/routes/users/profile.tsx index 05d3b72cdf..a0bfb3fe90 100644 --- a/src/apps/dashboard/routes/users/profile.tsx +++ b/src/apps/dashboard/routes/users/profile.tsx @@ -254,7 +254,7 @@ const UserEdit: FunctionComponent = () => { user.Policy.SyncPlayAccess = (page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value as SyncPlayUserAccessType; window.ApiClient.updateUser(user).then(() => ( - window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || {}) + window.ApiClient.updateUserPolicy(user.Id || '', user.Policy || { PasswordResetProviderId: '', AuthenticationProviderId: '' }) )).then(() => { onSaveComplete(); }).catch(err => { diff --git a/src/apps/experimental/components/LibraryIcon.tsx b/src/apps/experimental/components/LibraryIcon.tsx index 220682bc90..66975f0556 100644 --- a/src/apps/experimental/components/LibraryIcon.tsx +++ b/src/apps/experimental/components/LibraryIcon.tsx @@ -11,7 +11,7 @@ import Collections from '@mui/icons-material/Collections'; import Queue from '@mui/icons-material/Queue'; import Folder from '@mui/icons-material/Folder'; import React, { FC } from 'react'; -import { CollectionType } from 'types/collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; interface LibraryIconProps { item: BaseItemDto @@ -25,20 +25,20 @@ const LibraryIcon: FC = ({ return ; case CollectionType.Music: return ; - case CollectionType.HomeVideos: + case CollectionType.Homevideos: case CollectionType.Photos: return ; - case CollectionType.LiveTv: + case CollectionType.Livetv: return ; - case CollectionType.TvShows: + case CollectionType.Tvshows: return ; case CollectionType.Trailers: return ; - case CollectionType.MusicVideos: + case CollectionType.Musicvideos: return ; case CollectionType.Books: return ; - case CollectionType.BoxSets: + case CollectionType.Boxsets: return ; case CollectionType.Playlists: return ; diff --git a/src/apps/experimental/components/library/GenresItemsContainer.tsx b/src/apps/experimental/components/library/GenresItemsContainer.tsx index e573d80e53..b3f3b5f7bf 100644 --- a/src/apps/experimental/components/library/GenresItemsContainer.tsx +++ b/src/apps/experimental/components/library/GenresItemsContainer.tsx @@ -4,7 +4,7 @@ import { useGetGenres } from 'hooks/useFetchItems'; import globalize from 'scripts/globalize'; import Loading from 'components/loading/LoadingComponent'; import GenresSectionContainer from './GenresSectionContainer'; -import { CollectionType } from 'types/collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { ParentId } from 'types/library'; interface GenresItemsContainerProps { diff --git a/src/apps/experimental/components/library/GenresSectionContainer.tsx b/src/apps/experimental/components/library/GenresSectionContainer.tsx index ca1fb39dc9..13ba08ced6 100644 --- a/src/apps/experimental/components/library/GenresSectionContainer.tsx +++ b/src/apps/experimental/components/library/GenresSectionContainer.tsx @@ -11,7 +11,7 @@ import { useGetItems } from 'hooks/useFetchItems'; import Loading from 'components/loading/LoadingComponent'; import { appRouter } from 'components/router/appRouter'; import SectionContainer from './SectionContainer'; -import { CollectionType } from 'types/collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { ParentId } from 'types/library'; interface GenresSectionContainerProps { diff --git a/src/apps/experimental/components/library/GenresView.tsx b/src/apps/experimental/components/library/GenresView.tsx index 7916f83b63..9076c28c6d 100644 --- a/src/apps/experimental/components/library/GenresView.tsx +++ b/src/apps/experimental/components/library/GenresView.tsx @@ -2,7 +2,7 @@ import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-ite import React, { FC } from 'react'; import GenresItemsContainer from './GenresItemsContainer'; import { ParentId } from 'types/library'; -import { CollectionType } from 'types/collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; interface GenresViewProps { parentId: ParentId; diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index c3789b07c6..65b26ffcdc 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -23,7 +23,7 @@ import ShuffleButton from './ShuffleButton'; import SortButton from './SortButton'; import GridListViewButton from './GridListViewButton'; import { LibraryViewSettings, ParentId, ViewMode } from 'types/library'; -import { CollectionType } from 'types/collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { LibraryTab } from 'types/libraryTab'; import { CardOptions } from 'types/cardOptions'; diff --git a/src/apps/experimental/routes/movies/index.tsx b/src/apps/experimental/routes/movies/index.tsx index 995e666797..7c25b17d45 100644 --- a/src/apps/experimental/routes/movies/index.tsx +++ b/src/apps/experimental/routes/movies/index.tsx @@ -4,7 +4,7 @@ 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 { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { LibraryTabContent, LibraryTabMapping } from 'types/libraryTabContent'; import { MovieSuggestionsSectionsView } from 'types/sections'; diff --git a/src/apps/experimental/routes/music/index.tsx b/src/apps/experimental/routes/music/index.tsx index 0bfdff50c0..23c4b5739b 100644 --- a/src/apps/experimental/routes/music/index.tsx +++ b/src/apps/experimental/routes/music/index.tsx @@ -4,7 +4,7 @@ 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 { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { LibraryTabContent, LibraryTabMapping } from 'types/libraryTabContent'; import { MusicSuggestionsSectionsView } from 'types/sections'; diff --git a/src/apps/experimental/routes/shows/index.tsx b/src/apps/experimental/routes/shows/index.tsx index d199944258..41e99ac825 100644 --- a/src/apps/experimental/routes/shows/index.tsx +++ b/src/apps/experimental/routes/shows/index.tsx @@ -4,14 +4,14 @@ 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 { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { LibraryTabContent, LibraryTabMapping } from 'types/libraryTabContent'; import { TvShowSuggestionsSectionsView } from 'types/sections'; const episodesTabContent: LibraryTabContent = { viewType: LibraryTab.Episodes, itemType: [BaseItemKind.Episode], - collectionType: CollectionType.TvShows, + collectionType: CollectionType.Tvshows, isAlphabetPickerEnabled: false, noItemsMessage: 'MessageNoEpisodesFound' }; @@ -19,7 +19,7 @@ const episodesTabContent: LibraryTabContent = { const seriesTabContent: LibraryTabContent = { viewType: LibraryTab.Series, itemType: [BaseItemKind.Series], - collectionType: CollectionType.TvShows, + collectionType: CollectionType.Tvshows, isBtnShuffleEnabled: true }; @@ -38,14 +38,14 @@ const upcomingTabContent: LibraryTabContent = { const suggestionsTabContent: LibraryTabContent = { viewType: LibraryTab.Suggestions, - collectionType: CollectionType.TvShows, + collectionType: CollectionType.Tvshows, sectionsView: TvShowSuggestionsSectionsView }; const genresTabContent: LibraryTabContent = { viewType: LibraryTab.Genres, itemType: [BaseItemKind.Series], - collectionType: CollectionType.TvShows + collectionType: CollectionType.Tvshows }; const tvShowsTabMapping: LibraryTabMapping = { diff --git a/src/components/homesections/sections/recentlyAdded.ts b/src/components/homesections/sections/recentlyAdded.ts index a849e81229..9c39e681d8 100644 --- a/src/components/homesections/sections/recentlyAdded.ts +++ b/src/components/homesections/sections/recentlyAdded.ts @@ -1,6 +1,7 @@ import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client/models/base-item-dto'; import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; import type { UserDto } from '@jellyfin/sdk/lib/generated-client/models/user-dto'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import escapeHtml from 'escape-html'; import type { ApiClient } from 'jellyfin-apiclient'; @@ -24,12 +25,12 @@ function getFetchLatestItemsFn( let limit = 16; if (enableOverflow) { - if (collectionType === 'music') { + if (collectionType === CollectionType.Music) { limit = 30; } - } else if (collectionType === 'tvshows') { + } else if (collectionType === CollectionType.Tvshows) { limit = 5; - } else if (collectionType === 'music') { + } else if (collectionType === CollectionType.Music) { limit = 9; } else { limit = 8; diff --git a/src/components/itemHelper.js b/src/components/itemHelper.js index fff0d7ed1e..d763003fb9 100644 --- a/src/components/itemHelper.js +++ b/src/components/itemHelper.js @@ -1,5 +1,6 @@ import { appHost } from './apphost'; import globalize from '../scripts/globalize'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; export function getDisplayName(item, options = {}) { if (!item) { @@ -79,7 +80,7 @@ export function supportsAddingToPlaylist(item) { if (isLocalItem(item)) { return false; } - if (item.CollectionType === 'livetv') { + if (item.CollectionType === CollectionType.Livetv) { return false; } @@ -230,7 +231,7 @@ export function canConvert (item, user) { } const collectionType = item.CollectionType; - if (collectionType === 'livetv') { + if (collectionType === CollectionType.Livetv) { return false; } @@ -249,7 +250,7 @@ export function canConvert (item, user) { export function canRefreshMetadata (item, user) { if (user.Policy.IsAdministrator) { const collectionType = item.CollectionType; - if (collectionType === 'livetv') { + if (collectionType === CollectionType.Livetv) { return false; } diff --git a/src/components/router/appRouter.js b/src/components/router/appRouter.js index e03fff3a6a..de6b3c6871 100644 --- a/src/components/router/appRouter.js +++ b/src/components/router/appRouter.js @@ -10,6 +10,7 @@ import viewManager from '../viewManager/viewManager'; import ServerConnections from '../ServerConnections'; import alert from '../alert'; import { ConnectionState } from '../../utils/jellyfin-apiclient/ConnectionState.ts'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; export const history = createHashHistory(); @@ -623,7 +624,7 @@ class AppRouter { return '#/details?seriesTimerId=' + id + '&serverId=' + serverId; } - if (item.CollectionType == 'livetv') { + if (item.CollectionType == CollectionType.Livetv) { return '#/livetv.html'; } @@ -662,7 +663,7 @@ class AppRouter { } if (context !== 'folders' && !itemHelper.isLocalItem(item)) { - if (item.CollectionType == 'movies') { + if (item.CollectionType == CollectionType.Movies) { url = '#/movies.html?topParentId=' + item.Id; if (options && options.section === 'latest') { @@ -672,7 +673,7 @@ class AppRouter { return url; } - if (item.CollectionType == 'tvshows') { + if (item.CollectionType == CollectionType.Tvshows) { url = '#/tv.html?topParentId=' + item.Id; if (options && options.section === 'latest') { @@ -682,7 +683,7 @@ class AppRouter { return url; } - if (item.CollectionType == 'music') { + if (item.CollectionType == CollectionType.Music) { url = '#/music.html?topParentId=' + item.Id; if (options?.section === 'latest') { diff --git a/src/components/search/LiveTVSearchResults.tsx b/src/components/search/LiveTVSearchResults.tsx index c72199e9ae..0e115977ca 100644 --- a/src/components/search/LiveTVSearchResults.tsx +++ b/src/components/search/LiveTVSearchResults.tsx @@ -1,5 +1,6 @@ import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; import type { ApiClient } from 'jellyfin-apiclient'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import classNames from 'classnames'; import React, { FunctionComponent, useEffect, useState } from 'react'; @@ -72,7 +73,7 @@ const LiveTVSearchResults: FunctionComponent = ({ serv setPrograms([]); setChannels([]); - if (query && collectionType === 'livetv') { + if (query && collectionType === CollectionType.Livetv) { const apiClient = ServerConnections.getApiClient(serverId); // Movies row @@ -138,7 +139,7 @@ const LiveTVSearchResults: FunctionComponent = ({ serv 'searchResults', 'padded-bottom-page', 'padded-top', - { 'hide': !query || collectionType !== 'livetv' } + { 'hide': !query || collectionType !== CollectionType.Livetv } )} > ({ Items: result.Items || [] }); -const isMovies = (collectionType: string) => collectionType === 'movies'; +const isMovies = (collectionType: string) => collectionType === CollectionType.Movies; -const isMusic = (collectionType: string) => collectionType === 'music'; +const isMusic = (collectionType: string) => collectionType === CollectionType.Music; -const isTVShows = (collectionType: string) => collectionType === 'tvshows' || collectionType === 'tv'; +const isTVShows = (collectionType: string) => collectionType === CollectionType.Tvshows; /* * React component to display search result rows for global search and non-live tv library search @@ -239,7 +240,7 @@ const SearchResults: FunctionComponent = ({ serverId = windo 'searchResults', 'padded-bottom-page', 'padded-top', - { 'hide': !query || collectionType === 'livetv' } + { 'hide': !query || collectionType === CollectionType.Livetv } )} > {isLoading ? ( diff --git a/src/controllers/list.js b/src/controllers/list.js index 5d4c7069ce..c5497be276 100644 --- a/src/controllers/list.js +++ b/src/controllers/list.js @@ -12,6 +12,7 @@ import '../elements/emby-itemscontainer/emby-itemscontainer'; import '../elements/emby-scroller/emby-scroller'; import ServerConnections from '../components/ServerConnections'; import LibraryMenu from '../scripts/libraryMenu'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; function getInitialLiveTvQuery(instance, params, startIndex = 0, limit = 300) { const query = { @@ -306,9 +307,9 @@ function getItems(instance, params, item, sortBy, startIndex, limit) { if (item.Type === 'MusicGenre') { query.IncludeItemTypes = 'MusicAlbum'; - } else if (item.CollectionType === 'movies') { + } else if (item.CollectionType === CollectionType.Movies) { query.IncludeItemTypes = 'Movie'; - } else if (item.CollectionType === 'tvshows') { + } else if (item.CollectionType === CollectionType.Tvshows) { query.IncludeItemTypes = 'Series'; } else if (item.Type === 'Genre') { query.IncludeItemTypes = 'Movie,Series,Video'; @@ -605,7 +606,7 @@ class ItemsView { posterOptions.lines = lines; posterOptions.items = items; - if (item && item.CollectionType === 'folders') { + if (item && item.CollectionType === CollectionType.Folders) { posterOptions.context = 'folders'; } @@ -635,7 +636,7 @@ class ItemsView { function setTitle(item) { LibraryMenu.setTitle(getTitle(item) || ''); - if (item && item.CollectionType === 'playlists') { + if (item && item.CollectionType === CollectionType.Playlists) { hideOrShowAll(view.querySelectorAll('.btnNewItem'), false); } else { hideOrShowAll(view.querySelectorAll('.btnNewItem'), true); @@ -865,7 +866,7 @@ class ItemsView { // Folder, Playlist views && itemType !== 'UserView' // Only Photo (homevideos) CollectionFolders are supported - && !(itemType === 'CollectionFolder' && item?.CollectionType !== 'homevideos') + && !(itemType === 'CollectionFolder' && item?.CollectionType !== CollectionType.Homevideos) ) { // Show Play All buttons hideOrShowAll(view.querySelectorAll('.btnPlay'), false); @@ -878,7 +879,7 @@ class ItemsView { // Folder, Playlist views && itemType !== 'UserView' // Only Photo (homevideos) CollectionFolders are supported - && !(itemType === 'CollectionFolder' && item?.CollectionType !== 'homevideos') + && !(itemType === 'CollectionFolder' && item?.CollectionType !== CollectionType.Homevideos) ) { // Show Shuffle buttons hideOrShowAll(view.querySelectorAll('.btnShuffle'), false); diff --git a/src/types/cardOptions.ts b/src/types/cardOptions.ts index 075f983fdc..cb4f49c0af 100644 --- a/src/types/cardOptions.ts +++ b/src/types/cardOptions.ts @@ -1,5 +1,5 @@ import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; -import { CollectionType } from './collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; export interface CardOptions { itemsContainer?: HTMLElement | null; diff --git a/src/types/collectionType.ts b/src/types/collectionType.ts deleted file mode 100644 index c2e3b9d9ff..0000000000 --- a/src/types/collectionType.ts +++ /dev/null @@ -1,16 +0,0 @@ -// NOTE: This should be included in the OpenAPI spec ideally -// https://github.com/jellyfin/jellyfin/blob/47290a8c3665f3adb859bda19deb66f438f2e5d0/MediaBrowser.Model/Entities/CollectionType.cs -export enum CollectionType { - Movies = 'movies', - TvShows = 'tvshows', - Music = 'music', - MusicVideos = 'musicvideos', - Trailers = 'trailers', - HomeVideos = 'homevideos', - BoxSets = 'boxsets', - Books = 'books', - Photos = 'photos', - LiveTv = 'livetv', - Playlists = 'playlists', - Folders = 'folders' -} diff --git a/src/types/libraryTabContent.ts b/src/types/libraryTabContent.ts index 8fd5c8bf48..433744cd22 100644 --- a/src/types/libraryTabContent.ts +++ b/src/types/libraryTabContent.ts @@ -1,6 +1,6 @@ import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client'; import { LibraryTab } from './libraryTab'; -import { CollectionType } from './collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { SectionType } from './sections'; export interface SectionsView { diff --git a/src/types/listOptions.ts b/src/types/listOptions.ts index 25e14c49da..7df383a48b 100644 --- a/src/types/listOptions.ts +++ b/src/types/listOptions.ts @@ -1,6 +1,6 @@ import { BaseItemDto, SeriesTimerInfoDto } from '@jellyfin/sdk/lib/generated-client'; import { ItemSortBy } from '@jellyfin/sdk/lib/models/api/item-sort-by'; -import { CollectionType } from './collectionType'; +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; export interface ListOptions { items?: BaseItemDto[] | SeriesTimerInfoDto[] | null;