aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorFrankie <frankie.diamond@gmail.com>2016-12-22 06:31:07 +0800
committerGitHub <noreply@github.com>2016-12-22 06:31:07 +0800
commit6f7c23fd28ef37ae51478b735c1f5888c97bbaf5 (patch)
treeb927871ed00c33a66341a26de09f00cf006314b8 /ui
parenta85c691b71d5142d2412000930328fbe9161760a (diff)
parent73cdf0bfd49470bad1f0da4d0d894278c87af54e (diff)
downloadtangerine-wallet-browser-6f7c23fd28ef37ae51478b735c1f5888c97bbaf5.tar.gz
tangerine-wallet-browser-6f7c23fd28ef37ae51478b735c1f5888c97bbaf5.tar.zst
tangerine-wallet-browser-6f7c23fd28ef37ae51478b735c1f5888c97bbaf5.zip
Merge branch 'dev' into TxManager
Diffstat (limited to 'ui')
-rw-r--r--ui/app/actions.js56
-rw-r--r--ui/app/app.js16
-rw-r--r--ui/app/components/drop-menu-item.js3
-rw-r--r--ui/app/components/network.js12
-rw-r--r--ui/app/config.js30
-rw-r--r--ui/app/first-time/disclaimer.js12
-rw-r--r--ui/app/first-time/init-menu.js16
-rw-r--r--ui/app/keychains/hd/restore-vault.js8
-rw-r--r--ui/app/notice.js118
-rw-r--r--ui/app/reducers/app.js18
-rw-r--r--ui/app/reducers/metamask.js13
-rw-r--r--ui/app/unlock.js2
12 files changed, 255 insertions, 49 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 41be1004c..1c32c9bb1 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -13,12 +13,21 @@ var actions = {
// remote state
UPDATE_METAMASK_STATE: 'UPDATE_METAMASK_STATE',
updateMetamaskState: updateMetamaskState,
+ // notices
+ MARK_NOTICE_READ: 'MARK_NOTICE_READ',
+ markNoticeRead: markNoticeRead,
+ SHOW_NOTICE: 'SHOW_NOTICE',
+ showNotice: showNotice,
+ CLEAR_NOTICES: 'CLEAR_NOTICES',
+ clearNotices: clearNotices,
// intialize screen
AGREE_TO_DISCLAIMER: 'AGREE_TO_DISCLAIMER',
agreeToDisclaimer: agreeToDisclaimer,
CREATE_NEW_VAULT_IN_PROGRESS: 'CREATE_NEW_VAULT_IN_PROGRESS',
SHOW_CREATE_VAULT: 'SHOW_CREATE_VAULT',
SHOW_RESTORE_VAULT: 'SHOW_RESTORE_VAULT',
+ FORGOT_PASSWORD: 'FORGOT_PASSWORD',
+ forgotPassword: forgotPassword,
SHOW_INIT_MENU: 'SHOW_INIT_MENU',
SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED',
SHOW_INFO_PAGE: 'SHOW_INFO_PAGE',
@@ -177,13 +186,13 @@ function tryUnlockMetamask (password) {
}
}
-function transitionForward() {
+function transitionForward () {
return {
type: this.TRANSITION_FORWARD,
}
}
-function transitionBackward() {
+function transitionBackward () {
return {
type: this.TRANSITION_BACKWARD,
}
@@ -380,6 +389,12 @@ function showRestoreVault () {
}
}
+function forgotPassword () {
+ return {
+ type: actions.FORGOT_PASSWORD,
+ }
+}
+
function showInitializeMenu () {
return {
type: actions.SHOW_INIT_MENU,
@@ -540,6 +555,43 @@ function goBackToInitView () {
}
//
+// notice
+//
+
+function markNoticeRead (notice) {
+ return (dispatch) => {
+ dispatch(this.showLoadingIndication())
+ background.markNoticeRead(notice, (err, notice) => {
+ dispatch(this.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.showWarning(err))
+ }
+ if (notice) {
+ return dispatch(actions.showNotice(notice))
+ } else {
+ dispatch(this.clearNotices())
+ return {
+ type: actions.SHOW_ACCOUNTS_PAGE,
+ }
+ }
+ })
+ }
+}
+
+function showNotice (notice) {
+ return {
+ type: actions.SHOW_NOTICE,
+ value: notice,
+ }
+}
+
+function clearNotices () {
+ return {
+ type: actions.CLEAR_NOTICES,
+ }
+}
+
+//
// config
//
diff --git a/ui/app/app.js b/ui/app/app.js
index 9538a6b93..2fa6415dd 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -15,6 +15,8 @@ const AccountsScreen = require('./accounts')
const AccountDetailScreen = require('./account-detail')
const SendTransactionScreen = require('./send')
const ConfirmTxScreen = require('./conf-tx')
+// notice
+const NoticeScreen = require('./notice')
// other views
const ConfigScreen = require('./config')
const InfoScreen = require('./info')
@@ -40,6 +42,7 @@ function mapStateToProps (state) {
// state from plugin
isLoading: state.appState.isLoading,
isDisclaimerConfirmed: state.metamask.isDisclaimerConfirmed,
+ noActiveNotices: state.metamask.noActiveNotices,
isInitialized: state.metamask.isInitialized,
isUnlocked: state.metamask.isUnlocked,
currentView: state.appState.currentView,
@@ -241,15 +244,6 @@ App.prototype.renderNetworkDropdown = function () {
}),
h(DropMenuItem, {
- label: 'Morden Test Network',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setProviderType('morden')),
- icon: h('.menu-icon.red-dot'),
- activeNetworkRender: props.network,
- provider: props.provider,
- }),
-
- h(DropMenuItem, {
label: 'Localhost 8545',
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action: () => props.dispatch(actions.setRpcTarget('http://localhost:8545')),
@@ -372,6 +366,10 @@ App.prototype.renderPrimary = function () {
}
}
+ if (!props.noActiveNotices) {
+ return h(NoticeScreen, {key: 'NoticeScreen'})
+ }
+
// show current view
switch (props.currentView.name) {
diff --git a/ui/app/components/drop-menu-item.js b/ui/app/components/drop-menu-item.js
index 7cf686cab..9f002234e 100644
--- a/ui/app/components/drop-menu-item.js
+++ b/ui/app/components/drop-menu-item.js
@@ -44,9 +44,6 @@ DropMenuItem.prototype.activeNetworkRender = function () {
case 'Ropsten Test Network':
if (provider.type === 'testnet') return h('.check', '✓')
break
- case 'Morden Test Network':
- if (provider.type === 'morden') return h('.check', '✓')
- break
case 'Localhost 8545':
if (activeNetwork === 'http://localhost:8545') return h('.check', '✓')
break
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index 9cf597648..43dc747b3 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -40,9 +40,6 @@ Network.prototype.render = function () {
} else if (parseInt(networkNumber) === 3) {
hoverText = 'Ropsten Test Network'
iconName = 'ropsten-test-network'
- } else if (parseInt(networkNumber) === 2) {
- hoverText = 'Morden Test Network'
- iconName = 'morden-test-network'
} else {
hoverText = 'Unknown Private Network'
iconName = 'unknown-private-network'
@@ -77,15 +74,6 @@ Network.prototype.render = function () {
}},
'Ropsten Test Net'),
])
- case 'morden-test-network':
- return h('.network-indicator', [
- h('.menu-icon.red-dot'),
- h('.network-name', {
- style: {
- color: '#ff6666',
- }},
- 'Morden Test Net'),
- ])
default:
return h('.network-indicator', [
h('i.fa.fa-question-circle.fa-lg', {
diff --git a/ui/app/config.js b/ui/app/config.js
index 7e49cf048..65b1ed712 100644
--- a/ui/app/config.js
+++ b/ui/app/config.js
@@ -4,11 +4,13 @@ const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('./actions')
const currencies = require('./conversion.json').rows
+const validUrl = require('valid-url')
module.exports = connect(mapStateToProps)(ConfigScreen)
function mapStateToProps (state) {
return {
metamask: state.metamask,
+ warning: state.appState.warning,
}
}
@@ -20,6 +22,7 @@ function ConfigScreen () {
ConfigScreen.prototype.render = function () {
var state = this.props
var metamaskState = state.metamask
+ var warning = state.warning
return (
h('.flex-column.flex-grow', [
@@ -34,6 +37,14 @@ ConfigScreen.prototype.render = function () {
h('h2.page-subtitle', 'Settings'),
]),
+ h('.error', {
+ style: {
+ display: warning ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, warning),
+
// conf view
h('.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-space-around', {
@@ -57,7 +68,7 @@ ConfigScreen.prototype.render = function () {
if (event.key === 'Enter') {
var element = event.target
var newRpc = element.value
- state.dispatch(actions.setRpcTarget(newRpc))
+ rpcValidation(newRpc, state)
}
},
}),
@@ -69,7 +80,7 @@ ConfigScreen.prototype.render = function () {
event.preventDefault()
var element = document.querySelector('input#new_rpc')
var newRpc = element.value
- state.dispatch(actions.setRpcTarget(newRpc))
+ rpcValidation(newRpc, state)
},
}, 'Save'),
]),
@@ -99,6 +110,19 @@ ConfigScreen.prototype.render = function () {
)
}
+function rpcValidation (newRpc, state) {
+ if (validUrl.isWebUri(newRpc)) {
+ state.dispatch(actions.setRpcTarget(newRpc))
+ } else {
+ var appendedRpc = `http://${newRpc}`
+ if (validUrl.isWebUri(appendedRpc)) {
+ state.dispatch(actions.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.'))
+ } else {
+ state.dispatch(actions.displayWarning('Invalid RPC URI'))
+ }
+ }
+}
+
function currentConversionInformation (metamaskState, state) {
var currentFiat = metamaskState.currentFiat
var conversionDate = metamaskState.conversionDate
@@ -133,7 +157,7 @@ function currentProviderDisplay (metamaskState) {
case 'testnet':
title = 'Current Network'
- value = 'Morden Test Network'
+ value = 'Ropsten Test Network'
break
default:
diff --git a/ui/app/first-time/disclaimer.js b/ui/app/first-time/disclaimer.js
index 819d4a110..a8bafd39b 100644
--- a/ui/app/first-time/disclaimer.js
+++ b/ui/app/first-time/disclaimer.js
@@ -6,6 +6,8 @@ const actions = require('../actions')
const ReactMarkdown = require('react-markdown')
const fs = require('fs')
const path = require('path')
+const linker = require('extension-link-enabler')
+const findDOMNode = require('react-dom').findDOMNode
const disclaimer = fs.readFileSync(path.join(__dirname, '..', '..', '..', 'USER_AGREEMENT.md')).toString()
module.exports = connect(mapStateToProps)(DisclaimerScreen)
@@ -98,3 +100,13 @@ DisclaimerScreen.prototype.render = function () {
])
)
}
+
+DisclaimerScreen.prototype.componentDidMount = function () {
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+}
+
+DisclaimerScreen.prototype.componentWillUnmount = function () {
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+}
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index c41aecc48..152d28809 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -21,7 +21,6 @@ function mapStateToProps (state) {
// state from plugin
currentView: state.appState.currentView,
warning: state.appState.warning,
- forgottenPassword: state.metamask.isInitialized,
}
}
@@ -118,17 +117,6 @@ InitializeMenuScreen.prototype.renderMenu = function (state) {
},
}, 'Create'),
- state.forgottenPassword ? h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.backToUnlockView.bind(this),
- style: {
- fontSize: '0.8em',
- color: 'rgb(247, 134, 28)',
- textDecoration: 'underline',
- },
- }, 'Return to Login'),
- ]) : null,
-
h('.flex-row.flex-center.flex-grow', [
h('p.pointer', {
onClick: this.showRestoreVault.bind(this),
@@ -159,10 +147,6 @@ InitializeMenuScreen.prototype.showRestoreVault = function () {
this.props.dispatch(actions.showRestoreVault())
}
-InitializeMenuScreen.prototype.backToUnlockView = function () {
- this.props.dispatch(actions.backToUnlockView())
-}
-
InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
var passwordBox = document.getElementById('password-box')
var password = passwordBox.value
diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js
index 3fa25a2eb..06e51d9b3 100644
--- a/ui/app/keychains/hd/restore-vault.js
+++ b/ui/app/keychains/hd/restore-vault.js
@@ -14,6 +14,7 @@ function RestoreVaultScreen () {
function mapStateToProps (state) {
return {
warning: state.appState.warning,
+ forgottenPassword: state.appState.forgottenPassword,
}
}
@@ -100,14 +101,17 @@ RestoreVaultScreen.prototype.render = function () {
}, 'OK'),
]),
-
])
)
}
RestoreVaultScreen.prototype.showInitializeMenu = function () {
- this.props.dispatch(actions.showInitializeMenu())
+ if (this.props.forgottenPassword) {
+ this.props.dispatch(actions.backToUnlockView())
+ } else {
+ this.props.dispatch(actions.showInitializeMenu())
+ }
}
RestoreVaultScreen.prototype.createOnEnter = function (event) {
diff --git a/ui/app/notice.js b/ui/app/notice.js
new file mode 100644
index 000000000..3c2c746f2
--- /dev/null
+++ b/ui/app/notice.js
@@ -0,0 +1,118 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const ReactMarkdown = require('react-markdown')
+const connect = require('react-redux').connect
+const actions = require('./actions')
+const linker = require('extension-link-enabler')
+const findDOMNode = require('react-dom').findDOMNode
+
+module.exports = connect(mapStateToProps)(Notice)
+
+function mapStateToProps (state) {
+ return {
+ lastUnreadNotice: state.metamask.lastUnreadNotice,
+ }
+}
+
+inherits(Notice, Component)
+function Notice () {
+ Component.call(this)
+}
+
+Notice.prototype.render = function () {
+ const props = this.props
+ const title = props.lastUnreadNotice.title
+ const date = props.lastUnreadNotice.date
+
+ return (
+ h('.flex-column.flex-center.flex-grow', [
+ h('h3.flex-center.text-transform-uppercacse.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ title,
+ ]),
+
+ h('h5.flex-center.text-transform-uppercacse.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ date,
+ ]),
+
+ h('style', `
+
+ .markdown {
+ overflow-x: hidden;
+ }
+ .markdown h1, .markdown h2, .markdown h3 {
+ margin: 10px 0;
+ font-weight: bold;
+ }
+
+ .markdown strong {
+ font-weight: bold;
+ }
+ .markdown em {
+ font-style: italic;
+ }
+
+ .markdown p {
+ margin: 10px 0;
+ }
+
+ .markdown a {
+ color: #df6b0e;
+ }
+
+ `),
+
+ h('div.markdown', {
+ style: {
+ background: 'rgb(235, 235, 235)',
+ height: '310px',
+ padding: '6px',
+ width: '90%',
+ overflowY: 'scroll',
+ scroll: 'auto',
+ },
+ }, [
+ h(ReactMarkdown, {
+ source: props.lastUnreadNotice.body,
+ skipHtml: true,
+ }),
+ ]),
+
+ h('button', {
+ onClick: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
+ style: {
+ marginTop: '18px',
+ },
+ }, 'Continue'),
+ ])
+ )
+}
+
+Notice.prototype.componentDidMount = function () {
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+}
+
+Notice.prototype.componentWillUnmount = function () {
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+}
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 67a926948..65a3dba49 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -72,6 +72,16 @@ function reduceApp (state, action) {
name: 'restoreVault',
},
transForward: true,
+ forgottenPassword: true,
+ })
+
+ case actions.FORGOT_PASSWORD:
+ return extend(appState, {
+ currentView: {
+ name: 'restoreVault',
+ },
+ transForward: false,
+ forgottenPassword: true,
})
case actions.SHOW_INIT_MENU:
@@ -169,7 +179,7 @@ function reduceApp (state, action) {
return extend(appState, {
warning: null,
transForward: true,
- forgottenPassword: !appState.forgottenPassword,
+ forgottenPassword: false,
currentView: {
name: 'UnlockScreen',
},
@@ -248,6 +258,12 @@ function reduceApp (state, action) {
forgottenPassword: false,
})
+ case actions.SHOW_NOTICE:
+ return extend(appState, {
+ transForward: true,
+ isLoading: false,
+ })
+
case actions.REVEAL_ACCOUNT:
return extend(appState, {
scrollToBottom: true,
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 1a4514a21..8679ab062 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -16,6 +16,8 @@ function reduceMetamask (state, action) {
currentFiat: 'USD',
conversionRate: 0,
conversionDate: 'N/A',
+ noActiveNotices: true,
+ lastUnreadNotice: undefined,
}, state.metamask)
switch (action.type) {
@@ -25,6 +27,17 @@ function reduceMetamask (state, action) {
delete newState.seedWords
return newState
+ case actions.SHOW_NOTICE:
+ return extend(metamaskState, {
+ noActiveNotices: false,
+ lastUnreadNotice: action.value,
+ })
+
+ case actions.CLEAR_NOTICES:
+ return extend(metamaskState, {
+ noActiveNotices: true,
+ })
+
case actions.UPDATE_METAMASK_STATE:
return extend(metamaskState, action.value)
diff --git a/ui/app/unlock.js b/ui/app/unlock.js
index 17416766d..19f5eaec2 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -70,7 +70,7 @@ UnlockScreen.prototype.render = function () {
h('.flex-row.flex-center.flex-grow', [
h('p.pointer', {
- onClick: () => this.props.dispatch(actions.goBackToInitView()),
+ onClick: () => this.props.dispatch(actions.forgotPassword()),
style: {
fontSize: '0.8em',
color: 'rgb(247, 134, 28)',