import classNames from 'classnames'; import React, { useCallback, useMemo, useState } from 'react'; import TextTruncate from 'react-text-truncate'; import CommandNames from 'Commands/CommandNames'; import { useExecuteCommand } from 'Commands/useCommands'; import IconButton from 'Components/Link/IconButton'; import Link from 'Components/Link/Link'; import SpinnerIconButton from 'Components/Link/SpinnerIconButton'; import SeriesTagList from 'Components/SeriesTagList'; import { icons } from 'Helpers/Props'; import DeleteSeriesModal from 'Series/Delete/DeleteSeriesModal'; import EditSeriesModal from 'Series/Edit/EditSeriesModal'; import SeriesIndexProgressBar from 'Series/Index/ProgressBar/SeriesIndexProgressBar'; import SeriesIndexPosterSelect from 'Series/Index/Select/SeriesIndexPosterSelect'; import { Statistics } from 'Series/Series'; import { useSeriesOverviewOptions } from 'Series/seriesOptionsStore'; import SeriesPoster from 'Series/SeriesPoster'; import dimensions from 'Styles/Variables/dimensions'; import fonts from 'Styles/Variables/fonts'; import translate from 'Utilities/String/translate'; import useSeriesIndexItem from '../useSeriesIndexItem'; import SeriesIndexOverviewInfo from './SeriesIndexOverviewInfo'; import styles from './SeriesIndexOverview.css'; const columnPadding = parseInt(dimensions.seriesIndexColumnPadding); const columnPaddingSmallScreen = parseInt( dimensions.seriesIndexColumnPaddingSmallScreen ); const defaultFontSize = parseInt(fonts.defaultFontSize); const lineHeight = parseFloat(fonts.lineHeight); // Hardcoded height based on line-height of 32 + bottom margin of 10. // Less side-effecty than using react-measure. const TITLE_HEIGHT = 42; interface SeriesIndexOverviewProps { seriesId: number; sortKey: string; posterWidth: number; posterHeight: number; rowHeight: number; isSelectMode: boolean; isSmallScreen: boolean; } function SeriesIndexOverview(props: SeriesIndexOverviewProps) { const { seriesId, sortKey, posterWidth, posterHeight, rowHeight, isSelectMode, isSmallScreen, } = props; const { series, qualityProfile, isRefreshingSeries, isSearchingSeries } = useSeriesIndexItem(seriesId); const overviewOptions = useSeriesOverviewOptions(); const executeCommand = useExecuteCommand(); const [isEditSeriesModalOpen, setIsEditSeriesModalOpen] = useState(false); const [isDeleteSeriesModalOpen, setIsDeleteSeriesModalOpen] = useState(false); const onRefreshPress = useCallback(() => { executeCommand({ name: CommandNames.RefreshSeries, seriesIds: [seriesId], }); }, [seriesId, executeCommand]); const onSearchPress = useCallback(() => { executeCommand({ name: CommandNames.SeriesSearch, seriesId, }); }, [seriesId, executeCommand]); const onEditSeriesPress = useCallback(() => { setIsEditSeriesModalOpen(true); }, [setIsEditSeriesModalOpen]); const onEditSeriesModalClose = useCallback(() => { setIsEditSeriesModalOpen(false); }, [setIsEditSeriesModalOpen]); const onDeleteSeriesPress = useCallback(() => { setIsEditSeriesModalOpen(false); setIsDeleteSeriesModalOpen(true); }, [setIsDeleteSeriesModalOpen]); const onDeleteSeriesModalClose = useCallback(() => { setIsDeleteSeriesModalOpen(false); }, [setIsDeleteSeriesModalOpen]); const contentHeight = useMemo(() => { const padding = isSmallScreen ? columnPaddingSmallScreen : columnPadding; return rowHeight - padding; }, [rowHeight, isSmallScreen]); const overviewHeight = contentHeight - TITLE_HEIGHT; if (!series) { return null; } const { title, monitored, status, path, titleSlug, nextAiring, previousAiring, added, overview, statistics = {} as Statistics, images, tags, network, } = series; const { seasonCount = 0, episodeCount = 0, episodeFileCount = 0, totalEpisodeCount = 0, sizeOnDisk = 0, } = statistics; const link = `/series/${titleSlug}`; const elementStyle = { width: `${posterWidth}px`, height: `${posterHeight}px`, }; return (