|
| 1 | +import { Context as SettingsContext } from '../../providers/Settings' |
| 2 | +import { Box } from '@material-ui/core' |
| 3 | +import { ReactElement, useContext, useEffect, useRef, useState } from 'react' |
| 4 | +import { DocumentationText } from '../../components/DocumentationText' |
| 5 | +import { LinearProgressWithLabel } from '../../components/ProgressBar' |
| 6 | + |
| 7 | +interface Props { |
| 8 | + reference: string |
| 9 | +} |
| 10 | + |
| 11 | +export function AssetSyncing({ reference }: Props): ReactElement { |
| 12 | + const { beeApi } = useContext(SettingsContext) |
| 13 | + |
| 14 | + const syncTimer = useRef<NodeJS.Timer>() |
| 15 | + const [isRetrieveChecking, setIsRetrieveChecking] = useState<boolean>(false) |
| 16 | + const [syncProgress, setSyncProgress] = useState<number>(0) |
| 17 | + |
| 18 | + const syncCheck = async () => { |
| 19 | + if (!beeApi) { |
| 20 | + return |
| 21 | + } |
| 22 | + |
| 23 | + const tags = await beeApi.getAllTags() |
| 24 | + const tag = tags.find(t => t.address === reference) |
| 25 | + |
| 26 | + if (tag) { |
| 27 | + const progress = ((tag.seen + tag.synced) / tag.split) * 100 |
| 28 | + setSyncProgress(progress) |
| 29 | + } |
| 30 | + } |
| 31 | + |
| 32 | + useEffect(() => { |
| 33 | + syncTimer.current = setInterval(syncCheck, 2000) |
| 34 | + |
| 35 | + return () => { |
| 36 | + if (syncTimer.current) { |
| 37 | + clearInterval(syncTimer.current) |
| 38 | + } |
| 39 | + } |
| 40 | + // eslint-disable-next-line react-hooks/exhaustive-deps |
| 41 | + }, [reference]) |
| 42 | + |
| 43 | + useEffect(() => { |
| 44 | + if (syncProgress === 100 && syncTimer.current) { |
| 45 | + clearInterval(syncTimer.current) |
| 46 | + } |
| 47 | + }, [syncProgress]) |
| 48 | + |
| 49 | + useEffect(() => { |
| 50 | + /* |
| 51 | + There are instances when it seems that the content isn't synchronized, despite being already available. |
| 52 | + To ensure it's not due to invalid synchronization data, |
| 53 | + verify availability from at least 70% using one of the stewardship endpoints. |
| 54 | + |
| 55 | + TODO: is 70 a good number? |
| 56 | + */ |
| 57 | + if (beeApi && !isRetrieveChecking && syncProgress > 10 && syncProgress < 100) { |
| 58 | + // It's a long running task make sure only one run occurs at a time. |
| 59 | + setIsRetrieveChecking(true) |
| 60 | + |
| 61 | + beeApi.isReferenceRetrievable(reference).then(isRetriavable => { |
| 62 | + if (isRetriavable) { |
| 63 | + setSyncProgress(100) |
| 64 | + } |
| 65 | + |
| 66 | + setIsRetrieveChecking(false) |
| 67 | + }) |
| 68 | + } |
| 69 | + }, [syncProgress, isRetrieveChecking, beeApi, reference]) |
| 70 | + |
| 71 | + return ( |
| 72 | + <> |
| 73 | + <Box mb={2}> |
| 74 | + <DocumentationText> |
| 75 | + Files are not immediately accessible on the Swarm network. Please wait until your upload is synced to the |
| 76 | + network.{' '} |
| 77 | + <a href="https://docs.ethswarm.org/docs/develop/access-the-swarm/syncing">Learn more about syncing</a>. |
| 78 | + </DocumentationText> |
| 79 | + </Box> |
| 80 | + <Box mb={4}> |
| 81 | + <LinearProgressWithLabel value={syncProgress}></LinearProgressWithLabel> |
| 82 | + </Box> |
| 83 | + </> |
| 84 | + ) |
| 85 | +} |
0 commit comments