5bfe2a0331
* feat: add file manager module - Complete file manager implementation with UI/UX - Add drive management functionality - Add file upload/download with progress tracking - Add stamp integration and handling - Add bulk operations and context menus Co-authored-by: Roland Seres <roland.seres90@gmail.com> Co-authored-by: nidishk <nidishkrishnan45@gmail.com>
131 lines
3.9 KiB
TypeScript
131 lines
3.9 KiB
TypeScript
import { ReactElement, useCallback } from 'react'
|
|
import { FileItem } from '../FileItem/FileItem'
|
|
import { FileInfo, DriveInfo } from '@solarpunkltd/file-manager-lib'
|
|
import { DownloadProgress, TrackDownloadProps, ViewType } from '../../../constants/transfers'
|
|
import { getFileId } from '../../../utils/common'
|
|
|
|
interface FileBrowserContentProps {
|
|
listToRender: FileInfo[]
|
|
drives: DriveInfo[]
|
|
currentDrive: DriveInfo | null
|
|
view: ViewType
|
|
isSearchMode: boolean
|
|
trackDownload: (props: TrackDownloadProps) => (dp: DownloadProgress) => void
|
|
selectedIds?: Set<string>
|
|
onToggleSelected?: (fi: FileInfo, checked: boolean) => void
|
|
bulkSelectedCount?: number
|
|
onBulk: {
|
|
download?: () => void
|
|
restore?: () => void
|
|
forget?: () => void
|
|
destroy?: () => void
|
|
delete?: () => void
|
|
}
|
|
setErrorMessage?: (error: string) => void
|
|
}
|
|
|
|
export function FileBrowserContent({
|
|
listToRender,
|
|
drives,
|
|
currentDrive,
|
|
view,
|
|
isSearchMode,
|
|
trackDownload,
|
|
selectedIds,
|
|
onToggleSelected,
|
|
bulkSelectedCount,
|
|
onBulk,
|
|
setErrorMessage,
|
|
}: FileBrowserContentProps): ReactElement {
|
|
const renderEmptyState = useCallback((): ReactElement => {
|
|
if (drives.length === 0) {
|
|
return <div className="fm-drop-hint">Create a drive to start using the file manager</div>
|
|
}
|
|
|
|
if (!currentDrive) {
|
|
return <div className="fm-drop-hint">Select a drive to upload or view its files</div>
|
|
}
|
|
|
|
if (view === ViewType.Trash) {
|
|
return (
|
|
<div className="fm-drop-hint">
|
|
Files from "{currentDrive?.name}" that are trashed can be viewed here
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return <div className="fm-drop-hint">Drag & drop files here into "{currentDrive?.name}"</div>
|
|
}, [drives, currentDrive, view])
|
|
|
|
const renderFileList = useCallback(
|
|
(filesToRender: FileInfo[], showDriveColumn = false): ReactElement[] => {
|
|
return filesToRender
|
|
.map(fi => {
|
|
const drive = drives.find(d => d.id.toString() === fi.driveId.toString())
|
|
|
|
return drive ? { fi, driveName: drive.name } : null
|
|
})
|
|
.filter((item): item is { fi: FileInfo; driveName: string } => item !== null)
|
|
.map(({ fi, driveName }) => {
|
|
const key = `${getFileId(fi)}::${fi.version ?? ''}::${showDriveColumn ? 'search' : 'normal'}`
|
|
|
|
return (
|
|
<FileItem
|
|
key={key}
|
|
fileInfo={fi}
|
|
onDownload={trackDownload}
|
|
showDriveColumn={showDriveColumn}
|
|
driveName={driveName}
|
|
selected={Boolean(selectedIds?.has(getFileId(fi)))}
|
|
onToggleSelected={onToggleSelected}
|
|
bulkSelectedCount={bulkSelectedCount}
|
|
onBulk={onBulk}
|
|
setErrorMessage={setErrorMessage}
|
|
/>
|
|
)
|
|
})
|
|
},
|
|
[trackDownload, drives, selectedIds, onToggleSelected, bulkSelectedCount, onBulk, setErrorMessage],
|
|
)
|
|
|
|
if (drives.length === 0) {
|
|
return renderEmptyState()
|
|
}
|
|
|
|
if (!isSearchMode) {
|
|
if (!currentDrive) {
|
|
return <div className="fm-drop-hint">Select a drive to upload or view its files</div>
|
|
}
|
|
|
|
if (view === ViewType.Expired) {
|
|
return (
|
|
<div className="fm-drop-hint">
|
|
The stamp for drive "{currentDrive?.name}" is expired, no files can be found
|
|
</div>
|
|
)
|
|
}
|
|
|
|
if (listToRender.length === 0) {
|
|
if (view === ViewType.Trash) {
|
|
return (
|
|
<div className="fm-drop-hint">
|
|
Files from "{currentDrive?.name}" that are trashed can be viewed here
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return <div className="fm-drop-hint">Drag & drop files here into "{currentDrive?.name}"</div>
|
|
}
|
|
|
|
return <>{renderFileList(listToRender)}</>
|
|
}
|
|
|
|
if (listToRender.length === 0) {
|
|
return <div className="fm-drop-hint">No results found.</div>
|
|
}
|
|
|
|
return <>{renderFileList(listToRender, true)}</>
|
|
}
|
|
|
|
export default FileBrowserContent
|