feat: wait for upload sync (#649)
* feat: add basic progress bar (#605) * feat: add syncing to share page (#605) * refactor: use the documentation text comp (#605) * refactor: move sync logic to new comp (#605) * refactor: optimize sync check (#605) * chore: linting (#605) --------- Co-authored-by: Levente Kiss <levente.kiss@solarpunk.bzz>
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
import React, { ReactElement } from 'react'
|
||||||
|
import LinearProgress, { LinearProgressProps } from '@material-ui/core/LinearProgress'
|
||||||
|
import Typography from '@material-ui/core/Typography'
|
||||||
|
import Box from '@material-ui/core/Box'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
linearProgressProps?: LinearProgressProps
|
||||||
|
value: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LinearProgressWithLabel(props: Props): ReactElement {
|
||||||
|
return (
|
||||||
|
<Box display="flex" alignItems="center">
|
||||||
|
<Box width="100%" mr={1}>
|
||||||
|
<LinearProgress variant="determinate" {...props} />
|
||||||
|
</Box>
|
||||||
|
<Box minWidth={35}>
|
||||||
|
<Typography variant="body2" color="textSecondary">{`${Math.round(props.value)}%`}</Typography>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { Context as SettingsContext } from '../../providers/Settings'
|
||||||
|
import { Box } from '@material-ui/core'
|
||||||
|
import { ReactElement, useContext, useEffect, useRef, useState } from 'react'
|
||||||
|
import { DocumentationText } from '../../components/DocumentationText'
|
||||||
|
import { LinearProgressWithLabel } from '../../components/ProgressBar'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
reference: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AssetSyncing({ reference }: Props): ReactElement {
|
||||||
|
const { beeApi } = useContext(SettingsContext)
|
||||||
|
|
||||||
|
const syncTimer = useRef<NodeJS.Timer>()
|
||||||
|
const [isRetrieveChecking, setIsRetrieveChecking] = useState<boolean>(false)
|
||||||
|
const [syncProgress, setSyncProgress] = useState<number>(0)
|
||||||
|
|
||||||
|
const syncCheck = async () => {
|
||||||
|
if (!beeApi) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const tags = await beeApi.getAllTags()
|
||||||
|
const tag = tags.find(t => t.address === reference)
|
||||||
|
|
||||||
|
if (tag) {
|
||||||
|
const progress = ((tag.seen + tag.synced) / tag.split) * 100
|
||||||
|
setSyncProgress(progress)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
syncTimer.current = setInterval(syncCheck, 2000)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (syncTimer.current) {
|
||||||
|
clearInterval(syncTimer.current)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [reference])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (syncProgress === 100 && syncTimer.current) {
|
||||||
|
clearInterval(syncTimer.current)
|
||||||
|
}
|
||||||
|
}, [syncProgress])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
/*
|
||||||
|
There are instances when it seems that the content isn't synchronized, despite being already available.
|
||||||
|
To ensure it's not due to invalid synchronization data,
|
||||||
|
verify availability from at least 70% using one of the stewardship endpoints.
|
||||||
|
|
||||||
|
TODO: is 70 a good number?
|
||||||
|
*/
|
||||||
|
if (beeApi && !isRetrieveChecking && syncProgress > 10 && syncProgress < 100) {
|
||||||
|
// It's a long running task make sure only one run occurs at a time.
|
||||||
|
setIsRetrieveChecking(true)
|
||||||
|
|
||||||
|
beeApi.isReferenceRetrievable(reference).then(isRetriavable => {
|
||||||
|
if (isRetriavable) {
|
||||||
|
setSyncProgress(100)
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsRetrieveChecking(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [syncProgress, isRetrieveChecking, beeApi, reference])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box mb={2}>
|
||||||
|
<DocumentationText>
|
||||||
|
Files are not immediately accessible on the Swarm network. Please wait until your upload is synced to the
|
||||||
|
network.{' '}
|
||||||
|
<a href="https://docs.ethswarm.org/docs/develop/access-the-swarm/syncing">Learn more about syncing</a>.
|
||||||
|
</DocumentationText>
|
||||||
|
</Box>
|
||||||
|
<Box mb={4}>
|
||||||
|
<LinearProgressWithLabel value={syncProgress}></LinearProgressWithLabel>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import { ManifestJs } from '../../utils/manifest'
|
|||||||
import { AssetPreview } from './AssetPreview'
|
import { AssetPreview } from './AssetPreview'
|
||||||
import { AssetSummary } from './AssetSummary'
|
import { AssetSummary } from './AssetSummary'
|
||||||
import { DownloadActionBar } from './DownloadActionBar'
|
import { DownloadActionBar } from './DownloadActionBar'
|
||||||
|
import { AssetSyncing } from './AssetSyncing'
|
||||||
|
|
||||||
export function Share(): ReactElement {
|
export function Share(): ReactElement {
|
||||||
const { apiUrl, beeApi } = useContext(SettingsContext)
|
const { apiUrl, beeApi } = useContext(SettingsContext)
|
||||||
@@ -152,6 +153,9 @@ export function Share(): ReactElement {
|
|||||||
<Box mb={4}>
|
<Box mb={4}>
|
||||||
<AssetSummary isWebsite={metadata?.isWebsite} reference={reference} />
|
<AssetSummary isWebsite={metadata?.isWebsite} reference={reference} />
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box mb={4}>
|
||||||
|
<AssetSyncing reference={reference} />
|
||||||
|
</Box>
|
||||||
<DownloadActionBar
|
<DownloadActionBar
|
||||||
onOpen={onOpen}
|
onOpen={onOpen}
|
||||||
onCancel={onClose}
|
onCancel={onClose}
|
||||||
|
|||||||
@@ -204,7 +204,16 @@ export function Upload(): ReactElement {
|
|||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{step === 2 && stamp && <StampPreview stamp={stamp} />}
|
{step === 2 && stamp && (
|
||||||
|
<>
|
||||||
|
<StampPreview stamp={stamp} />
|
||||||
|
<Box mb={4}>
|
||||||
|
<DocumentationText>
|
||||||
|
Please do not close the application until your file is uploaded to your local node!
|
||||||
|
</DocumentationText>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<UploadActionBar
|
<UploadActionBar
|
||||||
step={step}
|
step={step}
|
||||||
onCancel={reset}
|
onCancel={reset}
|
||||||
|
|||||||
Reference in New Issue
Block a user