import { faCheck, faDownload, faInfoCircle, faTimes, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import React, { FunctionComponent, useCallback, useEffect, useMemo, useState, } from "react"; import { Badge, Button, Col, Container, Dropdown, OverlayTrigger, Popover, Row, } from "react-bootstrap"; import { Column } from "react-table"; import { AsyncButton, BaseModal, BaseModalProps, LanguageText, LoadingIndicator, PageTable, usePayload, } from ".."; import { ProvidersApi } from "../../apis"; import { isMovie } from "../../utilites"; type SupportType = Item.Movie | Item.Episode; interface Props { onSelect: (item: SupportType, result: SearchResultType) => Promise; onDownload?: () => void; } export const ManualSearchModal: FunctionComponent = ( props ) => { const { onSelect, onDownload, ...modal } = props; const [result, setResult] = useState([]); const [searching, setSearch] = useState(false); const [start, setStart] = useState(false); const item = usePayload(modal.modalKey); const search = useCallback(() => { if (item) { setStart(true); setSearch(true); let promise: Promise; if (isMovie(item)) { promise = ProvidersApi.movies(item.radarrId); } else { promise = ProvidersApi.episodes(item.sonarrEpisodeId); } promise.then((data) => setResult(data)).finally(() => setSearch(false)); } }, [item]); const reset = useCallback(() => { setStart(false); setSearch(false); }, []); useEffect(() => { if (item) { reset(); } }, [item, reset]); const columns = useMemo[]>( () => [ { accessor: "subtitle", Cell: ({ row, externalUpdate }) => { const result = row.original; return ( onSelect(item!, result)} onSuccess={() => externalUpdate && externalUpdate(row)} > ); }, }, { Header: "Score", accessor: (d) => `${d.score}%`, }, { accessor: "language", Cell: ({ row: { original }, value }) => { const lang: Language = { code2: value, hi: original.hearing_impaired === "True", forced: original.forced === "True", name: "", }; return ( ); }, }, { Header: "Provider", accessor: "provider", Cell: (row) => { const value = row.value; const { url } = row.row.original; if (url) { return ( {value} ); } else { return value; } }, }, { Header: "Release", accessor: "release_info", className: "text-nowrap", Cell: (row) => { const value = row.value; const items = useMemo( () => value.slice(1).map((v, idx) => ( {v} )), [value] ); if (value.length !== 0) { const display = value[0]; return ( {display} {items} ); } else { return "Cannot get release info"; } }, }, { Header: "Upload", accessor: (d) => d.uploader ?? "-", }, { accessor: "matches", Cell: (row) => { const { matches, dont_matches } = row.row.original; return ; }, }, ], [onSelect, item] ); const content = useMemo(() => { if (!start) { return (

{item?.path ?? ""}

); } else if (searching) { return ; } else { return (

{item?.path ?? ""}

); } }, [start, searching, columns, result, search, item?.path, onDownload]); const footer = useMemo( () => ( ), [start, reset] ); const title = useMemo(() => { let title = "Unknown"; if (item) { if (item.sceneName) { title = item.sceneName; } else if (isMovie(item)) { title = item.title; } else { title = item.title; } } return `Search - ${title}`; }, [item]); return ( {content} ); }; const StateIcon: FunctionComponent<{ matches: string[]; dont: string[] }> = ({ matches, dont, }) => { let icon = faCheck; let color = "var(--success)"; if (dont.length > 0) { icon = faInfoCircle; color = "var(--warning)"; } const matchElements = useMemo( () => matches.map((v, idx) => (

{v}

)), [matches] ); const dontElements = useMemo( () => dont.map((v, idx) => (

{v}

)), [dont] ); const popover = useMemo( () => ( {matchElements} {dontElements} ), [matchElements, dontElements] ); return ( ); };