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:
parent
0e421ece8e
commit
4bb3ba4aef
12
app/_locales/en/messages.json
generated
12
app/_locales/en/messages.json
generated
@ -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"
|
||||||
},
|
},
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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(
|
||||||
|
@ -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',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)}
|
||||||
|
@ -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),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
export const THEME_TYPE = {
|
||||||
|
DEFAULT: 'default',
|
||||||
|
DARK: 'dark',
|
||||||
|
};
|
@ -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)),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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());
|
||||||
|
Loading…
Reference in New Issue
Block a user