/* * 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 { useTranslation } from 'react-i18next'; import { useLayoutEffect } from 'react'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import Switch from '@mui/material/Switch'; import ListSubheader from '@mui/material/ListSubheader'; import { t as translate } from 'i18next'; import { GlobalUpdateSettings } from '@/modules/settings/components/globalUpdate/GlobalUpdateSettings.tsx'; import { makeToast } from '@/modules/core/utils/Toast.ts'; import { createUpdateMetadataServerSettings, useMetadataServerSettings, } from '@/modules/settings/services/ServerSettingsMetadata.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { Mangas } from '@/modules/manga/services/Mangas.ts'; import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx'; import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx'; import { ListItemLink } from '@/modules/core/components/ListItemLink.tsx'; import { GetCategoriesSettingsQuery, GetCategoriesSettingsQueryVariables, GetMangasBaseQuery, GetMangasBaseQueryVariables, } from '@/lib/graphql/generated/graphql.ts'; import { GET_CATEGORIES_SETTINGS } from '@/lib/graphql/queries/CategoryQuery.ts'; import { GET_MANGAS_BASE } from '@/lib/graphql/queries/MangaQuery.ts'; import { MetadataLibrarySettings } from '@/modules/library/Library.types.ts'; import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; const removeNonLibraryMangasFromCategories = async (): Promise => { try { const nonLibraryMangas = await requestManager.getMangas( GET_MANGAS_BASE, { filter: { inLibrary: { equalTo: false }, categoryId: { isNull: false } }, }, ).response; const mangaIdsToRemove = Mangas.getIds(nonLibraryMangas.data.mangas.nodes); if (mangaIdsToRemove.length) { await requestManager.updateMangasCategories(mangaIdsToRemove, { clearCategories: true, }).response; } makeToast(translate('library.settings.advanced.database.cleanup.label.success'), 'success'); } catch (e) { makeToast(translate('library.settings.advanced.database.cleanup.label.error'), 'error', getErrorMessage(e)); } }; export function LibrarySettings() { const { t } = useTranslation(); const { setTitle, setAction } = useNavBarContext(); useLayoutEffect(() => { setTitle(t('library.settings.title')); setAction(null); return () => { setTitle(''); setAction(null); }; }, [t]); const categories = requestManager.useGetCategories( GET_CATEGORIES_SETTINGS, ); const serverSettings = requestManager.useGetServerSettings({ notifyOnNetworkStatusChange: true }); const { settings, loading: areMetadataServerSettingsLoading, request: { error: metadataServerSettingsError, refetch: refetchMetadataServerSettings }, } = useMetadataServerSettings(); const setSettingValue = createUpdateMetadataServerSettings((e) => makeToast(t('search.error.label.failed_to_save_settings'), 'error', getErrorMessage(e)), ); const loading = serverSettings.loading || areMetadataServerSettingsLoading || categories.loading; if (loading) { return ; } const error = serverSettings.error ?? metadataServerSettingsError ?? categories.error; if (error) { return ( { if (serverSettings.error) { serverSettings ?.refetch() .catch(defaultPromiseErrorHandler('LibrarySettings::refetchServerSettings')); } if (metadataServerSettingsError) { refetchMetadataServerSettings().catch( defaultPromiseErrorHandler('LibrarySettings::refetchMetadataServerSettings'), ); } if (categories.error) { categories.refetch().catch(defaultPromiseErrorHandler('LibrarySettings::refetchCategories')); } }} /> ); } return ( {t('global.label.general')} } > setSettingValue('ignoreFilters', e.target.checked)} /> setSettingValue('showAddToLibraryCategorySelectDialog', e.target.checked)} /> setSettingValue('removeMangaFromCategories', e.target.checked)} /> {t('global.label.advanced')} } > removeNonLibraryMangasFromCategories()}> ); }