import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by'; import { SortOrder } from '@jellyfin/sdk/lib/generated-client/models/sort-order'; import React, { FC, useCallback } from 'react'; import Button from '@mui/material/Button'; import MenuItem from '@mui/material/MenuItem'; import Popover from '@mui/material/Popover'; import Typography from '@mui/material/Typography'; import Divider from '@mui/material/Divider'; import InputLabel from '@mui/material/InputLabel'; import FormControl from '@mui/material/FormControl'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import SortByAlphaIcon from '@mui/icons-material/SortByAlpha'; import globalize from 'lib/globalize'; import { LibraryViewSettings } from 'types/library'; import { LibraryTab } from 'types/libraryTab'; type SortOption = { label: string; value: ItemSortBy; }; type SortOptionsMapping = Record; const movieOrFavoriteOptions = [ { label: 'Name', value: ItemSortBy.SortName }, { label: 'OptionRandom', value: ItemSortBy.Random }, { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, { label: 'OptionCriticRating', value: ItemSortBy.CriticRating }, { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, { label: 'Runtime', value: ItemSortBy.Runtime } ]; const photosOrPhotoAlbumsOptions = [ { label: 'Name', value: ItemSortBy.SortName }, { label: 'OptionRandom', value: ItemSortBy.Random }, { label: 'OptionDateAdded', value: ItemSortBy.DateCreated } ]; const sortOptionsMapping: SortOptionsMapping = { [LibraryTab.Movies]: movieOrFavoriteOptions, [LibraryTab.Favorites]: movieOrFavoriteOptions, [LibraryTab.Series]: [ { label: 'Name', value: ItemSortBy.SortName }, { label: 'OptionRandom', value: ItemSortBy.Random }, { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, { label: 'OptionDateShowAdded', value: ItemSortBy.DateCreated }, { label: 'OptionDateEpisodeAdded', value: ItemSortBy.DateLastContentAdded }, { label: 'OptionDatePlayed', value: ItemSortBy.SeriesDatePlayed }, { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate } ], [LibraryTab.Episodes]: [ { label: 'Name', value: ItemSortBy.SeriesSortName }, { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, { label: 'OptionParentalRating', value: ItemSortBy.OfficialRating }, { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, { label: 'Runtime', value: ItemSortBy.Runtime }, { label: 'OptionRandom', value: ItemSortBy.Random } ], [LibraryTab.Albums]: [ { label: 'Name', value: ItemSortBy.SortName }, { label: 'OptionRandom', value: ItemSortBy.Random }, { label: 'AlbumArtist', value: ItemSortBy.AlbumArtist }, { label: 'OptionCommunityRating', value: ItemSortBy.CommunityRating }, { label: 'OptionCriticRating', value: ItemSortBy.CriticRating }, { label: 'OptionReleaseDate', value: ItemSortBy.ProductionYear }, { label: 'OptionDateAdded', value: ItemSortBy.DateCreated } ], [LibraryTab.Songs]: [ { label: 'Name', value: ItemSortBy.SortName }, { label: 'Album', value: ItemSortBy.Album }, { label: 'AlbumArtist', value: ItemSortBy.AlbumArtist }, { label: 'Artist', value: ItemSortBy.Artist }, { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, { label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate }, { label: 'Runtime', value: ItemSortBy.Runtime }, { label: 'OptionRandom', value: ItemSortBy.Random } ], [LibraryTab.PhotoAlbums]: photosOrPhotoAlbumsOptions, [LibraryTab.Photos]: photosOrPhotoAlbumsOptions, [LibraryTab.Videos]: [ { label: 'Name', value: ItemSortBy.SortName }, { label: 'OptionDateAdded', value: ItemSortBy.DateCreated }, { label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed }, { label: 'OptionPlayCount', value: ItemSortBy.PlayCount }, { label: 'Runtime', value: ItemSortBy.Runtime }, { label: 'OptionRandom', value: ItemSortBy.Random } ] }; const getSortMenuOptions = (viewType: LibraryTab): SortOption[] => { return sortOptionsMapping[viewType] || []; }; const sortOrderMenuOptions = [ { label: 'Ascending', value: SortOrder.Ascending }, { label: 'Descending', value: SortOrder.Descending } ]; interface SortButtonProps { viewType: LibraryTab; libraryViewSettings: LibraryViewSettings; setLibraryViewSettings: React.Dispatch< React.SetStateAction >; } const SortButton: FC = ({ viewType, libraryViewSettings, setLibraryViewSettings }) => { const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); const id = open ? 'sort-popover' : undefined; const handleClick = useCallback((event: React.MouseEvent) => { setAnchorEl(event.currentTarget); }, []); const handleClose = useCallback(() => { setAnchorEl(null); }, []); const onSelectChange = useCallback( (event: SelectChangeEvent) => { const name = event.target.name; setLibraryViewSettings((prevState) => ({ ...prevState, StartIndex: 0, [name]: event.target.value })); }, [setLibraryViewSettings] ); const sortMenuOptions = getSortMenuOptions(viewType); return ( <> {globalize.translate('LabelSortBy')} {globalize.translate('LabelSortOrder')} ); }; export default SortButton;