/* * 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 ArrowForwardIcon from '@mui/icons-material/ArrowForward'; import DialogContent from '@mui/material/DialogContent'; import DialogTitle from '@mui/material/DialogTitle'; import InputAdornment from '@mui/material/InputAdornment'; import InfoIcon from '@mui/icons-material/Info'; import PopupState, { bindPopover, bindTrigger } from 'material-ui-popup-state'; import Popover from '@mui/material/Popover'; import Typography from '@mui/material/Typography'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx'; import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx'; import { Tracker, TTrackerBase } from '@/modules/tracker/services/Trackers.ts'; import { SearchTextField } from '@/modules/core/components/inputs/SearchTextField.tsx'; import { makeToast } from '@/modules/core/utils/Toast.ts'; import { TrackerMangaCard } from '@/modules/tracker/components/cards/TrackerMangaCard.tsx'; import { DIALOG_PADDING } from '@/modules/tracker/Tracker.constants.ts'; import { useGetOptionForDirection } from '@/modules/theme/services/ThemeCreator.ts'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { MangaType } from '@/lib/graphql/generated/graphql.ts'; import { MangaIdInfo } from '@/modules/manga/Manga.types.ts'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; export const TrackerSearch = ({ manga, tracker, closeSearchMode, trackedId, }: { manga: MangaIdInfo & Pick; tracker: Pick; closeSearchMode: () => void; trackedId?: string; }) => { const { t } = useTranslation(); const getOptionForDirection = useGetOptionForDirection(); const [searchString, setSearchString] = useState(manga.title); const [tmpSearchString, setTmpSearchString] = useState(searchString); const [selectedTrackerRemoteId, setSelectedTrackerRemoteId] = useState(trackedId); const trackerSearch = requestManager.useTrackerSearch(tracker.id, searchString, { notifyOnNetworkStatusChange: true, }); const searchResults = trackerSearch.data?.searchTracker.trackSearches ?? []; const hasResults = !!searchResults.length; useEffect(() => { setSelectedTrackerRemoteId(trackedId); return () => trackerSearch.abortRequest(new Error(`MangaTrackerSearchCard(${tracker.id}, ${manga.id}): 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: manga.id, remoteId: selectedTrackerRemoteId, trackerId: tracker.id } }) .then(() => { makeToast(t('manga.action.track.add.label.success'), 'success'); closeSearchMode(); }) .catch((e) => makeToast(t('manga.action.track.add.label.error'), 'error', getErrorMessage(e))); }; return ( <> {getOptionForDirection(, )} setTmpSearchString(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { setSearchString(tmpSearchString); } }} onCancel={() => setTmpSearchString('')} InputProps={{ startAdornment: tracker.id === Tracker.MYANIMELIST && ( {(popupState) => ( <> {t('tracking.my_anime_list.search.label.hint')} )} ), }} /> {!trackerSearch.loading && !trackerSearch.error && !hasResults && ( )} {trackerSearch.loading && } {trackerSearch.error && !trackerSearch.loading && ( trackerSearch.refetch().catch(defaultPromiseErrorHandler('TrackerSearch::refetch')) } /> )} {hasResults && searchResults.map((trackerManga) => ( setSelectedTrackerRemoteId(trackerManga.remoteId)} /> ))} {showTrackButton && ( )} ); };