feat: switch color theme based on operating system preferences
This commit is contained in:
1 parent
d2c5d6211c
commit
5b6903c7f0
2 files changed
+66
-1
No files matched your search
@@ -36,6 +36,7 @@ import storage from '../lib/storage';
|
||||
import vmListenerHOC from '../lib/vm-listener-hoc.jsx';
|
||||
import vmManagerHOC from '../lib/vm-manager-hoc.jsx';
|
||||
import cloudManagerHOC from '../lib/cloud-manager-hoc.jsx';
|
||||
import systemPreferencesHOC from '../lib/system-preferences-hoc.jsx';
|
||||
|
||||
import GUIComponent from '../components/gui/gui.jsx';
|
||||
import {setIsScratchDesktop} from '../lib/isScratchDesktop.js';
|
||||
@@ -183,7 +184,8 @@ const WrappedGui = compose(
|
||||
vmListenerHOC,
|
||||
vmManagerHOC,
|
||||
SBFileUploaderHOC,
|
||||
cloudManagerHOC
|
||||
cloudManagerHOC,
|
||||
systemPreferencesHOC
|
||||
)(ConnectedGUI);
|
||||
|
||||
WrappedGui.setAppElement = ReactModal.setAppElement;
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {connect} from 'react-redux';
|
||||
import {DEFAULT_THEME} from './themes';
|
||||
import {setTheme} from '../reducers/theme';
|
||||
|
||||
const prefersDarkQuery = '(prefers-color-scheme: dark)';
|
||||
const prefersHighContrastQuery = '(prefers-contrast: more)';
|
||||
|
||||
const getTheme = () => {
|
||||
const highContrast = window.matchMedia(prefersHighContrastQuery).matches;
|
||||
|
||||
if (highContrast) return 'high-contrast';
|
||||
|
||||
const dark = window.matchMedia(prefersDarkQuery).matches;
|
||||
|
||||
if (dark) return 'dark-mode';
|
||||
|
||||
return DEFAULT_THEME;
|
||||
};
|
||||
|
||||
const systemPreferencesHOC = function (WrappedComponent) {
|
||||
class SystemPreferences extends React.Component {
|
||||
componentDidMount () {
|
||||
this.props.onSetTheme(getTheme());
|
||||
this.preferencesListener = () => this.props.onSetTheme(getTheme());
|
||||
this.highContrastMatchMedia = window.matchMedia(prefersHighContrastQuery);
|
||||
this.highContrastMatchMedia.addEventListener('change', this.preferencesListener);
|
||||
this.darkMatchMedia = window.matchMedia(prefersDarkQuery);
|
||||
this.darkMatchMedia.addEventListener('change', this.preferencesListener);
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.highContrastMatchMedia.removeEventListener('change', this.preferencesListener);
|
||||
this.darkMatchMedia.removeEventListener('change', this.preferencesListener);
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
/* eslint-disable no-unused-vars */
|
||||
onSetTheme,
|
||||
/* eslint-enable no-unused-vars */
|
||||
...props
|
||||
} = this.props;
|
||||
return <WrappedComponent {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
SystemPreferences.propTypes = {
|
||||
onSetTheme: PropTypes.func
|
||||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onSetTheme: theme => dispatch(setTheme(theme))
|
||||
});
|
||||
|
||||
return connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(SystemPreferences);
|
||||
};
|
||||
|
||||
export default systemPreferencesHOC;
|
||||
Reference in new issue
Block a user