From cd65f6a2b4795058af8c646c63f6236d2e56ab82 Mon Sep 17 00:00:00 2001 From: emizzle Date: Sat, 14 Jul 2018 07:50:15 +0200 Subject: [PATCH] first stab at showing multiple accounts dropdown better error handling for error page (more description) add config support for embark to autmoatically generate and fund accounts updated test to use default account --- app/css/dapp.css | 1 + app/js/components/App.js | 19 ++++++++++------ app/js/components/Error.js | 17 +++++++++----- app/js/components/FieldGroup.js | 3 +-- app/js/components/Header.js | 20 +++++++++++++++-- app/js/components/UserTweets.js | 4 ++-- chains.json | 39 +-------------------------------- config/blockchain.js | 8 +++++-- test/dtwitter_spec.js | 2 +- 9 files changed, 54 insertions(+), 59 deletions(-) diff --git a/app/css/dapp.css b/app/css/dapp.css index 4536325..4641b69 100644 --- a/app/css/dapp.css +++ b/app/css/dapp.css @@ -42,6 +42,7 @@ nav .navbar-text a:hover, nav .navbar-text a:focus { text-decoration:none; } nav .error {color:red} +nav.error .navbar-brand {padding-top:10px;} .tweets .tweet .list-group-item-text { white-space: pre-line; } diff --git a/app/js/components/App.js b/app/js/components/App.js index 7144746..d2e14e4 100644 --- a/app/js/components/App.js +++ b/app/js/components/App.js @@ -21,7 +21,8 @@ class App extends Component { this.state = { user: {}, account: '', - error: {} + error: {}, + accounts: [] } } //#endregion @@ -43,7 +44,7 @@ class App extends Component { const accounts = await web3.eth.getAccounts(); try { // get the owner associated with the current defaultAccount - const usernameHash = await DTwitter.methods.owners(accounts[0]).call(); + const usernameHash = await DTwitter.methods.owners(web3.eth.defaultAccount).call(); // get user details from contract const user = await DTwitter.methods.users(usernameHash).call(); @@ -52,10 +53,10 @@ class App extends Component { user.picture = user.picture.length > 0 ? EmbarkJS.Storage.getUrl(user.picture) : imgAvatar; // update state with user details - return this.setState({ user: user, account: accounts[0] }); + return this.setState({ user: user, account: web3.eth.defaultAccount, accounts: accounts }); } catch (err) { - this._onError(err); + this._onError(err, 'App._loadCurrentUser'); } } @@ -64,7 +65,8 @@ class App extends Component { * * @param {Error} err - error encountered */ - _onError(err) { + _onError(err, source) { + if(source) err.source = source; this.setState({ error: err }); this.props.history.push('/whoopsie'); } @@ -83,13 +85,16 @@ class App extends Component {
+ accounts={this.state.accounts} + error={this.state.error} + onAfterUserUpdate={(e) => this._loadCurrentUser()} />
this._loadCurrentUser()} - onError={(err) => this._onError(err)} /> + onError={(err, source) => this._onError(err, source)} /> ); } diff --git a/app/js/components/Error.js b/app/js/components/Error.js index d6cb1ee..7937d49 100644 --- a/app/js/components/Error.js +++ b/app/js/components/Error.js @@ -17,9 +17,8 @@ class Error extends Component { //#region React lifecycle events render() { - const metaMaskPossible = (this.props.error.message.indexOf('Internal JSON-RPC error') > 0 || this.props.error.code === -32603); - console.log('error = ' + this.props.error.code); - console.log('metaMaskPossible = ' + this.props.error.message.indexOf('Internal JSON-RPC error') > 0); + const metaMaskPossible = (this.props.error.message.indexOf('Internal JSON-RPC error') > 0 || this.props.error.message.indexOf('Failed to fetch') > 0); + return ( @@ -30,13 +29,21 @@ class Error extends Component { {metaMaskPossible ?

Metamask error?

-

It appears you are using metamask. Have you signed in and are you on the right network?

+

It appears you might be using metamask. Have you signed in and are you on the right network?

: '' }

Error details

