fix: use upload and download abort signals (#212)

* fix: use upload and download abort signals

* fix: progress trackers

chore: update fm-lib and bee-js

* chore: bump-up fm-lib version
This commit is contained in:
Bálint Ujvári
2026-03-05 16:55:09 +01:00
parent e00918b192
commit 308ec3dcc0
13 changed files with 154 additions and 85 deletions
@@ -62,6 +62,8 @@ export function CreateDriveModal({
const validationError = duplicate && nameExists ? 'Drive already exists. Please choose another name.' : ''
useEffect(() => {
isMountedRef.current = true
return () => {
isMountedRef.current = false
}
@@ -210,6 +210,7 @@ export function FileBrowser({ errorMessage, setErrorMessage }: FileBrowserProps)
const [confirmBulkRestore, setConfirmBulkRestore] = useState(false)
const [isRefreshing, setIsRefreshing] = useState(false)
const [pendingCancelUpload, setPendingCancelUpload] = useState<string | null>(null)
const [pendingCancelDownload, setPendingCancelDownload] = useState<string | null>(null)
const q = query.trim().toLowerCase()
const isSearchMode = q.length > 0
@@ -371,6 +372,16 @@ export function FileBrowser({ errorMessage, setErrorMessage }: FileBrowserProps)
setShowError,
])
const handleDownloadClose = (uuid: string) => {
const row = downloadItems.find(i => i.uuid === uuid)
if (row?.status === TransferStatus.Downloading) {
setPendingCancelDownload(uuid)
} else {
cancelOrDismissDownload(uuid)
}
}
const handleUploadClose = (uuid: string) => {
const row = uploadItems.find(i => i.uuid === uuid)
@@ -425,6 +436,18 @@ export function FileBrowser({ errorMessage, setErrorMessage }: FileBrowserProps)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [showContext, pos, contextRef])
useEffect(() => {
isMountedRef.current = true
return () => {
isMountedRef.current = false
if (rafIdRef.current) {
cancelAnimationFrame(rafIdRef.current)
}
}
}, [])
useEffect(() => {
let title = currentDrive?.name || ''
@@ -446,16 +469,6 @@ export function FileBrowser({ errorMessage, setErrorMessage }: FileBrowserProps)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSearchMode])
useEffect(() => {
return () => {
isMountedRef.current = false
if (rafIdRef.current) {
cancelAnimationFrame(rafIdRef.current)
}
}
}, [])
const doRefresh = async () => {
handleCloseContext()
@@ -610,6 +623,14 @@ export function FileBrowser({ errorMessage, setErrorMessage }: FileBrowserProps)
}
}}
onCancelUploadCancel={() => setPendingCancelUpload(null)}
pendingCancelDownload={pendingCancelDownload}
onCancelDownloadConfirm={() => {
if (pendingCancelDownload) {
cancelOrDismissDownload(pendingCancelDownload)
setPendingCancelDownload(null)
}
}}
onCancelDownloadCancel={() => setPendingCancelDownload(null)}
/>
{isRefreshing && (
@@ -644,7 +665,7 @@ export function FileBrowser({ errorMessage, setErrorMessage }: FileBrowserProps)
type={FileTransferType.Download}
open={isDownloading}
items={downloadItems}
onRowClose={(name: string) => cancelOrDismissDownload(name)}
onRowClose={handleDownloadClose}
onCloseAll={() => dismissAllDownloads()}
/>
<NotificationBar setErrorMessage={setErrorMessage} />
@@ -17,6 +17,7 @@ interface FileBrowserModalsProps {
confirmBulkRestore: boolean
showDestroyDriveModal: boolean
pendingCancelUpload: string | null
pendingCancelDownload: string | null
onDeleteCancel: () => void
onDeleteProceed: (action: FileAction) => void
onForgetConfirm: () => Promise<void>
@@ -27,6 +28,8 @@ interface FileBrowserModalsProps {
onDestroyConfirm: () => Promise<void>
onCancelUploadConfirm: () => void
onCancelUploadCancel: () => void
onCancelDownloadConfirm: () => void
onCancelDownloadCancel: () => void
}
export function FileBrowserModals({
@@ -38,6 +41,7 @@ export function FileBrowserModals({
confirmBulkRestore,
showDestroyDriveModal,
pendingCancelUpload,
pendingCancelDownload,
onDeleteCancel,
onDeleteProceed,
onForgetConfirm,
@@ -48,6 +52,8 @@ export function FileBrowserModals({
onDestroyConfirm,
onCancelUploadConfirm,
onCancelUploadCancel,
onCancelDownloadCancel,
onCancelDownloadConfirm,
}: FileBrowserModalsProps): ReactElement {
return (
<>
@@ -124,6 +130,17 @@ export function FileBrowserModals({
onCancel={onCancelUploadCancel}
/>
)}
{pendingCancelDownload && (
<ConfirmModal
title="Cancel download?"
message="Are you sure you want to cancel this download?"
confirmLabel="Cancel download"
cancelLabel="Keep downloading"
onConfirm={onCancelDownloadConfirm}
onCancel={onCancelDownloadCancel}
/>
)}
</>
)
}
@@ -20,7 +20,7 @@ import { DownloadProgress, FileAction, TrackDownloadProps, ViewType } from '../.
import { useContextMenu } from '../../../hooks/useContextMenu'
import { getUsableStamps, handleDestroyAndForgetDrive, verifyDriveSpace } from '../../../utils/bee'
import { Dir, formatBytes, isTrashed, safeSetState, truncateNameMiddle } from '../../../utils/common'
import { createDownloadAbort, startDownloadingQueue } from '../../../utils/download'
import { startDownloadingQueue } from '../../../utils/download'
import { FileOperation, performFileOperation } from '../../../utils/fileOperations'
import { GetIconElement } from '../../../utils/GetIconElement'
import type { FilePropertyGroup } from '../../../utils/infoGroups'
@@ -168,15 +168,14 @@ export function FileItem({
const rawSize = latestFileInfo.customMetadata?.size
const expectedSize = rawSize ? Number(rawSize) : undefined
createDownloadAbort(latestFileInfo.name)
const uuid = uuidV4()
await startDownloadingQueue(
fm,
[latestFileInfo],
[{ uuid, info: latestFileInfo }],
[
onDownload({
uuid: uuidV4(),
uuid,
name: latestFileInfo.name,
size: formatBytes(rawSize),
expectedSize,
@@ -89,6 +89,8 @@ export function InitialModal({
const isMountedRef = useRef(true)
useEffect(() => {
isMountedRef.current = true
return () => {
isMountedRef.current = false
}
@@ -159,6 +159,14 @@ export function UpgradeDriveModal({
[beeApi, walletBalance, isMountedRef, setErrorMessage, setShowError],
)
useEffect(() => {
isMountedRef.current = true
return () => {
isMountedRef.current = false
}
}, [])
useEffect(() => {
const fetchSizes = () => {
const sizes = Array.from(Utils.getStampEffectiveBytesBreakpoints(false, defaultErasureCodeLevel).values())
@@ -207,12 +215,6 @@ export function UpgradeDriveModal({
setValidityEndDate(getExpiryDateByLifetime(lifetimeIndex, stamp.duration.toEndDate()))
}, [lifetimeIndex, stamp.duration])
useEffect(() => {
return () => {
isMountedRef.current = false
}
}, [])
const batchIdStr = stamp.batchID.toString()
const shortBatchId = batchIdStr.length > 12 ? `${batchIdStr.slice(0, 4)}...${batchIdStr.slice(-4)}` : batchIdStr
@@ -426,13 +426,16 @@ export function VersionsList({ versions, headFi, restoreVersion, onDownload }: V
handleCloseContext()
if (!fm || !beeApi) return
const rawSize = fileInfo.customMetadata?.size
const expectedSize = rawSize ? Number(rawSize) : undefined
const driveName = drives.find(d => d.id.toString() === fileInfo.driveId.toString())?.name ?? currentDrive?.name
const uuid = uuidV4()
await startDownloadingQueue(
fm,
[fileInfo],
[onDownload({ uuid: uuidV4(), name: fileInfo.name, size: formatBytes(rawSize), expectedSize, driveName })],
[{ uuid, info: fileInfo }],
[onDownload({ uuid, name: fileInfo.name, size: formatBytes(rawSize), expectedSize, driveName })],
)
},
[handleCloseContext, fm, beeApi, onDownload, drives, currentDrive],