diff --git a/frontend/src/components/modals/ManualSearchModal.tsx b/frontend/src/components/modals/ManualSearchModal.tsx index f1739ff69..5f3e1a6f0 100644 --- a/frontend/src/components/modals/ManualSearchModal.tsx +++ b/frontend/src/components/modals/ManualSearchModal.tsx @@ -1,7 +1,6 @@ -import { useEpisodesProvider, useMoviesProvider } from "@/apis/hooks"; import { usePayload } from "@/modules/redux/hooks/modal"; import { createAndDispatchTask } from "@/modules/task/utilities"; -import { isMovie } from "@/utilities"; +import { GetItemId, isMovie } from "@/utilities"; import { faCaretDown, faCheck, @@ -11,7 +10,13 @@ import { } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import clsx from "clsx"; -import { FunctionComponent, useCallback, useMemo, useState } from "react"; +import { + FunctionComponent, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; import { Badge, Button, @@ -22,6 +27,7 @@ import { Popover, Row, } from "react-bootstrap"; +import { UseQueryResult } from "react-query"; import { Column } from "react-table"; import { BaseModal, BaseModalProps, LoadingIndicator, PageTable } from ".."; import Language from "../bazarr/Language"; @@ -30,42 +36,39 @@ type SupportType = Item.Movie | Item.Episode; interface Props { download: (item: T, result: SearchResultType) => Promise; + query: ( + id?: number + ) => UseQueryResult; } export function ManualSearchModal( props: Props & BaseModalProps ) { - const { download, ...modal } = props; + const { download, query: useSearch, ...modal } = props; const item = usePayload(modal.modalKey); - const [episodeId, setEpisodeId] = useState(undefined); - const [radarrId, setRadarrId] = useState(undefined); + const itemId = useMemo(() => GetItemId(item ?? {}), [item]); - const episodes = useEpisodesProvider(episodeId); - const movies = useMoviesProvider(radarrId); + const [id, setId] = useState(undefined); - const isInitial = episodeId === undefined && radarrId === undefined; - const isFetching = episodes.isFetching || movies.isFetching; + // Cleanup the ID when user switches episode / movie + useEffect(() => { + if (itemId !== undefined && itemId !== id) { + setId(undefined); + } + }, [id, itemId]); - const results = useMemo( - () => [...(episodes.data ?? []), ...(movies.data ?? [])], - [episodes.data, movies.data] - ); + const results = useSearch(id); + + const isStale = results.data === undefined; const search = useCallback(() => { - setEpisodeId(undefined); - setRadarrId(undefined); - if (item) { - if (isMovie(item)) { - setRadarrId(item.radarrId); - movies.refetch(); - } else { - setEpisodeId(item.sonarrEpisodeId); - episodes.refetch(); - } + if (itemId !== undefined) { + setId(itemId); + results.refetch(); } - }, [episodes, item, movies]); + }, [itemId, results]); const columns = useMemo[]>( () => [ @@ -197,7 +200,9 @@ export function ManualSearchModal( ); const content = () => { - if (isInitial) { + if (results.isFetching) { + return ; + } else if (isStale) { return (

{item?.path ?? ""}

@@ -206,8 +211,6 @@ export function ManualSearchModal(
); - } else if (isFetching) { - return ; } else { return ( <> @@ -215,7 +218,7 @@ export function ManualSearchModal( ); @@ -223,11 +226,7 @@ export function ManualSearchModal( }; const footer = ( - ); @@ -249,7 +248,7 @@ export function ManualSearchModal( return ( = ({ ); diff --git a/frontend/src/pages/Movies/Details/index.tsx b/frontend/src/pages/Movies/Details/index.tsx index 842ceb025..d6731f4de 100644 --- a/frontend/src/pages/Movies/Details/index.tsx +++ b/frontend/src/pages/Movies/Details/index.tsx @@ -1,6 +1,7 @@ import { useDownloadMovieSubtitles, useIsMovieActionRunning, + useMoviesProvider, } from "@/apis/hooks"; import { useMovieAction, @@ -180,6 +181,7 @@ const MovieDetailView: FunctionComponent = () => { );