1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 09:57:02 +01:00

Adding new settings dropdown for Dark mode in Experimental tab (#13097)

This commit is contained in:
Niranjana Binoy 2022-03-07 13:53:19 -05:00 committed by GitHub
parent 0e421ece8e
commit 4bb3ba4aef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 136 additions and 1 deletions

View File

@ -742,6 +742,9 @@
"message": "$1 has recommended this price.", "message": "$1 has recommended this price.",
"description": "$1 represents the Dapp's origin" "description": "$1 represents the Dapp's origin"
}, },
"darkTheme": {
"message": "Dark"
},
"data": { "data": {
"message": "Data" "message": "Data"
}, },
@ -777,6 +780,9 @@
"decryptRequest": { "decryptRequest": {
"message": "Decrypt request" "message": "Decrypt request"
}, },
"defaultTheme": {
"message": "Default"
},
"delete": { "delete": {
"message": "Delete" "message": "Delete"
}, },
@ -3439,6 +3445,12 @@
"testFaucet": { "testFaucet": {
"message": "Test Faucet" "message": "Test Faucet"
}, },
"theme": {
"message": "Theme"
},
"themeDescription": {
"message": "Choose your preferred MetaMask theme."
},
"thisWillCreate": { "thisWillCreate": {
"message": "This will create a new wallet and Secret Recovery Phrase" "message": "This will create a new wallet and Secret Recovery Phrase"
}, },

View File

