/* * 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 { useContext, useLayoutEffect } from 'react'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemText from '@mui/material/ListItemText'; import MenuItem from '@mui/material/MenuItem'; import ListSubheader from '@mui/material/ListSubheader'; import Switch from '@mui/material/Switch'; import Link from '@mui/material/Link'; import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { ThemeMode, ThemeModeContext } from '@/components/context/ThemeModeContext.tsx'; import { Select } from '@/modules/core/components/inputs/Select.tsx'; import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; import { NumberSetting } from '@/modules/core/components/settings/NumberSetting.tsx'; import { useLocalStorage } from '@/modules/core/hooks/useStorage.tsx'; import { I18nResourceCode, i18nResources } from '@/i18n'; import { langCodeToName } from '@/lib/Languages.tsx'; import { getTheme } from '@/lib/ui/AppThemes.ts'; import { ThemeList } from '@/screens/settings/appearance/theme/ThemeList.tsx'; import { createUpdateMetadataServerSettings, useMetadataServerSettings, } from '@/lib/metadata/metadataServerSettings.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 { MetadataThemeSettings } from '@/typings.ts'; import { makeToast } from '@/lib/ui/Toast.ts'; export const Appearance = () => { const { t, i18n } = useTranslation(); const { themeMode, setThemeMode, pureBlackMode, setPureBlackMode, appTheme } = useContext(ThemeModeContext); const { setTitle, setAction } = useContext(NavBarContext); useLayoutEffect(() => { setTitle(t('settings.appearance.title')); setAction(null); return () => { setTitle(''); setAction(null); }; }, [t]); const { settings, request: { loading, error, refetch }, } = useMetadataServerSettings(); const updateMetadataSetting = createUpdateMetadataServerSettings(() => makeToast(t('global.error.label.failed_to_save_changes'), 'error'), ); const isDarkMode = getTheme(appTheme).muiTheme.palette?.mode === 'dark' || MediaQuery.getThemeMode() === ThemeMode.DARK; const DEFAULT_ITEM_WIDTH = 300; const [itemWidth, setItemWidth] = useLocalStorage('ItemWidth', DEFAULT_ITEM_WIDTH); if (loading) { return ; } if (error) { return ( refetch().catch(defaultPromiseErrorHandler('Appearance::refetch'))} /> ); } return ( {t('settings.appearance.theme.title')} } > value={themeMode} onChange={(e) => setThemeMode(e.target.value as ThemeMode)}> System Dark Light {isDarkMode && ( setPureBlackMode(enabled)} /> )} {t('global.label.display')} } > {t('settings.label.language_description')} {t('global.language.title.weblate')} } /> updateMetadataSetting('mangaThumbnailBackdrop', e.target.checked)} /> ); };