diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 0aed4dbdf..0dd9eae1b 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -10,6 +10,7 @@ class PreferencesController { currentAccountTab: 'history', tokens: [], useBlockie: false, + featureFlags: {}, }, opts.initState) this.store = new ObservableStore(initState) } @@ -100,6 +101,22 @@ class PreferencesController { getFrequentRpcList () { return this.store.getState().frequentRpcList } + + setFeatureFlag (feature, activated) { + const currentFeatureFlags = this.store.getState().featureFlags + const updatedFeatureFlags = { + ...currentFeatureFlags, + [feature]: activated, + } + + this.store.updateState({ featureFlags: updatedFeatureFlags }) + console.log(`!!! updatedFeatureFlags`, updatedFeatureFlags); + return Promise.resolve(updatedFeatureFlags) + } + + getFeatureFlags () { + return this.store.getState().featureFlags + } // // PRIVATE METHODS // diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 4dce89e3a..8966ba393 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -341,6 +341,7 @@ module.exports = class MetamaskController extends EventEmitter { addToken: nodeify(preferencesController.addToken, preferencesController), removeToken: nodeify(preferencesController.removeToken, preferencesController), setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab, preferencesController), + setFeatureFlag: nodeify(preferencesController.setFeatureFlag, preferencesController), // AddressController setAddressBook: nodeify(addressBookController.setAddressBook, addressBookController), diff --git a/app/scripts/popup.js b/app/scripts/popup.js index 5f17f0651..8cef06931 100644 --- a/app/scripts/popup.js +++ b/app/scripts/popup.js @@ -12,6 +12,7 @@ const notificationManager = new NotificationManager() global.platform = new ExtensionPlatform() // inject css +console.log(`MetaMaskUiCss`, MetaMaskUiCss); const css = MetaMaskUiCss() injectCss(css) diff --git a/old-ui/app/app.js b/old-ui/app/app.js index e3f72793c..dcf19a0a9 100644 --- a/old-ui/app/app.js +++ b/old-ui/app/app.js @@ -93,31 +93,32 @@ App.prototype.render = function () { log.debug('Main ui render function') return ( - - h('.flex-column.full-height', { - style: { - // Windows was showing a vertical scroll bar: - overflow: 'hidden', - position: 'relative', - alignItems: 'center', - }, - }, [ - - // app bar - this.renderAppBar(), - this.renderNetworkDropdown(), - this.renderDropdown(), - - this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }), - - // panel content - h('.app-primary' + (transForward ? '.from-right' : '.from-left'), { + h('.old-ui', [ + h('.flex-column.full-height', { style: { - width: '100%', + // Windows was showing a vertical scroll bar: + overflow: 'hidden', + position: 'relative', + alignItems: 'center', }, }, [ - this.renderPrimary(), - ]), + + // app bar + this.renderAppBar(), + this.renderNetworkDropdown(), + this.renderDropdown(), + + this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }), + + // panel content + h('.app-primary' + (transForward ? '.from-right' : '.from-left'), { + style: { + width: '100%', + }, + }, [ + this.renderPrimary(), + ]), + ]) ]) ) } diff --git a/ui/app/actions.js b/ui/app/actions.js index e79f4373e..745b8779e 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -237,6 +237,11 @@ var actions = { SET_USE_BLOCKIE: 'SET_USE_BLOCKIE', setUseBlockie, + + // Feature Flags + setFeatureFlag, + updateFeatureFlags, + UPDATE_FEATURE_FLAGS: 'UPDATE_FEATURE_FLAGS', } module.exports = actions @@ -1506,6 +1511,30 @@ function updateTokenExchangeRate (token = '') { } } +function setFeatureFlag (feature, activated) { + return (dispatch) => { + dispatch(actions.showLoadingIndication()) + return new Promise((resolve, reject) => { + background.setFeatureFlag(feature, activated, (err, updatedFeatureFlags) => { + dispatch(actions.hideLoadingIndication()) + if (err) { + dispatch(actions.displayWarning(err.message)) + reject(err) + } + dispatch(actions.updateFeatureFlags(updatedFeatureFlags)) + resolve(updatedFeatureFlags) + }) + }) + } +} + +function updateFeatureFlags (updatedFeatureFlags) { + return { + type: actions.UPDATE_FEATURE_FLAGS, + value: updatedFeatureFlags, + } +} + // Call Background Then Update // // A function generator for a common pattern wherein: diff --git a/ui/app/app.js b/ui/app/app.js index e90c3e98e..7e1eb200f 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -116,40 +116,41 @@ App.prototype.render = function () { log.debug('Main ui render function') return ( + h('.new-ui', [ + h('.flex-column.full-height', { + style: { + overflowX: 'hidden', + position: 'relative', + alignItems: 'center', + }, + }, [ - h('.flex-column.full-height', { - style: { - overflowX: 'hidden', - position: 'relative', - alignItems: 'center', - }, - }, [ + // global modal + h(Modal, {}, []), - // global modal - h(Modal, {}, []), + // app bar + this.renderAppBar(), - // app bar - this.renderAppBar(), + // sidebar + this.renderSidebar(), - // sidebar - this.renderSidebar(), + // network dropdown + h(NetworkDropdown, { + provider: this.props.provider, + frequentRpcList: this.props.frequentRpcList, + }, []), - // network dropdown - h(NetworkDropdown, { - provider: this.props.provider, - frequentRpcList: this.props.frequentRpcList, - }, []), + h(AccountMenu), - h(AccountMenu), + (isLoading || isLoadingNetwork) && h(Loading, { + loadingMessage: loadMessage, + }), - (isLoading || isLoadingNetwork) && h(Loading, { - loadingMessage: loadMessage, - }), + // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }), - // this.renderLoadingIndicator({ isLoading, isLoadingNetwork, loadMessage }), - - // content - this.renderPrimary(), + // content + this.renderPrimary(), + ]) ]) ) } @@ -268,6 +269,13 @@ App.prototype.renderAppBar = function () { }, }, 'MetaMask'), + h('span', { + style: {}, + onClick: () => { + props.dispatch(actions.setFeatureFlag('betaUI', false)) + }, + }, 'Leave Beta') + ]), h('div.header__right-actions', [ diff --git a/ui/app/css/index.scss b/ui/app/css/index.scss index 01899ccad..445c819ff 100644 --- a/ui/app/css/index.scss +++ b/ui/app/css/index.scss @@ -4,6 +4,7 @@ http://www.creativebloq.com/web-design/manage-large-css-projects-itcss-101517528 https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/ */ + @import './itcss/settings/index.scss'; @import './itcss/tools/index.scss'; @import './itcss/generic/index.scss'; diff --git a/ui/app/css/itcss/components/menu.scss b/ui/app/css/itcss/components/menu.scss index 17e24de98..77c49bbcf 100644 --- a/ui/app/css/itcss/components/menu.scss +++ b/ui/app/css/itcss/components/menu.scss @@ -11,7 +11,7 @@ flex-flow: row nowrap; align-items: center; position: relative; - z-index: 200; + z-index: 201; font-weight: 200; @media screen and (max-width: 575px) { diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index fb53bbaef..6d6068d05 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -37,6 +37,7 @@ function reduceMetamask (state, action) { }, coinOptions: {}, useBlockie: false, + featureFlags: {}, }, state.metamask) switch (action.type) { @@ -320,6 +321,11 @@ function reduceMetamask (state, action) { useBlockie: action.value, }) + case actions.UPDATE_FEATURE_FLAGS: + return extend(metamaskState, { + featureFlags: action.value, + }) + default: return metamaskState diff --git a/ui/app/root.js b/ui/app/root.js index 9e7314b20..21d6d1829 100644 --- a/ui/app/root.js +++ b/ui/app/root.js @@ -2,7 +2,7 @@ const inherits = require('util').inherits const Component = require('react').Component const Provider = require('react-redux').Provider const h = require('react-hyperscript') -const App = require('./app') +const SelectedApp = require('./select-app') module.exports = Root @@ -15,7 +15,7 @@ Root.prototype.render = function () { h(Provider, { store: this.props.store, }, [ - h(App), + h(SelectedApp), ]) ) diff --git a/ui/app/select-app.js b/ui/app/select-app.js new file mode 100644 index 000000000..3cba44052 --- /dev/null +++ b/ui/app/select-app.js @@ -0,0 +1,21 @@ +const inherits = require('util').inherits +const Component = require('react').Component +const connect = require('react-redux').connect +const h = require('react-hyperscript') +const App = require('./app') +const OldApp = require('../../old-ui/app/app') + +function mapStateToProps (state) { + return { betaUI: state.metamask.featureFlags.betaUI } +} + +module.exports = connect(mapStateToProps)(SelectedApp) + +inherits(SelectedApp, Component) +function SelectedApp () { Component.call(this) } + +SelectedApp.prototype.render = function () { + const { betaUI } = this.props + const Selected = betaUI ? App : OldApp + return h(Selected) +}