import type { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; import { ImageType } from '@jellyfin/sdk/lib/generated-client'; import { ItemSortBy } from '@jellyfin/sdk/lib/models/api/item-sort-by'; import React, { FC, useCallback } from 'react'; import Box from '@mui/material/Box'; import { useLocalStorage } from 'hooks/useLocalStorage'; import { useGetItem, useGetItemsViewByType } from 'hooks/useFetchItems'; import { getDefaultLibraryViewSettings, getSettingsKey } from 'utils/items'; import Loading from 'components/loading/LoadingComponent'; import listview from 'components/listview/listview'; import cardBuilder from 'components/cardbuilder/cardBuilder'; import { playbackManager } from 'components/playback/playbackmanager'; import globalize from 'scripts/globalize'; import ItemsContainer from 'elements/emby-itemscontainer/ItemsContainer'; import AlphabetPicker from './AlphabetPicker'; import FilterButton from './filter/FilterButton'; import NewCollectionButton from './NewCollectionButton'; import Pagination from './Pagination'; import PlayAllButton from './PlayAllButton'; import QueueButton from './QueueButton'; 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 { LibraryTab } from 'types/libraryTab'; import { CardOptions } from 'types/cardOptions'; import { ListOptions } from 'types/listOptions'; interface ItemsViewProps { viewType: LibraryTab; parentId: ParentId; itemType: BaseItemKind[]; collectionType?: CollectionType; isBtnPlayAllEnabled?: boolean; isBtnQueueEnabled?: boolean; isBtnShuffleEnabled?: boolean; isBtnSortEnabled?: boolean; isBtnFilterEnabled?: boolean; isBtnNewCollectionEnabled?: boolean; isBtnGridListEnabled?: boolean; isAlphabetPickerEnabled?: boolean; noItemsMessage: string; } const ItemsView: FC = ({ viewType, parentId, collectionType, isBtnPlayAllEnabled = false, isBtnQueueEnabled = false, isBtnShuffleEnabled = false, isBtnSortEnabled = true, isBtnFilterEnabled = true, isBtnNewCollectionEnabled = false, isBtnGridListEnabled = true, isAlphabetPickerEnabled = true, itemType, noItemsMessage }) => { const [libraryViewSettings, setLibraryViewSettings] = useLocalStorage( getSettingsKey(viewType, parentId), getDefaultLibraryViewSettings(viewType) ); const { isLoading, data: itemsResult, isPreviousData, refetch } = useGetItemsViewByType( viewType, parentId, itemType, libraryViewSettings ); 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; if (libraryViewSettings.ImageType === ImageType.Banner) { shape = 'banner'; } else if (libraryViewSettings.ImageType === ImageType.Disc) { shape = 'square'; preferDisc = true; } else if (libraryViewSettings.ImageType === ImageType.Logo) { shape = 'backdrop'; preferLogo = true; } else if (libraryViewSettings.ImageType === ImageType.Thumb) { shape = 'backdrop'; preferThumb = true; } else { shape = 'auto'; } const cardOptions: CardOptions = { shape: shape, showTitle: libraryViewSettings.ShowTitle, showYear: libraryViewSettings.ShowYear, cardLayout: libraryViewSettings.CardLayout, centerText: true, context: collectionType, coverImage: true, preferThumb: preferThumb, preferDisc: preferDisc, preferLogo: preferLogo, overlayPlayButton: false, overlayMoreButton: true, overlayText: !libraryViewSettings.ShowTitle }; if ( viewType === LibraryTab.Songs || viewType === LibraryTab.Albums || viewType === LibraryTab.Episodes ) { cardOptions.showParentTitle = libraryViewSettings.ShowTitle; } else if (viewType === LibraryTab.Artists) { cardOptions.lines = 1; } return cardOptions; }, [ libraryViewSettings.ShowTitle, libraryViewSettings.ImageType, libraryViewSettings.ShowYear, libraryViewSettings.CardLayout, collectionType, viewType ]); const getItemsHtml = useCallback(() => { let html = ''; if (libraryViewSettings.ViewMode === ViewMode.ListView) { html = listview.getListViewHtml(getListOptions()); } else { html = cardBuilder.getCardsHtml( itemsResult?.Items ?? [], getCardOptions() ); } if (!itemsResult?.Items?.length) { html += '
'; html += '

' + globalize.translate('MessageNothingHere') + '

'; html += '

' + globalize.translate(noItemsMessage) + '

'; html += '
'; } return html; }, [libraryViewSettings.ViewMode, itemsResult?.Items, getListOptions, getCardOptions, noItemsMessage]); const totalRecordCount = itemsResult?.TotalRecordCount ?? 0; const items = itemsResult?.Items ?? []; const hasFilters = Object.values(libraryViewSettings.Filters ?? {}).some( (filter) => !!filter ); const hasSortName = libraryViewSettings.SortBy.includes( ItemSortBy.SortName ); return ( {isBtnPlayAllEnabled && ( )} {isBtnQueueEnabled && item && playbackManager.canQueue(item) && ( )} {isBtnShuffleEnabled && totalRecordCount > 1 && ( )} {isBtnSortEnabled && ( )} {isBtnFilterEnabled && ( )} {isBtnNewCollectionEnabled && } {isBtnGridListEnabled && ( )} {isAlphabetPickerEnabled && hasSortName && ( )} {isLoading ? ( ) : ( )} ); }; export default ItemsView;