fix: add loading state to info page (#584)
* fix: add loading state to info page * refactor: use bee-js for readiness check
This commit is contained in:
+13
-2
@@ -2,6 +2,7 @@ import { createStyles, makeStyles, Theme, Typography } from '@material-ui/core'
|
||||
import { ReactElement } from 'react'
|
||||
import Check from 'remixicon-react/CheckLineIcon'
|
||||
import AlertCircle from 'remixicon-react/ErrorWarningFillIcon'
|
||||
import RefreshLine from 'remixicon-react/RefreshLineIcon'
|
||||
import { SwarmButton, SwarmButtonProps } from './SwarmButton'
|
||||
|
||||
interface Props {
|
||||
@@ -9,7 +10,7 @@ interface Props {
|
||||
title: string
|
||||
subtitle: string
|
||||
buttonProps: SwarmButtonProps
|
||||
status: 'ok' | 'error'
|
||||
status: 'ok' | 'error' | 'loading'
|
||||
}
|
||||
|
||||
const useStyles = (backgroundColor: string) =>
|
||||
@@ -56,12 +57,22 @@ export default function Card({ buttonProps, icon, title, subtitle, status }: Pro
|
||||
const { className, ...rest } = buttonProps
|
||||
const classes = useStyles(backgroundColor)()
|
||||
|
||||
let statusIcon = null
|
||||
|
||||
if (status === 'ok') {
|
||||
statusIcon = <Check size="13" color="#09ca6c" />
|
||||
} else if (status === 'error') {
|
||||
statusIcon = <AlertCircle size="13" color="#f44336" />
|
||||
} else if (status === 'loading') {
|
||||
statusIcon = <RefreshLine size="13" color="#096cca" />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.iconWrapper}>
|
||||
{icon}
|
||||
{status === 'ok' ? <Check size="13" color="#09ca6c" /> : <AlertCircle size="13" color="#f44336" />}
|
||||
{statusIcon}
|
||||
</div>
|
||||
<Typography variant="h2" style={{ marginBottom: '8px' }}>
|
||||
{title}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { useContext } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
import ExchangeFunds from 'remixicon-react/ExchangeFundsLineIcon'
|
||||
import Card from '../../components/Card'
|
||||
import { Context as BeeContext } from '../../providers/Bee'
|
||||
import { ROUTES } from '../../routes'
|
||||
|
||||
export function ChequebookInfoCard() {
|
||||
const { chequebookBalance } = useContext(BeeContext)
|
||||
const navigate = useNavigate()
|
||||
|
||||
if (
|
||||
chequebookBalance?.availableBalance !== undefined &&
|
||||
chequebookBalance?.availableBalance.toBigNumber.isGreaterThan(0)
|
||||
) {
|
||||
return (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: ExchangeFunds,
|
||||
children: 'View chequebook',
|
||||
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
|
||||
}}
|
||||
icon={<ExchangeFunds />}
|
||||
title={`${chequebookBalance?.availableBalance.toSignificantDigits(4)} xBZZ`}
|
||||
subtitle="Current chequebook balance."
|
||||
status="ok"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: ExchangeFunds,
|
||||
children: 'View chequebook',
|
||||
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
|
||||
}}
|
||||
icon={<ExchangeFunds />}
|
||||
title={
|
||||
chequebookBalance?.availableBalance
|
||||
? `${chequebookBalance.availableBalance.toSignificantDigits(4)} xBZZ`
|
||||
: 'No available balance.'
|
||||
}
|
||||
subtitle="Chequebook not setup."
|
||||
status="error"
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -1,17 +1,29 @@
|
||||
import { ReactElement, useContext } from 'react'
|
||||
import Search from 'remixicon-react/SearchLineIcon'
|
||||
import Globe from 'remixicon-react/GlobalLineIcon'
|
||||
import Search from 'remixicon-react/SearchLineIcon'
|
||||
import Settings from 'remixicon-react/Settings2LineIcon'
|
||||
|
||||
import { CheckState, Context as BeeContext } from '../../providers/Bee'
|
||||
import Card from '../../components/Card'
|
||||
import { useNavigate } from 'react-router'
|
||||
import Card from '../../components/Card'
|
||||
import { CheckState, Context as BeeContext } from '../../providers/Bee'
|
||||
import { ROUTES } from '../../routes'
|
||||
|
||||
export default function NodeInfoCard(): ReactElement {
|
||||
const { status } = useContext(BeeContext)
|
||||
const { debugApiHealth, debugApiReadiness, status } = useContext(BeeContext)
|
||||
const navigate = useNavigate()
|
||||
|
||||
if (debugApiHealth && !debugApiReadiness) {
|
||||
return (
|
||||
<Card
|
||||
buttonProps={{ iconType: Settings, children: 'Open node setup', onClick: () => navigate(ROUTES.STATUS) }}
|
||||
icon={<Globe />}
|
||||
title="Starting up..."
|
||||
subtitle="Your Bee node is currently launching."
|
||||
status="loading"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (status.all === CheckState.ERROR) {
|
||||
return (
|
||||
<Card
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { useContext } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
import Upload from 'remixicon-react/UploadLineIcon'
|
||||
import Wallet from 'remixicon-react/Wallet3LineIcon'
|
||||
import Card from '../../components/Card'
|
||||
import { Context as BeeContext } from '../../providers/Bee'
|
||||
import { Context as BalanceProvider } from '../../providers/WalletBalance'
|
||||
import { ROUTES } from '../../routes'
|
||||
|
||||
export function WalletInfoCard() {
|
||||
const { nodeInfo } = useContext(BeeContext)
|
||||
const { balance, error } = useContext(BalanceProvider)
|
||||
const navigate = useNavigate()
|
||||
|
||||
let balanceText = 'Loading...'
|
||||
|
||||
if (error) {
|
||||
balanceText = 'Could not load...'
|
||||
console.error(error) // eslint-disable-line
|
||||
} else if (balance) {
|
||||
balanceText = `${balance.bzz.toSignificantDigits(4)} xBZZ | ${balance.dai.toSignificantDigits(4)} xDAI`
|
||||
}
|
||||
|
||||
if (nodeInfo?.beeMode && ['light', 'full', 'dev'].includes(nodeInfo.beeMode)) {
|
||||
return (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: Wallet,
|
||||
children: 'Manage your wallet',
|
||||
onClick: () => navigate(ROUTES.ACCOUNT_WALLET),
|
||||
}}
|
||||
icon={<Wallet />}
|
||||
title={balanceText}
|
||||
subtitle="Current wallet balance."
|
||||
status="ok"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: Wallet,
|
||||
children: 'Setup wallet',
|
||||
onClick: () => navigate(ROUTES.TOP_UP),
|
||||
}}
|
||||
icon={<Upload />}
|
||||
title="Your wallet is not setup."
|
||||
subtitle="To share content on Swarm, please setup your wallet."
|
||||
status="error"
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -1,110 +1,41 @@
|
||||
import { Button } from '@material-ui/core'
|
||||
import { ReactElement, useContext } from 'react'
|
||||
import { useNavigate } from 'react-router'
|
||||
import ExchangeFunds from 'remixicon-react/ExchangeFundsLineIcon'
|
||||
import Upload from 'remixicon-react/UploadLineIcon'
|
||||
import Wallet from 'remixicon-react/Wallet3LineIcon'
|
||||
import Card from '../../components/Card'
|
||||
import ExpandableListItem from '../../components/ExpandableListItem'
|
||||
import Map from '../../components/Map'
|
||||
import { BEE_DESKTOP_LATEST_RELEASE_PAGE } from '../../constants'
|
||||
import { useBeeDesktop, useNewBeeDesktopVersion } from '../../hooks/apiHooks'
|
||||
import { Context as BeeContext } from '../../providers/Bee'
|
||||
import { Context as SettingsContext } from '../../providers/Settings'
|
||||
import { Context as BalanceProvider } from '../../providers/WalletBalance'
|
||||
import { ROUTES } from '../../routes'
|
||||
import { chainIdToName } from '../../utils/chain'
|
||||
import { ChequebookInfoCard } from './ChequebookInfoCard'
|
||||
import NodeInfoCard from './NodeInfoCard'
|
||||
import { BEE_DESKTOP_LATEST_RELEASE_PAGE } from '../../constants'
|
||||
import { WalletInfoCard } from './WalletInfoCard'
|
||||
|
||||
export default function Status(): ReactElement {
|
||||
const {
|
||||
debugApiReadiness,
|
||||
status,
|
||||
latestUserVersion,
|
||||
isLatestBeeVersion,
|
||||
latestBeeVersionUrl,
|
||||
topology,
|
||||
nodeInfo,
|
||||
chequebookBalance,
|
||||
chainId,
|
||||
} = useContext(BeeContext)
|
||||
const { isDesktop, desktopUrl } = useContext(SettingsContext)
|
||||
const { balance, error } = useContext(BalanceProvider)
|
||||
const { beeDesktopVersion } = useBeeDesktop(isDesktop, desktopUrl)
|
||||
const { newBeeDesktopVersion } = useNewBeeDesktopVersion(isDesktop, desktopUrl, false)
|
||||
const navigate = useNavigate()
|
||||
|
||||
let balanceText = 'Loading...'
|
||||
|
||||
if (error) {
|
||||
balanceText = 'Could not load...'
|
||||
console.error(error) // eslint-disable-line
|
||||
} else if (balance) {
|
||||
balanceText = `${balance.bzz.toSignificantDigits(4)} xBZZ | ${balance.dai.toSignificantDigits(4)} xDAI`
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'stretch', alignContent: 'stretch' }}>
|
||||
<NodeInfoCard />
|
||||
<div style={{ width: '8px' }}></div>
|
||||
{nodeInfo?.beeMode && ['light', 'full', 'dev'].includes(nodeInfo.beeMode) ? (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: Wallet,
|
||||
children: 'Manage your wallet',
|
||||
onClick: () => navigate(ROUTES.ACCOUNT_WALLET),
|
||||
}}
|
||||
icon={<Wallet />}
|
||||
title={balanceText}
|
||||
subtitle="Current wallet balance."
|
||||
status="ok"
|
||||
/>
|
||||
) : (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: Wallet,
|
||||
children: 'Setup wallet',
|
||||
onClick: () => navigate(ROUTES.TOP_UP),
|
||||
}}
|
||||
icon={<Upload />}
|
||||
title="Your wallet is not setup."
|
||||
subtitle="To share content on Swarm, please setup your wallet."
|
||||
status="error"
|
||||
/>
|
||||
)}
|
||||
{nodeInfo?.beeMode && ['light', 'full', 'dev'].includes(nodeInfo.beeMode) && (
|
||||
{debugApiReadiness && (
|
||||
<>
|
||||
<div style={{ width: '8px' }} />
|
||||
{chequebookBalance?.availableBalance !== undefined &&
|
||||
chequebookBalance?.availableBalance.toBigNumber.isGreaterThan(0) ? (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: ExchangeFunds,
|
||||
children: 'View chequebook',
|
||||
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
|
||||
}}
|
||||
icon={<ExchangeFunds />}
|
||||
title={`${chequebookBalance?.availableBalance.toSignificantDigits(4)} xBZZ`}
|
||||
subtitle="Current chequebook balance."
|
||||
status="ok"
|
||||
/>
|
||||
) : (
|
||||
<Card
|
||||
buttonProps={{
|
||||
iconType: ExchangeFunds,
|
||||
children: 'View chequebook',
|
||||
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
|
||||
}}
|
||||
icon={<ExchangeFunds />}
|
||||
title={
|
||||
chequebookBalance?.availableBalance
|
||||
? `${chequebookBalance.availableBalance.toSignificantDigits(4)} xBZZ`
|
||||
: 'No available balance.'
|
||||
}
|
||||
subtitle="Chequebook not setup."
|
||||
status="error"
|
||||
/>
|
||||
)}
|
||||
<div style={{ width: '8px' }}></div>
|
||||
<WalletInfoCard />
|
||||
<div style={{ width: '8px' }}></div>
|
||||
<ChequebookInfoCard />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -52,6 +52,7 @@ interface ContextInterface {
|
||||
error: Error | null
|
||||
apiHealth: boolean
|
||||
debugApiHealth: Health | null
|
||||
debugApiReadiness: boolean
|
||||
nodeAddresses: NodeAddresses | null
|
||||
nodeInfo: NodeInfo | null
|
||||
topology: Topology | null
|
||||
@@ -89,6 +90,7 @@ const initialValues: ContextInterface = {
|
||||
error: null,
|
||||
apiHealth: false,
|
||||
debugApiHealth: null,
|
||||
debugApiReadiness: false,
|
||||
nodeAddresses: null,
|
||||
nodeInfo: null,
|
||||
topology: null,
|
||||
@@ -190,6 +192,7 @@ 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 [debugApiReadiness, setDebugApiReadiness] = useState(false)
|
||||
const [nodeAddresses, setNodeAddresses] = useState<NodeAddresses | null>(null)
|
||||
const [nodeInfo, setNodeInfo] = useState<NodeInfo | null>(null)
|
||||
const [topology, setNodeTopology] = useState<Topology | null>(null)
|
||||
@@ -299,6 +302,12 @@ export function Provider({ children }: Props): ReactElement {
|
||||
.then(setDebugApiHealth)
|
||||
.catch(() => setDebugApiHealth(null)),
|
||||
|
||||
// Debug API readiness
|
||||
beeDebugApi
|
||||
.getReadiness({ timeout: TIMEOUT })
|
||||
.then(setDebugApiReadiness)
|
||||
.catch(() => setDebugApiReadiness(false)),
|
||||
|
||||
// Node Addresses
|
||||
beeDebugApi
|
||||
.getNodeAddresses({ timeout: TIMEOUT })
|
||||
@@ -426,6 +435,7 @@ export function Provider({ children }: Props): ReactElement {
|
||||
error,
|
||||
apiHealth,
|
||||
debugApiHealth,
|
||||
debugApiReadiness,
|
||||
nodeAddresses,
|
||||
nodeInfo,
|
||||
topology,
|
||||
|
||||
Reference in New Issue
Block a user