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));