diff --git a/apps/voting/app/package.json b/apps/voting/app/package.json
index 7fa36c969c..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.39.0",
+ "@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 d76d704d91..9b084b8dd3 100644
--- a/apps/voting/app/src/app-logic.js
+++ b/apps/voting/app/src/app-logic.js
@@ -99,6 +99,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()
@@ -111,6 +113,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 f22d233c84..93b738661c 100644
--- a/apps/voting/app/src/script.js
+++ b/apps/voting/app/src/script.js
@@ -1,16 +1,11 @@
-import Aragon from '@aragon/api'
-import { of } from 'rxjs'
-import { map, publishReplay } from 'rxjs/operators'
+import Aragon, { events } from '@aragon/api'
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'
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,6 +56,34 @@ retryEvery(retry => {
})
async function initialize(tokenAddr) {
+ return app.store(
+ async (state, { event, returnValues }) => {
+ let nextState = {
+ ...state,
+ }
+
+ switch (event) {
+ 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':
+ return executeVote(nextState, returnValues)
+ case 'StartVote':
+ return startVote(nextState, returnValues)
+ default:
+ return nextState
+ }
+ },
+ { init: initState(tokenAddr) }
+ )
+}
+
+const initState = tokenAddr => async cachedState => {
const token = app.external(tokenAddr, tokenAbi)
let tokenSymbol
@@ -84,76 +107,23 @@ 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 {
+ ...cachedState,
+ isSyncing: true,
+ tokenDecimals,
+ tokenSymbol,
+ ...voteSettings,
+ }
}
/***********************