Files
bee-dashboard/src/modules/filemanager/components/NotificationBar/NotificationBar.tsx
T
Ferenc Sárai e6f882d7e1 fix: for upcoming v0.53.1 (#731)
* fix: swap error caused by invalid id and batchcount
* fix: enhance creation messages for admin drive and user drives (#238)
* fix: enhance creation messages for admin drive and user drives
* fix: update creation message to indicate longer processing time
* fix: identity and wallet creation (#240)
* fix: asset preview types
* fix: fm search unicode text
* fix: feed identity and stamp usage
* fix: ui display changes (#239)
* fix: ui layout changes

* fix: stamp buy and dilute (#242)

fix: vite polyfill warning for stream
refactor: stamp depth and amount validation

* fix: spdv-917 (#243)

* fix: spdv-917

* refactor: spdv-917

* fix: add syncing message for Bee node and update page state handling spdv-955 (#244)

* fix: spdv-1037 (#245)

* fix: spdv-1038 (#246)

* fix: spdv-1038

* refactor: spdv-1038

* fix: validate stamp before every upgrade click (#247)

* fix: validate stamp before every upgrade click
---------

Co-authored-by: Roland Seres <roland.seres90@gmail.com>

* fix: use tochecksum() and toplurbigint() for ethers v6 compatibility (#248)

---------

Co-authored-by: Balint Ujvari <balint.ujvari@solarpunk.buzz>
Co-authored-by: Bálint Ujvári <58116288+bosi95@users.noreply.github.com>
Co-authored-by: rolandlor <33499567+rolandlor@users.noreply.github.com>
Co-authored-by: Roland Seres <roland.seres90@gmail.com>
2026-04-10 10:59:20 +02:00

128 lines
4.0 KiB
TypeScript

import { PostageBatch } from '@ethersphere/bee-js'
import { DriveInfo } from '@solarpunkltd/file-manager-lib'
import { ReactElement, useContext, useEffect, useState } from 'react'
import UpIcon from 'remixicon-react/ArrowUpSLineIcon'
import { Context as FMContext } from '../../../../providers/FileManager'
import { Context as SettingsContext } from '../../../../providers/Settings'
import { FILE_MANAGER_EVENTS } from '../../constants/common'
import { getUsableStamps } from '../../utils/bee'
import { ExpiringNotificationModal } from '../ExpiringNotificationModal/ExpiringNotificationModal'
import './NotificationBar.scss'
const NUMBER_OF_DAYS_WARNING = 7
const DAYS_TO_MILLISECONDS_MULTIPLIER = 24 * 60 * 60 * 1000
const isExpiring = (s: PostageBatch): boolean => {
return (
s.duration &&
s.duration.toEndDate().getTime() <= Date.now() + NUMBER_OF_DAYS_WARNING * DAYS_TO_MILLISECONDS_MULTIPLIER
)
}
interface NotificationBarProps {
setErrorMessage?: (error: string) => void
}
export function NotificationBar({ setErrorMessage }: NotificationBarProps): ReactElement | null {
const [showExpiringModal, setShowExpiringModal] = useState(false)
const [stampsToExpire, setStampsToExpire] = useState<PostageBatch[]>([])
const [drivesToExpire, setDrivesToExpire] = useState<DriveInfo[]>([])
const { beeApi } = useContext(SettingsContext)
const { drives, files, adminDrive, setShowError } = useContext(FMContext)
const showExpiration = stampsToExpire.length > 0
useEffect(() => {
let isMounted = true
const getStamps = async () => {
if (!beeApi) {
return
}
const allStamps = await getUsableStamps(beeApi)
const expiringStamps: PostageBatch[] = []
const expiringDrives: DriveInfo[] = []
allStamps.forEach(stamp => {
const matchingDrive =
drives.find(d => d.batchId.toString() === stamp.batchID.toString()) ||
(adminDrive?.batchId.toString() === stamp.batchID.toString() ? adminDrive : null)
if (matchingDrive) {
if (isExpiring(stamp)) {
expiringStamps.push(stamp)
expiringDrives.push(matchingDrive)
}
}
})
if (isMounted) {
setStampsToExpire(expiringStamps)
setDrivesToExpire(expiringDrives)
}
}
getStamps()
return () => {
isMounted = false
}
}, [beeApi, drives, adminDrive, setErrorMessage])
useEffect(() => {
const onDriveUpgradeEnd = (e: Event) => {
const { driveId, success, updatedStamp } = (e as CustomEvent).detail || {}
if (success && updatedStamp && driveId) {
if (!isExpiring(updatedStamp)) {
setTimeout(() => {
setStampsToExpire(prev => {
const stampIx = prev.findIndex(s => s.batchID.toString() === updatedStamp.batchID.toString())
return stampIx !== -1 ? prev.filter((_, i) => i !== stampIx) : prev
})
setDrivesToExpire(prev => {
const driveIx = prev.findIndex(d => d.id.toString() === driveId)
return driveIx !== -1 ? prev.filter((_, i) => i !== driveIx) : prev
})
}, 150)
}
}
}
window.addEventListener(FILE_MANAGER_EVENTS.DRIVE_UPGRADE_END, onDriveUpgradeEnd as EventListener)
return () => {
window.removeEventListener(FILE_MANAGER_EVENTS.DRIVE_UPGRADE_END, onDriveUpgradeEnd as EventListener)
}
}, [])
if (!showExpiration) return null
return (
<>
<div className="fm-notification-bar fm-red-font" onClick={() => setShowExpiringModal(true)}>
{stampsToExpire.length} drive{stampsToExpire.length > 1 ? 's' : ''} expiring soon <UpIcon size="16px" />
</div>
{showExpiringModal && beeApi && (
<ExpiringNotificationModal
bee={beeApi}
stamps={stampsToExpire}
drives={drivesToExpire}
files={files}
onCancelClick={() => {
setShowExpiringModal(false)
}}
setErrorMessage={setErrorMessage}
setShowError={setShowError}
/>
)}
</>
)
}