import React, { useCallback, useState } from 'react'; import { useSelector } from 'react-redux'; import Icon from 'Components/Icon'; import IconButton from 'Components/Link/IconButton'; import Link from 'Components/Link/Link'; import SpinnerIconButton from 'Components/Link/SpinnerIconButton'; import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell'; import VirtualTableSelectCell from 'Components/Table/Cells/VirtualTableSelectCell'; import Column from 'Components/Table/Column'; import Popover from 'Components/Tooltip/Popover'; import DownloadProtocol from 'DownloadClient/DownloadProtocol'; import { icons, kinds, tooltipPositions } from 'Helpers/Props'; import ProtocolLabel from 'Indexer/Index/Table/ProtocolLabel'; import { IndexerCategory } from 'Indexer/Indexer'; import OverrideMatchModal from 'Search/Table/OverrideMatch/OverrideMatchModal'; import createEnabledDownloadClientsSelector from 'Store/Selectors/createEnabledDownloadClientsSelector'; import { SelectStateInputProps } from 'typings/props'; import formatDateTime from 'Utilities/Date/formatDateTime'; import formatAge from 'Utilities/Number/formatAge'; import formatBytes from 'Utilities/Number/formatBytes'; import titleCase from 'Utilities/String/titleCase'; import translate from 'Utilities/String/translate'; import CategoryLabel from './CategoryLabel'; import Peers from './Peers'; import ReleaseLinks from './ReleaseLinks'; import styles from './SearchIndexRow.css'; function getDownloadIcon( isGrabbing: boolean, isGrabbed: boolean, grabError?: string ) { if (isGrabbing) { return icons.SPINNER; } else if (isGrabbed) { return icons.DOWNLOADING; } else if (grabError) { return icons.DOWNLOADING; } return icons.DOWNLOAD; } function getDownloadKind(isGrabbed: boolean, grabError?: string) { if (isGrabbed) { return kinds.SUCCESS; } if (grabError) { return kinds.DANGER; } return kinds.DEFAULT; } function getDownloadTooltip( isGrabbing: boolean, isGrabbed: boolean, grabError?: string ) { if (isGrabbing) { return ''; } else if (isGrabbed) { return translate('AddedToDownloadClient'); } else if (grabError) { return grabError; } return translate('AddToDownloadClient'); } interface SearchIndexRowProps { guid: string; protocol: DownloadProtocol; age: number; ageHours: number; ageMinutes: number; publishDate: string; title: string; fileName: string; infoUrl: string; downloadUrl?: string; magnetUrl?: string; indexerId: number; indexer: string; categories: IndexerCategory[]; size: number; files?: number; grabs?: number; seeders?: number; leechers?: number; imdbId?: string; tmdbId?: number; tvdbId?: number; tvMazeId?: number; indexerFlags: string[]; isGrabbing: boolean; isGrabbed: boolean; grabError?: string; longDateFormat: string; timeFormat: string; columns: Column[]; isSelected?: boolean; onSelectedChange(result: SelectStateInputProps): void; onGrabPress(...args: unknown[]): void; onSavePress(...args: unknown[]): void; } function SearchIndexRow(props: SearchIndexRowProps) { const { guid, indexerId, protocol, categories, age, ageHours, ageMinutes, publishDate, title, fileName, infoUrl, downloadUrl, magnetUrl, indexer, size, files, grabs, seeders, leechers, imdbId, tmdbId, tvdbId, tvMazeId, indexerFlags = [], isGrabbing = false, isGrabbed = false, grabError, longDateFormat, timeFormat, columns, isSelected, onSelectedChange, onGrabPress, onSavePress, } = props; const [isOverrideModalOpen, setIsOverrideModalOpen] = useState(false); const { items: downloadClients } = useSelector( createEnabledDownloadClientsSelector(protocol) ); const onGrabPressWrapper = useCallback(() => { onGrabPress({ guid, indexerId, }); }, [guid, indexerId, onGrabPress]); const onSavePressWrapper = useCallback(() => { onSavePress({ downloadUrl, fileName, }); }, [downloadUrl, fileName, onSavePress]); const onOverridePress = useCallback(() => { setIsOverrideModalOpen(true); }, [setIsOverrideModalOpen]); const onOverrideModalClose = useCallback(() => { setIsOverrideModalOpen(false); }, [setIsOverrideModalOpen]); return ( <> {columns.map((column) => { const { name, isVisible } = column; if (!isVisible) { return null; } if (name === 'select') { return ( ); } if (name === 'protocol') { return ( ); } if (name === 'age') { return ( {formatAge(age, ageHours, ageMinutes)} ); } if (name === 'sortTitle') { return (
{title}
); } if (name === 'indexer') { return ( {indexer} ); } if (name === 'size') { return ( {formatBytes(size)} ); } if (name === 'files') { return ( {files} ); } if (name === 'grabs') { return ( {grabs} ); } if (name === 'peers') { return ( {protocol === 'torrent' && ( )} ); } if (name === 'category') { return ( ); } if (name === 'indexerFlags') { return ( {!!indexerFlags.length && ( } title={translate('IndexerFlags')} body={
    {indexerFlags.map((flag, index) => { return
  • {titleCase(flag)}
  • ; })}
} position={tooltipPositions.LEFT} /> )}
); } if (name === 'actions') { return ( {downloadClients.length > 1 ? (
) : null} {downloadUrl ? ( ) : null} {magnetUrl ? ( ) : null} {imdbId || tmdbId || tvdbId || tvMazeId ? ( } title={translate('Links')} body={ } position={tooltipPositions.TOP} /> ) : null}
); } return null; })} ); } export default SearchIndexRow;