From 8130de23ff376ff7f81f9fde20335c51b9a81fa9 Mon Sep 17 00:00:00 2001 From: Alexey Kunitsky Date: Sat, 11 Nov 2023 20:44:44 +0100 Subject: [PATCH 1/2] feat: support auto theme change according to system --- .../src/components/Preferences/Theme/index.js | 18 +++++++++++++++++- .../bruno-app/src/providers/Theme/index.js | 12 +++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/bruno-app/src/components/Preferences/Theme/index.js b/packages/bruno-app/src/components/Preferences/Theme/index.js index 8f0719f98..7e9a2a100 100644 --- a/packages/bruno-app/src/components/Preferences/Theme/index.js +++ b/packages/bruno-app/src/components/Preferences/Theme/index.js @@ -13,7 +13,7 @@ const Theme = () => { theme: storedTheme }, validationSchema: Yup.object({ - theme: Yup.string().oneOf(['light', 'dark']).required('theme is required') + theme: Yup.string().oneOf(['light', 'dark', 'system']).required('theme is required') }), onSubmit: (values) => { setStoredTheme(values.theme); @@ -55,6 +55,22 @@ const Theme = () => { + + { + formik.handleChange(e); + formik.handleSubmit(); + }} + value="system" + checked={formik.values.theme === 'system'} + /> + diff --git a/packages/bruno-app/src/providers/Theme/index.js b/packages/bruno-app/src/providers/Theme/index.js index b2d475e05..1a639c464 100644 --- a/packages/bruno-app/src/providers/Theme/index.js +++ b/packages/bruno-app/src/providers/Theme/index.js @@ -1,15 +1,21 @@ import themes from 'themes/index'; import useLocalStorage from 'hooks/useLocalStorage/index'; -import { createContext, useContext } from 'react'; +import { createContext, useContext, useState } from 'react'; import { ThemeProvider as SCThemeProvider } from 'styled-components'; export const ThemeContext = createContext(); export const ThemeProvider = (props) => { const isBrowserThemeLight = window.matchMedia('(prefers-color-scheme: light)').matches; - const [storedTheme, setStoredTheme] = useLocalStorage('bruno.theme', isBrowserThemeLight ? 'light' : 'dark'); + const [displayedTheme, setDisplayedTheme] = useState(isBrowserThemeLight ? 'light' : 'dark'); + const [storedTheme, setStoredTheme] = useLocalStorage('bruno.theme', 'system'); - const theme = themes[storedTheme]; + window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => { + if (storedTheme !== 'system') return; + setDisplayedTheme(e.matches ? 'light' : 'dark'); + }); + + const theme = storedTheme === 'system' ? themes[displayedTheme] : themes[storedTheme]; const themeOptions = Object.keys(themes); const value = { theme, From 1ee6b5f974c498f40f2ce90f98a4776951100746 Mon Sep 17 00:00:00 2001 From: Alexey Kunitsky Date: Tue, 14 Nov 2023 11:00:44 +0100 Subject: [PATCH 2/2] fix: wrap watcher into useEffect --- packages/bruno-app/src/providers/Theme/index.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/bruno-app/src/providers/Theme/index.js b/packages/bruno-app/src/providers/Theme/index.js index 1a639c464..724ef4fa6 100644 --- a/packages/bruno-app/src/providers/Theme/index.js +++ b/packages/bruno-app/src/providers/Theme/index.js @@ -1,7 +1,7 @@ import themes from 'themes/index'; import useLocalStorage from 'hooks/useLocalStorage/index'; -import { createContext, useContext, useState } from 'react'; +import { createContext, useContext, useEffect, useState } from 'react'; import { ThemeProvider as SCThemeProvider } from 'styled-components'; export const ThemeContext = createContext(); @@ -10,10 +10,12 @@ export const ThemeProvider = (props) => { const [displayedTheme, setDisplayedTheme] = useState(isBrowserThemeLight ? 'light' : 'dark'); const [storedTheme, setStoredTheme] = useLocalStorage('bruno.theme', 'system'); - window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => { - if (storedTheme !== 'system') return; - setDisplayedTheme(e.matches ? 'light' : 'dark'); - }); + useEffect(() => { + window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => { + if (storedTheme !== 'system') return; + setDisplayedTheme(e.matches ? 'light' : 'dark'); + }); + }, []); const theme = storedTheme === 'system' ? themes[displayedTheme] : themes[storedTheme]; const themeOptions = Object.keys(themes);