Reduce requested manga data in queries
This commit is contained in:
@@ -16,11 +16,12 @@ import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCe
|
||||
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
|
||||
import { Trackers } from '@/lib/data/Trackers.ts';
|
||||
import { TrackerCard, TrackerMode } from '@/components/tracker/TrackerCard.tsx';
|
||||
import { TManga } from '@/typings.ts';
|
||||
import { makeToast } from '@/components/util/Toast.tsx';
|
||||
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
||||
import { GetTrackersBindQuery } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { GetMangaTrackRecordsQuery, GetTrackersBindQuery, MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { GET_TRACKERS_BIND } from '@/lib/graphql/queries/TrackerQuery.ts';
|
||||
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
|
||||
import { GET_MANGA_TRACK_RECORDS } from '@/lib/graphql/queries/MangaQuery.ts';
|
||||
|
||||
const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracker?: number): TrackerMode => {
|
||||
if (id === searchModeForTracker) {
|
||||
@@ -34,7 +35,7 @@ const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracke
|
||||
return TrackerMode.UNTRACKED;
|
||||
};
|
||||
|
||||
export const TrackManga = ({ manga }: { manga: Pick<TManga, 'id' | 'trackRecords'> }) => {
|
||||
export const TrackManga = ({ manga }: { manga: MangaIdInfo & Pick<MangaType, 'title'> }) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -43,26 +44,32 @@ export const TrackManga = ({ manga }: { manga: Pick<TManga, 'id' | 'trackRecords
|
||||
const trackerList = requestManager.useGetTrackerList<GetTrackersBindQuery>(GET_TRACKERS_BIND, {
|
||||
notifyOnNetworkStatusChange: true,
|
||||
});
|
||||
const mangaTrackers = manga.trackRecords.nodes;
|
||||
const trackers = trackerList.data?.trackers.nodes ?? [];
|
||||
|
||||
const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []);
|
||||
const trackersInUse = Trackers.getLoggedIn(Trackers.getTrackers(mangaTrackers));
|
||||
const mangaTrackRecordsList = requestManager.useGetManga<GetMangaTrackRecordsQuery>(
|
||||
GET_MANGA_TRACK_RECORDS,
|
||||
manga.id,
|
||||
);
|
||||
const mangaTrackRecords = mangaTrackRecordsList.data?.manga.trackRecords.nodes ?? [];
|
||||
|
||||
const loggedInTrackers = Trackers.getLoggedIn(trackers);
|
||||
const trackersInUse = Trackers.getLoggedIn(Trackers.getTrackers(mangaTrackRecords, trackers));
|
||||
const trackersInUseIds = Trackers.getIds(trackersInUse);
|
||||
|
||||
const isSearchActive = searchModeForTracker !== undefined;
|
||||
const OptionalDialogContent = useMemo(() => (isSearchActive ? Box : DialogContent), [isSearchActive]);
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all(manga.trackRecords.nodes.map((trackRecord) => requestManager.fetchTrackBind(trackRecord.id))).catch(
|
||||
() => makeToast(t('tracking.error.label.could_not_fetch_track_info'), 'error'),
|
||||
Promise.all(mangaTrackRecords.map((trackRecord) => requestManager.fetchTrackBind(trackRecord.id))).catch(() =>
|
||||
makeToast(t('tracking.error.label.could_not_fetch_track_info'), 'error'),
|
||||
);
|
||||
}, [manga.id]);
|
||||
}, [mangaTrackRecords]);
|
||||
|
||||
const trackerComponents = useMemo(
|
||||
() =>
|
||||
loggedInTrackers.map((tracker) => {
|
||||
const mode = getTrackerMode(tracker.id, trackersInUseIds, searchModeForTracker);
|
||||
const trackRecord = Trackers.getTrackRecordFor(tracker, manga.trackRecords.nodes);
|
||||
const trackRecord = Trackers.getTrackRecordFor(tracker, mangaTrackRecords);
|
||||
|
||||
const isSearchForTracker = mode === TrackerMode.SEARCH;
|
||||
if (isSearchActive && !isSearchForTracker) {
|
||||
@@ -73,27 +80,39 @@ export const TrackManga = ({ manga }: { manga: Pick<TManga, 'id' | 'trackRecords
|
||||
<TrackerCard
|
||||
key={tracker.id}
|
||||
tracker={tracker}
|
||||
mangaId={manga.id}
|
||||
manga={manga}
|
||||
trackRecord={trackRecord}
|
||||
mode={mode}
|
||||
setSearchMode={(id) => setSearchModeForTracker(id)}
|
||||
/>
|
||||
);
|
||||
}),
|
||||
[trackersInUseIds, searchModeForTracker, manga.id],
|
||||
[trackersInUseIds, searchModeForTracker, mangaTrackRecords],
|
||||
);
|
||||
|
||||
if (trackerList.error) {
|
||||
const error = trackerList.error ?? mangaTrackRecordsList.error;
|
||||
if (error) {
|
||||
return (
|
||||
<EmptyViewAbsoluteCentered
|
||||
message={t('global.error.label.failed_to_load_data')}
|
||||
messageExtra={trackerList.error.message}
|
||||
retry={() => trackerList.refetch().catch(defaultPromiseErrorHandler('TrackManga::refetch'))}
|
||||
messageExtra={error.message}
|
||||
retry={() => {
|
||||
if (trackerList.error) {
|
||||
trackerList.refetch().catch(defaultPromiseErrorHandler('TrackManga::refetch: trackerList'));
|
||||
}
|
||||
|
||||
if (mangaTrackRecordsList.error) {
|
||||
mangaTrackRecordsList
|
||||
.refetch()
|
||||
.catch(defaultPromiseErrorHandler('TrackManga::refetch: mangaTrackRecordsList'));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (trackerList.loading) {
|
||||
const loading = trackerList.loading || mangaTrackRecordsList.loading;
|
||||
if (loading) {
|
||||
return <LoadingPlaceholder />;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import { TrackerUntrackedCard } from '@/components/tracker/TrackerUntrackedCard.
|
||||
import { TrackerSearch } from '@/components/tracker/TrackerSearch.tsx';
|
||||
import { TrackerActiveCard } from '@/components/tracker/TrackerActiveCard.tsx';
|
||||
import { TTrackerBind, TTrackRecordBind } from '@/lib/data/Trackers.ts';
|
||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
|
||||
|
||||
export enum TrackerMode {
|
||||
UNTRACKED,
|
||||
@@ -19,13 +21,13 @@ export enum TrackerMode {
|
||||
|
||||
export const TrackerCard = ({
|
||||
tracker,
|
||||
mangaId,
|
||||
manga,
|
||||
trackRecord,
|
||||
mode,
|
||||
setSearchMode,
|
||||
}: {
|
||||
tracker: TTrackerBind;
|
||||
mangaId: number;
|
||||
manga: MangaIdInfo & Pick<MangaType, 'title'>;
|
||||
trackRecord?: TTrackRecordBind;
|
||||
mode: TrackerMode;
|
||||
setSearchMode: (id?: number) => void;
|
||||
@@ -37,7 +39,7 @@ export const TrackerCard = ({
|
||||
if (mode === TrackerMode.SEARCH) {
|
||||
return (
|
||||
<TrackerSearch
|
||||
mangaId={mangaId}
|
||||
manga={manga}
|
||||
tracker={tracker}
|
||||
trackedId={trackRecord?.remoteId}
|
||||
closeSearchMode={() => setSearchMode(undefined)}
|
||||
@@ -46,7 +48,7 @@ export const TrackerCard = ({
|
||||
}
|
||||
|
||||
if (mode === TrackerMode.INFO && !trackRecord) {
|
||||
throw new Error(`TrackerCard: unable to find track record for tracker "${tracker.id}" of manga "${mangaId}"}`);
|
||||
throw new Error(`TrackerCard: unable to find track record for tracker "${tracker.id}" of manga "${manga.id}"}`);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -31,24 +31,23 @@ import { TrackerMangaCard } from '@/components/tracker/TrackerMangaCard.tsx';
|
||||
import { DIALOG_PADDING } from '@/components/tracker/constants.ts';
|
||||
import { getOptionForDirection } from '@/theme.ts';
|
||||
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
|
||||
|
||||
export const TrackerSearch = ({
|
||||
mangaId,
|
||||
manga,
|
||||
tracker,
|
||||
closeSearchMode,
|
||||
trackedId,
|
||||
}: {
|
||||
mangaId: number;
|
||||
manga: MangaIdInfo & Pick<MangaType, 'title'>;
|
||||
tracker: Pick<TTrackerBase, 'id'>;
|
||||
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<string>(manga.data!.manga.title);
|
||||
const [searchString, setSearchString] = useState<string>(manga.title);
|
||||
const [tmpSearchString, setTmpSearchString] = useState(searchString);
|
||||
|
||||
const [selectedTrackerRemoteId, setSelectedTrackerRemoteId] = useState<string | undefined>(trackedId);
|
||||
@@ -62,7 +61,7 @@ export const TrackerSearch = ({
|
||||
setSelectedTrackerRemoteId(trackedId);
|
||||
|
||||
return () =>
|
||||
trackerSearch.abortRequest(new Error(`MangaTrackerSearchCard(${tracker.id}, ${mangaId}): search changed`));
|
||||
trackerSearch.abortRequest(new Error(`MangaTrackerSearchCard(${tracker.id}, ${manga.id}): search changed`));
|
||||
}, [searchString]);
|
||||
|
||||
const [bindTracker, bindTrackerMutation] = requestManager.useBindTracker();
|
||||
@@ -82,7 +81,7 @@ export const TrackerSearch = ({
|
||||
return;
|
||||
}
|
||||
|
||||
bindTracker({ variables: { mangaId, remoteId: selectedTrackerRemoteId, trackerId: tracker.id } })
|
||||
bindTracker({ variables: { mangaId: manga.id, remoteId: selectedTrackerRemoteId, trackerId: tracker.id } })
|
||||
.then(() => {
|
||||
makeToast(t('manga.action.track.add.label.success'), 'success');
|
||||
closeSearchMode();
|
||||
|
||||
Reference in New Issue
Block a user