Introduce dark theme
Summary: Adds support for switching dark mode on the fly. Also added the option to apply certain settings without restarting Flipper, as that isn't needed in all cases. Reviewed By: cekkaewnumchai Differential Revision: D23625854 fbshipit-source-id: 82175ba10524daf1b48a65feec8c610460df9418
This commit is contained in:
committed by
Facebook GitHub Bot
parent
908a8bab1e
commit
2d2a8bd675
@@ -81,6 +81,13 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
applyChangesWithoutRestart = async () => {
|
||||||
|
this.props.updateSettings(this.state.updatedSettings);
|
||||||
|
this.props.updateLauncherSettings(this.state.updatedLauncherSettings);
|
||||||
|
await flush();
|
||||||
|
this.props.onHide();
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
enableAndroid,
|
enableAndroid,
|
||||||
@@ -90,8 +97,14 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
enablePrefetching,
|
enablePrefetching,
|
||||||
idbPath,
|
idbPath,
|
||||||
reactNative,
|
reactNative,
|
||||||
|
enableSandy,
|
||||||
|
darkMode,
|
||||||
} = this.state.updatedSettings;
|
} = this.state.updatedSettings;
|
||||||
|
|
||||||
|
const settingsPristine =
|
||||||
|
isEqual(this.props.settings, this.state.updatedSettings) &&
|
||||||
|
isEqual(this.props.launcherSettings, this.state.updatedLauncherSettings);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Title>Settings</Title>
|
<Title>Settings</Title>
|
||||||
@@ -195,6 +208,20 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{enableSandy && (
|
||||||
|
<ToggledSection
|
||||||
|
label="Enable dark theme"
|
||||||
|
toggled={darkMode}
|
||||||
|
onChange={(enabled) => {
|
||||||
|
this.setState((prevState) => ({
|
||||||
|
updatedSettings: {
|
||||||
|
...prevState.updatedSettings,
|
||||||
|
darkMode: enabled,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<ToggledSection
|
<ToggledSection
|
||||||
label="React Native keyboard shortcuts"
|
label="React Native keyboard shortcuts"
|
||||||
toggled={reactNative.shortcuts.enabled}
|
toggled={reactNative.shortcuts.enabled}
|
||||||
@@ -256,13 +283,14 @@ class SettingsSheet extends Component<Props, State> {
|
|||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
disabled={
|
disabled={settingsPristine}
|
||||||
isEqual(this.props.settings, this.state.updatedSettings) &&
|
compact
|
||||||
isEqual(
|
padded
|
||||||
this.props.launcherSettings,
|
onClick={this.applyChangesWithoutRestart}>
|
||||||
this.state.updatedLauncherSettings,
|
Apply
|
||||||
)
|
</Button>
|
||||||
}
|
<Button
|
||||||
|
disabled={settingsPristine}
|
||||||
type="primary"
|
type="primary"
|
||||||
compact
|
compact
|
||||||
padded
|
padded
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import QuickPerformanceLogger, {FLIPPER_QPL_EVENTS} from './fb-stubs/QPL';
|
|||||||
import {PopoverProvider} from './ui/components/PopoverProvider';
|
import {PopoverProvider} from './ui/components/PopoverProvider';
|
||||||
import {initializeFlipperLibImplementation} from './utils/flipperLibImplementation';
|
import {initializeFlipperLibImplementation} from './utils/flipperLibImplementation';
|
||||||
import {enableConsoleHook} from './chrome/ConsoleLogs';
|
import {enableConsoleHook} from './chrome/ConsoleLogs';
|
||||||
|
import {sideEffect} from './utils/sideEffect';
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development' && os.platform() === 'darwin') {
|
if (process.env.NODE_ENV === 'development' && os.platform() === 'darwin') {
|
||||||
// By default Node.JS has its internal certificate storage and doesn't use
|
// By default Node.JS has its internal certificate storage and doesn't use
|
||||||
@@ -96,6 +97,23 @@ function init() {
|
|||||||
registerRecordingHooks(store);
|
registerRecordingHooks(store);
|
||||||
enableConsoleHook();
|
enableConsoleHook();
|
||||||
window.flipperGlobalStoreDispatch = store.dispatch;
|
window.flipperGlobalStoreDispatch = store.dispatch;
|
||||||
|
|
||||||
|
// listen to settings and load the right theme
|
||||||
|
sideEffect(
|
||||||
|
store,
|
||||||
|
{name: 'loadTheme', fireImmediately: true, throttleMs: 500},
|
||||||
|
(state) =>
|
||||||
|
state.settingsState.enableSandy
|
||||||
|
? state.settingsState.darkMode
|
||||||
|
? 'themes/dark'
|
||||||
|
: 'themes/light'
|
||||||
|
: 'none',
|
||||||
|
(theme) => {
|
||||||
|
(document.getElementById(
|
||||||
|
'flipper-theme-import',
|
||||||
|
) as HTMLLinkElement).href = `${theme}.css`;
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rehydrate app state before exposing init
|
// rehydrate app state before exposing init
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export type Settings = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
enableSandy: boolean;
|
enableSandy: boolean;
|
||||||
|
darkMode: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Action =
|
export type Action =
|
||||||
@@ -77,6 +78,7 @@ const initialState: Settings = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
enableSandy: false,
|
enableSandy: false,
|
||||||
|
darkMode: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function reducer(
|
export default function reducer(
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {createStore} from 'redux';
|
import {createStore} from 'redux';
|
||||||
import reducers, {Actions, State as StoreState} from './reducers/index';
|
import reducers, {Actions, State as StoreState, Store} from './reducers/index';
|
||||||
import {stateSanitizer} from './utils/reduxDevToolsConfig';
|
import {stateSanitizer} from './utils/reduxDevToolsConfig';
|
||||||
import isProduction from './utils/isProduction';
|
import isProduction from './utils/isProduction';
|
||||||
import produce from 'immer';
|
import produce from 'immer';
|
||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
getPluginKey,
|
getPluginKey,
|
||||||
} from './utils/pluginUtils';
|
} from './utils/pluginUtils';
|
||||||
|
|
||||||
export const store = createStore<StoreState, Actions, any, any>(
|
export const store: Store = createStore<StoreState, Actions, any, any>(
|
||||||
rootReducer,
|
rootReducer,
|
||||||
// @ts-ignore Type definition mismatch
|
// @ts-ignore Type definition mismatch
|
||||||
window.__REDUX_DEVTOOLS_EXTENSION__
|
window.__REDUX_DEVTOOLS_EXTENSION__
|
||||||
|
|||||||
@@ -243,7 +243,7 @@
|
|||||||
"build:babel-transformer": "cd babel-transformer && yarn build",
|
"build:babel-transformer": "cd babel-transformer && yarn build",
|
||||||
"build:pkg": "cd pkg && yarn build",
|
"build:pkg": "cd pkg && yarn build",
|
||||||
"build:eslint": "cd eslint-plugin-flipper && yarn build",
|
"build:eslint": "cd eslint-plugin-flipper && yarn build",
|
||||||
"build:themes": "lessc --js themes/light.less static/themes/light.css",
|
"build:themes": "lessc --js themes/light.less static/themes/light.css && lessc --js themes/dark.less static/themes/dark.css",
|
||||||
"prebuild": "yarn build:pkg && yarn rm-dist && yarn build:themes",
|
"prebuild": "yarn build:pkg && yarn rm-dist && yarn build:themes",
|
||||||
"build": "cross-env NODE_ENV=production ./ts-node scripts/build-release.ts $@",
|
"build": "cross-env NODE_ENV=production ./ts-node scripts/build-release.ts $@",
|
||||||
"build:dev": "cross-env NODE_ENV=development ./ts-node scripts/build-release.ts $@",
|
"build:dev": "cross-env NODE_ENV=development ./ts-node scripts/build-release.ts $@",
|
||||||
|
|||||||
12
desktop/static/empy.css
Normal file
12
desktop/static/empy.css
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
used as theme in case Sandy is not enabled
|
||||||
|
*/
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<link id="flipper-theme-import" rel="stylesheet" href="themes/light.css">
|
<link id="flipper-theme-import" rel="stylesheet" href="empty.css">
|
||||||
<link rel="stylesheet" href="graphiql/graphiql.css">
|
<link rel="stylesheet" href="graphiql/graphiql.css">
|
||||||
<link rel="stylesheet" href="vis/vis.min.css">
|
<link rel="stylesheet" href="vis/vis.min.css">
|
||||||
<title>Flipper</title>
|
<title>Flipper</title>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<link id="flipper-theme-import" rel="stylesheet" href="themes/light.css">
|
<link id="flipper-theme-import" rel="stylesheet" href="empty.css">
|
||||||
<link rel="stylesheet" href="graphiql/graphiql.css">
|
<link rel="stylesheet" href="graphiql/graphiql.css">
|
||||||
<link rel="stylesheet" href="vis/vis.min.css">
|
<link rel="stylesheet" href="vis/vis.min.css">
|
||||||
<title>Flipper</title>
|
<title>Flipper</title>
|
||||||
|
|||||||
4
desktop/themes/dark.less
Normal file
4
desktop/themes/dark.less
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
@import '../node_modules/antd/lib/style/themes/dark.less';
|
||||||
|
@import '../node_modules/antd/dist/antd.less';
|
||||||
|
|
||||||
|
@primary-color: yellow;
|
||||||
Reference in New Issue
Block a user