Add in-app network switch (#203)
* add network select * new network select component * improve network switch * Fixes and refactoring * Refactoring
This commit is contained in:
parent
8acf0348db
commit
1cecd5d169
|
@ -4266,7 +4266,8 @@
|
|||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
|
@ -4284,11 +4285,13 @@
|
|||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -4301,15 +4304,18 @@
|
|||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
|
@ -4412,7 +4418,8 @@
|
|||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
|
@ -4422,6 +4429,7 @@
|
|||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
@ -4434,17 +4442,20 @@
|
|||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
|
@ -4461,6 +4472,7 @@
|
|||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -4533,7 +4545,8 @@
|
|||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
|
@ -4543,6 +4556,7 @@
|
|||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -4618,7 +4632,8 @@
|
|||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
|
@ -4648,6 +4663,7 @@
|
|||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
@ -4665,6 +4681,7 @@
|
|||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
@ -4703,11 +4720,13 @@
|
|||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true
|
||||
"bundled": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicons/favicon.ico">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito:300,400,700" rel="stylesheet">
|
||||
<title>POA Network Governance DApp</title>
|
||||
<title>POA Governance DApp</title>
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD97qDOBYZ2fH86Wq1vzhDOiSUsZGVqbVQ&libraries=places"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
53
src/App.js
53
src/App.js
|
@ -5,7 +5,7 @@ import { Route, Redirect } from 'react-router-dom'
|
|||
import { constants } from './utils/constants'
|
||||
import { getNetworkBranch } from './utils/utils'
|
||||
import { inject, observer } from 'mobx-react'
|
||||
import { messages } from './utils/messages'
|
||||
import messages from './utils/messages'
|
||||
|
||||
import './assets/stylesheets/index.css'
|
||||
|
||||
|
@ -41,16 +41,29 @@ class App extends Component {
|
|||
onNewBallotRender = () => {
|
||||
const { commonStore, contractsStore } = this.props
|
||||
|
||||
if (!contractsStore.web3Instance) {
|
||||
if (!commonStore.loading) {
|
||||
if (!commonStore.loading) {
|
||||
if (!contractsStore.injectedWeb3) {
|
||||
commonStore.hideLoading()
|
||||
swal({
|
||||
title: 'Error',
|
||||
html: messages.NO_METAMASK_MSG,
|
||||
icon: 'error',
|
||||
type: 'error'
|
||||
})
|
||||
} else if (!contractsStore.networkMatch) {
|
||||
commonStore.hideLoading()
|
||||
swal({
|
||||
title: 'Warning!',
|
||||
html: messages.networkMatchError(contractsStore.netId),
|
||||
type: 'warning'
|
||||
})
|
||||
} else if (contractsStore.votingKey && !contractsStore.isValidVotingKey) {
|
||||
commonStore.hideLoading()
|
||||
swal({
|
||||
title: 'Warning!',
|
||||
html: messages.invalidVotingKeyMsg(contractsStore.votingKey),
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
return null
|
||||
}
|
||||
return <NewBallot networkBranch={this.getVotingNetworkBranch()} />
|
||||
}
|
||||
|
@ -60,8 +73,7 @@ class App extends Component {
|
|||
}
|
||||
|
||||
onSearch = e => {
|
||||
const { commonStore } = this.props
|
||||
commonStore.setSearchTerm(e.target.value.toLowerCase())
|
||||
this.setSearchTerm(e.target.value)
|
||||
}
|
||||
|
||||
hideSearch = () => {
|
||||
|
@ -85,13 +97,28 @@ class App extends Component {
|
|||
return 'All'
|
||||
}
|
||||
|
||||
setSearchTerm = term => {
|
||||
const { commonStore } = this.props
|
||||
commonStore.setSearchTerm(term.toLowerCase())
|
||||
if (this.refs.searchBar) {
|
||||
this.refs.searchBar.setSearchTerm(term)
|
||||
}
|
||||
}
|
||||
|
||||
onNetworkChange = e => {
|
||||
this.setSearchTerm('')
|
||||
this.props.onNetworkChange(e)
|
||||
}
|
||||
|
||||
isNewBallotPage() {
|
||||
return `${constants.rootPath}/new` === this.props.location.pathname
|
||||
}
|
||||
|
||||
render() {
|
||||
const { commonStore, contractsStore } = this.props
|
||||
const networkBranch = this.getVotingNetworkBranch()
|
||||
const networkBranch = commonStore.loadingNetworkBranch
|
||||
? commonStore.loadingNetworkBranch
|
||||
: this.getVotingNetworkBranch()
|
||||
|
||||
return networkBranch ? (
|
||||
<div
|
||||
|
@ -104,10 +131,18 @@ class App extends Component {
|
|||
baseRootPath={commonStore.rootPath}
|
||||
netId={contractsStore.netId}
|
||||
networkBranch={networkBranch}
|
||||
onChange={this.onNetworkChange}
|
||||
onMenuToggle={this.toggleMobileMenu}
|
||||
showMobileMenu={this.state.showMobileMenu}
|
||||
/>
|
||||
{this.hideSearch() ? null : <SearchBar networkBranch={networkBranch} onSearch={this.onSearch} />}
|
||||
{this.hideSearch() ? null : (
|
||||
<SearchBar
|
||||
networkBranch={networkBranch}
|
||||
onSearch={this.onSearch}
|
||||
searchTerm={commonStore.searchTerm}
|
||||
ref="searchBar"
|
||||
/>
|
||||
)}
|
||||
<MainTitle text={this.getTitle()} />
|
||||
<section
|
||||
className={`lo-App_Content lo-App_Content-${networkBranch} ${
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
height: $header-height;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
|
@ -58,4 +57,4 @@
|
|||
@media (min-width: $breakpoint-md) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.nl-IconNetwork_Path {
|
||||
@include menu-icon-colors();
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
.NetworkSelect {
|
||||
display: flex;
|
||||
@media (min-width: $breakpoint-md) {
|
||||
position: relative;
|
||||
margin-left: 34px;
|
||||
&:hover {
|
||||
.NetworkSelect_List {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sw-Header_Content .NetworkSelect {
|
||||
display: none;
|
||||
@media (min-width: $breakpoint-md) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.NetworkSelect_Top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: .7;
|
||||
transition: .15s ease-in;
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
@media (min-width: $breakpoint-md) {
|
||||
.nl-IconNetwork_Arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nl-NavigationLinks_Link.opacityFull {
|
||||
opacity: 1;
|
||||
flex-direction: column;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.nl-IconNetwork_Arrow {
|
||||
margin-left: 10px;
|
||||
transition: .15s ease-in;
|
||||
path {
|
||||
fill: #fff;
|
||||
opacity: .52;
|
||||
}
|
||||
}
|
||||
|
||||
.NetworkSelect_List {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
@media (min-width: $breakpoint-md) {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
background-color: #fff;
|
||||
width: 180px;
|
||||
border-radius: 4px 0 4px 4px;
|
||||
box-shadow: 0 5px 10px rgba(#000, .05);
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
li.currentNetwork {
|
||||
@media (max-width: $breakpoint-md) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
button {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
transition: .15s ease-in;
|
||||
height: 50px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
@media (min-width: $breakpoint-md) {
|
||||
padding: 8px 18px;
|
||||
height: auto;
|
||||
color: $base-text-color;
|
||||
justify-content: flex-start;
|
||||
&:hover {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
.top-Select {
|
||||
flex-grow: 1;
|
||||
max-width: 140px;
|
||||
|
||||
@media (min-width: $breakpoint-xl) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@
|
|||
@import "IconGithub";
|
||||
@import "IconLoadMore";
|
||||
@import "IconMobileMenu";
|
||||
@import "IconNetwork";
|
||||
@import "IconPOA";
|
||||
@import "IconTelegram";
|
||||
@import "IconToFinalize";
|
||||
|
@ -47,9 +48,11 @@
|
|||
@import "NewBallot";
|
||||
@import "NewBallotMenu";
|
||||
@import "NewBallotMenuInfo";
|
||||
@import "NetworkSelect";
|
||||
@import "SearchBar";
|
||||
@import "Select";
|
||||
@import "Separator";
|
||||
@import "SocialIcons";
|
||||
@import "Validator";
|
||||
@import "VoteProgressBar";
|
||||
@import "Votes";
|
||||
@import "Votes";
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -7,7 +7,7 @@ import { BallotInfoContainer } from '../BallotInfoContainer'
|
|||
import { Votes } from '../Votes'
|
||||
import { getNetworkBranch } from '../../utils/utils'
|
||||
import { inject, observer } from 'mobx-react'
|
||||
import { messages } from '../../utils/messages'
|
||||
import messages from '../../utils/messages'
|
||||
import { observable, action, computed } from 'mobx'
|
||||
import { sendTransactionByVotingKey } from '../../utils/helpers'
|
||||
|
||||
|
@ -374,6 +374,9 @@ export class BallotCard extends React.Component {
|
|||
if (!contractsStore.votingKey) {
|
||||
swal('Warning!', messages.NO_METAMASK_MSG, 'warning')
|
||||
return
|
||||
} else if (!contractsStore.networkMatch) {
|
||||
swal('Warning!', messages.networkMatchError(contractsStore.netId), 'warning')
|
||||
return
|
||||
} else if (!contractsStore.isValidVotingKey) {
|
||||
swal('Warning!', messages.invalidVotingKeyMsg(contractsStore.votingKey), 'warning')
|
||||
return
|
||||
|
@ -511,6 +514,9 @@ export class BallotCard extends React.Component {
|
|||
if (!contractsStore.votingKey) {
|
||||
swal('Warning!', messages.NO_METAMASK_MSG, 'warning')
|
||||
return
|
||||
} else if (!contractsStore.networkMatch) {
|
||||
swal('Warning!', messages.networkMatchError(contractsStore.netId), 'warning')
|
||||
return
|
||||
} else if (!contractsStore.isValidVotingKey) {
|
||||
swal('Warning!', messages.invalidVotingKeyMsg(contractsStore.votingKey), 'warning')
|
||||
return
|
||||
|
|
|
@ -2,14 +2,12 @@ import React from 'react'
|
|||
import { FormInput } from '../FormInput'
|
||||
import { FormSelect } from '../FormSelect'
|
||||
import { inject, observer } from 'mobx-react'
|
||||
import { constants } from '../../utils/constants'
|
||||
import { getNetworkName } from '../../utils/utils'
|
||||
|
||||
@inject('ballotStore', 'contractsStore')
|
||||
@inject('ballotStore')
|
||||
@observer
|
||||
export class BallotProxyMetadata extends React.Component {
|
||||
render() {
|
||||
const { ballotStore, contractsStore, networkBranch } = this.props
|
||||
const { ballotStore, networkBranch } = this.props
|
||||
let options = [
|
||||
/*0*/ { value: '', label: '' },
|
||||
/*1*/ { value: '1', label: ballotStore.ProxyBallotType[1] }, // KeysManager
|
||||
|
|
|
@ -1,20 +1,31 @@
|
|||
import React from 'react'
|
||||
|
||||
import { ButtonNewBallot } from '../ButtonNewBallot'
|
||||
import { IconMobileMenu } from '../IconMobileMenu'
|
||||
import { Logo } from '../Logo'
|
||||
import { MobileMenuLinks } from '../MobileMenuLinks'
|
||||
import { NavigationLinks } from '../NavigationLinks'
|
||||
import NetworkSelect from '../NetworkSelect'
|
||||
|
||||
export const Header = ({ baseRootPath = '', networkBranch = undefined, onMenuToggle, showMobileMenu = false }) => {
|
||||
export const Header = ({
|
||||
baseRootPath = '',
|
||||
networkBranch = undefined,
|
||||
onChange,
|
||||
onMenuToggle,
|
||||
showMobileMenu = false
|
||||
}) => {
|
||||
return (
|
||||
<header className={`sw-Header sw-Header-${networkBranch} ${showMobileMenu ? 'sw-Header-menu-open' : ''}`}>
|
||||
{showMobileMenu ? <MobileMenuLinks networkBranch={networkBranch} onClick={onMenuToggle} /> : null}
|
||||
{showMobileMenu ? (
|
||||
<MobileMenuLinks networkBranch={networkBranch} onClick={onMenuToggle} onNetworkChange={onChange} />
|
||||
) : null}
|
||||
<div className="sw-Header_Content">
|
||||
<Logo networkBranch={networkBranch} href={baseRootPath} />
|
||||
<div className="sw-Header_Links">
|
||||
<NavigationLinks networkBranch={networkBranch} />
|
||||
<ButtonNewBallot networkBranch={networkBranch} />
|
||||
</div>
|
||||
<NetworkSelect networkBranch={networkBranch} onChange={onChange} />
|
||||
<IconMobileMenu networkBranch={networkBranch} isOpen={showMobileMenu} onClick={onMenuToggle} />
|
||||
</div>
|
||||
</header>
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import React from 'react'
|
||||
import { ButtonNewBallot } from '../ButtonNewBallot'
|
||||
import { NavigationLinks } from '../NavigationLinks'
|
||||
import NetworkSelect from '../NetworkSelect'
|
||||
|
||||
export const MobileMenuLinks = ({ onClick, networkBranch }) => {
|
||||
export const MobileMenuLinks = ({ onClick, networkBranch, onNetworkChange }) => {
|
||||
return (
|
||||
<div className={`hd-MobileMenuLinks hd-MobileMenuLinks-${networkBranch}`} onClick={onClick}>
|
||||
<NavigationLinks networkBranch={networkBranch} />
|
||||
<ButtonNewBallot networkBranch={networkBranch} />
|
||||
<NetworkSelect networkBranch={networkBranch} onChange={onNetworkChange} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
import React, { Component } from 'react'
|
||||
import { constants } from '../../utils/constants'
|
||||
|
||||
export default class NetworkSelect extends Component {
|
||||
changeNetworkRPC(e) {
|
||||
e.preventDefault()
|
||||
let getCurrentClickedLink = e.target.innerHTML
|
||||
let getCurrentClickedLinkId = ''
|
||||
for (const _netId in constants.NETWORKS) {
|
||||
if (constants.NETWORKS[_netId].FULLNAME === getCurrentClickedLink) {
|
||||
getCurrentClickedLinkId = _netId
|
||||
}
|
||||
}
|
||||
this.props.onChange({ value: getCurrentClickedLinkId })
|
||||
}
|
||||
|
||||
render() {
|
||||
let networkFullNames = []
|
||||
let currentNetworkFullName = ''
|
||||
|
||||
const networks = constants.NETWORKS
|
||||
|
||||
let netIds = []
|
||||
Object.keys(networks)
|
||||
.sort((a, b) => (networks[a].SORTORDER > networks[b].SORTORDER ? 1 : -1))
|
||||
.forEach(function(_netId) {
|
||||
netIds.push(_netId)
|
||||
})
|
||||
|
||||
let selectedNetworkIndex = -1
|
||||
|
||||
netIds.forEach(_netId => {
|
||||
networkFullNames.push(networks[_netId].FULLNAME)
|
||||
if (networks[_netId].BRANCH === this.props.networkBranch) {
|
||||
currentNetworkFullName = networks[_netId].FULLNAME
|
||||
selectedNetworkIndex = networkFullNames.length - 1
|
||||
}
|
||||
})
|
||||
|
||||
const listItems = networkFullNames.map((name, index) => {
|
||||
let className = ''
|
||||
if (index === selectedNetworkIndex) {
|
||||
className = 'currentNetwork'
|
||||
}
|
||||
return (
|
||||
<li key={name.toString()} className={className}>
|
||||
<button onClick={e => this.changeNetworkRPC(e)}>{name}</button>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<div className={`NetworkSelect nl-NavigationLinks_Link opacityFull`}>
|
||||
<div className={`NetworkSelect_Top`}>
|
||||
<svg className={`nl-IconNetwork`} xmlns="http://www.w3.org/2000/svg" width="18" height="18">
|
||||
<path
|
||||
className={`nl-IconNetwork_Path nl-IconNetwork_Path-${this.props.networkBranch}`}
|
||||
d="M9 18a9 9 0 0 1-9-9 9 9 0 0 1 9-9 9 9 0 0 1 9 9 9 9 0 0 1-9 9zm6.923-8h-1.974c-.116 1.85-.525 3.539-1.167 4.876A6.993 6.993 0 0 0 15.923 10zM9 16c1.51 0 2.747-2.612 2.957-6H6.043c.21 3.388 1.447 6 2.957 6zm-3.782-1.124C4.576 13.539 4.167 11.85 4.051 10H2.077a6.993 6.993 0 0 0 3.141 4.876zM2.077 8h1.974c.116-1.85.525-3.538 1.167-4.876A6.993 6.993 0 0 0 2.077 8zM9 2C7.49 2 6.253 4.612 6.043 8h5.914C11.747 4.612 10.51 2 9 2zm3.782 1.124C13.424 4.462 13.833 6.15 13.949 8h1.974a6.993 6.993 0 0 0-3.141-4.876z"
|
||||
/>
|
||||
</svg>
|
||||
<span className={`nl-NavigationLinks_Text nl-NavigationLinks_Text-${this.props.networkBranch}`}>
|
||||
{currentNetworkFullName}
|
||||
</span>
|
||||
<svg className={`nl-IconNetwork_Arrow`} xmlns="http://www.w3.org/2000/svg" width="8" height="4">
|
||||
<path d="M0 0h8L4 4 0 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<ul className={`NetworkSelect_List`}>{listItems}</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ import { Validator } from '../Validator'
|
|||
import { constants } from '../../utils/constants'
|
||||
import { getNetworkBranch } from '../../utils/utils'
|
||||
import { inject, observer } from 'mobx-react'
|
||||
import { messages } from '../../utils/messages'
|
||||
import messages from '../../utils/messages'
|
||||
import { sendTransactionByVotingKey } from '../../utils/helpers'
|
||||
|
||||
@inject('commonStore', 'ballotStore', 'validatorStore', 'contractsStore', 'routing', 'ballotsStore')
|
||||
|
@ -40,9 +40,10 @@ export class NewBallot extends React.Component {
|
|||
}
|
||||
|
||||
checkValidation() {
|
||||
const { commonStore, contractsStore, ballotStore, validatorStore } = this.props
|
||||
const { commonStore, contractsStore, ballotStore } = this.props
|
||||
|
||||
// Temporarily commented (until we implement https://github.com/poanetwork/poa-dapps-voting/issues/120)
|
||||
// const { validatorStore } = this.props
|
||||
// if (ballotStore.isNewValidatorPersonalData) {
|
||||
// for (let validatorProp in validatorStore) {
|
||||
// if (validatorStore[validatorProp].length === 0) {
|
||||
|
@ -255,6 +256,9 @@ export class NewBallot extends React.Component {
|
|||
if (!contractsStore.votingKey) {
|
||||
swal('Warning!', messages.NO_METAMASK_MSG, 'warning')
|
||||
return
|
||||
} else if (!contractsStore.networkMatch) {
|
||||
swal('Warning!', messages.networkMatchError(contractsStore.netId), 'warning')
|
||||
return
|
||||
} else if (!contractsStore.isValidVotingKey) {
|
||||
swal('Warning!', messages.invalidVotingKeyMsg(contractsStore.votingKey), 'warning')
|
||||
return
|
||||
|
|
|
@ -1,16 +1,36 @@
|
|||
import React from 'react'
|
||||
|
||||
export const SearchBar = ({ extraClassName = '', networkBranch = false, onSearch }) => {
|
||||
return (
|
||||
<div className={`sw-SearchBar sw-SearchBar-${networkBranch} ${extraClassName}`}>
|
||||
<div className="sw-SearchBar_Content">
|
||||
<input
|
||||
className={`sw-SearchBar_Input sw-SearchBar_Input-${networkBranch}`}
|
||||
onChange={onSearch}
|
||||
placeholder="Search..."
|
||||
type="search"
|
||||
/>
|
||||
export class SearchBar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { searchTerm: '' }
|
||||
}
|
||||
|
||||
setSearchTerm(searchTerm) {
|
||||
this.setState({ searchTerm })
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { searchTerm } = this.props
|
||||
if (searchTerm !== undefined) {
|
||||
this.setSearchTerm(searchTerm)
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { networkBranch, onSearch } = this.props
|
||||
return (
|
||||
<div className={`sw-SearchBar sw-SearchBar-${networkBranch}`}>
|
||||
<div className="sw-SearchBar_Content">
|
||||
<input
|
||||
className={`sw-SearchBar_Input sw-SearchBar_Input-${networkBranch}`}
|
||||
onChange={onSearch}
|
||||
placeholder="Search..."
|
||||
type="search"
|
||||
value={this.state.searchTerm}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import { FormAutocomplete } from '../FormAutocomplete'
|
||||
import { FormInput } from '../FormInput'
|
||||
import { FormSelect } from '../FormSelect'
|
||||
//import { FormAutocomplete } from '../FormAutocomplete'
|
||||
//import { FormInput } from '../FormInput'
|
||||
//import { FormSelect } from '../FormSelect'
|
||||
import { constants } from '../../utils/constants'
|
||||
import { geocodeByAddress } from 'react-places-autocomplete'
|
||||
import { inject, observer } from 'mobx-react'
|
||||
|
@ -64,6 +64,7 @@ export class Validator extends React.Component {
|
|||
|
||||
render() {
|
||||
return null // Temporarily empty (until we implement https://github.com/poanetwork/poa-dapps-voting/issues/120)
|
||||
/*
|
||||
const { validatorStore, networkBranch } = this.props
|
||||
const inputProps = {
|
||||
value: validatorStore.address,
|
||||
|
@ -190,5 +191,6 @@ export class Validator extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { constants } from '../utils/constants'
|
||||
import { messages } from '../utils/messages'
|
||||
import messages from '../utils/messages'
|
||||
import swal from 'sweetalert2'
|
||||
|
||||
function addressesURL(branch) {
|
||||
|
|
126
src/index.js
126
src/index.js
|
@ -16,6 +16,7 @@ import { Router, Route } from 'react-router-dom'
|
|||
import { RouterStore, syncHistoryWithStore } from 'mobx-react-router'
|
||||
import { constants } from './utils/constants'
|
||||
import { getContractsAddresses } from './contracts/addresses'
|
||||
import { getNetworkBranch } from './utils/utils'
|
||||
|
||||
const browserHistory = createBrowserHistory()
|
||||
const routingStore = new RouterStore()
|
||||
|
@ -32,56 +33,14 @@ class AppMainRouter extends Component {
|
|||
super(props)
|
||||
commonStore.showLoading()
|
||||
|
||||
getWeb3()
|
||||
window.addEventListener('load', () => this.initChain())
|
||||
}
|
||||
|
||||
initChain = () => {
|
||||
const netId = window.localStorage.netId
|
||||
getWeb3(netId, this.onAccountChange)
|
||||
.then(async web3Config => {
|
||||
await getContractsAddresses(constants.NETWORKS[web3Config.netId].BRANCH)
|
||||
|
||||
contractsStore.setWeb3Instance(web3Config)
|
||||
|
||||
const setPoaConsensus = contractsStore.setPoaConsensus(web3Config)
|
||||
const setBallotsStorage = contractsStore.setBallotsStorage(web3Config)
|
||||
const setKeysManager = contractsStore.setKeysManager(web3Config)
|
||||
const setProxyStorage = contractsStore.setProxyStorage(web3Config)
|
||||
const setVotingToChangeKeys = contractsStore.setVotingToChangeKeys(web3Config)
|
||||
const setVotingToChangeMinThreshold = contractsStore.setVotingToChangeMinThreshold(web3Config)
|
||||
const setVotingToChangeProxy = contractsStore.setVotingToChangeProxy(web3Config)
|
||||
const setValidatorMetadata = contractsStore.setValidatorMetadata(web3Config)
|
||||
|
||||
let promises = [
|
||||
setPoaConsensus,
|
||||
setBallotsStorage,
|
||||
setKeysManager,
|
||||
setProxyStorage,
|
||||
setVotingToChangeKeys,
|
||||
setVotingToChangeMinThreshold,
|
||||
setVotingToChangeProxy,
|
||||
setValidatorMetadata
|
||||
]
|
||||
|
||||
const networkName = constants.NETWORKS[web3Config.netId].NAME.toLowerCase()
|
||||
if (networkName === constants.CORE || networkName === constants.SOKOL) {
|
||||
// if we're in Core or Sokol
|
||||
promises.push(contractsStore.setEmissionFunds(web3Config))
|
||||
promises.push(contractsStore.setVotingToManageEmissionFunds(web3Config))
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
await contractsStore.setMiningKey(web3Config)
|
||||
await contractsStore.setVotingKey(web3Config)
|
||||
|
||||
contractsStore.getKeysBallotThreshold()
|
||||
contractsStore.getProxyBallotThreshold()
|
||||
contractsStore.getBallotCancelingThreshold()
|
||||
|
||||
await contractsStore.getBallotsLimits()
|
||||
|
||||
await contractsStore.getAllValidatorMetadata()
|
||||
await contractsStore.getAllBallots()
|
||||
|
||||
console.log('votingKey', contractsStore.votingKey)
|
||||
console.log('miningKey', contractsStore.miningKey)
|
||||
|
||||
await this.initialize(web3Config)
|
||||
commonStore.hideLoading()
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -90,17 +49,82 @@ class AppMainRouter extends Component {
|
|||
swal({
|
||||
title: 'Error',
|
||||
html: generateElement(error.message),
|
||||
icon: 'error',
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
initialize = async web3Config => {
|
||||
await getContractsAddresses(constants.NETWORKS[web3Config.netId].BRANCH)
|
||||
|
||||
contractsStore.setWeb3Instance(web3Config)
|
||||
|
||||
const setPoaConsensus = contractsStore.setPoaConsensus(web3Config)
|
||||
const setBallotsStorage = contractsStore.setBallotsStorage(web3Config)
|
||||
const setKeysManager = contractsStore.setKeysManager(web3Config)
|
||||
const setProxyStorage = contractsStore.setProxyStorage(web3Config)
|
||||
const setVotingToChangeKeys = contractsStore.setVotingToChangeKeys(web3Config)
|
||||
const setVotingToChangeMinThreshold = contractsStore.setVotingToChangeMinThreshold(web3Config)
|
||||
const setVotingToChangeProxy = contractsStore.setVotingToChangeProxy(web3Config)
|
||||
const setValidatorMetadata = contractsStore.setValidatorMetadata(web3Config)
|
||||
|
||||
let promises = [
|
||||
setPoaConsensus,
|
||||
setBallotsStorage,
|
||||
setKeysManager,
|
||||
setProxyStorage,
|
||||
setVotingToChangeKeys,
|
||||
setVotingToChangeMinThreshold,
|
||||
setVotingToChangeProxy,
|
||||
setValidatorMetadata
|
||||
]
|
||||
|
||||
const networkName = constants.NETWORKS[web3Config.netId].NAME.toLowerCase()
|
||||
if (networkName === constants.CORE || networkName === constants.SOKOL) {
|
||||
// if we're in Core or Sokol
|
||||
promises.push(contractsStore.setEmissionFunds(web3Config))
|
||||
promises.push(contractsStore.setVotingToManageEmissionFunds(web3Config))
|
||||
}
|
||||
|
||||
await Promise.all(promises)
|
||||
|
||||
await this.setKeys(web3Config.defaultAccount)
|
||||
|
||||
contractsStore.getKeysBallotThreshold()
|
||||
contractsStore.getProxyBallotThreshold()
|
||||
contractsStore.getBallotCancelingThreshold()
|
||||
|
||||
await contractsStore.getBallotsLimits()
|
||||
|
||||
await contractsStore.getAllValidatorMetadata()
|
||||
await contractsStore.getAllBallots()
|
||||
}
|
||||
|
||||
onNetworkChange = e => {
|
||||
commonStore.showLoading(getNetworkBranch(e.value))
|
||||
window.localStorage.netId = e.value
|
||||
contractsStore.resetContracts()
|
||||
ballotsStore.reset()
|
||||
this.initChain()
|
||||
}
|
||||
|
||||
onAccountChange = account => {
|
||||
this.setKeys(account)
|
||||
}
|
||||
|
||||
setKeys = async account => {
|
||||
await contractsStore.setMiningKey(account)
|
||||
await contractsStore.setVotingKey(account)
|
||||
|
||||
console.log('votingKey', contractsStore.votingKey)
|
||||
console.log('miningKey', contractsStore.miningKey)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Provider {...stores}>
|
||||
<Router history={history}>
|
||||
<Route component={App} />
|
||||
<Route component={props => <App onNetworkChange={this.onNetworkChange} {...props} />} />
|
||||
</Router>
|
||||
</Provider>
|
||||
)
|
||||
|
|
|
@ -4,6 +4,10 @@ class BallotsStore {
|
|||
@observable ballotCards
|
||||
|
||||
constructor() {
|
||||
this.reset()
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.ballotCards = []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { observable, action } from 'mobx'
|
|||
|
||||
class CommonStore {
|
||||
@observable loading
|
||||
@observable loadingNetworkBranch
|
||||
@observable rootPath
|
||||
@observable isActiveFilter
|
||||
@observable isToFinalizeFilter
|
||||
|
@ -10,6 +11,7 @@ class CommonStore {
|
|||
|
||||
constructor() {
|
||||
this.loading = false
|
||||
this.loadingNetworkBranch = null
|
||||
this.isActiveFilter = false
|
||||
this.isToFinalizeFilter = false
|
||||
this.rootPath = '/poa-dapps-voting'
|
||||
|
@ -17,13 +19,15 @@ class CommonStore {
|
|||
}
|
||||
|
||||
@action('show loading')
|
||||
showLoading() {
|
||||
showLoading(loadingNetworkBranch) {
|
||||
this.loading = true
|
||||
this.loadingNetworkBranch = loadingNetworkBranch
|
||||
}
|
||||
|
||||
@action('hide loading')
|
||||
hideLoading() {
|
||||
this.loading = false
|
||||
this.loadingNetworkBranch = null
|
||||
}
|
||||
|
||||
@action('set search term')
|
||||
|
|
|
@ -46,6 +46,7 @@ class ContractsStore {
|
|||
@observable minBallotDuration
|
||||
@observable validatorsMetadata
|
||||
@observable netId
|
||||
@observable injectedWeb3
|
||||
|
||||
constructor() {
|
||||
this.votingKey = null
|
||||
|
@ -53,6 +54,7 @@ class ContractsStore {
|
|||
this.validatorsMetadata = {}
|
||||
this.validatorLimits = { keys: null, minThreshold: null, proxy: null }
|
||||
this.minBallotDuration = { keys: 0, minThreshold: 0, proxy: 0 }
|
||||
this.injectedWeb3 = false
|
||||
}
|
||||
|
||||
@computed
|
||||
|
@ -84,6 +86,22 @@ class ContractsStore {
|
|||
setWeb3Instance = web3Config => {
|
||||
this.web3Instance = web3Config.web3Instance
|
||||
this.netId = web3Config.netId
|
||||
this.injectedWeb3 = web3Config.injectedWeb3
|
||||
this.networkMatch = web3Config.networkMatch
|
||||
}
|
||||
|
||||
@action('Reset contracts')
|
||||
resetContracts = () => {
|
||||
this.poaConsensus = null
|
||||
this.ballotsStorage = null
|
||||
this.emissionFunds = null
|
||||
this.keysManager = null
|
||||
this.proxyStorage = null
|
||||
this.votingToChangeKeys = null
|
||||
this.votingToChangeMinThreshold = null
|
||||
this.votingToChangeProxy = null
|
||||
this.votingToManageEmissionFunds = null
|
||||
this.validatorMetadata = null
|
||||
}
|
||||
|
||||
@action('Set PoA Consensus contract')
|
||||
|
@ -182,14 +200,14 @@ class ContractsStore {
|
|||
}
|
||||
|
||||
@action('Set voting key')
|
||||
setVotingKey = web3Config => {
|
||||
this.votingKey = web3Config.defaultAccount
|
||||
setVotingKey = account => {
|
||||
this.votingKey = account
|
||||
}
|
||||
|
||||
@action('Set mining key')
|
||||
setMiningKey = async web3Config => {
|
||||
setMiningKey = async account => {
|
||||
try {
|
||||
this.miningKey = await this.keysManager.instance.methods.miningKeyByVoting(web3Config.defaultAccount).call()
|
||||
this.miningKey = await this.keysManager.instance.methods.miningKeyByVoting(account).call()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
this.miningKey = '0x0000000000000000000000000000000000000000'
|
||||
|
|
|
@ -59,27 +59,31 @@ constants.KOVAN = 'kovan'
|
|||
constants.NETWORKS = {
|
||||
'42': {
|
||||
NAME: 'Kovan',
|
||||
FULLNAME: 'Kovan Testnet',
|
||||
RPC: 'https://kovan.infura.io/v3/1125fe73d87c4e5396678f4e3089b3dd',
|
||||
BRANCH: constants.KOVAN,
|
||||
TESTNET: true
|
||||
SORTORDER: 3
|
||||
},
|
||||
'77': {
|
||||
NAME: 'Sokol',
|
||||
FULLNAME: 'Sokol Testnet',
|
||||
RPC: 'https://sokol.poa.network',
|
||||
BRANCH: constants.SOKOL,
|
||||
TESTNET: true
|
||||
SORTORDER: 4
|
||||
},
|
||||
'99': {
|
||||
NAME: 'Core',
|
||||
FULLNAME: 'POA Core',
|
||||
RPC: 'https://core.poa.network',
|
||||
BRANCH: constants.CORE,
|
||||
TESTNET: false
|
||||
SORTORDER: 1
|
||||
},
|
||||
'100': {
|
||||
NAME: 'Dai',
|
||||
NAME: 'xDai',
|
||||
FULLNAME: 'xDai Stable Chain',
|
||||
RPC: 'https://dai.poa.network',
|
||||
BRANCH: constants.DAI,
|
||||
TESTNET: false
|
||||
SORTORDER: 2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,80 +1,71 @@
|
|||
import Web3 from 'web3'
|
||||
import { messages } from './messages'
|
||||
import helpers from './helpers'
|
||||
import { constants } from './constants'
|
||||
import { netIdByName } from './helpers'
|
||||
|
||||
let getWeb3 = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Wait for loading completion to avoid race conditions with web3 injection timing.
|
||||
window.addEventListener('load', async () => {
|
||||
let web3 = null
|
||||
const defaultNetId = helpers.netIdByBranch(constants.CORE)
|
||||
|
||||
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
|
||||
if (window.ethereum) {
|
||||
web3 = new Web3(window.ethereum)
|
||||
console.log('Injected web3 detected.')
|
||||
try {
|
||||
await window.ethereum.enable()
|
||||
} catch (e) {
|
||||
console.error('User denied account access')
|
||||
reject({ message: messages.USER_DENIED_ACCOUNT_ACCESS })
|
||||
return
|
||||
}
|
||||
} else if (typeof window.web3 !== 'undefined') {
|
||||
web3 = new Web3(window.web3.currentProvider)
|
||||
console.log('Injected web3 detected.')
|
||||
export default async function getWeb3(netId = defaultNetId, onAccountChange) {
|
||||
let web3 = null
|
||||
netId = Number(netId)
|
||||
|
||||
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
|
||||
if (window.ethereum) {
|
||||
web3 = new Web3(window.ethereum)
|
||||
console.log('Injected web3 detected.')
|
||||
try {
|
||||
await window.ethereum.enable()
|
||||
} catch (e) {
|
||||
throw Error('You have denied access to your accounts')
|
||||
}
|
||||
window.ethereum.autoRefreshOnNetworkChange = true
|
||||
} else if (window.web3) {
|
||||
web3 = new Web3(window.web3.currentProvider)
|
||||
console.log('Injected web3 detected.')
|
||||
}
|
||||
|
||||
const network = constants.NETWORKS[netId]
|
||||
const injectedWeb3 = web3 !== null
|
||||
let netIdName = network.NAME
|
||||
let defaultAccount = null
|
||||
let networkMatch = false
|
||||
|
||||
if (web3) {
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
defaultAccount = accounts[0] || null
|
||||
|
||||
if (!defaultAccount) {
|
||||
console.error('Unlock your wallet')
|
||||
}
|
||||
|
||||
let currentAccount = defaultAccount ? defaultAccount.toLowerCase() : ''
|
||||
web3.currentProvider.publicConfigStore.on('update', function(obj) {
|
||||
const account = obj.selectedAddress
|
||||
if (account && account !== currentAccount) {
|
||||
currentAccount = account
|
||||
onAccountChange(account)
|
||||
}
|
||||
|
||||
let errorMsg = null
|
||||
let netIdName
|
||||
let netId
|
||||
let defaultAccount = null
|
||||
|
||||
if (web3) {
|
||||
netId = await web3.eth.net.getId()
|
||||
console.log('netId', netId)
|
||||
|
||||
if (!(netId in constants.NETWORKS)) {
|
||||
netIdName = 'ERROR'
|
||||
errorMsg = messages.WRONG_NETWORK_MSG
|
||||
console.log('This is an unknown network.')
|
||||
} else {
|
||||
netIdName = constants.NETWORKS[netId].NAME
|
||||
console.log(`This is ${netIdName}`)
|
||||
}
|
||||
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
|
||||
defaultAccount = accounts[0] || null
|
||||
} else {
|
||||
// Fallback to local if no web3 injection.
|
||||
|
||||
console.log('No web3 instance injected, using Local web3.')
|
||||
console.error('Metamask not found')
|
||||
|
||||
netId = netIdByName(constants.CORE)
|
||||
|
||||
const network = constants.NETWORKS[netId]
|
||||
|
||||
web3 = new Web3(new Web3.providers.HttpProvider(network.RPC))
|
||||
netIdName = network.NAME
|
||||
}
|
||||
|
||||
document.title = `${netIdName} - POA Network Governance DApp`
|
||||
|
||||
if (errorMsg !== null) {
|
||||
reject({ message: errorMsg })
|
||||
return
|
||||
}
|
||||
|
||||
resolve({
|
||||
web3Instance: web3,
|
||||
netIdName,
|
||||
netId,
|
||||
defaultAccount
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default getWeb3
|
||||
const web3NetId = await web3.eth.net.getId()
|
||||
if (web3NetId === netId) {
|
||||
networkMatch = true
|
||||
} else {
|
||||
web3 = null
|
||||
}
|
||||
}
|
||||
|
||||
if (!web3) {
|
||||
web3 = new Web3(new Web3.providers.HttpProvider(network.RPC))
|
||||
}
|
||||
|
||||
document.title = `${netIdName} - POA Governance DApp`
|
||||
|
||||
return {
|
||||
web3Instance: web3,
|
||||
netId,
|
||||
netIdName,
|
||||
injectedWeb3,
|
||||
defaultAccount,
|
||||
networkMatch
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,10 +58,10 @@ function sendTransactionByVotingKey(props, to, data, cb, warning) {
|
|||
)
|
||||
}
|
||||
|
||||
function netIdByName(netName) {
|
||||
const netNameLowerCase = netName.toLowerCase()
|
||||
function netIdByBranch(branch) {
|
||||
const branchLowerCase = branch.toLowerCase()
|
||||
for (let netId in constants.NETWORKS) {
|
||||
if (constants.NETWORKS[netId].NAME.toLowerCase() === netNameLowerCase) {
|
||||
if (constants.NETWORKS[netId].BRANCH.toLowerCase() === branchLowerCase) {
|
||||
return netId
|
||||
}
|
||||
}
|
||||
|
@ -71,5 +71,5 @@ function netIdByName(netName) {
|
|||
module.exports = {
|
||||
toAscii,
|
||||
sendTransactionByVotingKey,
|
||||
netIdByName
|
||||
netIdByBranch
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { getNetworkFullName } from './utils'
|
||||
|
||||
let messages = {}
|
||||
messages.invalidVotingKeyMsg = key => {
|
||||
return `The key ${key} is not valid voting Key! Please make sure you have loaded correct voting key in Metamask`
|
||||
return `The key ${key} is not valid Voting Key! Please make sure you have loaded correct Voting Key in MetaMask.`
|
||||
}
|
||||
messages.VOTED_SUCCESS_MSG = 'You successfully voted'
|
||||
messages.BALLOT_CREATED_SUCCESS_MSG = 'You successfully created a new ballot'
|
||||
|
@ -16,12 +18,7 @@ messages.PROPOSED_ADDRESS_IS_NOT_ADDRESS_MSG = "Proposed address isn't address"
|
|||
messages.END_TIME_SHOULD_BE_GREATER_THAN_NOW_MSG = 'Ballot end time should be greater than now'
|
||||
messages.BALLOT_TYPE_IS_EMPTY_MSG = 'Ballot type is empty'
|
||||
messages.USER_DENIED_ACCOUNT_ACCESS = 'You have denied access to your accounts'
|
||||
messages.NO_METAMASK_MSG = `You haven't chosen any account in MetaMask.
|
||||
Please, choose your voting key in MetaMask and reload the page.
|
||||
Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info.`
|
||||
messages.WRONG_NETWORK_MSG = `You aren't connected to POA Network.
|
||||
Please, switch on POA plugin and refresh the page.
|
||||
Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info.`
|
||||
messages.NO_METAMASK_MSG = 'Your MetaMask is locked or not installed.'
|
||||
messages.ballotIsNotActiveMsg = timeToStart => {
|
||||
return `The ballot is not active yet. Time to start: ${timeToStart}`
|
||||
}
|
||||
|
@ -38,17 +35,20 @@ messages.EMISSION_RELEASE_TIME_IN_FUTURE = emissionReleaseTime => {
|
|||
}
|
||||
messages.PREVIOUS_BALLOT_NOT_FINALIZED = 'Previous ballot should be finalized first.'
|
||||
messages.BALLOT_CREATE_FAILED_TX = `Your transaction was failed. Please make sure you set correct parameters for ballot creation.
|
||||
Make sure you don't have Transaction Error. Exception thrown in contract code message in Metamask before you sign it.`
|
||||
Make sure you don't have Transaction Error. Exception thrown in contract code message in MetaMask before you sign it.`
|
||||
messages.VOTE_FAILED_TX = `Your transaction was failed. Please make sure you haven't already voted for this ballot.
|
||||
Make sure you don't have Transaction Error. Exception thrown in contract code message in Metamask before you sign it.`
|
||||
Make sure you don't have Transaction Error. Exception thrown in contract code message in MetaMask before you sign it.`
|
||||
messages.FINALIZE_FAILED_TX = `Your transaction was failed. Make sure you don't have Transaction Error.
|
||||
Exception thrown in contract code message in Metamask before you sign it.`
|
||||
Exception thrown in contract code message in MetaMask before you sign it.`
|
||||
messages.CANCEL_BALLOT_FAILED_TX = `Your transaction was failed. Make sure you don't have Transaction Error.
|
||||
Exception thrown in contract code message in Metamask before you sign it.`
|
||||
Exception thrown in contract code message in MetaMask before you sign it.`
|
||||
messages.DESCRIPTION_IS_EMPTY = 'Description cannot be empty'
|
||||
messages.wrongRepo = repo => {
|
||||
return `There is no contracts.json in configured repo ${repo}`
|
||||
}
|
||||
module.exports = {
|
||||
messages
|
||||
messages.networkMatchError = function(netId) {
|
||||
const networkName = getNetworkFullName(Number(netId))
|
||||
return `Networks in DApp and MetaMask do not match. Switch MetaMask to <b>${networkName}</b> or change the network in DApp.`
|
||||
}
|
||||
|
||||
export default messages
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import { constants } from './constants'
|
||||
|
||||
export const isTestnet = netId => {
|
||||
return netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
|
||||
}
|
||||
|
||||
export const isValidNetwork = netId => {
|
||||
return netId in constants.NETWORKS
|
||||
}
|
||||
|
||||
export const getNetworkBranch = netId => {
|
||||
return constants.NETWORKS[netId].BRANCH
|
||||
}
|
||||
|
||||
export const getNetworkName = netId => {
|
||||
return constants.NETWORKS[netId].NAME
|
||||
export const getNetworkFullName = netId => {
|
||||
return constants.NETWORKS[netId].FULLNAME
|
||||
}
|
||||
|
||||
export const scrollToTop = () => {
|
||||
|
|
Loading…
Reference in New Issue