Reduce requested tracker data in queries

This commit is contained in:
schroda
2024-07-04 22:00:39 +02:00
parent 7556ea9b38
commit 83be995fb8
20 changed files with 289 additions and 154 deletions

View File

@@ -19,6 +19,8 @@ import { GridLayout, useLibraryOptionsContext } from '@/components/context/Libra
import { OptionsTabs } from '@/components/molecules/OptionsTabs'; import { OptionsTabs } from '@/components/molecules/OptionsTabs';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { Trackers } from '@/lib/data/Trackers.ts'; import { Trackers } from '@/lib/data/Trackers.ts';
import { GetTrackersSettingsQuery } from '@/lib/graphql/generated/graphql.ts';
import { GET_TRACKERS_SETTINGS } from '@/lib/graphql/queries/TrackerQuery.ts';
const TITLES: { [key in 'filter' | 'sort' | 'display']: TranslationKey } = { const TITLES: { [key in 'filter' | 'sort' | 'display']: TranslationKey } = {
filter: 'global.label.filter', filter: 'global.label.filter',
@@ -44,7 +46,7 @@ export const LibraryOptionsPanel: React.FC<IProps> = ({ open, onClose }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { options, setOptions } = useLibraryOptionsContext(); const { options, setOptions } = useLibraryOptionsContext();
const trackerList = requestManager.useGetTrackerList(); const trackerList = requestManager.useGetTrackerList<GetTrackersSettingsQuery>(GET_TRACKERS_SETTINGS);
const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []); const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []);
const handleFilterChange = <T extends keyof LibraryOptions>(key: T, value: LibraryOptions[T]) => { const handleFilterChange = <T extends keyof LibraryOptions>(key: T, value: LibraryOptions[T]) => {

View File

@@ -18,12 +18,14 @@ import { TrackManga } from '@/components/tracker/TrackManga.tsx';
import { Trackers } from '@/lib/data/Trackers.ts'; import { Trackers } from '@/lib/data/Trackers.ts';
import { TManga } from '@/typings.ts'; import { TManga } from '@/typings.ts';
import { CustomIconButton } from '@/components/atoms/CustomIconButton.tsx'; import { CustomIconButton } from '@/components/atoms/CustomIconButton.tsx';
import { GetTrackersSettingsQuery } from '@/lib/graphql/generated/graphql.ts';
import { GET_TRACKERS_SETTINGS } from '@/lib/graphql/queries/TrackerQuery.ts';
export const TrackMangaButton = ({ manga }: { manga: TManga }) => { export const TrackMangaButton = ({ manga }: { manga: TManga }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const navigate = useNavigate(); const navigate = useNavigate();
const trackerList = requestManager.useGetTrackerList(); const trackerList = requestManager.useGetTrackerList<GetTrackersSettingsQuery>(GET_TRACKERS_SETTINGS);
const mangaTrackers = manga.trackRecords.nodes; const mangaTrackers = manga.trackRecords.nodes;
const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []); const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []);

View File

@@ -24,9 +24,9 @@ import Button from '@mui/material/Button';
import { PasswordTextField } from '@/components/atoms/PasswordTextField.tsx'; import { PasswordTextField } from '@/components/atoms/PasswordTextField.tsx';
import { makeToast } from '@/components/util/Toast.tsx'; import { makeToast } from '@/components/util/Toast.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { TBaseTracker, Trackers } from '@/lib/data/Trackers.ts'; import { Trackers, TTrackerSearch } from '@/lib/data/Trackers.ts';
export const SettingsTrackerCard = ({ tracker }: { tracker: TBaseTracker }) => { export const SettingsTrackerCard = ({ tracker }: { tracker: TTrackerSearch }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [loginTrackerCredentials, { loading: isCredentialLoginInProgress }] = const [loginTrackerCredentials, { loading: isCredentialLoginInProgress }] =

View File

@@ -19,6 +19,8 @@ import { TrackerCard, TrackerMode } from '@/components/tracker/TrackerCard.tsx';
import { TManga } from '@/typings.ts'; import { TManga } from '@/typings.ts';
import { makeToast } from '@/components/util/Toast.tsx'; import { makeToast } from '@/components/util/Toast.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { GetTrackersBindQuery } from '@/lib/graphql/generated/graphql.ts';
import { GET_TRACKERS_BIND } from '@/lib/graphql/queries/TrackerQuery.ts';
const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracker?: number): TrackerMode => { const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracker?: number): TrackerMode => {
if (id === searchModeForTracker) { if (id === searchModeForTracker) {
@@ -38,7 +40,9 @@ export const TrackManga = ({ manga }: { manga: Pick<TManga, 'id' | 'trackRecords
const [searchModeForTracker, setSearchModeForTracker] = useState<number>(); const [searchModeForTracker, setSearchModeForTracker] = useState<number>();
const trackerList = requestManager.useGetTrackerList({ notifyOnNetworkStatusChange: true }); const trackerList = requestManager.useGetTrackerList<GetTrackersBindQuery>(GET_TRACKERS_BIND, {
notifyOnNetworkStatusChange: true,
});
const mangaTrackers = manga.trackRecords.nodes; const mangaTrackers = manga.trackRecords.nodes;
const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []); const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []);

View File

@@ -29,7 +29,7 @@ import MoreVertIcon from '@mui/icons-material/MoreVert';
import PopupState, { bindDialog, bindMenu, bindTrigger } from 'material-ui-popup-state'; import PopupState, { bindDialog, bindMenu, bindTrigger } from 'material-ui-popup-state';
import { useMemo, useState } from 'react'; import { useMemo, useState } from 'react';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { Trackers, TTrackRecord, UNSET_DATE } from '@/lib/data/Trackers.ts'; import { Trackers, TTrackerBind, TTrackRecordBind, UNSET_DATE } from '@/lib/data/Trackers.ts';
import { ListPreference } from '@/components/sourceConfiguration/ListPreference.tsx'; import { ListPreference } from '@/components/sourceConfiguration/ListPreference.tsx';
import { NumberSetting } from '@/components/settings/NumberSetting.tsx'; import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
import { DateSetting } from '@/components/settings/DateSetting.tsx'; import { DateSetting } from '@/components/settings/DateSetting.tsx';
@@ -39,6 +39,7 @@ import { CARD_STYLING } from '@/components/tracker/constants.ts';
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx'; import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
import { SelectSetting, SelectSettingValue } from '@/components/settings/SelectSetting.tsx'; import { SelectSetting, SelectSettingValue } from '@/components/settings/SelectSetting.tsx';
import { CheckboxInput } from '@/components/atoms/CheckboxInput'; import { CheckboxInput } from '@/components/atoms/CheckboxInput';
import { TrackRecordType } from '@/lib/graphql/generated/graphql.ts';
const TrackerActiveLink = ({ children, url }: { children: React.ReactNode; url: string }) => ( const TrackerActiveLink = ({ children, url }: { children: React.ReactNode; url: string }) => (
<Link href={url} rel="noreferrer" target="_blank" underline="none" color="inherit"> <Link href={url} rel="noreferrer" target="_blank" underline="none" color="inherit">
@@ -46,12 +47,16 @@ const TrackerActiveLink = ({ children, url }: { children: React.ReactNode; url:
</Link> </Link>
); );
type TTrackerActive = Pick<TTrackerBind, 'id' | 'name' | 'icon' | 'supportsTrackDeletion'>;
type TTrackRecordActive = Pick<TTrackRecordBind, 'id' | 'remoteUrl' | 'title'>;
const TrackerActiveRemoveBind = ({ const TrackerActiveRemoveBind = ({
trackRecord: { tracker, ...trackRecord }, trackerRecordId,
tracker,
onClick, onClick,
onClose, onClose,
}: { }: {
trackRecord: TTrackRecord; trackerRecordId: TrackRecordType['id'];
tracker: TTrackerActive;
onClick: () => void; onClick: () => void;
onClose: () => void; onClose: () => void;
}) => { }) => {
@@ -62,7 +67,7 @@ const TrackerActiveRemoveBind = ({
const removeBind = () => { const removeBind = () => {
onClose(); onClose();
requestManager requestManager
.unbindTracker(trackRecord.id, removeRemoteTracking) .unbindTracker(trackerRecordId, removeRemoteTracking)
.response.then(() => makeToast(t('manga.action.track.remove.label.success'), 'success')) .response.then(() => makeToast(t('manga.action.track.remove.label.success'), 'success'))
.catch(() => makeToast(t('manga.action.track.remove.label.error'), 'error')); .catch(() => makeToast(t('manga.action.track.remove.label.error'), 'error'));
}; };
@@ -137,10 +142,12 @@ const TrackerActiveRemoveBind = ({
}; };
const TrackerActiveHeader = ({ const TrackerActiveHeader = ({
trackRecord: { tracker, ...trackRecord }, trackRecord,
tracker,
openSearch, openSearch,
}: { }: {
trackRecord: TTrackRecord; trackRecord: TTrackRecordActive;
tracker: TTrackerActive;
openSearch: () => void; openSearch: () => void;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -182,7 +189,8 @@ const TrackerActiveHeader = ({
</TrackerActiveLink>, </TrackerActiveLink>,
<TrackerActiveRemoveBind <TrackerActiveRemoveBind
key={`tracker-active-menu-item-remove-${tracker.id}`} key={`tracker-active-menu-item-remove-${tracker.id}`}
trackRecord={{ tracker, ...trackRecord }} trackerRecordId={trackRecord.id}
tracker={tracker}
onClick={() => setHideMenu(true)} onClick={() => setHideMenu(true)}
onClose={onClose} onClose={onClose}
/>, />,
@@ -205,10 +213,12 @@ const TrackerActiveCardInfoRow = ({ children }: { children: React.ReactNode }) =
const isUnsetScore = (score: string | number): boolean => !Math.trunc(Number(score)); const isUnsetScore = (score: string | number): boolean => !Math.trunc(Number(score));
export const TrackerActiveCard = ({ export const TrackerActiveCard = ({
trackRecord: { tracker, ...trackRecord }, trackRecord,
tracker,
onClick, onClick,
}: { }: {
trackRecord: TTrackRecord; trackRecord: TTrackRecordBind;
tracker: TTrackerBind;
onClick: () => void; onClick: () => void;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -221,7 +231,7 @@ export const TrackerActiveCard = ({
tracker.scores.map( tracker.scores.map(
(score) => (score) =>
[score, { text: isUnsetScore(score) ? '-' : score }] satisfies SelectSettingValue< [score, { text: isUnsetScore(score) ? '-' : score }] satisfies SelectSettingValue<
TTrackRecord['tracker']['scores'][number] TTrackerBind['scores'][number]
>, >,
), ),
[tracker.scores], [tracker.scores],
@@ -236,7 +246,7 @@ export const TrackerActiveCard = ({
return ( return (
<Card sx={CARD_STYLING}> <Card sx={CARD_STYLING}>
<CardContent sx={{ padding: 0 }}> <CardContent sx={{ padding: 0 }}>
<TrackerActiveHeader trackRecord={{ tracker, ...trackRecord }} openSearch={onClick} /> <TrackerActiveHeader trackRecord={trackRecord} tracker={tracker} openSearch={onClick} />
<Card> <Card>
<CardContent sx={{ padding: '0' }}> <CardContent sx={{ padding: '0' }}>
<Box sx={{ padding: 1 }}> <Box sx={{ padding: 1 }}>

View File

@@ -6,10 +6,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
import { TBaseTracker, TTrackRecord } from '@/lib/data/Trackers.ts';
import { TrackerUntrackedCard } from '@/components/tracker/TrackerUntrackedCard.tsx'; import { TrackerUntrackedCard } from '@/components/tracker/TrackerUntrackedCard.tsx';
import { TrackerSearch } from '@/components/tracker/TrackerSearch.tsx'; import { TrackerSearch } from '@/components/tracker/TrackerSearch.tsx';
import { TrackerActiveCard } from '@/components/tracker/TrackerActiveCard.tsx'; import { TrackerActiveCard } from '@/components/tracker/TrackerActiveCard.tsx';
import { TTrackerBind, TTrackRecordBind } from '@/lib/data/Trackers.ts';
export enum TrackerMode { export enum TrackerMode {
UNTRACKED, UNTRACKED,
@@ -24,9 +24,9 @@ export const TrackerCard = ({
mode, mode,
setSearchMode, setSearchMode,
}: { }: {
tracker: TBaseTracker; tracker: TTrackerBind;
mangaId: number; mangaId: number;
trackRecord?: TTrackRecord; trackRecord?: TTrackRecordBind;
mode: TrackerMode; mode: TrackerMode;
setSearchMode: (id?: number) => void; setSearchMode: (id?: number) => void;
}) => { }) => {
@@ -51,6 +51,7 @@ export const TrackerCard = ({
return ( return (
<TrackerActiveCard <TrackerActiveCard
tracker={tracker}
trackRecord={trackRecord!} trackRecord={trackRecord!}
onClick={() => { onClick={() => {
setSearchMode(tracker.id); setSearchMode(tracker.id);

View File

@@ -23,10 +23,10 @@ import parseHtml from 'html-react-parser';
import CheckCircleIcon from '@mui/icons-material/CheckCircle'; import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import sanitizeHtml from 'sanitize-html'; import sanitizeHtml from 'sanitize-html';
import { SpinnerImage } from '@/components/util/SpinnerImage.tsx'; import { SpinnerImage } from '@/components/util/SpinnerImage.tsx';
import { TrackerManga } from '@/lib/data/Trackers.ts';
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx'; import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
import { Metadata } from '@/components/atoms/Metadata.tsx'; import { Metadata } from '@/components/atoms/Metadata.tsx';
import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; import { MediaQuery } from '@/lib/ui/MediaQuery.tsx';
import { TTrackerManga } from '@/lib/data/Trackers.ts';
const TrackerMangaCardTitle = ({ title, selected }: { title: string; selected: boolean }) => ( const TrackerMangaCardTitle = ({ title, selected }: { title: string; selected: boolean }) => (
<Stack direction="row" gap="5px" justifyContent="space-between"> <Stack direction="row" gap="5px" justifyContent="space-between">
@@ -101,7 +101,7 @@ export const TrackerMangaCard = ({
selected, selected,
onSelect, onSelect,
}: { }: {
manga: TrackerManga; manga: TTrackerManga;
selected: boolean; selected: boolean;
onSelect: () => void; onSelect: () => void;
}) => { }) => {

View File

@@ -24,7 +24,7 @@ import Typography from '@mui/material/Typography';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx'; import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
import { TBaseTracker, Tracker } from '@/lib/data/Trackers.ts'; import { Tracker, TTrackerBase } from '@/lib/data/Trackers.ts';
import { SearchTextField } from '@/components/atoms/SearchTextField.tsx'; import { SearchTextField } from '@/components/atoms/SearchTextField.tsx';
import { makeToast } from '@/components/util/Toast.tsx'; import { makeToast } from '@/components/util/Toast.tsx';
import { TrackerMangaCard } from '@/components/tracker/TrackerMangaCard.tsx'; import { TrackerMangaCard } from '@/components/tracker/TrackerMangaCard.tsx';
@@ -39,7 +39,7 @@ export const TrackerSearch = ({
trackedId, trackedId,
}: { }: {
mangaId: number; mangaId: number;
tracker: TBaseTracker; tracker: Pick<TTrackerBase, 'id'>;
closeSearchMode: () => void; closeSearchMode: () => void;
trackedId?: string; trackedId?: string;
}) => { }) => {

View File

@@ -13,10 +13,16 @@ import Button from '@mui/material/Button';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import Stack from '@mui/material/Stack'; import Stack from '@mui/material/Stack';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { TBaseTracker } from '@/lib/data/Trackers.ts';
import { CARD_STYLING } from '@/components/tracker/constants.ts'; import { CARD_STYLING } from '@/components/tracker/constants.ts';
import { TTrackerBase } from '@/lib/data/Trackers.ts';
export const TrackerUntrackedCard = ({ tracker, onClick }: { tracker: TBaseTracker; onClick: () => void }) => { export const TrackerUntrackedCard = ({
tracker,
onClick,
}: {
tracker: Pick<TTrackerBase, 'name' | 'icon'>;
onClick: () => void;
}) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (

View File

@@ -6,13 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
import { import { TrackerType, TrackRecordType, TrackSearchType } from '@/lib/graphql/generated/graphql.ts';
GetMangaQuery,
GetTrackersQuery,
TrackerSearchQuery,
TrackerType,
TrackRecordType,
} from '@/lib/graphql/generated/graphql.ts';
export enum Tracker { export enum Tracker {
MYANIMELIST = 1, MYANIMELIST = 1,
@@ -20,15 +14,44 @@ export enum Tracker {
export const UNSET_DATE = '0'; export const UNSET_DATE = '0';
export type TTrackRecord = GetMangaQuery['manga']['trackRecords']['nodes'][number]; export type TTrackRecordBase = Pick<TrackRecordType, 'id' | 'remoteId' | 'title'>;
export type TrackerManga = TrackerSearchQuery['searchTracker']['trackSearches'][number]; export type TTrackRecordBind = TTrackRecordBase &
Pick<
TrackRecordType,
| 'trackerId'
| 'remoteUrl'
| 'status'
| 'lastChapterRead'
| 'totalChapters'
| 'score'
| 'displayScore'
| 'startDate'
| 'finishDate'
>;
export type TBaseTracker = GetTrackersQuery['trackers']['nodes'][number]; export type TTrackerManga = Pick<
TrackSearchType,
| 'id'
| 'remoteId'
| 'trackingUrl'
| 'title'
| 'coverUrl'
| 'publishingType'
| 'startDate'
| 'publishingStatus'
| 'summary'
>;
export type TTrackerBase = Pick<TrackerType, 'id' | 'name' | 'icon' | 'isLoggedIn' | 'isTokenExpired'>;
export type TTrackerSearch = TTrackerBase & Pick<TrackerType, 'authUrl'>;
export type TTrackerBind = TTrackerBase & Pick<TrackerType, 'icon' | 'supportsTrackDeletion' | 'scores' | 'statuses'>;
type LoggedInInfo = Pick<TrackerType, 'isLoggedIn' | 'isTokenExpired'>; type LoggedInInfo = Pick<TrackerType, 'isLoggedIn' | 'isTokenExpired'>;
type TrackRecordTrackerInfo = { tracker: Partial<TrackRecordType['tracker']> }; type TrackRecordTrackerInfo = { tracker: TTrackerBind };
export class Trackers { export class Trackers {
static getIds(trackers: { id: number }[]): number[] { static getIds(trackers: { id: number }[]): number[] {

View File

@@ -8,6 +8,8 @@
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { SOURCE_BASE_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts'; import { SOURCE_BASE_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts';
import { TRACKER_BIND_FIELDS } from '@/lib/graphql/fragments/TrackFragments.ts';
import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
export const PAGE_INFO = gql` export const PAGE_INFO = gql`
fragment PAGE_INFO on PageInfo { fragment PAGE_INFO on PageInfo {
@@ -52,53 +54,14 @@ export const UPDATER_CATEGORY_FIELDS = gql`
} }
`; `;
export const FULL_TRACKER_FIELDS = gql`
fragment FULL_TRACKER_FIELDS on TrackerType {
id
name
authUrl
icon
supportsTrackDeletion
isLoggedIn
isTokenExpired
scores
statuses {
name
value
}
}
`;
export const BASE_TRACK_RECORD_FIELDS = gql`
fragment BASE_TRACK_RECORD_FIELDS on TrackRecordType {
id
status
lastChapterRead
totalChapters
score
displayScore
startDate
finishDate
}
`;
export const QUERY_TRACK_RECORD_FIELDS = gql`
${BASE_TRACK_RECORD_FIELDS}
fragment QUERY_TRACK_RECORD_FIELDS on TrackRecordType {
...BASE_TRACK_RECORD_FIELDS
title
remoteUrl
remoteId
}
`;
export const FULL_TRACK_RECORD_FIELDS = gql` export const FULL_TRACK_RECORD_FIELDS = gql`
${QUERY_TRACK_RECORD_FIELDS} ${TRACK_RECORD_BIND_FIELDS}
${FULL_TRACKER_FIELDS} ${TRACKER_BIND_FIELDS}
fragment FULL_TRACK_RECORD_FIELDS on TrackRecordType { fragment FULL_TRACK_RECORD_FIELDS on TrackRecordType {
...QUERY_TRACK_RECORD_FIELDS ...TRACK_RECORD_BIND_FIELDS
tracker { tracker {
...FULL_TRACKER_FIELDS ...TRACKER_BIND_FIELDS
} }
} }
`; `;

View File

@@ -0,0 +1,54 @@
/*
* 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 gql from 'graphql-tag';
import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
export const TRACKER_BASE_FIELDS = gql`
fragment TRACKER_BASE_FIELDS on TrackerType {
id
name
icon
isLoggedIn
isTokenExpired
}
`;
export const TRACKER_SETTING_FIELDS = gql`
${TRACKER_BASE_FIELDS}
fragment TRACKER_SETTING_FIELDS on TrackerType {
...TRACKER_BASE_FIELDS
authUrl
}
`;
export const TRACKER_BIND_FIELDS = gql`
${TRACKER_BASE_FIELDS}
${TRACK_RECORD_BIND_FIELDS}
fragment TRACKER_BIND_FIELDS on TrackerType {
...TRACKER_BASE_FIELDS
icon
supportsTrackDeletion
scores
statuses {
name
value
}
trackRecords {
nodes {
...TRACK_RECORD_BIND_FIELDS
}
}
}
`;

View File

@@ -0,0 +1,40 @@
/*
* 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 gql from 'graphql-tag';
export const TRACK_RECORD_SEARCH_FIELDS = gql`
fragment TRACK_RECORD_SEARCH_FIELDS on TrackSearchType {
id
remoteId
title
trackingUrl
coverUrl
publishingType
startDate
publishingStatus
summary
}
`;
export const TRACK_RECORD_BIND_FIELDS = gql`
fragment TRACK_RECORD_BIND_FIELDS on TrackRecordType {
id
remoteId
trackerId
remoteUrl
title
status
lastChapterRead
totalChapters
score
displayScore
startDate
finishDate
}
`;

File diff suppressed because one or more lines are too long

View File

@@ -7,8 +7,8 @@
*/ */
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { BASE_TRACK_RECORD_FIELDS } from '@/lib/graphql/Fragments';
import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts'; import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts';
import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
export const DELETE_CHAPTER_METADATA = gql` export const DELETE_CHAPTER_METADATA = gql`
mutation DELETE_CHAPTER_METADATA($input: DeleteChapterMetaInput!) { mutation DELETE_CHAPTER_METADATA($input: DeleteChapterMetaInput!) {
@@ -90,7 +90,8 @@ export const SET_CHAPTER_METADATA = gql`
`; `;
export const UPDATE_CHAPTER = gql` export const UPDATE_CHAPTER = gql`
${BASE_TRACK_RECORD_FIELDS} ${TRACK_RECORD_BIND_FIELDS}
mutation UPDATE_CHAPTER( mutation UPDATE_CHAPTER(
$input: UpdateChapterInput! $input: UpdateChapterInput!
$getBookmarked: Boolean! $getBookmarked: Boolean!
@@ -141,14 +142,15 @@ export const UPDATE_CHAPTER = gql`
} }
trackProgress(input: { mangaId: $mangaId }) @include(if: $trackProgress) { trackProgress(input: { mangaId: $mangaId }) @include(if: $trackProgress) {
trackRecords { trackRecords {
...BASE_TRACK_RECORD_FIELDS ...TRACK_RECORD_BIND_FIELDS
} }
} }
} }
`; `;
export const UPDATE_CHAPTERS = gql` export const UPDATE_CHAPTERS = gql`
${BASE_TRACK_RECORD_FIELDS} ${TRACK_RECORD_BIND_FIELDS}
mutation UPDATE_CHAPTERS( mutation UPDATE_CHAPTERS(
$input: UpdateChaptersInput! $input: UpdateChaptersInput!
$getBookmarked: Boolean! $getBookmarked: Boolean!
@@ -199,7 +201,7 @@ export const UPDATE_CHAPTERS = gql`
} }
trackProgress(input: { mangaId: $mangaId }) @include(if: $trackProgress) { trackProgress(input: { mangaId: $mangaId }) @include(if: $trackProgress) {
trackRecords { trackRecords {
...BASE_TRACK_RECORD_FIELDS ...TRACK_RECORD_BIND_FIELDS
} }
} }
} }

View File

@@ -7,52 +7,54 @@
*/ */
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { BASE_TRACK_RECORD_FIELDS, QUERY_TRACK_RECORD_FIELDS } from '@/lib/graphql/Fragments.ts'; import { TRACK_RECORD_BIND_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
import { TRACKER_SETTING_FIELDS } from '@/lib/graphql/fragments/TrackFragments.ts';
export const TRACKER_LOGIN_OAUTH = gql` export const TRACKER_LOGIN_OAUTH = gql`
${TRACKER_SETTING_FIELDS}
mutation TRACKER_LOGIN_OAUTH($input: LoginTrackerOAuthInput!) { mutation TRACKER_LOGIN_OAUTH($input: LoginTrackerOAuthInput!) {
loginTrackerOAuth(input: $input) { loginTrackerOAuth(input: $input) {
tracker { tracker {
id ...TRACKER_SETTING_FIELDS
isLoggedIn
authUrl
} }
} }
} }
`; `;
export const TRACKER_LOGIN_CREDENTIALS = gql` export const TRACKER_LOGIN_CREDENTIALS = gql`
${TRACKER_SETTING_FIELDS}
mutation TRACKER_LOGIN_CREDENTIALS($input: LoginTrackerCredentialsInput!) { mutation TRACKER_LOGIN_CREDENTIALS($input: LoginTrackerCredentialsInput!) {
loginTrackerCredentials(input: $input) { loginTrackerCredentials(input: $input) {
isLoggedIn isLoggedIn
tracker { tracker {
id ...TRACKER_SETTING_FIELDS
isLoggedIn
authUrl
} }
} }
} }
`; `;
export const TRACKER_LOGOUT = gql` export const TRACKER_LOGOUT = gql`
${TRACKER_SETTING_FIELDS}
mutation TRACKER_LOGOUT($trackerId: Int!) { mutation TRACKER_LOGOUT($trackerId: Int!) {
logoutTracker(input: { trackerId: $trackerId }) { logoutTracker(input: { trackerId: $trackerId }) {
clientMutationId clientMutationId
tracker { tracker {
id ...TRACKER_SETTING_FIELDS
isLoggedIn
authUrl
} }
} }
} }
`; `;
export const TRACKER_BIND = gql` export const TRACKER_BIND = gql`
${QUERY_TRACK_RECORD_FIELDS} ${TRACK_RECORD_BIND_FIELDS}
mutation TRACKER_BIND($mangaId: Int!, $remoteId: LongString!, $trackerId: Int!) { mutation TRACKER_BIND($mangaId: Int!, $remoteId: LongString!, $trackerId: Int!) {
bindTrack(input: { mangaId: $mangaId, remoteId: $remoteId, trackerId: $trackerId }) { bindTrack(input: { mangaId: $mangaId, remoteId: $remoteId, trackerId: $trackerId }) {
trackRecord { trackRecord {
...QUERY_TRACK_RECORD_FIELDS ...TRACK_RECORD_BIND_FIELDS
tracker { tracker {
id id
} }
@@ -90,11 +92,12 @@ export const TRACKER_UNBIND = gql`
`; `;
export const TRACKER_UPDATE_BIND = gql` export const TRACKER_UPDATE_BIND = gql`
${QUERY_TRACK_RECORD_FIELDS} ${TRACK_RECORD_BIND_FIELDS}
mutation TRACKER_UPDATE_BIND($input: UpdateTrackInput!) { mutation TRACKER_UPDATE_BIND($input: UpdateTrackInput!) {
updateTrack(input: $input) { updateTrack(input: $input) {
trackRecord { trackRecord {
...QUERY_TRACK_RECORD_FIELDS ...TRACK_RECORD_BIND_FIELDS
manga { manga {
id id
trackRecords { trackRecords {
@@ -110,11 +113,12 @@ export const TRACKER_UPDATE_BIND = gql`
`; `;
export const TRACKER_FETCH_BIND = gql` export const TRACKER_FETCH_BIND = gql`
${BASE_TRACK_RECORD_FIELDS} ${TRACK_RECORD_BIND_FIELDS}
mutation TRACKER_FETCH_BIND($recordId: Int!) { mutation TRACKER_FETCH_BIND($recordId: Int!) {
fetchTrack(input: { recordId: $recordId }) { fetchTrack(input: { recordId: $recordId }) {
trackRecord { trackRecord {
...BASE_TRACK_RECORD_FIELDS ...TRACK_RECORD_BIND_FIELDS
} }
} }
} }

View File

@@ -7,39 +7,51 @@
*/ */
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { FULL_TRACKER_FIELDS, PAGE_INFO } from '@/lib/graphql/Fragments.ts'; import { PAGE_INFO } from '@/lib/graphql/Fragments.ts';
import { TRACKER_BIND_FIELDS, TRACKER_SETTING_FIELDS } from '@/lib/graphql/fragments/TrackFragments.ts';
import { TRACK_RECORD_SEARCH_FIELDS } from '@/lib/graphql/fragments/TrackRecordFragments.ts';
export const GET_TRACKERS = gql` export const GET_TRACKERS_SETTINGS = gql`
${PAGE_INFO} ${PAGE_INFO}
${FULL_TRACKER_FIELDS} ${TRACKER_SETTING_FIELDS}
query GET_TRACKERS {
query GET_TRACKERS_SETTINGS {
trackers { trackers {
totalCount totalCount
pageInfo { pageInfo {
...PAGE_INFO ...PAGE_INFO
} }
nodes { nodes {
...FULL_TRACKER_FIELDS ...TRACKER_SETTING_FIELDS
}
}
}
`;
export const GET_TRACKERS_BIND = gql`
${PAGE_INFO}
${TRACKER_BIND_FIELDS}
query GET_TRACKERS_BIND {
trackers {
totalCount
pageInfo {
...PAGE_INFO
}
nodes {
...TRACKER_BIND_FIELDS
} }
} }
} }
`; `;
export const TRACKER_SEARCH = gql` export const TRACKER_SEARCH = gql`
${TRACK_RECORD_SEARCH_FIELDS}
query TRACKER_SEARCH($query: String!, $trackerId: Int!) { query TRACKER_SEARCH($query: String!, $trackerId: Int!) {
searchTracker(input: { query: $query, trackerId: $trackerId }) { searchTracker(input: { query: $query, trackerId: $trackerId }) {
trackSearches { trackSearches {
id ...TRACK_RECORD_SEARCH_FIELDS
title
coverUrl
publishingStatus
publishingType
remoteId
startDate
summary
totalChapters
trackerId
trackingUrl
} }
} }
} }

View File

@@ -169,8 +169,6 @@ import {
GetMangaToMigrateQueryVariables, GetMangaToMigrateQueryVariables,
GetMangaToMigrateToFetchMutation, GetMangaToMigrateToFetchMutation,
GetMangaToMigrateToFetchMutationVariables, GetMangaToMigrateToFetchMutationVariables,
GetTrackersQuery,
GetTrackersQueryVariables,
TrackerLogoutMutation, TrackerLogoutMutation,
TrackerLogoutMutationVariables, TrackerLogoutMutationVariables,
TrackerLoginOauthMutation, TrackerLoginOauthMutation,
@@ -297,7 +295,7 @@ import { WEBUI_UPDATE_SUBSCRIPTION } from '@/lib/graphql/subscriptions/ServerInf
import { GET_DOWNLOAD_STATUS } from '@/lib/graphql/queries/DownloaderQuery.ts'; import { GET_DOWNLOAD_STATUS } from '@/lib/graphql/queries/DownloaderQuery.ts';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { Queue, QueuePriority } from '@/lib/Queue.ts'; import { Queue, QueuePriority } from '@/lib/Queue.ts';
import { GET_TRACKERS, TRACKER_SEARCH } from '@/lib/graphql/queries/TrackerQuery.ts'; import { TRACKER_SEARCH } from '@/lib/graphql/queries/TrackerQuery.ts';
import { import {
TRACKER_BIND, TRACKER_BIND,
TRACKER_FETCH_BIND, TRACKER_FETCH_BIND,
@@ -2545,10 +2543,11 @@ export class RequestManager {
return this.doRequest(GQLMethod.USE_QUERY, GET_MIGRATABLE_SOURCES, undefined, options); return this.doRequest(GQLMethod.USE_QUERY, GET_MIGRATABLE_SOURCES, undefined, options);
} }
public useGetTrackerList( public useGetTrackerList<Data, Variables extends OperationVariables = never>(
options?: QueryHookOptions<GetTrackersQuery, GetTrackersQueryVariables>, document: DocumentNode | TypedDocumentNode<Data, Variables>,
): AbortableApolloUseQueryResponse<GetTrackersQuery, GetTrackersQueryVariables> { options?: QueryHookOptions<Data, Variables>,
return this.doRequest(GQLMethod.USE_QUERY, GET_TRACKERS, undefined, options); ): AbortableApolloUseQueryResponse<Data, Variables> {
return this.doRequest(GQLMethod.USE_QUERY, document, undefined, options);
} }
public useLogoutFromTracker( public useLogoutFromTracker(
@@ -2601,7 +2600,7 @@ export class RequestManager {
GQLMethod.MUTATION, GQLMethod.MUTATION,
TRACKER_UNBIND, TRACKER_UNBIND,
{ input: { recordId, deleteRemoteTrack } }, { input: { recordId, deleteRemoteTrack } },
{ refetchQueries: [GET_MANGA, GET_CATEGORY_MANGAS, GET_MANGAS], ...options }, { refetchQueries: [GET_MANGA], ...options },
); );
} }

View File

@@ -26,6 +26,8 @@ import {
import { MetadataTrackingSettings } from '@/typings.ts'; import { MetadataTrackingSettings } from '@/typings.ts';
import { makeToast } from '@/components/util/Toast.tsx'; import { makeToast } from '@/components/util/Toast.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { GET_TRACKERS_SETTINGS } from '@/lib/graphql/queries/TrackerQuery.ts';
import { GetTrackersSettingsQuery } from '@/lib/graphql/generated/graphql.ts';
export const TrackingSettings = () => { export const TrackingSettings = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -49,7 +51,9 @@ export const TrackingSettings = () => {
loading: areTrackersLoading, loading: areTrackersLoading,
error: trackersError, error: trackersError,
refetch: refetchTrackersList, refetch: refetchTrackersList,
} = requestManager.useGetTrackerList({ notifyOnNetworkStatusChange: true }); } = requestManager.useGetTrackerList<GetTrackersSettingsQuery>(GET_TRACKERS_SETTINGS, {
notifyOnNetworkStatusChange: true,
});
const trackers = data?.trackers.nodes ?? []; const trackers = data?.trackers.nodes ?? [];
const loading = areMetadataServerSettingsLoading || areTrackersLoading; const loading = areMetadataServerSettingsLoading || areTrackersLoading;

View File

@@ -19,8 +19,8 @@ import {
GetSourceSettingsQuery, GetSourceSettingsQuery,
MetaType, MetaType,
SourcePreferenceChangeInput, SourcePreferenceChangeInput,
TrackerType,
} from '@/lib/graphql/generated/graphql.ts'; } from '@/lib/graphql/generated/graphql.ts';
import { TBaseTracker } from '@/lib/data/Trackers.ts';
type GenericLocation<State = any> = Omit<Location, 'state'> & { state?: State }; type GenericLocation<State = any> = Omit<Location, 'state'> & { state?: State };
@@ -282,7 +282,7 @@ export interface LibraryOptions {
sorts: NullAndUndefined<LibrarySortMode>; sorts: NullAndUndefined<LibrarySortMode>;
sortDesc: NullAndUndefined<boolean>; sortDesc: NullAndUndefined<boolean>;
showTabSize: boolean; showTabSize: boolean;
tracker: Record<TBaseTracker['id'], NullAndUndefined<boolean>>; tracker: Record<TrackerType['id'], NullAndUndefined<boolean>>;
} }
export type ServerSettings = GetServerSettingsQuery['settings']; export type ServerSettings = GetServerSettingsQuery['settings'];