From 1444d51ed2f58f075860fecdeb2d3582ae7b8bb2 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Thu, 5 Sep 2024 00:08:23 +0200 Subject: [PATCH] Add pure black mode option --- public/locales/en.json | 5 +++-- src/components/context/AppContext.tsx | 9 ++++++--- src/components/context/ThemeModeContext.tsx | 4 ++++ src/lib/ui/MediaQuery.tsx | 12 ++++++++++++ src/screens/settings/Appearance.tsx | 11 ++++++++++- src/theme.ts | 3 ++- 6 files changed, 37 insertions(+), 7 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index 0cf522af..808f70e0 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -818,6 +818,7 @@ }, "appearance": { "device_theme": "Device theme", + "pure_black_mode": "Pure black dark mode", "theme": "Theme", "title": "Appearance" }, @@ -914,12 +915,12 @@ } }, "label": { - "theme": "Theme", "hide_library_entries": "Hide entries already in library", "language_description": "Feel free to translate the project on", "manga_item_width": "Manga item width", "show_nsfw": "Show NSFW", - "show_nsfw_description": "Hide NSFW extensions and sources" + "show_nsfw_description": "Hide NSFW extensions and sources", + "theme": "Theme" }, "server": { "address": { diff --git a/src/components/context/AppContext.tsx b/src/components/context/AppContext.tsx index 92b5c11f..c387d3de 100644 --- a/src/components/context/AppContext.tsx +++ b/src/components/context/AppContext.tsx @@ -57,14 +57,17 @@ export const AppContext: React.FC = ({ children }) => { }, []); const [themeMode, setThemeMode] = useLocalStorage('themeMode', ThemeMode.SYSTEM); + const [pureBlackMode, setPureBlackMode] = useLocalStorage('pureBlackMode', false); const [activeDevice, setActiveDeviceContext] = useLocalStorage('activeDevice', DEFAULT_DEVICE); const darkThemeContext = useMemo( () => ({ themeMode, setThemeMode, + pureBlackMode, + setPureBlackMode, }), - [themeMode], + [themeMode, pureBlackMode], ); const activeDeviceContext = useMemo( @@ -73,8 +76,8 @@ export const AppContext: React.FC = ({ children }) => { ); const theme = useMemo( - () => createTheme(themeMode, currentDirection), - [themeMode, currentDirection, systemThemeMode], + () => createTheme(themeMode, currentDirection, undefined, pureBlackMode), + [themeMode, currentDirection, systemThemeMode, pureBlackMode], ); setActiveDevice(activeDevice); diff --git a/src/components/context/ThemeModeContext.tsx b/src/components/context/ThemeModeContext.tsx index 6f623f37..bf3bec20 100644 --- a/src/components/context/ThemeModeContext.tsx +++ b/src/components/context/ThemeModeContext.tsx @@ -17,9 +17,13 @@ export enum ThemeMode { type ContextType = { themeMode: ThemeMode; setThemeMode: React.Dispatch>; + pureBlackMode: boolean; + setPureBlackMode: React.Dispatch>; }; export const ThemeModeContext = React.createContext({ themeMode: ThemeMode.SYSTEM, setThemeMode: (): void => {}, + pureBlackMode: false, + setPureBlackMode: (): void => {}, }); diff --git a/src/lib/ui/MediaQuery.tsx b/src/lib/ui/MediaQuery.tsx index 3bf382f1..cd197bd0 100644 --- a/src/lib/ui/MediaQuery.tsx +++ b/src/lib/ui/MediaQuery.tsx @@ -10,6 +10,7 @@ import useMediaQuery from '@mui/material/useMediaQuery'; import { Breakpoint } from '@mui/material/styles'; import { getCurrentTheme } from '@/theme.ts'; import { ThemeMode } from '@/components/context/ThemeModeContext.tsx'; +import { AppStorage } from '@/util/AppStorage.ts'; export class MediaQuery { static useIsTouchDevice(): boolean { @@ -29,6 +30,17 @@ export class MediaQuery { return prefersDarkMode ? ThemeMode.DARK : ThemeMode.LIGHT; } + static getThemeMode(): Exclude { + const themeMode = AppStorage.local.getItemParsed('themeMode', ThemeMode.SYSTEM); + + const isSystemMode = themeMode === ThemeMode.SYSTEM; + if (isSystemMode) { + return this.getSystemThemeMode(); + } + + return themeMode; + } + static listenToSystemThemeChange(onChange: (themeMode: Exclude) => void): () => void { const handleSystemThemeModeChange = (e: MediaQueryListEvent) => { onChange(e.matches ? ThemeMode.DARK : ThemeMode.LIGHT); diff --git a/src/screens/settings/Appearance.tsx b/src/screens/settings/Appearance.tsx index 2de111f0..e637ffbc 100644 --- a/src/screens/settings/Appearance.tsx +++ b/src/screens/settings/Appearance.tsx @@ -13,13 +13,16 @@ 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 { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { ThemeMode, ThemeModeContext } from '@/components/context/ThemeModeContext.tsx'; import { Select } from '@/components/atoms/Select.tsx'; +import { MediaQuery } from '@/lib/ui/MediaQuery.tsx'; export const Appearance = () => { const { t } = useTranslation(); - const { themeMode, setThemeMode } = useContext(ThemeModeContext); + const { themeMode, setThemeMode, pureBlackMode, setPureBlackMode } = useContext(ThemeModeContext); + const isDarkMode = MediaQuery.getThemeMode() === ThemeMode.DARK; const { setTitle, setAction } = useContext(NavBarContext); useEffect(() => { @@ -54,6 +57,12 @@ export const Appearance = () => { + {isDarkMode && ( + + + setPureBlackMode(enabled)} /> + + )} ); }; diff --git a/src/theme.ts b/src/theme.ts index 19be1ea5..0f49bd35 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -31,6 +31,7 @@ export const createTheme = ( const systemMode = MediaQuery.getSystemThemeMode(); const mode = themeMode === ThemeMode.SYSTEM ? systemMode : themeMode; const isDarkMode = mode === ThemeMode.DARK; + const setPureBlackMode = isDarkMode && pureBlackMode; const baseTheme = createMuiTheme({ direction, @@ -55,7 +56,7 @@ export const createTheme = ( default: lighten(baseTheme.palette.primary.dark, 0.85), }; const backgroundThemeMode = isDarkMode ? backgroundDark : backgroundLight; - const background = pureBlackMode ? backgroundTrueBlack : backgroundThemeMode; + const background = setPureBlackMode ? backgroundTrueBlack : backgroundThemeMode; const colorTheme = createMuiTheme(baseTheme, { palette: {