/* * 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 type { MessageDescriptor } from '@lingui/core'; import FormLabel from '@mui/material/FormLabel'; import RadioGroup from '@mui/material/RadioGroup'; import { useLingui } from '@lingui/react/macro'; import { msg } from '@lingui/core/macro'; import { CheckboxInput } from '@/base/components/inputs/CheckboxInput.tsx'; import { RadioInput } from '@/base/components/inputs/RadioInput.tsx'; import { SortRadioInput } from '@/base/components/inputs/SortRadioInput.tsx'; import { ThreeStateCheckboxInput } from '@/base/components/inputs/ThreeStateCheckboxInput.tsx'; import { OptionsTabs } from '@/base/components/modals/OptionsTabs.tsx'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { Trackers } from '@/features/tracker/services/Trackers.ts'; import type { GetTrackersSettingsQuery } from '@/lib/graphql/generated/graphql.ts'; import { MangaStatus } from '@/lib/graphql/generated/graphql.ts'; import { GET_TRACKERS_SETTINGS } from '@/lib/graphql/tracker/TrackerQuery.ts'; import { createUpdateCategoryMetadata, useGetCategoryMetadata } from '@/features/category/services/CategoryMetadata.ts'; import { makeToast } from '@/base/utils/Toast.ts'; import { createUpdateMetadataServerSettings, updateMetadataServerSettings, useMetadataServerSettings, } from '@/features/settings/services/ServerSettingsMetadata.ts'; import type { LibrarySortMode } from '@/features/library/Library.types.ts'; import type { CategoryMetadataInfo } from '@/features/category/Category.types.ts'; import { MANGA_STATUS_TO_TRANSLATION } from '@/features/manga/Manga.constants.ts'; import { GridLayout } from '@/base/Base.types'; import { getErrorMessage } from '@/lib/HelperFunctions.ts'; const TITLES: { [key in 'filter' | 'sort' | 'display']: MessageDescriptor } = { filter: msg`Filter`, sort: msg`Sort`, display: msg`Display`, }; const SORT_OPTIONS: [LibrarySortMode, MessageDescriptor][] = [ ['unreadChapters', msg`Unread chapters`], ['totalChapters', msg`Total chapters`], ['alphabetically', msg`A-Z`], ['dateAdded', msg`Recently added`], ['lastRead', msg`Recently read`], ['latestFetchedChapter', msg`Latest fetched chapter`], ['latestUploadedChapter', msg`Latest uploaded chapter`], ]; export const LibraryOptionsPanel = ({ category, open, onClose, }: { category: CategoryMetadataInfo; open: boolean; onClose: () => void; }) => { const { t } = useLingui(); const trackerList = requestManager.useGetTrackerList(GET_TRACKERS_SETTINGS); const loggedInTrackers = Trackers.getLoggedIn(trackerList.data?.trackers.nodes ?? []); const categoryLibraryOptions = useGetCategoryMetadata(category); const updateCategoryLibraryOptions = createUpdateCategoryMetadata(category, (e) => makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)), ); const { settings: { showTabSize, showContinueReadingButton, showDownloadBadge, showUnreadBadge, gridLayout }, } = useMetadataServerSettings(); const setSettingValue = createUpdateMetadataServerSettings((e) => makeToast(t`Could not save the default search settings to the server`, 'error', getErrorMessage(e)), ); return ( open={open} onClose={onClose} tabs={['filter', 'sort', 'display']} tabTitle={(key) => t(TITLES[key])} tabContent={(key) => { if (key === 'filter') { return ( <> updateCategoryLibraryOptions('hasUnreadChapters', c)} /> updateCategoryLibraryOptions('hasReadChapters', c)} /> updateCategoryLibraryOptions('hasDownloadedChapters', c)} /> updateCategoryLibraryOptions('hasBookmarkedChapters', c)} /> updateCategoryLibraryOptions('hasDuplicateChapters', c)} /> {t`Status`} {Object.values(MangaStatus).map((status) => ( updateCategoryLibraryOptions('hasStatus', { ...categoryLibraryOptions.hasStatus, [status]: checked, }) } /> ))} {t`Tracked`} {loggedInTrackers.map((tracker) => ( updateCategoryLibraryOptions('hasTrackerBinding', { ...categoryLibraryOptions.hasTrackerBinding, [tracker.id]: checked, }) } /> ))} ); } if (key === 'sort') { return SORT_OPTIONS.map(([mode, label]) => ( mode !== categoryLibraryOptions.sortBy ? updateCategoryLibraryOptions('sortBy', mode) : updateCategoryLibraryOptions('sortDesc', !categoryLibraryOptions.sortDesc) } /> )); } if (key === 'display') { return ( <> {t`Display mode`} updateMetadataServerSettings('gridLayout', Number(e.target.value))} value={gridLayout} > {t`Badges`} updateMetadataServerSettings('showUnreadBadge', !showUnreadBadge)} /> updateMetadataServerSettings('showDownloadBadge', !showDownloadBadge)} /> {t`Tabs`} setSettingValue('showTabSize', !showTabSize)} /> {t`Other`} updateMetadataServerSettings( 'showContinueReadingButton', !showContinueReadingButton, ) } /> ); } return null; }} /> ); };