From 3c1457dbc95414d5d9e659f842decb948b8354d2 Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Mon, 6 May 2019 16:39:38 +0200 Subject: [PATCH 1/5] Move initial state loading to an init function --- apps/voting/app/src/script.js | 111 +++++++++++++++------------------- 1 file changed, 48 insertions(+), 63 deletions(-) diff --git a/apps/voting/app/src/script.js b/apps/voting/app/src/script.js index f22d233c84..cf412475ac 100644 --- a/apps/voting/app/src/script.js +++ b/apps/voting/app/src/script.js @@ -61,6 +61,46 @@ retryEvery(retry => { }) async function initialize(tokenAddr) { + // Hot observable which emits an web3.js event-like object with an account string of the current active account. + const accounts$ = app.accounts().pipe( + map(accounts => { + return { + event: ACCOUNTS_TRIGGER, + returnValues: { + account: accounts[0], + }, + } + }), + publishReplay(1) + ) + + accounts$.connect() + + return app.store( + async (state, { event, returnValues }) => { + let nextState = { + ...state, + } + + switch (event) { + case ACCOUNTS_TRIGGER: + return updateConnectedAccount(nextState, returnValues) + case 'CastVote': + return castVote(nextState, returnValues) + case 'ExecuteVote': + return executeVote(nextState, returnValues) + case 'StartVote': + return startVote(nextState, returnValues) + default: + return nextState + } + }, + [accounts$], + initState(tokenAddr) + ) +} + +const initState = tokenAddr => async () => { const token = app.external(tokenAddr, tokenAbi) let tokenSymbol @@ -84,76 +124,21 @@ async function initialize(tokenAddr) { try { tokenDecimals = (await token.decimals().toPromise()) || '0' } catch (err) { - console.err( + console.error( `Failed to load token decimals for token at ${tokenAddr} due to:`, err ) - console.err('Defaulting to 0...') + console.error('Defaulting to 0...') tokenDecimals = '0' } - return createStore(token, { decimals: tokenDecimals, symbol: tokenSymbol }) -} + const voteSettings = await loadVoteSettings() -// Hook up the script as an aragon.js store -async function createStore(token, tokenSettings) { - const { decimals: tokenDecimals, symbol: tokenSymbol } = tokenSettings - - // Hot observable which emits an web3.js event-like object with an account string of the current active account. - const accounts$ = app.accounts().pipe( - map(accounts => { - return { - event: ACCOUNTS_TRIGGER, - returnValues: { - account: accounts[0], - }, - } - }), - publishReplay(1) - ) - - accounts$.connect() - - return app.store( - async (state, { event, returnValues }) => { - let nextState = { - ...state, - // Fetch the app's settings, if we haven't already - ...(!hasLoadedVoteSettings(state) ? await loadVoteSettings() : {}), - } - - if (event === INITIALIZATION_TRIGGER) { - nextState = { - ...nextState, - tokenDecimals, - tokenSymbol, - } - } else { - switch (event) { - case ACCOUNTS_TRIGGER: - nextState = await updateConnectedAccount(nextState, returnValues) - break - case 'CastVote': - nextState = await castVote(nextState, returnValues) - break - case 'ExecuteVote': - nextState = await executeVote(nextState, returnValues) - break - case 'StartVote': - nextState = await startVote(nextState, returnValues) - break - default: - break - } - } - return nextState - }, - [ - // Always initialize the store with our own home-made event - of({ event: INITIALIZATION_TRIGGER }), - accounts$, - ] - ) + return { + tokenDecimals, + tokenSymbol, + ...voteSettings, + } } /*********************** From 095ec4016baaf150ab43f5ae74a83d24c3535ce9 Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Thu, 9 May 2019 16:28:01 +0200 Subject: [PATCH 2/5] Use accounts trigger from API --- apps/voting/app/src/script.js | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/apps/voting/app/src/script.js b/apps/voting/app/src/script.js index cf412475ac..65add20c2c 100644 --- a/apps/voting/app/src/script.js +++ b/apps/voting/app/src/script.js @@ -1,4 +1,4 @@ -import Aragon from '@aragon/api' +import Aragon, { ACCOUNTS_TRIGGER } from '@aragon/api' import { of } from 'rxjs' import { map, publishReplay } from 'rxjs/operators' import { addressesEqual } from './web3-utils' @@ -8,9 +8,6 @@ import { EMPTY_CALLSCRIPT } from './evmscript-utils' import tokenDecimalsAbi from './abi/token-decimals.json' import tokenSymbolAbi from './abi/token-symbol.json' -const INITIALIZATION_TRIGGER = Symbol('INITIALIZATION_TRIGGER') -const ACCOUNTS_TRIGGER = Symbol('ACCOUNTS_TRIGGER') - const tokenAbi = [].concat(tokenDecimalsAbi, tokenSymbolAbi) const app = new Aragon() @@ -61,21 +58,6 @@ retryEvery(retry => { }) async function initialize(tokenAddr) { - // Hot observable which emits an web3.js event-like object with an account string of the current active account. - const accounts$ = app.accounts().pipe( - map(accounts => { - return { - event: ACCOUNTS_TRIGGER, - returnValues: { - account: accounts[0], - }, - } - }), - publishReplay(1) - ) - - accounts$.connect() - return app.store( async (state, { event, returnValues }) => { let nextState = { @@ -95,8 +77,7 @@ async function initialize(tokenAddr) { return nextState } }, - [accounts$], - initState(tokenAddr) + { init: initState(tokenAddr) } ) } From 2f37fe6c7d02c52b109ac7515ec23619178be97e Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Thu, 9 May 2019 18:04:57 +0200 Subject: [PATCH 3/5] Remove unnecassary imports --- apps/voting/app/src/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/voting/app/src/script.js b/apps/voting/app/src/script.js index 65add20c2c..03a0f69243 100644 --- a/apps/voting/app/src/script.js +++ b/apps/voting/app/src/script.js @@ -1,8 +1,8 @@ import Aragon, { ACCOUNTS_TRIGGER } from '@aragon/api' import { of } from 'rxjs' -import { map, publishReplay } from 'rxjs/operators' +import { map } from 'rxjs/operators' import { addressesEqual } from './web3-utils' -import voteSettings, { hasLoadedVoteSettings } from './vote-settings' +import voteSettings from './vote-settings' import { voteTypeFromContractEnum } from './vote-utils' import { EMPTY_CALLSCRIPT } from './evmscript-utils' import tokenDecimalsAbi from './abi/token-decimals.json' From ca8bf173a232f47990d7110fc268363e0725e98d Mon Sep 17 00:00:00 2001 From: Daniel Norman Date: Wed, 15 May 2019 17:40:34 +0800 Subject: [PATCH 4/5] Remove unneeded imports --- apps/voting/app/src/script.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/voting/app/src/script.js b/apps/voting/app/src/script.js index 03a0f69243..72f56f462d 100644 --- a/apps/voting/app/src/script.js +++ b/apps/voting/app/src/script.js @@ -1,6 +1,4 @@ import Aragon, { ACCOUNTS_TRIGGER } from '@aragon/api' -import { of } from 'rxjs' -import { map } from 'rxjs/operators' import { addressesEqual } from './web3-utils' import voteSettings from './vote-settings' import { voteTypeFromContractEnum } from './vote-utils' From 5d0c57cd3c54ee5f63461a6b2f85d9f4ebedf19b Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 29 May 2019 12:26:07 +0200 Subject: [PATCH 5/5] Voting: display the syncing state (#875) --- apps/voting/app/package.json | 6 +++--- apps/voting/app/src/App.js | 6 ++++-- apps/voting/app/src/app-logic.js | 3 +++ apps/voting/app/src/script.js | 12 +++++++++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/voting/app/package.json b/apps/voting/app/package.json index ac729153d1..b6958e061e 100644 --- a/apps/voting/app/package.json +++ b/apps/voting/app/package.json @@ -4,9 +4,9 @@ "private": true, "license": "AGPL-3.0-or-later", "dependencies": { - "@aragon/api": "^1.0.0", - "@aragon/api-react": "^1.0.0-beta.2", - "@aragon/ui": "^0.38.1", + "@aragon/api": "^2.0.0-beta.2", + "@aragon/api-react": "^2.0.0-beta.1", + "@aragon/ui": "^0.40.1", "bn.js": "^4.11.8", "date-fns": "2.0.0-alpha.22", "onecolor": "^3.1.0", diff --git a/apps/voting/app/src/App.js b/apps/voting/app/src/App.js index 6b24b19403..bdebd0f4c5 100644 --- a/apps/voting/app/src/App.js +++ b/apps/voting/app/src/App.js @@ -1,5 +1,5 @@ import React from 'react' -import { Main } from '@aragon/ui' +import { SyncIndicator, Main } from '@aragon/ui' import EmptyState from './screens/EmptyState' import Votes from './screens/Votes' @@ -14,6 +14,7 @@ import { AppLogicProvider, useAppLogic } from './app-logic' function App() { const { + isSyncing, votes, selectedVote, actions, @@ -25,6 +26,7 @@ function App() { return (
+ 0 ? ( ) : ( - + !isSyncing && )} diff --git a/apps/voting/app/src/app-logic.js b/apps/voting/app/src/app-logic.js index 8ea8c934ff..00f963c0af 100644 --- a/apps/voting/app/src/app-logic.js +++ b/apps/voting/app/src/app-logic.js @@ -96,6 +96,8 @@ export function useSelectedVotePanel(selectedVote, selectVote) { // Handles the main logic of the app. export function useAppLogic() { + const { isSyncing, ready } = useAppState() + const votes = useVotes() const [selectedVote, selectVote] = useSelectedVote(votes) const newVotePanel = usePanelState() @@ -108,6 +110,7 @@ export function useAppLogic() { } return { + isSyncing: isSyncing || !ready, votes, selectVote, selectedVote, diff --git a/apps/voting/app/src/script.js b/apps/voting/app/src/script.js index 72f56f462d..93b738661c 100644 --- a/apps/voting/app/src/script.js +++ b/apps/voting/app/src/script.js @@ -1,4 +1,4 @@ -import Aragon, { ACCOUNTS_TRIGGER } from '@aragon/api' +import Aragon, { events } from '@aragon/api' import { addressesEqual } from './web3-utils' import voteSettings from './vote-settings' import { voteTypeFromContractEnum } from './vote-utils' @@ -63,8 +63,12 @@ async function initialize(tokenAddr) { } switch (event) { - case ACCOUNTS_TRIGGER: + case events.ACCOUNTS_TRIGGER: return updateConnectedAccount(nextState, returnValues) + case events.SYNC_STATUS_SYNCING: + return { ...nextState, isSyncing: true } + case events.SYNC_STATUS_SYNCED: + return { ...nextState, isSyncing: false } case 'CastVote': return castVote(nextState, returnValues) case 'ExecuteVote': @@ -79,7 +83,7 @@ async function initialize(tokenAddr) { ) } -const initState = tokenAddr => async () => { +const initState = tokenAddr => async cachedState => { const token = app.external(tokenAddr, tokenAbi) let tokenSymbol @@ -114,6 +118,8 @@ const initState = tokenAddr => async () => { const voteSettings = await loadVoteSettings() return { + ...cachedState, + isSyncing: true, tokenDecimals, tokenSymbol, ...voteSettings,