-
{this.props.error.message}
{this.props.error.stack}
+
{this.props.error.message}
+ {this.props.error.stack} + { this.props.error.source ? + +
Source: { this.props.error.source } +
+ : + '' + }
diff --git a/app/js/components/FieldGroup.js b/app/js/components/FieldGroup.js index a3ac8db..5502c78 100644 --- a/app/js/components/FieldGroup.js +++ b/app/js/components/FieldGroup.js @@ -39,7 +39,6 @@ import { FormGroup, ControlLabel, FormControl, HelpBlock, InputGroup } from 'rea * @returns {React.Component} The completed component to render. */ const FieldGroup = ({ id, label, help, validationState, hasFeedback, inputAddOn, ...props }) => { - return ( @@ -52,7 +51,7 @@ const FieldGroup = ({ id, label, help, validationState, hasFeedback, inputAddOn, { inputAddOn.location === 'after' ? { inputAddOn.addOn } : '' } : - + { props.children } } {hasFeedback ? : ''} {help && {help}} diff --git a/app/js/components/Header.js b/app/js/components/Header.js index 4c8fe72..25986ed 100644 --- a/app/js/components/Header.js +++ b/app/js/components/Header.js @@ -5,6 +5,7 @@ import DoTweet from './DoTweet'; import Search from './Search'; import { limitAddressLength } from '../utils'; import Spinner from 'react-spinkit'; +import FieldGroup from './FieldGroup'; /** * Class representing the header of the page that handles @@ -47,6 +48,11 @@ class Header extends Component { _handleToggle() { this.setState({ showTooltip: !this.state.showTooltip }); } + + _handleAcctChange(e){ + web3.eth.defaultAccount = e.target.value; + this.props.onAfterUserUpdate(); + } //#endregion //#region React lifecycle events @@ -118,9 +124,12 @@ class Header extends Component { ; + const accts = this.props.accounts.map(function(address, index){ + return + }); return ( - + dTwitter embark by Status @@ -132,7 +141,14 @@ class Header extends Component { - + this._handleAcctChange(e) }> + { accts } + { isLoading ? states.isLoading : diff --git a/app/js/components/UserTweets.js b/app/js/components/UserTweets.js index 76f6fed..73c9976 100644 --- a/app/js/components/UserTweets.js +++ b/app/js/components/UserTweets.js @@ -60,7 +60,7 @@ class UserTweets extends Component { fromBlock: 0 }, (err, event) => { if (err){ - this.props.onError(err); + this.props.onError(err, 'UserTweets._subscribeToNewTweetEvent'); } }) .on('data', (event) => { @@ -73,7 +73,7 @@ class UserTweets extends Component { this.setState({tweets: tweets}); }) .on('error', function(error){ - this.props.onError(err); + this.props.onError(err, 'UserTweets._subscribeToNewTweetEvent'); }); } diff --git a/chains.json b/chains.json index 764d6dd..0967ef4 100644 --- a/chains.json +++ b/chains.json @@ -1,38 +1 @@ -{ - "0x44be6d937485110cdc88ce58bd6b48c0c9f48bb2c9ae62c40c353ac5a8b0f226": { - "contracts": { - "0x35cbd109f501602ed728b03e78faa3df2cc6b5c9db220e139623f9ae41389b02": { - "name": "DTwitter", - "address": "0xce37C47cefd1d40dc058995616953C943C93657d" - }, - "0x1797453304e4b69b44fb7d649a72ca80394a8b4e1d14c2cc530f5dc3ae1f0ea3": { - "name": "ENSRegistry", - "address": "0xaaC3765Af434050d29f4b7188044Fa1C619bF614" - }, - "0x1c1c5eec1cd80df5fe51d3922a226a9009dd83ab9e65b707d5f20f439dfbb237": { - "name": "FIFSRegistrar", - "address": "0xB1014418a4f4436CDfa4D4D7516Fa5f0B2DF3feB" - }, - "0xd129cd954f5ea85193fd4eacbb0ec150e26459405df123408a122481ff1e1f66": { - "name": "FIFSRegistrar", - "address": "0xEa6bfC300214dDb918E24c24Af8A272E9e6EaFDF" - } - } - }, - "0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177": { - "contracts": { - "0x35cbd109f501602ed728b03e78faa3df2cc6b5c9db220e139623f9ae41389b02": { - "name": "DTwitter", - "address": "0xafaf19FbCB2E3d1c7DCC926fFC62E368f96326bD" - }, - "0x6d1e2e0bd96a493aaab99909e0fd4ed874e93edd9a58020916846e08876c3b01": { - "name": "FIFSRegistrar", - "address": "0x774a72b8509B6eEF6d22ac59159FB85B5be858e7" - }, - "0x1797453304e4b69b44fb7d649a72ca80394a8b4e1d14c2cc530f5dc3ae1f0ea3": { - "name": "ENSRegistry", - "address": "0xA5665431C52A0D9b9bC1DD4Da314Cce70d44ED1F" - } - } - } -} +{} diff --git a/config/blockchain.js b/config/blockchain.js index 50294f4..0cdfb0d 100644 --- a/config/blockchain.js +++ b/config/blockchain.js @@ -12,15 +12,19 @@ module.exports = { rpcHost: "localhost", rpcPort: 8545, rpcCorsDomain: "auto", - proxy: true, + rpcApi: ['eth', 'web3', 'net', 'debug', 'personal'], + proxy: false, account: { - password: "config/development/password" + password: "config/development/password", + numAccounts: 3, + balance: "5 ether" }, targetGasLimit: 10000000, wsOrigins: "auto", wsRPC: true, wsHost: "localhost", wsPort: 8546, + wsApi: ['eth', 'web3', 'net', 'shh', 'debug', 'personal'], simulatorMnemonic: "example exile argue silk regular smile grass bomb merge arm assist farm", simulatorBlocktime: 0 }, diff --git a/test/dtwitter_spec.js b/test/dtwitter_spec.js index 5414387..03f6d1b 100644 --- a/test/dtwitter_spec.js +++ b/test/dtwitter_spec.js @@ -54,7 +54,7 @@ contract("DTwitter contract", function () { it("should have created an owner for our defaultAccount", async function () { // read from the owners mapping - const usernameHash = await owners(accounts[0]).call(); + const usernameHash = await owners(web3.eth.defaultAccount).call(); // check the return value from owners mapping matches assert.equal(usernameHash, web3.utils.keccak256(username));