import { withModal } from "@/modules/modals"; import { task, TaskGroup } from "@/modules/task"; import { useTableStyles } from "@/styles"; import { BuildKey, GetItemId } from "@/utilities"; import { faCaretDown, faCheck, faCheckCircle, faDownload, faExclamationCircle, faInfoCircle, faTimes, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Alert, Anchor, Badge, Button, Code, Collapse, Divider, Group, List, Popover, Stack, Text, } from "@mantine/core"; import { useHover } from "@mantine/hooks"; import { isString } from "lodash"; import { FunctionComponent, useCallback, useMemo, useState } from "react"; import { UseQueryResult } from "react-query"; import { Column } from "react-table"; import { Action, PageTable } from ".."; import Language from "../bazarr/Language"; type SupportType = Item.Movie | Item.Episode; interface Props { download: (item: T, result: SearchResultType) => Promise; query: ( id?: number ) => UseQueryResult; item: T; } function ManualSearchView(props: Props) { const { download, query: useSearch, item } = props; const itemId = useMemo(() => GetItemId(item ?? {}), [item]); const [id, setId] = useState(undefined); const results = useSearch(id); const isStale = results.data === undefined; const search = useCallback(() => { setId(itemId); results.refetch(); }, [itemId, results]); const columns = useMemo[]>( () => [ { Header: "Score", accessor: "score", Cell: ({ value }) => { const { classes } = useTableStyles(); return {value}%; }, }, { accessor: "language", Cell: ({ row: { original }, value }) => { const lang: Language.Info = { code2: value, hi: original.hearing_impaired === "True", forced: original.forced === "True", name: "", }; return ( ); }, }, { Header: "Provider", accessor: "provider", Cell: (row) => { const { classes } = useTableStyles(); const value = row.value; const { url } = row.row.original; if (url) { return ( {value} ); } else { return value; } }, }, { Header: "Release", accessor: "release_info", Cell: ({ value }) => { const { classes } = useTableStyles(); const [open, setOpen] = useState(false); const items = useMemo( () => value.slice(1).map((v, idx) => {v}), [value] ); if (value.length === 0) { return Cannot get release info; } return ( setOpen((o) => !o)}> {value[0]} {value.length > 1 && ( )} <>{items} ); }, }, { Header: "Upload", accessor: "uploader", Cell: ({ value }) => { const { classes } = useTableStyles(); return {value ?? "-"}; }, }, { accessor: "matches", Cell: (row) => { const { matches, dont_matches } = row.row.original; return ; }, }, { accessor: "subtitle", Cell: ({ row }) => { const result = row.original; return ( { if (!item) return; task.create( item.title, TaskGroup.DownloadSubtitle, download, item, result ); }} > ); }, }, ], [download, item] ); const bSceneNameAvailable = isString(item.sceneName) && item.sceneName.length !== 0; return ( } > {item?.path} ); } export const MovieSearchModal = withModal>( ManualSearchView, "movie-manual-search", { title: "Search Subtitles", size: "xl" } ); export const EpisodeSearchModal = withModal>( ManualSearchView, "episode-manual-search", { title: "Search Subtitles", size: "xl" } ); const StateIcon: FunctionComponent<{ matches: string[]; dont: string[] }> = ({ matches, dont, }) => { const hasIssues = dont.length > 0; const { ref, hovered } = useHover(); return ( } > {matches.map((v, idx) => ( {v} ))} {dont.map((v, idx) => ( {v} ))} ); };