/* * Copyright (C) Contributors to the Suwayomi project * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import Button from '@mui/material/Button'; import { useTranslation } from 'react-i18next'; import List from '@mui/material/List'; import Stack from '@mui/material/Stack'; import { useEffect, useMemo, useState } from 'react'; import IconButton from '@mui/material/IconButton'; import ArrowBack from '@mui/icons-material/ArrowBack'; import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { EmptyView } from '@/components/util/EmptyView.tsx'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx'; import { TBaseTracker } from '@/lib/data/Trackers.ts'; import { SearchTextField } from '@/components/atoms/SearchTextField.tsx'; import { makeToast } from '@/components/util/Toast.tsx'; import { TrackerMangaCard } from '@/components/tracker/TrackerMangaCard.tsx'; import { DIALOG_PADDING } from '@/components/tracker/constants.ts'; export const TrackerSearch = ({ mangaId, tracker, closeSearchMode, trackedId, }: { mangaId: number; tracker: TBaseTracker; closeSearchMode: () => void; trackedId?: string; }) => { const { t } = useTranslation(); // can't be undefined, since this can only be opened from the manga screen const manga = requestManager.useGetManga(mangaId); const [searchString, setSearchString] = useState(manga.data!.manga.title); const [tmpSearchString, setTmpSearchString] = useState(searchString); const [selectedTrackerRemoteId, setSelectedTrackerRemoteId] = useState(trackedId); const trackerSearch = requestManager.useTrackerSearch(tracker.id, searchString, { addAbortSignal: true }); const searchResults = trackerSearch.data?.searchTracker.trackSearches ?? []; const hasResults = !!searchResults.length; useEffect(() => { setSelectedTrackerRemoteId(trackedId); return () => trackerSearch.abortRequest(new Error(`MangaTrackerSearchCard(${tracker.id}, ${mangaId}): search changed`)); }, [searchString]); const [bindTracker, bindTrackerMutation] = requestManager.useBindTracker(); const showTrackButton = useMemo( () => !!selectedTrackerRemoteId && !!searchResults.find((searchResult) => searchResult.remoteId === selectedTrackerRemoteId), [selectedTrackerRemoteId, searchResults], ) && !trackerSearch.loading && !trackerSearch.error; const trackManga = () => { if (selectedTrackerRemoteId === undefined) { return; } bindTracker({ variables: { mangaId, remoteId: selectedTrackerRemoteId, trackerId: tracker.id } }) .then(() => { makeToast(t('manga.action.track.add.label.success'), 'success'); closeSearchMode(); }) .catch(() => makeToast(t('manga.action.track.add.label.error'), 'error')); }; return ( <> setTmpSearchString(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { setSearchString(tmpSearchString); } }} onCancel={() => setTmpSearchString('')} /> {!trackerSearch.loading && !trackerSearch.error && !hasResults && ( )} {trackerSearch.loading && } {trackerSearch.error && !trackerSearch.loading && ( )} {hasResults && searchResults.map((trackerManga) => ( setSelectedTrackerRemoteId(trackerManga.remoteId)} /> ))} {showTrackButton && ( )} ); };