aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package.json2
-rw-r--r--ui/app/actions.js20
-rw-r--r--ui/app/app.js124
-rw-r--r--ui/app/components/drop-menu-item.js31
-rw-r--r--ui/app/reducers/app.js11
5 files changed, 157 insertions, 31 deletions
diff --git a/package.json b/package.json
index d7f41097f..99569e5db 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"identicon.js": "^1.2.1",
"inject-css": "^0.1.1",
"jazzicon": "^1.1.3",
+ "menu-droppo": "^1.1.0",
"metamask-logo": "^1.1.5",
"multiplex": "^6.7.0",
"once": "^1.3.3",
@@ -52,6 +53,7 @@
"redux": "^3.0.5",
"redux-logger": "^2.3.1",
"redux-thunk": "^1.0.2",
+ "sandwich-expando": "^1.0.5",
"textarea-caret": "^3.0.1",
"three.js": "^0.73.2",
"through2": "^2.0.1",
diff --git a/ui/app/actions.js b/ui/app/actions.js
index f489eede7..ee5e417d4 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1,6 +1,11 @@
var actions = {
GO_HOME: 'GO_HOME',
goHome: goHome,
+ // menu state
+ TOGGLE_MENU: 'TOGGLE_MENU',
+ toggleMenu: toggleMenu,
+ SET_MENU_STATE: 'SET_MENU_STATE',
+ closeMenu: closeMenu,
// remote state
UPDATE_METAMASK_STATE: 'UPDATE_METAMASK_STATE',
updateMetamaskState: updateMetamaskState,
@@ -105,6 +110,21 @@ function goHome() {
}
}
+// menu state
+
+function toggleMenu() {
+ return {
+ type: this.TOGGLE_MENU,
+ }
+}
+
+function closeMenu() {
+ return {
+ type: this.SET_MENU_STATE,
+ value: false,
+ }
+}
+
// async actions
function tryUnlockMetamask(password) {
diff --git a/ui/app/app.js b/ui/app/app.js
index 68d34e52f..511012fab 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -24,6 +24,9 @@ const ConfigScreen = require('./config')
const InfoScreen = require('./info')
const LoadingIndicator = require('./loading')
const txHelper = require('../lib/tx-helper')
+const SandwichExpando = require('sandwich-expando')
+const MenuDroppo = require('menu-droppo')
+const DropMenuItem = require('./components/drop-menu-item')
module.exports = connect(mapStateToProps)(App)
@@ -42,6 +45,7 @@ function mapStateToProps(state) {
seedWords: state.metamask.seedWords,
unconfTxs: state.metamask.unconfTxs,
unconfMsgs: state.metamask.unconfMsgs,
+ menuOpen: state.appState.menuOpen,
}
}
@@ -64,6 +68,7 @@ App.prototype.render = function() {
// app bar
this.renderAppBar(),
+ this.renderDropdown(),
// panel content
h('.app-primary.flex-grow' + (transForward ? '.from-right' : '.from-left'), {
@@ -127,47 +132,104 @@ App.prototype.renderAppBar = function(){
return (
- h('.app-header.flex-row.flex-space-between', {
- style: {
- alignItems: 'center',
- visibility: state.isUnlocked ? 'visibile' : 'none',
- background: state.isUnlocked ? 'white' : 'none',
- height: '36px',
- },
- }, state.isUnlocked && [
-
- // mini logo
- h('img', {
- height: 24,
- width: 24,
- src: '/images/icon-128.png',
- }),
-
- // metamask name
- h('h1', 'MetaMask'),
-
- // hamburger
- h('i.fa.fa-bars.cursor-pointer.color-orange', {
- onClick: (event) => state.dispatch(actions.showConfigPage()),
- }),
+ h('div', [
- ])
+ h('.app-header.flex-row.flex-space-between', {
+ style: {
+ alignItems: 'center',
+ visibility: state.isUnlocked ? 'visible' : 'none',
+ background: state.isUnlocked ? 'white' : 'none',
+ height: '36px',
+ position: 'relative',
+ zIndex: 1,
+ },
+ }, state.isUnlocked && [
+
+ // mini logo
+ h('img', {
+ height: 24,
+ width: 24,
+ src: '/images/icon-128.png',
+ }),
+ // metamask name
+ h('h1', 'MetaMask'),
+
+ // hamburger
+ h(SandwichExpando, {
+ width: 16,
+ barHeight: 2,
+ padding: 0,
+ isOpen: state.menuOpen,
+ color: 'rgb(247,146,30)',
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ this.props.dispatch(actions.toggleMenu())
+ },
+ }),
+ ]),
+ ])
)
}
-App.prototype.renderPrimary = function(state){
- var state = this.props
+App.prototype.renderDropdown = function() {
+ const props = this.props
+ return h(MenuDroppo, {
+ isOpen: props.menuOpen,
+ onClickOutside: (event) => {
+ this.props.dispatch(actions.closeMenu())
+ },
+ style: {
+ position: 'fixed',
+ right: 0,
+ zIndex: 0,
+ },
+ innerStyle: {
+ background: 'white',
+ boxShadow: '1px 1px 2px rgba(0,0,0,0.1)',
+ },
+ }, [ // DROP MENU ITEMS
+ h('style', `
+ .drop-menu-item:hover { background:rgb(235, 235, 235); }
+ .drop-menu-item i { margin: 11px; }
+ `),
+
+ h(DropMenuItem, {
+ label: 'Settings',
+ closeMenu:() => this.props.dispatch(actions.closeMenu()),
+ action:() => this.props.dispatch(actions.showConfigPage()),
+ icon: h('i.fa.fa-gear.fa-lg', { ariaHidden: true }),
+ }),
+
+ h(DropMenuItem, {
+ label: 'Lock Account',
+ closeMenu:() => this.props.dispatch(actions.closeMenu()),
+ action:() => this.props.dispatch(actions.lockMetamask()),
+ icon: h('i.fa.fa-lock.fa-lg', { ariaHidden: true }),
+ }),
+
+ h(DropMenuItem, {
+ label: 'Help',
+ closeMenu:() => this.props.dispatch(actions.closeMenu()),
+ action:() => this.props.dispatch(actions.showInfoPage()),
+ icon: h('i.fa.fa-question.fa-lg', { ariaHidden: true }),
+ }),
+ ])
+}
+
+App.prototype.renderPrimary = function(){
+ var props = this.props
- if (state.seedWords) {
+ if (props.seedWords) {
return h(CreateVaultCompleteScreen, {key: 'createVaultComplete'})
}
// show initialize screen
- if (!state.isInitialized) {
+ if (!props.isInitialized) {
// show current view
- switch (state.currentView.name) {
+ switch (props.currentView.name) {
case 'createVault':
return h(CreateVaultScreen, {key: 'createVault'})
@@ -185,12 +247,12 @@ App.prototype.renderPrimary = function(state){
}
// show unlock screen
- if (!state.isUnlocked) {
+ if (!props.isUnlocked) {
return h(UnlockScreen, {key: 'locked'})
}
// show current view
- switch (state.currentView.name) {
+ switch (props.currentView.name) {
case 'accounts':
return h(AccountsScreen, {key: 'accounts'})
diff --git a/ui/app/components/drop-menu-item.js b/ui/app/components/drop-menu-item.js
new file mode 100644
index 000000000..c8e61278c
--- /dev/null
+++ b/ui/app/components/drop-menu-item.js
@@ -0,0 +1,31 @@
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const inherits = require('util').inherits
+
+module.exports = DropMenuItem
+
+
+inherits(DropMenuItem, Component)
+function DropMenuItem() {
+ Component.call(this)
+}
+
+DropMenuItem.prototype.render = function() {
+
+ return h('li.drop-menu-item', {
+ onClick:() => {
+ this.props.closeMenu()
+ this.props.action()
+ },
+ style: {
+ listStyle: 'none',
+ padding: '6px 16px 6px 5px',
+ fontFamily: 'Transat Medium',
+ color: 'rgb(125, 128, 130)',
+ cursor: 'pointer',
+ },
+ }, [
+ this.props.icon,
+ this.props.label,
+ ])
+}
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 0e0740c9d..2cdbaf6f3 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -22,6 +22,7 @@ function reduceApp(state, action) {
var seedWords = state.metamask.seedWords
var appState = extend({
+ menuOpen: false,
currentView: seedWords ? seedConfView : defaultView,
accountDetail: {
subview: 'transactions',
@@ -34,6 +35,16 @@ function reduceApp(state, action) {
switch (action.type) {
+ case actions.TOGGLE_MENU:
+ return extend(appState, {
+ menuOpen: !appState.menuOpen,
+ })
+
+ case actions.SET_MENU_STATE:
+ return extend(appState, {
+ menuOpen: action.value,
+ })
+
// intialize
case actions.SHOW_CREATE_VAULT: