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;