feat: changing API urls does not need the app refresh (#173)

* feat: changing API urls does not need the app refresh

* fix: propagate beeDebugApi and beeApi change to the refresh interval

* fix: any failed request on the Bee provider does not stop the execution of other requests

* fix: error handling for incorrect bee and bee debug urls

* fix: change debug API in the settings tab
This commit is contained in:
Vojtech Simetka
2021-08-20 15:14:14 +02:00
committed by GitHub
parent 2624cf04c9
commit d6d03bf7c6
21 changed files with 336 additions and 380 deletions
+125 -28
View File
@@ -1,9 +1,9 @@
import type { ChequebookBalance, Balance, Settlements } from '../types'
import { createContext, ReactChild, ReactElement, useEffect, useState } from 'react'
import { beeApi, beeDebugApi } from '../services/bee'
import { createContext, ReactChild, ReactElement, useEffect, useState, useContext } from 'react'
import { Token } from '../models/Token'
import semver from 'semver'
import { engines } from '../../package.json'
import { Context as SettingsContext } from './Settings'
import type {
NodeAddresses,
@@ -125,6 +125,7 @@ function getStatus(
}
export function Provider({ children }: Props): ReactElement {
const { beeApi, beeDebugApi } = useContext(SettingsContext)
const [apiHealth, setApiHealth] = useState<boolean>(false)
const [debugApiHealth, setDebugApiHealth] = useState<Health | null>(null)
const [nodeAddresses, setNodeAddresses] = useState<NodeAddresses | null>(null)
@@ -147,47 +148,143 @@ export function Provider({ children }: Props): ReactElement {
const latestUserVersion = semver.coerce(debugApiHealth?.version)?.version
const latestUserVersionExact = debugApiHealth?.version
useEffect(() => {
setIsLoading(true)
setApiHealth(false)
refresh()
}, [beeApi])
useEffect(() => {
setIsLoading(true)
setDebugApiHealth(null)
setNodeAddresses(null)
setNodeTopology(null)
setPeers(null)
setChequebookAddress(null)
setChequebookBalance(null)
setPeerBalances(null)
setPeerCheques(null)
setSettlements(null)
refresh()
}, [beeDebugApi])
const refresh = async () => {
// Don't want to refresh when already refreshing
if (isRefreshing) return
// Not a valid bee api
if (!beeApi || !beeDebugApi) {
setIsLoading(false)
return
}
try {
setIsRefreshing(true)
setError(null)
setApiHealth(await beeApi.status.health())
setDebugApiHealth(await beeDebugApi.status.nodeHealth())
setNodeAddresses(await beeDebugApi.connectivity.addresses())
setNodeTopology(await beeDebugApi.connectivity.topology())
setChequebookAddress(await beeDebugApi.chequebook.address())
setPeers(await beeDebugApi.connectivity.listPeers())
// Wrap the chequebook balance call to return BZZ values as Token object
const chequeBalanceWrapper = async () => {
const { totalBalance, availableBalance } = await beeDebugApi.getChequebookBalance()
const { totalBalance, availableBalance } = await beeDebugApi.chequebook.balance()
setChequebookBalance({
totalBalance: new Token(totalBalance),
availableBalance: new Token(availableBalance),
})
return {
totalBalance: new Token(totalBalance),
availableBalance: new Token(availableBalance),
}
}
const { balances } = await beeDebugApi.balance.balances()
setPeerBalances(balances.map(({ peer, balance }) => ({ peer, balance: new Token(balance) })))
// Wrap the balances call to return BZZ values as Token object
const peerBalanceWrapper = async () => {
const { balances } = await beeDebugApi.getAllBalances()
setPeerCheques(await beeDebugApi.chequebook.getLastCheques())
const { totalReceived, settlements, totalSent } = await beeDebugApi.settlements.getSettlements()
setSettlements({
totalReceived: new Token(totalReceived),
totalSent: new Token(totalSent),
settlements: settlements.map(({ peer, received, sent }) => ({
peer,
received: new Token(received),
sent: new Token(sent),
})),
})
return balances.map(({ peer, balance }) => ({ peer, balance: new Token(balance) }))
}
setLastUpdate(Date.now())
// Wrap the settlements call to return BZZ values as Token object
const settlementsWrapper = async () => {
const { totalReceived, settlements, totalSent } = await beeDebugApi.getAllSettlements()
return {
totalReceived: new Token(totalReceived),
totalSent: new Token(totalSent),
settlements: settlements.map(({ peer, received, sent }) => ({
peer,
received: new Token(received),
sent: new Token(sent),
})),
}
}
const promises = [
// API health
beeApi
.isConnected()
.then(setApiHealth)
.catch(() => setApiHealth(false)),
// Debug API health
beeDebugApi
.getHealth()
.then(setDebugApiHealth)
.catch(() => setDebugApiHealth(null)),
// Node Addresses
beeDebugApi
.getNodeAddresses()
.then(setNodeAddresses)
.catch(() => setNodeAddresses(null)),
// Network Topology
beeDebugApi
.getTopology()
.then(setNodeTopology)
.catch(() => setNodeTopology(null)),
// Peers
beeDebugApi
.getPeers()
.then(setPeers)
.catch(() => setPeers(null)),
// Chequebook address
beeDebugApi
.getChequebookAddress()
.then(setChequebookAddress)
.catch(() => setChequebookAddress(null)),
// Cheques
beeDebugApi
.getLastCheques()
.then(setPeerCheques)
.catch(() => setPeerCheques(null)),
// Chequebook balance
chequeBalanceWrapper()
.then(setChequebookBalance)
.catch(() => setChequebookBalance(null)),
// Peer balances
peerBalanceWrapper()
.then(setPeerBalances)
.catch(() => setPeerBalances(null)),
// Settlements
settlementsWrapper()
.then(setSettlements)
.catch(() => setSettlements(null)),
]
await Promise.allSettled(promises)
} catch (e) {
setError(e)
} finally {
setIsLoading(false)
setIsRefreshing(false)
setLastUpdate(Date.now())
}
}
@@ -204,7 +301,7 @@ export function Provider({ children }: Props): ReactElement {
return () => clearInterval(interval)
}
}, [frequency])
}, [frequency, beeDebugApi, beeApi])
return (
<Context.Provider