From 9a4d94c971d0719efa520f3d82abdb4d23e3b558 Mon Sep 17 00:00:00 2001 From: ZHANG Qichuan Date: Wed, 8 Sep 2021 03:27:36 -0700 Subject: [PATCH] Add option for automatic dark theme (#2759) Summary: Add an setting option to allow automatic dark theme A feature requested by swrobel https://github.com/facebook/flipper/issues/2708 ## Changelog ### UI change Replace the `Enable Dark Theme` Toggle button with a Radio group containing three Radio buttons. The available options are `Dark`, `Light` and `Use System Default`, of which `Use System Default` is the default value Screenshot 2021-08-31 at 3 32 44 PM ### Data structure change The `darkMode` property of [Settings](https://github.com/facebook/flipper/blob/c0cd32564ad4b07a42365af886045095877a6a6b/desktop/app/src/reducers/settings.tsx#L20) is changed from `boolean` to `string`, the available values are `dark`, `light` and `auto` Pull Request resolved: https://github.com/facebook/flipper/pull/2759 Test Plan: ### Test 1 - Step: Choose `Dark` in the Settings page and click on `Apply and Restart` button - Expect: The application is displayed in Dark mode ### Test 2 - Step: Choose `Light` in the Settings page and click on `Apply and Restart` button - Expect: The application is displayed in Light mode ### Test 3 - Step: Choose `Use System Default` in the Settings page and click on `Apply and Restart` button - Expect: The application is displayed in System Default mode Reviewed By: mweststrate Differential Revision: D30666966 Pulled By: passy fbshipit-source-id: a63e91f2d0dbff96890e267062cb75bffd0007f4 --- desktop/app/src/chrome/SettingsSheet.tsx | 32 ++++++++++++++---------- desktop/app/src/init.tsx | 26 +++++++++++++------ desktop/app/src/reducers/settings.tsx | 4 +-- desktop/app/src/utils/useIsDarkMode.tsx | 13 +++++++++- desktop/static/main.ts | 8 +++--- desktop/static/setup.ts | 3 ++- 6 files changed, 57 insertions(+), 29 deletions(-) diff --git a/desktop/app/src/chrome/SettingsSheet.tsx b/desktop/app/src/chrome/SettingsSheet.tsx index 8a1f75717..9987624c4 100644 --- a/desktop/app/src/chrome/SettingsSheet.tsx +++ b/desktop/app/src/chrome/SettingsSheet.tsx @@ -7,8 +7,9 @@ * @format */ -import {Button} from '../ui'; +import {Button, FlexColumn} from '../ui'; import React, {Component, useContext} from 'react'; +import {Radio} from 'antd'; import {updateSettings, Action} from '../reducers/settings'; import { Action as LauncherAction, @@ -245,18 +246,23 @@ class SettingsSheet extends Component { })); }} /> - { - this.setState((prevState) => ({ - updatedSettings: { - ...prevState.updatedSettings, - darkMode: enabled, - }, - })); - }} - /> + + Theme Selection + { + this.setState((prevState) => ({ + updatedSettings: { + ...prevState.updatedSettings, + darkMode: event.target.value, + }, + })); + }}> + Dark + Light + Use System Setting + + ({ - dark: state.settingsState.darkMode, - }), - (theme) => { + (state) => { + const theme = state.settingsState.darkMode; + let shouldUseDarkMode = remote.nativeTheme.shouldUseDarkColors; + if (theme === 'dark') { + shouldUseDarkMode = true; + } else if (theme === 'light') { + shouldUseDarkMode = false; + } else if (theme === 'system') { + shouldUseDarkMode = remote.nativeTheme.shouldUseDarkColors; + } + return { + shouldUseDarkMode: shouldUseDarkMode, + theme: theme, + }; + }, + (result) => { ( document.getElementById('flipper-theme-import') as HTMLLinkElement - ).href = `themes/${theme.dark ? 'dark' : 'light'}.css`; - ipcRenderer.send('setTheme', theme.dark ? 'dark' : 'light'); + ).href = `themes/${result.shouldUseDarkMode ? 'dark' : 'light'}.css`; + ipcRenderer.send('setTheme', result.theme); }, ); } diff --git a/desktop/app/src/reducers/settings.tsx b/desktop/app/src/reducers/settings.tsx index af816ab52..56e3e316b 100644 --- a/desktop/app/src/reducers/settings.tsx +++ b/desktop/app/src/reducers/settings.tsx @@ -43,7 +43,7 @@ export type Settings = { openDevMenu: string; }; }; - darkMode: boolean; + darkMode: string; showWelcomeAtStartup: boolean; suppressPluginErrors: boolean; }; @@ -78,7 +78,7 @@ const initialState: Settings = { openDevMenu: 'Alt+Shift+D', }, }, - darkMode: false, + darkMode: 'auto', showWelcomeAtStartup: true, suppressPluginErrors: false, }; diff --git a/desktop/app/src/utils/useIsDarkMode.tsx b/desktop/app/src/utils/useIsDarkMode.tsx index 82eeddee5..220d2b93b 100644 --- a/desktop/app/src/utils/useIsDarkMode.tsx +++ b/desktop/app/src/utils/useIsDarkMode.tsx @@ -8,6 +8,7 @@ */ import {useStore} from './useStore'; +import {remote} from 'electron'; /** * This hook returns whether dark mode is currently being used. @@ -15,5 +16,15 @@ import {useStore} from './useStore'; * which will provide colors that reflect the theme */ export function useIsDarkMode(): boolean { - return useStore((state) => state.settingsState.darkMode); + return useStore((state) => { + const darkMode = state.settingsState.darkMode; + if (darkMode === 'dark') { + return true; + } else if (darkMode === 'light') { + return false; + } else if (darkMode === 'system') { + return remote.nativeTheme.shouldUseDarkColors; + } + return false; + }); } diff --git a/desktop/static/main.ts b/desktop/static/main.ts index cbd840b98..f549f8299 100644 --- a/desktop/static/main.ts +++ b/desktop/static/main.ts @@ -109,9 +109,7 @@ if (argv['disable-gpu'] || process.env.FLIPPER_DISABLE_GPU === '1') { } process.env.CONFIG = JSON.stringify(config); -if (config.darkMode) { - nativeTheme.themeSource = 'dark'; -} +nativeTheme.themeSource = config.darkMode || 'light'; // possible reference to main app window let win: BrowserWindow; @@ -290,7 +288,7 @@ ipcMain.on('getLaunchTime', (event) => { } }); -ipcMain.on('setTheme', (_e, mode: 'light' | 'dark') => { +ipcMain.on('setTheme', (_e, mode: 'light' | 'dark' | 'system') => { nativeTheme.themeSource = mode; }); @@ -382,7 +380,7 @@ function createWindow() { configPath, JSON.stringify({ ...config, - darkMode: nativeTheme.themeSource === 'dark', + darkMode: nativeTheme.themeSource, lastWindowPosition: { x, y, diff --git a/desktop/static/setup.ts b/desktop/static/setup.ts index 987390527..e41d0cb0b 100644 --- a/desktop/static/setup.ts +++ b/desktop/static/setup.ts @@ -24,7 +24,7 @@ export type Config = { launcherMsg?: string | undefined; updaterEnabled?: boolean; launcherEnabled?: boolean; - darkMode?: boolean; + darkMode: 'system' | 'light' | 'dark'; }; export default function setup(argv: any) { @@ -38,6 +38,7 @@ export default function setup(argv: any) { let config: Config = { pluginPaths: [], disabledPlugins: [], + darkMode: 'light', }; try {