jellyfish-web/src/apps/experimental/components/library/ItemsView.tsx

311 lines
11 KiB
TypeScript
Raw Normal View History

2023-10-04 23:14:14 +03:00
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';
2024-01-12 21:08:06 +03:00
import classNames from 'classnames';
2023-10-04 23:14:14 +03:00
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';
2023-10-13 02:07:49 +03:00
import ItemsContainer from 'elements/emby-itemscontainer/ItemsContainer';
2023-10-04 23:14:14 +03:00
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';
2023-10-28 22:10:46 +03:00
import { ListOptions } from 'types/listOptions';
2023-10-04 23:14:14 +03:00
interface ItemsViewProps {
viewType: LibraryTab;
parentId: ParentId;
itemType: BaseItemKind[];
collectionType?: CollectionType;
2024-01-12 21:08:06 +03:00
isPaginationEnabled?: boolean;
2023-10-04 23:14:14 +03:00
isBtnPlayAllEnabled?: boolean;
isBtnQueueEnabled?: boolean;
isBtnShuffleEnabled?: boolean;
isBtnSortEnabled?: boolean;
isBtnFilterEnabled?: boolean;
isBtnNewCollectionEnabled?: boolean;
isBtnGridListEnabled?: boolean;
isAlphabetPickerEnabled?: boolean;
noItemsMessage: string;
}
const ItemsView: FC<ItemsViewProps> = ({
viewType,
parentId,
collectionType,
2024-01-12 21:08:06 +03:00
isPaginationEnabled = true,
2023-10-04 23:14:14 +03:00
isBtnPlayAllEnabled = false,
isBtnQueueEnabled = false,
isBtnShuffleEnabled = false,
isBtnSortEnabled = true,
isBtnFilterEnabled = true,
isBtnNewCollectionEnabled = false,
isBtnGridListEnabled = true,
isAlphabetPickerEnabled = true,
itemType,
noItemsMessage
}) => {
const [libraryViewSettings, setLibraryViewSettings] =
useLocalStorage<LibraryViewSettings>(
getSettingsKey(viewType, parentId),
getDefaultLibraryViewSettings(viewType)
);
const {
isLoading,
data: itemsResult,
2023-10-13 02:07:49 +03:00
isPreviousData,
refetch
2023-10-04 23:14:14 +03:00
} = useGetItemsViewByType(
viewType,
parentId,
itemType,
libraryViewSettings
);
const { data: item } = useGetItem(parentId);
2023-10-28 22:10:46 +03:00
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]);
2023-10-04 23:14:14 +03:00
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) {
2023-10-28 22:10:46 +03:00
cardOptions.lines = 1;
2024-01-12 21:08:06 +03:00
cardOptions.showYear = false;
} else if (viewType === LibraryTab.Channels) {
cardOptions.shape = 'square';
cardOptions.showDetailsMenu = true;
cardOptions.showCurrentProgram = true;
cardOptions.showCurrentProgramTime = true;
} else if (viewType === LibraryTab.SeriesTimers) {
cardOptions.defaultShape = 'portrait';
cardOptions.preferThumb = 'auto';
cardOptions.showSeriesTimerTime = true;
cardOptions.showSeriesTimerChannel = true;
cardOptions.lines = 3;
2023-10-04 23:14:14 +03:00
}
return cardOptions;
}, [
libraryViewSettings.ShowTitle,
libraryViewSettings.ImageType,
libraryViewSettings.ShowYear,
libraryViewSettings.CardLayout,
collectionType,
viewType
]);
const getItemsHtml = useCallback(() => {
let html = '';
if (libraryViewSettings.ViewMode === ViewMode.ListView) {
2023-10-28 22:10:46 +03:00
html = listview.getListViewHtml(getListOptions());
2023-10-04 23:14:14 +03:00
} else {
html = cardBuilder.getCardsHtml(
itemsResult?.Items ?? [],
getCardOptions()
);
}
if (!itemsResult?.Items?.length) {
html += '<div class="noItemsMessage centerMessage">';
html += '<h1>' + globalize.translate('MessageNothingHere') + '</h1>';
html += '<p>' + globalize.translate(noItemsMessage) + '</p>';
html += '</div>';
}
return html;
2023-10-28 22:10:46 +03:00
}, [libraryViewSettings.ViewMode, itemsResult?.Items, getListOptions, getCardOptions, noItemsMessage]);
2023-10-04 23:14:14 +03:00
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
);
2024-01-12 21:08:06 +03:00
const itemsContainerClass = classNames(
'centered padded-left padded-right padded-right-withalphapicker',
libraryViewSettings.ViewMode === ViewMode.ListView ?
'vertical-list' :
'vertical-wrap'
);
2023-10-04 23:14:14 +03:00
return (
<Box>
<Box className='flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom focuscontainer-x'>
2024-01-12 21:08:06 +03:00
{isPaginationEnabled && (
<Pagination
totalRecordCount={totalRecordCount}
libraryViewSettings={libraryViewSettings}
isPreviousData={isPreviousData}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
2023-10-04 23:14:14 +03:00
{isBtnPlayAllEnabled && (
<PlayAllButton
item={item}
items={items}
viewType={viewType}
hasFilters={hasFilters}
libraryViewSettings={libraryViewSettings}
/>
)}
{isBtnQueueEnabled
&& item
&& playbackManager.canQueue(item) && (
<QueueButton
item={item}
items={items}
hasFilters={hasFilters}
/>
)}
{isBtnShuffleEnabled && totalRecordCount > 1 && (
<ShuffleButton
item={item}
items={items}
viewType={viewType}
hasFilters={hasFilters}
libraryViewSettings={libraryViewSettings}
/>
)}
{isBtnSortEnabled && (
<SortButton
viewType={viewType}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isBtnFilterEnabled && (
<FilterButton
parentId={parentId}
itemType={itemType}
viewType={viewType}
hasFilters={hasFilters}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isBtnNewCollectionEnabled && <NewCollectionButton />}
{isBtnGridListEnabled && (
<GridListViewButton
viewType={viewType}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
</Box>
{isAlphabetPickerEnabled && hasSortName && (
<AlphabetPicker
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isLoading ? (
<Loading />
) : (
<ItemsContainer
2024-01-12 21:08:06 +03:00
className={itemsContainerClass}
2023-10-13 02:07:49 +03:00
parentId={parentId}
reloadItems={refetch}
2023-10-04 23:14:14 +03:00
getItemsHtml={getItemsHtml}
/>
)}
2024-01-12 21:08:06 +03:00
{isPaginationEnabled && (
<Box className='flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom focuscontainer-x'>
<Pagination
totalRecordCount={totalRecordCount}
libraryViewSettings={libraryViewSettings}
isPreviousData={isPreviousData}
setLibraryViewSettings={setLibraryViewSettings}
/>
</Box>
)}
2023-10-04 23:14:14 +03:00
</Box>
);
};
export default ItemsView;