From 1ac97c878a49c458154d3bea279ed981bb57f7e0 Mon Sep 17 00:00:00 2001 From: grafixeyehero Date: Wed, 5 Oct 2022 02:44:28 +0300 Subject: [PATCH] use viewSettings instead of libraryBrowser.showLayoutMenu --- src/components/viewSettings/viewSettings.js | 12 +- .../viewSettings/viewSettings.template.html | 7 + src/strings/en-us.json | 1 + src/view/components/AlphaPickerContainer.tsx | 39 ++--- src/view/components/GenresItemsContainer.tsx | 2 +- src/view/components/ItemsContainer.tsx | 140 +++++++++--------- src/view/components/Pagination.tsx | 34 +++-- .../components/RecommendationContainer.tsx | 2 +- src/view/components/SectionContainer.tsx | 2 +- src/view/components/SelectView.tsx | 49 +++--- src/view/components/Shuffle.tsx | 2 +- src/view/components/ViewItemsContainer.tsx | 92 +++++++++--- src/view/components/interface.ts | 65 ++++++-- src/view/movies/GenresView.tsx | 2 +- src/view/movies/SuggestionsView.tsx | 6 +- 15 files changed, 287 insertions(+), 168 deletions(-) diff --git a/src/components/viewSettings/viewSettings.js b/src/components/viewSettings/viewSettings.js index c872561307..d6cbf2e92b 100644 --- a/src/components/viewSettings/viewSettings.js +++ b/src/components/viewSettings/viewSettings.js @@ -57,7 +57,7 @@ function showIfAllowed(context, selector, visible) { class ViewSettings { show(options) { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve) { const dialogOptions = { removeOnClose: true, scrollY: false @@ -99,8 +99,9 @@ class ViewSettings { initEditor(dlg, options.settings); dlg.querySelector('.selectImageType').addEventListener('change', function () { - showIfAllowed(dlg, '.chkTitleContainer', this.value !== 'list'); - showIfAllowed(dlg, '.chkYearContainer', this.value !== 'list'); + showIfAllowed(dlg, '.chkTitleContainer', this.value !== 'list' && this.value !== 'banner'); + showIfAllowed(dlg, '.chkYearContainer', this.value !== 'list' && this.value !== 'banner'); + showIfAllowed(dlg, '.chkCardLayoutContainer', this.value !== 'list' && this.value !== 'banner'); }); dlg.querySelector('.btnCancel').addEventListener('click', function () { @@ -126,11 +127,10 @@ class ViewSettings { if (submitted) { saveValues(dlg, options.settings, options.settingsKey); - resolve(); - return; + return resolve(); } - reject(); + return resolve(); }); }); } diff --git a/src/components/viewSettings/viewSettings.template.html b/src/components/viewSettings/viewSettings.template.html index 8aea2fac26..5989b3f83e 100644 --- a/src/components/viewSettings/viewSettings.template.html +++ b/src/components/viewSettings/viewSettings.template.html @@ -35,6 +35,13 @@ ${GroupBySeries} + +
+ +
diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 7106cbceee..1487f8bf29 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -236,6 +236,7 @@ "EnableNextVideoInfoOverlayHelp": "At the end of a video, display info about the next video coming up in the current playlist.", "EnablePhotos": "Display the photos", "EnablePhotosHelp": "Images will be detected and displayed alongside other media files.", + "EnableCardLayout": "Display visual CardBox", "EnableRewatchingNextUp": "Enable Rewatching in Next Up", "EnableRewatchingNextUpHelp": "Enable showing already watched episodes in 'Next Up' sections.", "EnableQuickConnect": "Enable Quick Connect on this server", diff --git a/src/view/components/AlphaPickerContainer.tsx b/src/view/components/AlphaPickerContainer.tsx index b85e99e0bd..57b87e0b52 100644 --- a/src/view/components/AlphaPickerContainer.tsx +++ b/src/view/components/AlphaPickerContainer.tsx @@ -1,33 +1,34 @@ -import React, { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'; +import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import AlphaPicker from '../../components/alphaPicker/alphaPicker'; -import { IQuery } from './type'; +import { AlphaPickerValueI, QueryI } from './interface'; -type AlphaPickerProps = { - query: IQuery; - reloadItems: () => void; -}; +interface AlphaPickerContainerI { + getQuery: () => QueryI + setAlphaPickerValue: React.Dispatch; + setStartIndex: React.Dispatch>; +} -const AlphaPickerContainer: FunctionComponent = ({ query, reloadItems }: AlphaPickerProps) => { +const AlphaPickerContainer: FC = ({ getQuery, setAlphaPickerValue, setStartIndex }) => { const [ alphaPicker, setAlphaPicker ] = useState(); const element = useRef(null); + const query = getQuery(); alphaPicker?.updateControls(query); const onAlphaPickerChange = useCallback((e) => { const newValue = (e as CustomEvent).detail.value; + let updatedValue; if (newValue === '#') { - query.NameLessThan = 'A'; - delete query.NameStartsWith; + updatedValue = {NameLessThan: 'A'}; } else { - query.NameStartsWith = newValue; - delete query.NameLessThan; + updatedValue = {NameStartsWith: newValue}; } - query.StartIndex = 0; - reloadItems(); - }, [query, reloadItems]); + setAlphaPickerValue(updatedValue); + setStartIndex(0); + }, [setStartIndex, setAlphaPickerValue]); useEffect(() => { - const alphaPickerElement = element.current?.querySelector('.alphaPicker'); + const alphaPickerElement = element.current; setAlphaPicker(new AlphaPicker({ element: alphaPickerElement, @@ -37,12 +38,14 @@ const AlphaPickerContainer: FunctionComponent = ({ query, relo if (alphaPickerElement) { alphaPickerElement.addEventListener('alphavaluechanged', onAlphaPickerChange); } + + return () => { + alphaPickerElement?.removeEventListener('alphavaluechanged', onAlphaPickerChange); + }; }, [onAlphaPickerChange]); return ( -
-
-
+
); }; diff --git a/src/view/components/GenresItemsContainer.tsx b/src/view/components/GenresItemsContainer.tsx index 1b90e49e70..9c8d268396 100644 --- a/src/view/components/GenresItemsContainer.tsx +++ b/src/view/components/GenresItemsContainer.tsx @@ -1,7 +1,7 @@ import '../../elements/emby-button/emby-button'; import '../../elements/emby-itemscontainer/emby-itemscontainer'; -import { BaseItemDtoQueryResult } from '@thornbill/jellyfin-sdk/dist/generated-client'; +import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; import escapeHTML from 'escape-html'; import React, { FC, useCallback, useEffect, useRef } from 'react'; diff --git a/src/view/components/ItemsContainer.tsx b/src/view/components/ItemsContainer.tsx index 806cad279e..3deb0829bc 100644 --- a/src/view/components/ItemsContainer.tsx +++ b/src/view/components/ItemsContainer.tsx @@ -1,5 +1,5 @@ -import { BaseItemDto } from '@thornbill/jellyfin-sdk/dist/generated-client'; -import React, { FC, useEffect, useRef } from 'react'; +import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; +import React, { FC, useCallback, useEffect, useRef } from 'react'; import ItemsContainerElement from '../../elements/ItemsContainerElement'; import cardBuilder from '../../components/cardbuilder/cardBuilder'; @@ -7,82 +7,78 @@ import listview from '../../components/listview/listview'; import globalize from '../../scripts/globalize'; import imageLoader from '../../components/images/imageLoader'; import '../../elements/emby-itemscontainer/emby-itemscontainer'; -import { QueryI } from './interface'; +import { CardOptionsI } from './interface'; interface ItemsContainerI { - getCurrentViewStyle: () => string; - query: QueryI; + getViewSettings: () => { + showTitle: string | boolean; + cardLayout: string | boolean; + showYear: string | boolean; + imageType: string; + viewType: string; + }; getContext: () => string | null; items?: BaseItemDto[] | null; noItemsMessage?: string; } -const ItemsContainer: FC = ({ getCurrentViewStyle, query, getContext, items = [], noItemsMessage }) => { +const ItemsContainer: FC = ({ getViewSettings, getContext, items = [], noItemsMessage }) => { const element = useRef(null); - const viewStyle = getCurrentViewStyle(); + const viewsettings = getViewSettings(); - useEffect(() => { - let html; + const getCardOptions = useCallback(() => { + let shape; + let preferThumb; + let preferDisc; + let preferLogo; - if (viewStyle == 'Thumb') { - html = cardBuilder.getCardsHtml(items, { - items: items, - shape: 'backdrop', - preferThumb: true, - context: getContext(), - lazy: true, - overlayPlayButton: true, - showTitle: true, - showYear: true, - centerText: true - }); - } else if (viewStyle == 'ThumbCard') { - html = cardBuilder.getCardsHtml(items, { - items: items, - shape: 'backdrop', - preferThumb: true, - context: getContext(), - lazy: true, - cardLayout: true, - showTitle: true, - showYear: true, - centerText: true - }); - } else if (viewStyle == 'Banner') { - html = cardBuilder.getCardsHtml(items, { - items: items, - shape: 'banner', - preferBanner: true, - context: getContext(), - lazy: true - }); - } else if (viewStyle == 'List') { + if (viewsettings.imageType === 'banner') { + shape = 'banner'; + } else if (viewsettings.imageType === 'disc') { + shape = 'square'; + preferDisc = true; + } else if (viewsettings.imageType === 'logo') { + shape = 'backdrop'; + preferLogo = true; + } else if (viewsettings.imageType === 'thumb') { + shape = 'backdrop'; + preferThumb = true; + } else { + shape = 'autoVertical'; + } + + const cardOptions: CardOptionsI = { + shape: shape, + showTitle: viewsettings.showTitle, + showYear: viewsettings.showTitle, + cardLayout: viewsettings.cardLayout, + centerText: true, + context: getContext(), + coverImage: true, + preferThumb: preferThumb, + preferDisc: preferDisc, + preferLogo: preferLogo, + overlayPlayButton: false, + overlayMoreButton: true, + overlayText: !viewsettings.showTitle + }; + + cardOptions.items = items; + + return cardOptions; + }, [getContext, items, viewsettings.cardLayout, viewsettings.imageType, viewsettings.showTitle]); + + const getItemsHtml = useCallback(() => { + const settings = getViewSettings(); + + let html = ''; + + if (settings.imageType === 'list') { html = listview.getListViewHtml({ items: items, - context: getContext(), - sortBy: query.SortBy - }); - } else if (viewStyle == 'PosterCard') { - html = cardBuilder.getCardsHtml(items, { - items: items, - shape: 'portrait', - context: getContext(), - showTitle: true, - showYear: true, - centerText: true, - lazy: true, - cardLayout: true - }); + context: getContext()}); } else { - html = cardBuilder.getCardsHtml(items, { - items: items, - shape: 'portrait', - context: getContext(), - overlayPlayButton: true, - showTitle: true, - showYear: true, - centerText: true - }); + html = cardBuilder.getCardsHtml(items, getCardOptions()); } if (!items?.length) { @@ -94,12 +90,16 @@ const ItemsContainer: FC = ({ getCurrentViewStyle, query, getCo html += '
'; } - const itemsContainer = element.current?.querySelector('.itemsContainer') as HTMLDivElement; - itemsContainer.innerHTML = html; - imageLoader.lazyChildren(itemsContainer); - }, [query.SortBy, items, noItemsMessage, viewStyle, getContext]); + return html; + }, [getCardOptions, getContext, getViewSettings, items, noItemsMessage]); - const cssClass = viewStyle == 'List' ? 'vertical-list' : 'vertical-wrap'; + useEffect(() => { + const itemsContainer = element.current?.querySelector('.itemsContainer') as HTMLDivElement; + itemsContainer.innerHTML = getItemsHtml(); + imageLoader.lazyChildren(itemsContainer); + }, [getItemsHtml]); + + const cssClass = viewsettings.imageType == 'List' ? 'vertical-list' : 'vertical-wrap'; return (
diff --git a/src/view/components/Pagination.tsx b/src/view/components/Pagination.tsx index 37eb168ea3..7a6da59a2a 100644 --- a/src/view/components/Pagination.tsx +++ b/src/view/components/Pagination.tsx @@ -1,36 +1,35 @@ -import { BaseItemDtoQueryResult } from '@thornbill/jellyfin-sdk/dist/generated-client'; +import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; import React, { FC, useCallback, useEffect, useRef } from 'react'; import IconButtonElement from '../../elements/IconButtonElement'; import globalize from '../../scripts/globalize'; -import { QueryI } from './interface'; +import * as userSettings from '../../scripts/settings/userSettings'; interface PaginationI { - query: QueryI; + startIndex: number + setStartIndex: React.Dispatch>; itemsResult?: BaseItemDtoQueryResult; - reloadItems: () => void; } -const Pagination: FC = ({ query, itemsResult = {}, reloadItems }) => { - const startIndex = query.StartIndex; - const limit = query.Limit; +const Pagination: FC = ({ startIndex, setStartIndex, itemsResult = {} }) => { + const limit = userSettings.libraryPageSize(undefined); const totalRecordCount = itemsResult.TotalRecordCount || 0; const recordsEnd = Math.min(startIndex + limit, totalRecordCount); const showControls = limit < totalRecordCount; const element = useRef(null); const onNextPageClick = useCallback(() => { - if (query.Limit > 0) { - query.StartIndex += query.Limit; + if (limit > 0) { + const newIndex = startIndex + limit; + setStartIndex(newIndex); } - reloadItems(); - }, [query, reloadItems]); + }, [limit, setStartIndex, startIndex]); const onPreviousPageClick = useCallback(() => { - if (query.Limit > 0) { - query.StartIndex = Math.max(0, query.StartIndex - query.Limit); + if (limit > 0) { + const newIndex = Math.max(0, startIndex - limit); + setStartIndex(newIndex); } - reloadItems(); - }, [query, reloadItems]); + }, [limit, setStartIndex, startIndex]); useEffect(() => { const btnNextPage = element.current?.querySelector('.btnNextPage') as HTMLButtonElement; @@ -52,6 +51,11 @@ const Pagination: FC = ({ query, itemsResult = {}, reloadItems }) = } btnPreviousPage.addEventListener('click', onPreviousPageClick); } + + return () => { + btnNextPage?.removeEventListener('click', onNextPageClick); + btnPreviousPage?.removeEventListener('click', onPreviousPageClick); + }; }, [totalRecordCount, onNextPageClick, onPreviousPageClick, limit, startIndex]); return ( diff --git a/src/view/components/RecommendationContainer.tsx b/src/view/components/RecommendationContainer.tsx index 836e2126fb..a88cf2f404 100644 --- a/src/view/components/RecommendationContainer.tsx +++ b/src/view/components/RecommendationContainer.tsx @@ -1,4 +1,4 @@ -import { RecommendationDto } from '@thornbill/jellyfin-sdk/dist/generated-client'; +import type { RecommendationDto } from '@jellyfin/sdk/lib/generated-client'; import React, { FC } from 'react'; import globalize from '../../scripts/globalize'; diff --git a/src/view/components/SectionContainer.tsx b/src/view/components/SectionContainer.tsx index eb9daacb1f..b1ecff8716 100644 --- a/src/view/components/SectionContainer.tsx +++ b/src/view/components/SectionContainer.tsx @@ -1,6 +1,6 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer'; -import { BaseItemDto } from '@thornbill/jellyfin-sdk/dist/generated-client'; +import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; import React, { FC, useEffect, useRef } from 'react'; import cardBuilder from '../../components/cardbuilder/cardBuilder'; diff --git a/src/view/components/SelectView.tsx b/src/view/components/SelectView.tsx index 4a308c11db..6b48a86b99 100644 --- a/src/view/components/SelectView.tsx +++ b/src/view/components/SelectView.tsx @@ -1,32 +1,43 @@ -import React, { FC, useEffect, useRef } from 'react'; +import React, { FC, useCallback, useEffect, useRef } from 'react'; import IconButtonElement from '../../elements/IconButtonElement'; -import libraryBrowser from '../../scripts/libraryBrowser'; -import * as userSettings from '../../scripts/settings/userSettings'; -import { QueryI } from './interface'; - interface SelectViewI { - getCurrentViewStyle: () => string; - query: QueryI; - getViewSettings: () => string; + getSettingsKey: () => string; + getVisibleViewSettings: () => string[]; + getViewSettings: () => { + showTitle: string | boolean; + cardLayout: string | boolean; + showYear: string | boolean; + imageType: string; + viewType: string; + }; reloadItems: () => void; } -const SelectView: FC = ({ getCurrentViewStyle, getViewSettings, query, reloadItems }) => { +const SelectView: FC = ({ getSettingsKey, getVisibleViewSettings, getViewSettings, reloadItems }) => { const element = useRef(null); + const showViewSettingsMenu = useCallback(() => { + import('../../components/viewSettings/viewSettings').then(({default: ViewSettings}) => { + const viewSettings = new ViewSettings(); + viewSettings.show({ + settingsKey: getSettingsKey(), + settings: getViewSettings(), + visibleSettings: getVisibleViewSettings() + }).then(() => { + reloadItems(); + }); + }); + }, [getSettingsKey, getViewSettings, getVisibleViewSettings, reloadItems]); + useEffect(() => { const btnSelectView = element.current?.querySelector('.btnSelectView') as HTMLButtonElement; - btnSelectView.addEventListener('click', (e) => { - libraryBrowser.showLayoutMenu(e.target, getCurrentViewStyle(), 'Banner,List,Poster,PosterCard,Thumb,ThumbCard'.split(',')); - }); - btnSelectView.addEventListener('layoutchange', (e) => { - const viewStyle = (e as CustomEvent).detail.viewStyle; - userSettings.set(getViewSettings(), viewStyle, false); - query.StartIndex = 0; - reloadItems(); - }); - }, [getCurrentViewStyle, query, reloadItems, getViewSettings]); + btnSelectView?.addEventListener('click', showViewSettingsMenu); + + return () => { + btnSelectView?.removeEventListener('click', showViewSettingsMenu); + }; + }, [showViewSettingsMenu]); return (
diff --git a/src/view/components/Shuffle.tsx b/src/view/components/Shuffle.tsx index 35da1f7f9f..e808c7f3d8 100644 --- a/src/view/components/Shuffle.tsx +++ b/src/view/components/Shuffle.tsx @@ -1,4 +1,4 @@ -import { BaseItemDtoQueryResult } from '@thornbill/jellyfin-sdk/dist/generated-client'; +import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; import React, { FC, useCallback, useEffect, useRef } from 'react'; import { playbackManager } from '../../components/playback/playbackmanager'; diff --git a/src/view/components/ViewItemsContainer.tsx b/src/view/components/ViewItemsContainer.tsx index 10a1046da2..cb2650a5ab 100644 --- a/src/view/components/ViewItemsContainer.tsx +++ b/src/view/components/ViewItemsContainer.tsx @@ -1,5 +1,5 @@ -import { BaseItemDtoQueryResult } from '@thornbill/jellyfin-sdk/dist/generated-client'; -import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; +import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; +import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import loading from '../../components/loading/loading'; import * as userSettings from '../../scripts/settings/userSettings'; @@ -10,9 +10,10 @@ import Pagination from './Pagination'; import SelectView from './SelectView'; import Shuffle from './Shuffle'; import Sort from './Sort'; -import { QueryI } from './interface'; import NewCollection from './NewCollection'; import globalize from '../../scripts/globalize'; +import layoutManager from '../../components/layoutManager'; +import { AlphaPickerValueI, QueryI } from './interface'; interface ViewItemsContainerI { topParentId: string | null; @@ -36,15 +37,37 @@ const ViewItemsContainer: FC = ({ getNoItemsMessage }) => { const [ itemsResult, setItemsResult ] = useState({}); + const [ startIndex, setStartIndex ] = useState(0); + const [ alphaPickerValue, setAlphaPickerValue ] = useState({}); const element = useRef(null); + const queryAlphaPickerValue = useMemo(() => ({ + ...alphaPickerValue + }), [alphaPickerValue]); + const getSettingsKey = useCallback(() => { return `${topParentId} - ${getBasekey()}`; }, [getBasekey, topParentId]); + const getVisibleViewSettings = useCallback(() => { + return [ + 'showTitle', + 'showYear', + 'imageType', + 'cardLayout' + ]; + }, []); + const getViewSettings = useCallback(() => { - return `${getSettingsKey()} -view`; + const basekey = getSettingsKey(); + return { + showTitle: userSettings.get(basekey + '-showTitle', false) !== 'false', + showYear: userSettings.get(basekey + '-showYear', false) !== 'false', + imageType: userSettings.get(basekey + '-imageType', false) || 'primary', + viewType: userSettings.get(basekey + '-viewType', false) || 'images', + cardLayout: userSettings.get(basekey + '-cardLayout', false) !== 'false' + }; }, [getSettingsKey]); const getDefaultSortBy = useCallback(() => { @@ -102,16 +125,26 @@ const ViewItemsContainer: FC = ({ }, []); const getQuery = useCallback(() => { + let fields = 'BasicSyncInfo,MediaSourceCount'; + const viewsettings = getViewSettings(); + if (viewsettings.imageType === 'primary') { + fields += ',PrimaryImageAspectRatio'; + } + + if (viewsettings.showYear) { + fields += ',ProductionYear'; + } + const query: QueryI = { SortBy: getSortValues().sortBy, SortOrder: getSortValues().sortOrder, IncludeItemTypes: getItemTypes().join(','), Recursive: true, - Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo', + Fields: fields, ImageTypeLimit: 1, - EnableImageTypes: 'Primary,Backdrop,Banner,Thumb', + EnableImageTypes: 'Primary,Backdrop,Banner,Thumb,Disc,Logo', Limit: userSettings.libraryPageSize(undefined), - StartIndex: 0, + StartIndex: startIndex, ParentId: topParentId }; @@ -119,13 +152,13 @@ const ViewItemsContainer: FC = ({ query.IsFavorite = true; } - userSettings.loadQuerySettings(getSettingsKey(), query); - return query; - }, [getSortValues, getItemTypes, topParentId, getBasekey, getSettingsKey]); + const queryInfo: QueryI = Object.assign(query, queryAlphaPickerValue || {}); + + return queryInfo; + }, [getViewSettings, getSortValues, getItemTypes, startIndex, topParentId, getBasekey, queryAlphaPickerValue]); const getQueryWithFilters = useCallback(() => { const query = getQuery(); - const queryFilters = []; let hasFilters; @@ -248,10 +281,6 @@ const ViewItemsContainer: FC = ({ }]; }, []); - const getCurrentViewStyle = useCallback(() => { - return userSettings.get(getViewSettings(), false) || 'Poster'; - }, [getViewSettings]); - const getContext = useCallback(() => { const itemType = getItemTypes().join(','); if (itemType === 'Movie' || itemType === 'BoxSet') { @@ -269,8 +298,8 @@ const ViewItemsContainer: FC = ({ return; } loading.show(); - const querywithfilters = getQueryWithFilters().query; - window.ApiClient.getItems(window.ApiClient.getCurrentUserId(), querywithfilters).then((result) => { + const query = getQueryWithFilters().query; + window.ApiClient.getItems(window.ApiClient.getCurrentUserId(), query).then((result) => { setItemsResult(result); window.scrollTo(0, 0); @@ -289,10 +318,20 @@ const ViewItemsContainer: FC = ({ return (
- + {isBtnShuffleEnabled && } - + + {} = ({
- {isAlphaPickerEnabled && } + {isAlphaPickerEnabled && }
- +
); diff --git a/src/view/components/interface.ts b/src/view/components/interface.ts index ba1e459ce0..224859e3da 100644 --- a/src/view/components/interface.ts +++ b/src/view/components/interface.ts @@ -1,3 +1,9 @@ +import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; + +export interface AlphaPickerValueI { + NameLessThan?: string; + NameStartsWith?: string | null; +} export interface QueryI { SortBy?: string; SortOrder?: string; @@ -7,14 +13,14 @@ export interface QueryI { ImageTypeLimit?: number; EnableTotalRecordCount?: boolean; EnableImageTypes?: string; - StartIndex: number; + StartIndex?: number; ParentId?: string | null; IsFavorite?: boolean; IsMissing?: boolean; Limit:number; NameStartsWithOrGreater?: string; NameLessThan?: string; - NameStartsWith?: string; + NameStartsWith?: string | null; VideoTypes?: string; GenreIds?: string; Is4K?: boolean; @@ -48,8 +54,9 @@ export interface FiltersI { } export interface CardOptionsI { - itemsContainer?: HTMLElement; - parentContainer?: HTMLElement; + itemsContainer?: HTMLElement | null; + parentContainer?: HTMLElement | null; + items?: BaseItemDto[] | null; allowBottomPadding?: boolean; centerText?: boolean; coverImage?: boolean; @@ -58,17 +65,19 @@ export interface CardOptionsI { overlayPlayButton?: boolean; overlayText?: boolean; preferThumb?: boolean; + preferDisc?: boolean; + preferLogo?: boolean; scalable?: boolean; - shape?: string; + shape?: string | null; lazy?: boolean; - cardLayout?: boolean; + cardLayout?: boolean | string; showParentTitle?: boolean; showParentTitleOrTitle?: boolean; showAirTime?: boolean; showAirDateTime?: boolean; showChannelName?: boolean; - showTitle?: boolean; - showYear?: boolean; + showTitle?: boolean | string; + showYear?: boolean | string; showDetailsMenu?: boolean; missingIndicator?: boolean; showLocationTypeIndicator?: boolean; @@ -76,5 +85,43 @@ export interface CardOptionsI { showUnplayedIndicator?: boolean; showChildCountIndicator?: boolean; lines?: number; - context?: string; + context?: string | null; + action?: string | null; + defaultShape?: string; + indexBy?: string; + parentId?: string | null; + showMenu?: boolean; + cardCssClass?: string | null; + cardClass?: string | null; + centerPlayButton?: boolean; + overlayInfoButton?: boolean; + autoUpdate?: boolean; + cardFooterAside?: string; + includeParentInfoInTitle?: boolean; + maxLines?: number; + overlayMarkPlayedButton?: boolean; + overlayRateButton?: boolean; + showAirEndTime?: boolean; + showCurrentProgram?: boolean; + showCurrentProgramTime?: boolean; + showItemCounts?: boolean; + showPersonRoleOrType?: boolean; + showProgressBar?: boolean; + showPremiereDate?: boolean; + showRuntime?: boolean; + showSeriesTimerTime?: boolean; + showSeriesTimerChannel?: boolean; + showSongCount?: boolean; + width?: number; + showChannelLogo?: boolean; + showLogo?: boolean; + serverId?: string; + collectionId?: string | null; + playlistId?: string | null; + defaultCardImageIcon?: string; + disableHoverMenu?: boolean; + disableIndicators?: boolean; + showGroupCount?: boolean; + containerClass?: string; + noItemsMessage?: string; } diff --git a/src/view/movies/GenresView.tsx b/src/view/movies/GenresView.tsx index b61b97b76f..4f8cb1dfaa 100644 --- a/src/view/movies/GenresView.tsx +++ b/src/view/movies/GenresView.tsx @@ -1,4 +1,4 @@ -import { BaseItemDtoQueryResult } from '@thornbill/jellyfin-sdk/dist/generated-client'; +import type { BaseItemDtoQueryResult } from '@jellyfin/sdk/lib/generated-client'; import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import loading from '../../components/loading/loading'; diff --git a/src/view/movies/SuggestionsView.tsx b/src/view/movies/SuggestionsView.tsx index 5bd73f0ae4..befde0e832 100644 --- a/src/view/movies/SuggestionsView.tsx +++ b/src/view/movies/SuggestionsView.tsx @@ -1,5 +1,5 @@ -import { BaseItemDto, BaseItemDtoQueryResult, RecommendationDto } from '@thornbill/jellyfin-sdk/dist/generated-client'; -import React, { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'; +import type { BaseItemDto, BaseItemDtoQueryResult, RecommendationDto } from '@jellyfin/sdk/lib/generated-client'; +import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import layoutManager from '../../components/layoutManager'; import loading from '../../components/loading/loading'; @@ -12,7 +12,7 @@ interface SuggestionsViewI { topParentId: string | null; } -const SuggestionsView: FunctionComponent = ({topParentId}) => { +const SuggestionsView: FC = ({topParentId}) => { const [ latestItems, setLatestItems ] = useState([]); const [ resumeResult, setResumeResult ] = useState({}); const [ recommendations, setRecommendations ] = useState([]);