diff --git a/public/locales/en.json b/public/locales/en.json index fb5fcdae..4f80c5d6 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -520,6 +520,9 @@ "no_history_available": "You have not read any series yet." } }, + "settings": { + "hide": "Hide history" + }, "title": "History" }, "hotkeys": { diff --git a/src/App.tsx b/src/App.tsx index 9b8487f3..b8a21cb1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -23,6 +23,8 @@ import { ErrorBoundary } from '@/modules/core/components/ErrorBoundary.tsx'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; import { Reader } from '@/modules/reader/screens/Reader.tsx'; import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; +import { HistorySettings } from '@/modules/history/screens/HistorySettings.tsx'; +import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts'; const { Browse } = loadable(() => import('@/modules/browse/screens/Browse.tsx'), lazyLoadFallback); const { DownloadQueue } = loadable(() => import('@/modules/downloads/screens/DownloadQueue.tsx'), lazyLoadFallback); @@ -101,6 +103,10 @@ const BackgroundSubscriptions = () => { const MainApp = () => { const { navBarWidth, appBarHeight, bottomBarHeight } = useNavBarContext(); + const { + settings: { hideHistory }, + } = useMetadataServerSettings(); + return ( { } /> } /> } /> + } /> } /> } /> } /> @@ -159,7 +166,7 @@ const MainApp = () => { } /> } /> - } /> + {!hideHistory && } />} } /> } /> diff --git a/src/modules/core/AppRoute.constants.ts b/src/modules/core/AppRoute.constants.ts index 5767d8b1..d1bb15fd 100644 --- a/src/modules/core/AppRoute.constants.ts +++ b/src/modules/core/AppRoute.constants.ts @@ -84,6 +84,10 @@ export const AppRoutes = { match: 'appearance', path: '/settings/appearance', }, + history: { + match: 'history', + path: '/settings/history', + }, }, }, sources: { diff --git a/src/modules/history/History.types.ts b/src/modules/history/History.types.ts new file mode 100644 index 00000000..58011f5b --- /dev/null +++ b/src/modules/history/History.types.ts @@ -0,0 +1,11 @@ +/* + * 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/. + */ + +export type MetadataHistorySettings = { + hideHistory: boolean; +}; diff --git a/src/modules/history/screens/HistorySettings.tsx b/src/modules/history/screens/HistorySettings.tsx new file mode 100644 index 00000000..b9276c50 --- /dev/null +++ b/src/modules/history/screens/HistorySettings.tsx @@ -0,0 +1,70 @@ +/* + * 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 ListItemText from '@mui/material/ListItemText'; +import Switch from '@mui/material/Switch'; +import { + createUpdateMetadataServerSettings, + useMetadataServerSettings, +} from '@/modules/settings/services/ServerSettingsMetadata.ts'; +import { LoadingPlaceholder } from '@/modules/core/components/placeholder/LoadingPlaceholder.tsx'; +import { EmptyViewAbsoluteCentered } from '@/modules/core/components/placeholder/EmptyViewAbsoluteCentered.tsx'; +import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'; +import { makeToast } from '@/modules/core/utils/Toast.ts'; +import { getErrorMessage } from '@/lib/HelperFunctions.ts'; +import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; +import { MetadataHistorySettings } from '@/modules/history/History.types.ts'; + +export const HistorySettings = () => { + const { t } = useTranslation(); + const { setTitle, setAction } = useNavBarContext(); + + useLayoutEffect(() => { + setTitle(t('history.title')); + setAction(null); + }, [t]); + + const { + settings: { hideHistory }, + request: { loading, error, refetch }, + } = useMetadataServerSettings(); + const updateMetadataServerSettings = createUpdateMetadataServerSettings((e) => + makeToast(t('global.error.label.failed_to_save_changes'), 'error', getErrorMessage(e)), + ); + + if (loading) { + return ; + } + + if (error) { + return ( + refetch().catch(defaultPromiseErrorHandler('HistorySettings::refetch'))} + /> + ); + } + + return ( + + + + updateMetadataServerSettings('hideHistory', !hideHistory)} + /> + + + ); +}; diff --git a/src/modules/navigation-bar/components/DefaultNavBar.tsx b/src/modules/navigation-bar/components/DefaultNavBar.tsx index 389e47df..610e09f9 100644 --- a/src/modules/navigation-bar/components/DefaultNavBar.tsx +++ b/src/modules/navigation-bar/components/DefaultNavBar.tsx @@ -37,6 +37,7 @@ import { MobileBottomBar } from '@/modules/navigation-bar/components/MobileBotto import { NavbarItem } from '@/modules/navigation-bar/NavigationBar.types.ts'; import { AppRoutes } from '@/modules/core/AppRoute.constants.ts'; import { useNavBarContext } from '@/modules/navigation-bar/contexts/NavbarContext.tsx'; +import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts'; const navbarItems: Array = [ { @@ -93,6 +94,10 @@ export function DefaultNavBar() { const handleBack = useBackButton(); const isMobileWidth = MediaQuery.useIsMobileWidth(); + const { + settings: { hideHistory }, + } = useMetadataServerSettings(); + const appBarRef = useRef(null); useResizeObserver( appBarRef, @@ -123,8 +128,15 @@ export function DefaultNavBar() { const activeNavBar: NavbarItem['show'] = isMobileWidth ? 'mobile' : 'desktop'; const visibleNavBarItems = useMemo( - () => navbarItems.filter(({ show }) => ['both', activeNavBar].includes(show)), - [isMobileWidth], + () => + navbarItems + .filter((item) => { + const isHistory = item.title === 'history.title'; + + return !isHistory || !hideHistory; + }) + .filter(({ show }) => ['both', activeNavBar].includes(show)), + [isMobileWidth, hideHistory], ); const NavBarComponent = useMemo(() => (isMobileWidth ? MobileBottomBar : DesktopSideBar), [isMobileWidth]); diff --git a/src/modules/settings/Settings.constants.ts b/src/modules/settings/Settings.constants.ts index 04c2572d..cb428d6e 100644 --- a/src/modules/settings/Settings.constants.ts +++ b/src/modules/settings/Settings.constants.ts @@ -41,6 +41,9 @@ export const SERVER_SETTINGS_METADATA_DEFAULT: MetadataServerSettings = { // browse hideLibraryEntries: false, + // history + hideHistory: false, + // tracking updateProgressAfterReading: true, updateProgressManualMarkRead: false, diff --git a/src/modules/settings/Settings.types.ts b/src/modules/settings/Settings.types.ts index 91570814..14a364c4 100644 --- a/src/modules/settings/Settings.types.ts +++ b/src/modules/settings/Settings.types.ts @@ -15,6 +15,7 @@ import { MetadataTrackingSettings } from '@/modules/tracker/Tracker.types.ts'; import { MetadataUpdateSettings } from '@/modules/app-updates/AppUpdateChecker.types.ts'; import { MetadataThemeSettings } from '@/modules/theme/AppTheme.types.ts'; import { GetServerSettingsQuery } from '@/lib/graphql/generated/graphql.ts'; +import { MetadataHistorySettings } from '@/modules/history/History.types.ts'; export type MetadataServerSettingKeys = keyof MetadataServerSettings; @@ -27,7 +28,8 @@ export type MetadataServerSettings = MetadataDownloadSettings & MetadataBrowseSettings & MetadataTrackingSettings & MetadataUpdateSettings & - MetadataThemeSettings; + MetadataThemeSettings & + MetadataHistorySettings; export interface ISearchSettings { ignoreFilters: boolean; diff --git a/src/modules/settings/screens/Settings.tsx b/src/modules/settings/screens/Settings.tsx index fe7d6b4a..a158109c 100644 --- a/src/modules/settings/screens/Settings.tsx +++ b/src/modules/settings/screens/Settings.tsx @@ -23,6 +23,7 @@ import ExploreOutlinedIcon from '@mui/icons-material/ExploreOutlined'; import DevicesIcon from '@mui/icons-material/Devices'; import SyncIcon from '@mui/icons-material/Sync'; import PaletteIcon from '@mui/icons-material/Palette'; +import HistoryIcon from '@mui/icons-material/History'; import { ListItemLink } from '@/modules/core/components/ListItemLink.tsx'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { makeToast } from '@/modules/core/utils/Toast.ts'; @@ -109,6 +110,12 @@ export function Settings() { + + + + + +