commit
4371801083
@ -0,0 +1,17 @@ |
|||||||
|
const MessageManager = require('./lib/message-manager') |
||||||
|
const PersonalMessageManager = require('./lib/personal-message-manager') |
||||||
|
const TypedMessageManager = require('./lib/typed-message-manager') |
||||||
|
|
||||||
|
class UserActionController { |
||||||
|
|
||||||
|
constructor (opts = {}) { |
||||||
|
|
||||||
|
this.messageManager = new MessageManager() |
||||||
|
this.personalMessageManager = new PersonalMessageManager() |
||||||
|
this.typedMessageManager = new TypedMessageManager() |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
module.exports = UserActionController |
@ -0,0 +1,71 @@ |
|||||||
|
class DiagnosticsReporter { |
||||||
|
|
||||||
|
constructor ({ firstTimeInfo, version }) { |
||||||
|
this.firstTimeInfo = firstTimeInfo |
||||||
|
this.version = version |
||||||
|
} |
||||||
|
|
||||||
|
async reportOrphans(orphans) { |
||||||
|
try { |
||||||
|
return await this.submit({ |
||||||
|
accounts: Object.keys(orphans), |
||||||
|
metadata: { |
||||||
|
type: 'orphans', |
||||||
|
}, |
||||||
|
}) |
||||||
|
} catch (err) { |
||||||
|
console.error('DiagnosticsReporter - "reportOrphans" encountered an error:') |
||||||
|
console.error(err) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async reportMultipleKeyrings(rawKeyrings) { |
||||||
|
try { |
||||||
|
const keyrings = await Promise.all(rawKeyrings.map(async (keyring, index) => { |
||||||
|
return { |
||||||
|
index, |
||||||
|
type: keyring.type, |
||||||
|
accounts: await keyring.getAccounts(), |
||||||
|
} |
||||||
|
})) |
||||||
|
return await this.submit({ |
||||||
|
accounts: [], |
||||||
|
metadata: { |
||||||
|
type: 'keyrings', |
||||||
|
keyrings, |
||||||
|
}, |
||||||
|
}) |
||||||
|
} catch (err) { |
||||||
|
console.error('DiagnosticsReporter - "reportMultipleKeyrings" encountered an error:') |
||||||
|
console.error(err) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async submit (message) { |
||||||
|
try { |
||||||
|
// add metadata
|
||||||
|
message.metadata.version = this.version |
||||||
|
message.metadata.firstTimeInfo = this.firstTimeInfo |
||||||
|
return await postData(message) |
||||||
|
} catch (err) { |
||||||
|
console.error('DiagnosticsReporter - "submit" encountered an error:') |
||||||
|
throw err |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
function postData(data) { |
||||||
|
const uri = 'https://diagnostics.metamask.io/v1/orphanedAccounts' |
||||||
|
return fetch(uri, { |
||||||
|
body: JSON.stringify(data), // must match 'Content-Type' header
|
||||||
|
credentials: 'same-origin', // include, same-origin, *omit
|
||||||
|
headers: { |
||||||
|
'content-type': 'application/json', |
||||||
|
}, |
||||||
|
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||||||
|
mode: 'cors', // no-cors, cors, *same-origin
|
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = DiagnosticsReporter |
@ -0,0 +1,54 @@ |
|||||||
|
import React, { Component } from 'react' |
||||||
|
import PropTypes from 'prop-types' |
||||||
|
import Button from '../../button' |
||||||
|
|
||||||
|
class ConfirmResetAccount extends Component { |
||||||
|
static propTypes = { |
||||||
|
hideModal: PropTypes.func.isRequired, |
||||||
|
resetAccount: PropTypes.func.isRequired, |
||||||
|
} |
||||||
|
|
||||||
|
static contextTypes = { |
||||||
|
t: PropTypes.func, |
||||||
|
} |
||||||
|
|
||||||
|
handleReset () { |
||||||
|
this.props.resetAccount() |
||||||
|
.then(() => this.props.hideModal()) |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
const { t } = this.context |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="modal-container"> |
||||||
|
<div className="modal-container__content"> |
||||||
|
<div className="modal-container__title"> |
||||||
|
{ `${t('resetAccount')}?` } |
||||||
|
</div> |
||||||
|
<div className="modal-container__description"> |
||||||
|
{ t('resetAccountDescription') } |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div className="modal-container__footer"> |
||||||
|
<Button |
||||||
|
type="default" |
||||||
|
className="modal-container__footer-button" |
||||||
|
onClick={() => this.props.hideModal()} |
||||||
|
> |
||||||
|
{ t('nevermind') } |
||||||
|
</Button> |
||||||
|
<Button |
||||||
|
type="secondary" |
||||||
|
className="modal-container__footer-button" |
||||||
|
onClick={() => this.handleReset()} |
||||||
|
> |
||||||
|
{ t('reset') } |
||||||
|
</Button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default ConfirmResetAccount |
@ -0,0 +1,13 @@ |
|||||||
|
import { connect } from 'react-redux' |
||||||
|
import ConfirmResetAccount from './confirm-reset-account.component' |
||||||
|
|
||||||
|
const { hideModal, resetAccount } = require('../../../actions') |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
hideModal: () => dispatch(hideModal()), |
||||||
|
resetAccount: () => dispatch(resetAccount()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(null, mapDispatchToProps)(ConfirmResetAccount) |
@ -0,0 +1,2 @@ |
|||||||
|
import ConfirmResetAccount from './confirm-reset-account.container' |
||||||
|
module.exports = ConfirmResetAccount |
@ -1 +1,52 @@ |
|||||||
@import './transaction-confirmed/index'; |
.modal-container { |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background-color: #fff; |
||||||
|
display: flex; |
||||||
|
flex-flow: column; |
||||||
|
border-radius: 8px; |
||||||
|
|
||||||
|
&__title { |
||||||
|
font-size: 1.5rem; |
||||||
|
font-weight: 500; |
||||||
|
padding: 16px 0; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
&__description { |
||||||
|
text-align: center; |
||||||
|
font-size: .875rem; |
||||||
|
} |
||||||
|
|
||||||
|
&__content { |
||||||
|
overflow-y: auto; |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
padding: 32px; |
||||||
|
|
||||||
|
@media screen and (max-width: 575px) { |
||||||
|
justify-content: center; |
||||||
|
padding: 28px 20px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&__footer { |
||||||
|
display: flex; |
||||||
|
flex-flow: row; |
||||||
|
justify-content: center; |
||||||
|
border-top: 1px solid #d2d8dd; |
||||||
|
padding: 16px; |
||||||
|
flex: 0 0 auto; |
||||||
|
|
||||||
|
&-button { |
||||||
|
min-width: 0; |
||||||
|
margin-right: 16px; |
||||||
|
|
||||||
|
&:last-of-type { |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
@ -1,46 +0,0 @@ |
|||||||
const { Component } = require('react') |
|
||||||
const PropTypes = require('prop-types') |
|
||||||
const h = require('react-hyperscript') |
|
||||||
const connect = require('react-redux').connect |
|
||||||
const actions = require('../../../actions') |
|
||||||
const NotifcationModal = require('../notification-modal') |
|
||||||
|
|
||||||
class ConfirmResetAccount extends Component { |
|
||||||
render () { |
|
||||||
const { resetAccount } = this.props |
|
||||||
|
|
||||||
return h(NotifcationModal, { |
|
||||||
header: 'Are you sure you want to reset account?', |
|
||||||
message: h('div', [ |
|
||||||
|
|
||||||
h('span', `Resetting is for developer use only. This button wipes the current account's transaction history,
|
|
||||||
which is used to calculate the current account nonce. `),
|
|
||||||
|
|
||||||
h('a.notification-modal__link', { |
|
||||||
href: 'http://metamask.helpscoutdocs.com/article/36-resetting-an-account', |
|
||||||
target: '_blank', |
|
||||||
onClick (event) { global.platform.openWindow({ url: event.target.href }) }, |
|
||||||
}, 'Read more.'), |
|
||||||
|
|
||||||
]), |
|
||||||
showCancelButton: true, |
|
||||||
showConfirmButton: true, |
|
||||||
onConfirm: resetAccount, |
|
||||||
|
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
ConfirmResetAccount.propTypes = { |
|
||||||
resetAccount: PropTypes.func, |
|
||||||
} |
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => { |
|
||||||
return { |
|
||||||
resetAccount: () => { |
|
||||||
dispatch(actions.resetAccount()) |
|
||||||
}, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = connect(null, mapDispatchToProps)(ConfirmResetAccount) |
|
@ -0,0 +1,2 @@ |
|||||||
|
import Notification from './notification.container' |
||||||
|
module.exports = Notification |
@ -0,0 +1,30 @@ |
|||||||
|
import React from 'react' |
||||||
|
import PropTypes from 'prop-types' |
||||||
|
import Button from '../../button' |
||||||
|
|
||||||
|
const Notification = (props, context) => { |
||||||
|
return ( |
||||||
|
<div className="modal-container"> |
||||||
|
{ props.children } |
||||||
|
<div className="modal-container__footer"> |
||||||
|
<Button |
||||||
|
type="primary" |
||||||
|
onClick={() => props.onHide()} |
||||||
|
> |
||||||
|
{ context.t('ok') } |
||||||
|
</Button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
Notification.propTypes = { |
||||||
|
onHide: PropTypes.func.isRequired, |
||||||
|
children: PropTypes.element, |
||||||
|
} |
||||||
|
|
||||||
|
Notification.contextTypes = { |
||||||
|
t: PropTypes.func, |
||||||
|
} |
||||||
|
|
||||||
|
export default Notification |
@ -0,0 +1,38 @@ |
|||||||
|
import { connect } from 'react-redux' |
||||||
|
import Notification from './notification.component' |
||||||
|
|
||||||
|
const { hideModal } = require('../../../actions') |
||||||
|
|
||||||
|
const mapStateToProps = state => { |
||||||
|
const { appState: { modal: { modalState: { props } } } } = state |
||||||
|
const { onHide } = props |
||||||
|
return { |
||||||
|
onHide, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => { |
||||||
|
return { |
||||||
|
hideModal: () => dispatch(hideModal()), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const mergeProps = (stateProps, dispatchProps, ownProps) => { |
||||||
|
const { onHide, ...otherStateProps } = stateProps |
||||||
|
const { hideModal, ...otherDispatchProps } = dispatchProps |
||||||
|
|
||||||
|
return { |
||||||
|
...otherStateProps, |
||||||
|
...otherDispatchProps, |
||||||
|
...ownProps, |
||||||
|
onHide: () => { |
||||||
|
hideModal() |
||||||
|
|
||||||
|
if (onHide && typeof onHide === 'function') { |
||||||
|
onHide() |
||||||
|
} |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notification) |
@ -1,2 +1,2 @@ |
|||||||
import TransactionConfirmed from './transaction-confirmed.container' |
import TransactionConfirmed from './transaction-confirmed.component' |
||||||
module.exports = TransactionConfirmed |
module.exports = TransactionConfirmed |
||||||
|
@ -1,21 +0,0 @@ |
|||||||
.transaction-confirmed { |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
align-items: center; |
|
||||||
padding: 32px; |
|
||||||
|
|
||||||
&__title { |
|
||||||
font-size: 2rem; |
|
||||||
padding: 16px 0; |
|
||||||
} |
|
||||||
|
|
||||||
&__description { |
|
||||||
text-align: center; |
|
||||||
font-size: .875rem; |
|
||||||
line-height: 1.5rem; |
|
||||||
} |
|
||||||
|
|
||||||
@media screen and (max-width: 575px) { |
|
||||||
justify-content: center; |
|
||||||
} |
|
||||||
} |
|
@ -1,20 +0,0 @@ |
|||||||
import { connect } from 'react-redux' |
|
||||||
import TransactionConfirmed from './transaction-confirmed.component' |
|
||||||
|
|
||||||
const { hideModal } = require('../../../actions') |
|
||||||
|
|
||||||
const mapStateToProps = state => { |
|
||||||
const { appState: { modal: { modalState: { props } } } } = state |
|
||||||
const { onHide } = props |
|
||||||
return { |
|
||||||
onHide, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => { |
|
||||||
return { |
|
||||||
hideModal: () => dispatch(hideModal()), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(TransactionConfirmed) |
|
@ -0,0 +1,2 @@ |
|||||||
|
import WelcomeBeta from './welcome-beta.component' |
||||||
|
module.exports = WelcomeBeta |
@ -0,0 +1,23 @@ |
|||||||
|
import React from 'react' |
||||||
|
import PropTypes from 'prop-types' |
||||||
|
|
||||||
|
const TransactionConfirmed = (props, context) => { |
||||||
|
const { t } = context |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="modal-container__content"> |
||||||
|
<div className="modal-container__title"> |
||||||
|
{ `${t('uiWelcome')}` } |
||||||
|
</div> |
||||||
|
<div className="modal-container__description"> |
||||||
|
{ t('uiWelcomeMessage') } |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
TransactionConfirmed.contextTypes = { |
||||||
|
t: PropTypes.func, |
||||||
|
} |
||||||
|
|
||||||
|
export default TransactionConfirmed |
@ -0,0 +1,2 @@ |
|||||||
|
import SelectedAccount from './selected-account.container' |
||||||
|
module.exports = SelectedAccount |
@ -0,0 +1,38 @@ |
|||||||
|
.selected-account { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
flex: 1; |
||||||
|
|
||||||
|
&__name { |
||||||
|
max-width: 200px; |
||||||
|
text-overflow: ellipsis; |
||||||
|
overflow: hidden; |
||||||
|
white-space: nowrap; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
|
||||||
|
&__address { |
||||||
|
font-size: .75rem; |
||||||
|
color: $silver-chalice; |
||||||
|
} |
||||||
|
|
||||||
|
&__clickable { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
padding: 5px 15px; |
||||||
|
border-radius: 10px; |
||||||
|
cursor: pointer; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
background-color: #e8e6e8; |
||||||
|
} |
||||||
|
|
||||||
|
&:active { |
||||||
|
background-color: #d9d7da; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
import React, { Component } from 'react' |
||||||
|
import PropTypes from 'prop-types' |
||||||
|
import copyToClipboard from 'copy-to-clipboard' |
||||||
|
|
||||||
|
const Tooltip = require('../tooltip-v2.js') |
||||||
|
|
||||||
|
const addressStripper = (address = '') => { |
||||||
|
if (address.length < 4) { |
||||||
|
return address |
||||||
|
} |
||||||
|
|
||||||
|
return `${address.slice(0, 4)}...${address.slice(-4)}` |
||||||
|
} |
||||||
|
|
||||||
|
class SelectedAccount extends Component { |
||||||
|
state = { |
||||||
|
copied: false, |
||||||
|
} |
||||||
|
|
||||||
|
static contextTypes = { |
||||||
|
t: PropTypes.func, |
||||||
|
} |
||||||
|
|
||||||
|
static propTypes = { |
||||||
|
selectedAddress: PropTypes.string, |
||||||
|
selectedIdentity: PropTypes.object, |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
const { t } = this.context |
||||||
|
const { selectedAddress, selectedIdentity } = this.props |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="selected-account"> |
||||||
|
<Tooltip |
||||||
|
position="bottom" |
||||||
|
title={this.state.copied ? t('copiedExclamation') : t('copyToClipboard')} |
||||||
|
> |
||||||
|
<div |
||||||
|
className="selected-account__clickable" |
||||||
|
onClick={() => { |
||||||
|
this.setState({ copied: true }) |
||||||
|
setTimeout(() => this.setState({ copied: false }), 3000) |
||||||
|
copyToClipboard(selectedAddress) |
||||||
|
}} |
||||||
|
> |
||||||
|
<div className="selected-account__name"> |
||||||
|
{ selectedIdentity.name } |
||||||
|
</div> |
||||||
|
<div className="selected-account__address"> |
||||||
|
{ addressStripper(selectedAddress) } |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</Tooltip> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default SelectedAccount |
@ -0,0 +1,13 @@ |
|||||||
|
import { connect } from 'react-redux' |
||||||
|
import SelectedAccount from './selected-account.component' |
||||||
|
|
||||||
|
const selectors = require('../../selectors') |
||||||
|
|
||||||
|
const mapStateToProps = state => { |
||||||
|
return { |
||||||
|
selectedAddress: selectors.getSelectedAddress(state), |
||||||
|
selectedIdentity: selectors.getSelectedIdentity(state), |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default connect(mapStateToProps)(SelectedAccount) |
Loading…
Reference in new issue