@ -68,6 +68,7 @@ export default class PreferencesController {
ledgerTransportType: window.navigator.hid ledgerTransportType: window.navigator.hid
? LEDGER_TRANSPORT_TYPES.WEBHID ? LEDGER_TRANSPORT_TYPES.WEBHID
: LEDGER_TRANSPORT_TYPES.U2F, : LEDGER_TRANSPORT_TYPES.U2F,
theme: 'default',
...opts.initState, ...opts.initState,
}; };
@ -169,6 +170,15 @@ export default class PreferencesController {
this.store.updateState({ eip1559V2Enabled: val }); this.store.updateState({ eip1559V2Enabled: val });
} }
/**
* Setter for the `theme` property
*
* @param {string} val - 'default' or 'dark' value based on the mode selected by user.
*/
setTheme(val) {
this.store.updateState({ theme: val });
}
/** /**
* Add new methodData to state, to avoid requesting this information again through Infura * Add new methodData to state, to avoid requesting this information again through Infura
* *

View File

@ -351,4 +351,18 @@ describe('preferences controller', function () {
); );
}); });
}); });
describe('setTheme', function () {
it('should default to value "default"', function () {
const state = preferencesController.store.getState();
assert.equal(state.theme, 'default');
});
it('should set the setTheme property in state', function () {
const state = preferencesController.store.getState();
assert.equal(state.theme, 'default');
preferencesController.setTheme('dark');
assert.equal(preferencesController.store.getState().theme, 'dark');
});
});
}); });

View File

@ -1424,6 +1424,7 @@ export default class MetamaskController extends EventEmitter {
setEIP1559V2Enabled: preferencesController.setEIP1559V2Enabled.bind( setEIP1559V2Enabled: preferencesController.setEIP1559V2Enabled.bind(
preferencesController, preferencesController,
), ),
setTheme: preferencesController.setTheme.bind(preferencesController),
// AssetsContractController // AssetsContractController
getTokenStandardAndDetails: assetsContractController.getTokenStandardAndDetails.bind( getTokenStandardAndDetails: assetsContractController.getTokenStandardAndDetails.bind(

View File

@ -34,6 +34,7 @@ const metamaskrc = require('rc')('metamask', {
INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID, INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID,
ONBOARDING_V2: process.env.ONBOARDING_V2, ONBOARDING_V2: process.env.ONBOARDING_V2,
COLLECTIBLES_V1: process.env.COLLECTIBLES_V1, COLLECTIBLES_V1: process.env.COLLECTIBLES_V1,
DARK_MODE_V1: process.env.DARK_MODE_V1,
SEGMENT_HOST: process.env.SEGMENT_HOST, SEGMENT_HOST: process.env.SEGMENT_HOST,
SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY, SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY,
SEGMENT_BETA_WRITE_KEY: process.env.SEGMENT_BETA_WRITE_KEY, SEGMENT_BETA_WRITE_KEY: process.env.SEGMENT_BETA_WRITE_KEY,
@ -803,6 +804,7 @@ function getEnvironmentVariables({ buildType, devMode, testing }) {
SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1', SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1',
ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1', ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1',
COLLECTIBLES_V1: metamaskrc.COLLECTIBLES_V1 === '1', COLLECTIBLES_V1: metamaskrc.COLLECTIBLES_V1 === '1',
DARK_MODE_V1: metamaskrc.DARK_MODE_V1 === '1',
}; };
} }

View File

@ -94,6 +94,7 @@ export default class Routes extends Component {
prepareToLeaveSwaps: PropTypes.func, prepareToLeaveSwaps: PropTypes.func,
browserEnvironmentOs: PropTypes.string, browserEnvironmentOs: PropTypes.string,
browserEnvironmentBrowser: PropTypes.string, browserEnvironmentBrowser: PropTypes.string,
theme: PropTypes.string,
}; };
static contextTypes = { static contextTypes = {
@ -101,12 +102,22 @@ export default class Routes extends Component {
metricsEvent: PropTypes.func, metricsEvent: PropTypes.func,
}; };
componentDidUpdate(prevProps) {
if (process.env.DARK_MODE_V1) {
const { theme } = this.props;
if (theme !== prevProps.theme) {
document.documentElement.setAttribute('data-theme', theme);
}
}
}
UNSAFE_componentWillMount() { UNSAFE_componentWillMount() {
const { const {
currentCurrency, currentCurrency,
pageChanged, pageChanged,
setCurrentCurrencyToUSD, setCurrentCurrencyToUSD,
history, history,
theme,
} = this.props; } = this.props;
if (!currentCurrency) { if (!currentCurrency) {
setCurrentCurrencyToUSD(); setCurrentCurrencyToUSD();
@ -117,6 +128,9 @@ export default class Routes extends Component {
pageChanged(locationObj.pathname); pageChanged(locationObj.pathname);
} }
}); });
if (process.env.DARK_MODE_V1 && theme) {
document.documentElement.setAttribute('data-theme', theme);
}
} }
renderRoutes() { renderRoutes() {
@ -313,18 +327,19 @@ export default class Routes extends Component {
isMouseUser, isMouseUser,
browserEnvironmentOs: os, browserEnvironmentOs: os,
browserEnvironmentBrowser: browser, browserEnvironmentBrowser: browser,
theme,
} = this.props; } = this.props;
const loadMessage = const loadMessage =
loadingMessage || isNetworkLoading loadingMessage || isNetworkLoading
? this.getConnectingLabel(loadingMessage) ? this.getConnectingLabel(loadingMessage)
: null; : null;
return ( return (
<div <div
className={classnames('app', { className={classnames('app', {
[`os-${os}`]: os, [`os-${os}`]: os,
[`browser-${browser}`]: browser, [`browser-${browser}`]: browser,
'mouse-user-styles': isMouseUser, 'mouse-user-styles': isMouseUser,
[`theme-${theme}`]: process.env.DARK_MODE_V1 && theme,
})} })}
dir={textDirection} dir={textDirection}
onClick={() => setMouseUserState(true)} onClick={() => setMouseUserState(true)}

View File

@ -5,6 +5,7 @@ import {
getNetworkIdentifier, getNetworkIdentifier,
getPreferences, getPreferences,
isNetworkLoading, isNetworkLoading,
getTheme,
} from '../../selectors'; } from '../../selectors';
import { import {
lockMetamask, lockMetamask,
@ -36,6 +37,7 @@ function mapStateToProps(state) {
browserEnvironmentContainter: state.metamask.browserEnvironment?.browser, browserEnvironmentContainter: state.metamask.browserEnvironment?.browser,
providerId: getNetworkIdentifier(state), providerId: getNetworkIdentifier(state),
providerType: state.metamask.provider?.type, providerType: state.metamask.provider?.type,
theme: getTheme(state),
}; };
} }

View File

@ -5,6 +5,12 @@ import {
getSettingsSectionNumber, getSettingsSectionNumber,
handleSettingsRefs, handleSettingsRefs,
} from '../../../helpers/utils/settings-search'; } from '../../../helpers/utils/settings-search';
import Dropdown from '../../../components/ui/dropdown';
import { THEME_TYPE } from './experimental-tab.constant';
/*eslint-disable prefer-destructuring*/
const DARK_MODE_V1 = process.env.DARK_MODE_V1;
export default class ExperimentalTab extends PureComponent { export default class ExperimentalTab extends PureComponent {
static contextTypes = { static contextTypes = {
@ -21,6 +27,8 @@ export default class ExperimentalTab extends PureComponent {
openSeaEnabled: PropTypes.bool, openSeaEnabled: PropTypes.bool,
eip1559V2Enabled: PropTypes.bool, eip1559V2Enabled: PropTypes.bool,
setEIP1559V2Enabled: PropTypes.func, setEIP1559V2Enabled: PropTypes.func,
theme: PropTypes.string,
setTheme: PropTypes.func,
}; };
settingsRefs = Array( settingsRefs = Array(
@ -220,6 +228,46 @@ export default class ExperimentalTab extends PureComponent {
); );
} }
renderTheme() {
if (!DARK_MODE_V1) {
return null;
}
const { t } = this.context;
const { theme, setTheme } = this.props;
const themesOptions = [
{
name: t('defaultTheme'),
value: THEME_TYPE.DEFAULT,
},
{
name: t('darkTheme'),
value: THEME_TYPE.DARK,
},
];
return (
<div className="settings-page__content-row">
<div className="settings-page__content-item">
<span>{this.context.t('theme')}</span>
<div className="settings-page__content-description">
{this.context.t('themeDescription')}
</div>
</div>
<div className="settings-page__content-item">
<div className="settings-page__content-item-col">
<Dropdown
id="select-theme"
options={themesOptions}
selectedOption={theme}
onChange={async (newTheme) => setTheme(newTheme)}
/>
</div>
</div>
</div>
);
}
render() { render() {
return ( return (
<div className="settings-page__body"> <div className="settings-page__body">
@ -227,6 +275,7 @@ export default class ExperimentalTab extends PureComponent {
{this.renderOpenSeaEnabledToggle()} {this.renderOpenSeaEnabledToggle()}
{this.renderCollectibleDetectionToggle()} {this.renderCollectibleDetectionToggle()}
{this.renderEIP1559V2EnabledToggle()} {this.renderEIP1559V2EnabledToggle()}
{this.renderTheme()}
</div> </div>
); );
} }

View File

@ -0,0 +1,4 @@
export const THEME_TYPE = {
DEFAULT: 'default',
DARK: 'dark',
};

View File

@ -6,12 +6,14 @@ import {
setUseCollectibleDetection, setUseCollectibleDetection,
setOpenSeaEnabled, setOpenSeaEnabled,
setEIP1559V2Enabled, setEIP1559V2Enabled,
setTheme,
} from '../../../store/actions'; } from '../../../store/actions';
import { import {
getUseTokenDetection, getUseTokenDetection,
getUseCollectibleDetection, getUseCollectibleDetection,
getOpenSeaEnabled, getOpenSeaEnabled,
getEIP1559V2Enabled, getEIP1559V2Enabled,
getTheme,
} from '../../../selectors'; } from '../../../selectors';
import ExperimentalTab from './experimental-tab.component'; import ExperimentalTab from './experimental-tab.component';
@ -21,6 +23,7 @@ const mapStateToProps = (state) => {
useCollectibleDetection: getUseCollectibleDetection(state), useCollectibleDetection: getUseCollectibleDetection(state),
openSeaEnabled: getOpenSeaEnabled(state), openSeaEnabled: getOpenSeaEnabled(state),
eip1559V2Enabled: getEIP1559V2Enabled(state), eip1559V2Enabled: getEIP1559V2Enabled(state),
theme: getTheme(state),
}; };
}; };
@ -31,6 +34,7 @@ const mapDispatchToProps = (dispatch) => {
dispatch(setUseCollectibleDetection(val)), dispatch(setUseCollectibleDetection(val)),
setOpenSeaEnabled: (val) => dispatch(setOpenSeaEnabled(val)), setOpenSeaEnabled: (val) => dispatch(setOpenSeaEnabled(val)),
setEIP1559V2Enabled: (val) => dispatch(setEIP1559V2Enabled(val)), setEIP1559V2Enabled: (val) => dispatch(setEIP1559V2Enabled(val)),
setTheme: (val) => dispatch(setTheme(val)),
}; };
}; };

View File

@ -789,6 +789,16 @@ export function getOpenSeaEnabled(state) {
return Boolean(state.metamask.openSeaEnabled); return Boolean(state.metamask.openSeaEnabled);
} }
/**
* To get the `theme` value which determines which theme is selected
*
* @param {*} state
* @returns Boolean
*/
export function getTheme(state) {
return state.metamask.theme;
}
/** /**
* To retrieve the tokenList produced by TokenListcontroller * To retrieve the tokenList produced by TokenListcontroller
* *

View File

@ -2325,6 +2325,18 @@ export function setEIP1559V2Enabled(val) {
}; };
} }
export function setTheme(val) {
return async (dispatch) => {
dispatch(showLoadingIndication());
log.debug(`background.setTheme`);
try {
await promisifiedBackground.setTheme(val);
} finally {
dispatch(hideLoadingIndication());
}
};
}
export function setIpfsGateway(val) { export function setIpfsGateway(val) {
return (dispatch) => { return (dispatch) => {
dispatch(showLoadingIndication()); dispatch(showLoadingIndication());