From 12840046cda0d86f2a65657886636ca50507cd16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=9B=BD=E7=92=87?= <37972689+YangGuoXuan-0503@users.noreply.github.com> Date: Thu, 29 May 2025 16:20:20 +0800 Subject: [PATCH] refactor: download (#7388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: download * feat: update code * feat: rebase bug * feat: rebase bug --------- Co-authored-by: 杨国璇 Co-authored-by: 杨国璇 Co-authored-by: 杨国璇 --- .../src/components/common/event-bus-type.js | 3 + .../dirent-grid-view/dirent-grid-view.js | 50 +- .../dirent-list-view/dirent-list-item.js | 51 +-- .../dirent-list-view/dirent-list-view.js | 50 +- .../toolbar/selected-dirents-toolbar.js | 52 +-- frontend/src/hooks/download-file.js | 83 ++++ frontend/src/hooks/index.js | 1 + frontend/src/metadata/utils/file.js | 11 - .../views/gallery/context-menu/index.js | 54 +-- .../views/kanban/context-menu/index.js | 39 +- frontend/src/models/dirent.js | 1 + .../lib-content-view/lib-content-view.js | 427 +++++++++--------- 12 files changed, 346 insertions(+), 476 deletions(-) create mode 100644 frontend/src/hooks/download-file.js diff --git a/frontend/src/components/common/event-bus-type.js b/frontend/src/components/common/event-bus-type.js index 48df65f834..3ffbff7577 100644 --- a/frontend/src/components/common/event-bus-type.js +++ b/frontend/src/components/common/event-bus-type.js @@ -20,4 +20,7 @@ export const EVENT_BUS_TYPE = { TAGS_DATA: 'tags_data', SELECT_TAG: 'select_tag', UPDATE_SELECTED_TAG: 'update_selected_tag', + + // download file + DOWNLOAD_FILE: 'download_file', }; diff --git a/frontend/src/components/dirent-grid-view/dirent-grid-view.js b/frontend/src/components/dirent-grid-view/dirent-grid-view.js index 32b99285b0..2a25ccbd76 100644 --- a/frontend/src/components/dirent-grid-view/dirent-grid-view.js +++ b/frontend/src/components/dirent-grid-view/dirent-grid-view.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { siteRoot, username, enableSeadoc, thumbnailDefaultSize, thumbnailSizeForOriginal, gettext, fileServerRoot, enableWhiteboard, useGoFileserver, enableExcalidraw } from '../../utils/constants'; +import { siteRoot, username, enableSeadoc, thumbnailDefaultSize, thumbnailSizeForOriginal, gettext, fileServerRoot, enableWhiteboard, enableExcalidraw } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import { seafileAPI } from '../../utils/seafile-api'; import URLDecorator from '../../utils/url-decorator'; @@ -14,7 +14,6 @@ import TextTranslation from '../../utils/text-translation'; import MoveDirentDialog from '../dialog/move-dirent-dialog'; import CopyDirentDialog from '../dialog/copy-dirent-dialog'; import ShareDialog from '../dialog/share-dialog'; -import ZipDownloadDialog from '../dialog/zip-download-dialog'; import Rename from '../../components/dialog/rename-dirent'; import CreateFile from '../dialog/create-file-dialog'; import CreateFolder from '../dialog/create-folder-dialog'; @@ -24,6 +23,7 @@ import imageAPI from '../../utils/image-api'; import FileAccessLog from '../dialog/file-access-log'; import { EVENT_BUS_TYPE } from '../common/event-bus-type'; import EmptyTip from '../empty-tip'; +import { Dirent } from '../../models'; import '../../css/grid-view.css'; @@ -78,7 +78,6 @@ class DirentGridView extends React.Component { isShareDialogShow: false, isMoveDialogShow: false, isCopyDialogShow: false, - isZipDialogOpen: false, isRenameDialogShow: false, isCreateFolderDialogShow: false, isCreateFileDialogShow: false, @@ -458,39 +457,10 @@ class DirentGridView extends React.Component { return path === '/' ? path + dirent.name : path + '/' + dirent.name; }; - closeZipDialog = () => { - this.setState({ - isZipDialogOpen: false - }); - }; - onItemsDownload = () => { - let { path, repoID, selectedDirentList } = this.props; - if (selectedDirentList.length === 1 && !selectedDirentList[0].isDir()) { - let direntPath = Utils.joinPath(path, selectedDirentList[0].name); - let url = URLDecorator.getUrl({ type: 'download_file_url', repoID: repoID, filePath: direntPath }); - location.href = url; - return; - } - - let selectedDirentNames = selectedDirentList.map(dirent => { - return dirent.name; - }); - - if (useGoFileserver) { - seafileAPI.zipDownload(repoID, path, selectedDirentNames).then((res) => { - const zipToken = res.data['zip_token']; - location.href = `${fileServerRoot}zip/${zipToken}`; - }).catch((error) => { - let errorMsg = Utils.getErrorMsg(error); - toaster.danger(errorMsg); - }); - } else { - this.setState({ - isZipDialogOpen: true, - downloadItems: selectedDirentNames - }); - } + const { path, selectedDirentList, eventBus } = this.props; + const direntList = selectedDirentList.map(dirent => dirent instanceof Dirent ? dirent.toJson() : dirent); + eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList); }; onCreateFolderToggle = () => { @@ -999,16 +969,6 @@ class DirentGridView extends React.Component { onAddFolder={this.props.onAddFolder} /> } - {this.state.isZipDialogOpen && - - - - } {this.state.isCopyDialogShow && { e.preventDefault(); e.nativeEvent.stopImmediatePropagation(); - let dirent = this.state.dirent; - let repoID = this.props.repoID; - let direntPath = this.getDirentPath(dirent); - if (dirent.type === 'dir') { - if (!useGoFileserver) { - this.setState({ - isZipDialogOpen: true - }); - } else { - seafileAPI.zipDownload(repoID, this.props.path, this.state.dirent.name).then((res) => { - const zipToken = res.data['zip_token']; - location.href = `${fileServerRoot}zip/${zipToken}`; - }).catch((error) => { - let errorMsg = Utils.getErrorMsg(error); - this.setState({ - isLoading: false, - errorMsg: errorMsg - }); - }); - } - } else { - let url = URLDecorator.getUrl({ type: 'download_file_url', repoID: repoID, filePath: direntPath }); - location.href = url; - } - }; - - closeZipDialog = () => { - this.setState({ - isZipDialogOpen: false - }); + const { path, eventBus } = this.props; + const { dirent } = this.state; + const direntList = dirent instanceof Dirent ? [dirent.toJson()] : [dirent]; + eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList); }; getDirentPath = (dirent) => { @@ -973,16 +948,6 @@ class DirentListItem extends React.Component { /> } - {this.state.isZipDialogOpen && - - - - } {this.state.isShareDialogShow && { - let { path, repoID, selectedDirentList } = this.props; - if (selectedDirentList.length) { - if (selectedDirentList.length === 1 && !selectedDirentList[0].isDir()) { - let direntPath = Utils.joinPath(path, selectedDirentList[0].name); - let url = URLDecorator.getUrl({ type: 'download_file_url', repoID: repoID, filePath: direntPath }); - location.href = url; - return; - } - - let selectedDirentNames = selectedDirentList.map(dirent => { - return dirent.name; - }); - - if (useGoFileserver) { - seafileAPI.zipDownload(repoID, path, selectedDirentNames).then((res) => { - const zipToken = res.data['zip_token']; - location.href = `${fileServerRoot}zip/${zipToken}`; - }).catch((error) => { - let errorMsg = Utils.getErrorMsg(error); - toaster.danger(errorMsg); - }); - } else { - this.setState({ - isProgressDialogShow: true, - downloadItems: selectedDirentNames - }); - } - } - }; - - onCloseZipDownloadDialog = () => { - this.setState({ isProgressDialogShow: false }); + const { path, selectedDirentList, eventBus } = this.props; + const direntList = selectedDirentList.map(dirent => dirent instanceof Dirent ? dirent.toJson() : dirent); + eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList); }; // common contextmenu handle @@ -813,6 +782,7 @@ class DirentListView extends React.Component { path={this.props.path} repoID={this.props.repoID} currentRepoInfo={this.props.currentRepoInfo} + eventBus={this.props.eventBus} isAdmin={this.isAdmin} isRepoOwner={this.isRepoOwner} repoEncrypted={this.repoEncrypted} @@ -941,14 +911,6 @@ class DirentListView extends React.Component { onAddFolder={this.props.onAddFolder} /> } - {this.state.isProgressDialogShow && - - } ); diff --git a/frontend/src/components/toolbar/selected-dirents-toolbar.js b/frontend/src/components/toolbar/selected-dirents-toolbar.js index 9507cf5840..df66b3b40c 100644 --- a/frontend/src/components/toolbar/selected-dirents-toolbar.js +++ b/frontend/src/components/toolbar/selected-dirents-toolbar.js @@ -1,12 +1,11 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { gettext, siteRoot, name, fileServerRoot, useGoFileserver } from '../../utils/constants'; +import { gettext, siteRoot, name } from '../../utils/constants'; import { Utils } from '../../utils/utils'; import { seafileAPI } from '../../utils/seafile-api'; import URLDecorator from '../../utils/url-decorator'; import MoveDirentDialog from '../dialog/move-dirent-dialog'; import CopyDirentDialog from '../dialog/copy-dirent-dialog'; -import ZipDownloadDialog from '../dialog/zip-download-dialog'; import ShareDialog from '../dialog/share-dialog'; import Rename from '../dialog/rename-dirent'; import LibSubFolderPermissionDialog from '../dialog/lib-sub-folder-permission-dialog'; @@ -14,6 +13,8 @@ import ModalPortal from '../modal-portal'; import ItemDropdownMenu from '../dropdown-menu/item-dropdown-menu'; import toaster from '../toast'; import FileAccessLog from '../dialog/file-access-log'; +import { Dirent } from '../../models'; +import { EVENT_BUS_TYPE } from '../common/event-bus-type'; import '../../css/selected-dirents-toolbar.css'; @@ -23,6 +24,7 @@ const propTypes = { repoID: PropTypes.string.isRequired, repoEncrypted: PropTypes.bool.isRequired, selectedDirentList: PropTypes.array.isRequired, + eventBus: PropTypes.object.isRequired, onItemsMove: PropTypes.func.isRequired, onItemsCopy: PropTypes.func.isRequired, onItemsDelete: PropTypes.func.isRequired, @@ -45,7 +47,6 @@ class SelectedDirentsToolbar extends React.Component { constructor(props) { super(props); this.state = { - isZipDialogOpen: false, isFileAccessLogDialogOpen: false, isMoveDialogShow: false, isCopyDialogShow: false, @@ -71,38 +72,9 @@ class SelectedDirentsToolbar extends React.Component { }; onItemsDownload = () => { - let { path, repoID, selectedDirentList } = this.props; - if (selectedDirentList.length) { - if (selectedDirentList.length === 1 && !selectedDirentList[0].isDir()) { - let direntPath = Utils.joinPath(path, selectedDirentList[0].name); - let url = URLDecorator.getUrl({ type: 'download_file_url', repoID: repoID, filePath: direntPath }); - location.href = url; - return; - } - if (useGoFileserver) { - const target = this.props.selectedDirentList.map(dirent => dirent.name); - seafileAPI.zipDownload(repoID, path, target).then((res) => { - const zipToken = res.data['zip_token']; - location.href = `${fileServerRoot}zip/${zipToken}`; - }).catch((error) => { - let errorMsg = Utils.getErrorMsg(error); - this.setState({ - isLoading: false, - errorMsg: errorMsg - }); - }); - } else { - this.setState({ - isZipDialogOpen: true - }); - } - } - }; - - closeZipDialog = () => { - this.setState({ - isZipDialogOpen: false - }); + const { path, selectedDirentList, eventBus } = this.props; + const direntList = selectedDirentList.map(dirent => dirent instanceof Dirent ? dirent.toJson() : dirent); + eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList); }; checkDuplicatedName = (newName) => { @@ -433,16 +405,6 @@ class SelectedDirentsToolbar extends React.Component { onAddFolder={this.props.onAddFolder} /> } - {this.state.isZipDialogOpen && - - dirent.name)} - toggleDialog={this.closeZipDialog} - /> - - } {this.state.showLibContentViewDialogs && ( {this.state.showShareDialog && diff --git a/frontend/src/hooks/download-file.js b/frontend/src/hooks/download-file.js new file mode 100644 index 0000000000..fb7a2bb51c --- /dev/null +++ b/frontend/src/hooks/download-file.js @@ -0,0 +1,83 @@ +import React, { useContext, useEffect, useCallback, useState, useRef } from 'react'; +import { useGoFileserver, fileServerRoot } from '../utils/constants'; +import { Utils } from '../utils/utils'; +import { seafileAPI } from '../utils/seafile-api'; +import URLDecorator from '../utils/url-decorator'; +import ModalPortal from '../components/modal-portal'; +import ZipDownloadDialog from '../components/dialog/zip-download-dialog'; +import toaster from '../components/toast'; +import { EVENT_BUS_TYPE } from '../components/common/event-bus-type'; + +// This hook provides content about download +const DownloadFileContext = React.createContext(null); + +export const DownloadFileProvider = ({ repoID, eventBus, children }) => { + const [isZipDialogOpen, setZipDialogOpen] = useState(); + + const pathRef = useRef(''); + const direntListRef = useRef([]); + + const handelDownload = useCallback((path, direntList = []) => { + const direntCount = direntList.length; + if (direntCount === 0) return; + if (direntCount === 1 && !direntList[0].is_dir) { + const direntPath = Utils.joinPath(path, direntList[0].name); + const url = URLDecorator.getUrl({ type: 'download_file_url', repoID: repoID, filePath: direntPath }); + location.href = url; + return; + } + direntListRef.current = direntList.map(dirent => dirent.name); + + if (!useGoFileserver) { + pathRef.current = path; + setZipDialogOpen(true); + return; + } + + seafileAPI.zipDownload(repoID, path, direntListRef.current).then((res) => { + const zipToken = res.data['zip_token']; + location.href = `${fileServerRoot}zip/${zipToken}`; + }).catch((error) => { + const errorMsg = Utils.getErrorMsg(error); + toaster.danger(errorMsg); + }); + }, [repoID]); + + const cancelDownload = useCallback(() => { + setZipDialogOpen(false); + pathRef.current = ''; + direntListRef.current = []; + }, []); + + useEffect(() => { + const unsubscribeDownloadFile = eventBus.subscribe(EVENT_BUS_TYPE.DOWNLOAD_FILE, handelDownload); + return () => { + unsubscribeDownloadFile(); + }; + }, [eventBus, handelDownload]); + + return ( + + {children} + {isZipDialogOpen && ( + + + + )} + + ); +}; + +export const useDownloadFile = () => { + const context = useContext(DownloadFileContext); + if (!context) { + throw new Error('\'DownloadFileContext\' is null'); + } + return context; +}; + diff --git a/frontend/src/hooks/index.js b/frontend/src/hooks/index.js index 68b307d548..6037889dc7 100644 --- a/frontend/src/hooks/index.js +++ b/frontend/src/hooks/index.js @@ -1 +1,2 @@ export { MetadataStatusProvider, useMetadataStatus } from './metadata-status'; +export { DownloadFileProvider } from './download-file'; diff --git a/frontend/src/metadata/utils/file.js b/frontend/src/metadata/utils/file.js index 41bf819f54..e94fe1efba 100644 --- a/frontend/src/metadata/utils/file.js +++ b/frontend/src/metadata/utils/file.js @@ -2,7 +2,6 @@ import { getFileNameFromRecord, getParentDirFromRecord } from './cell'; import { checkIsDir } from './row'; import { Utils } from '../../utils/utils'; import { siteRoot } from '../../utils/constants'; -import URLDecorator from '../../utils/url-decorator'; const FILE_TYPE = { FOLDER: 'folder', @@ -116,13 +115,3 @@ export const openParentFolder = (record) => { const url = window.location.origin + window.location.pathname + Utils.encodePath(parentDir); window.open(url, '_blank'); }; - -export const downloadFile = (repoID, record) => { - if (!repoID || !record) return; - if (checkIsDir(record)) return; - const parentDir = _getParentDir(record); - const name = getFileNameFromRecord(record); - const direntPath = Utils.joinPath(parentDir, name); - const url = URLDecorator.getUrl({ type: 'download_file_url', repoID: repoID, filePath: direntPath }); - location.href = url; -}; diff --git a/frontend/src/metadata/views/gallery/context-menu/index.js b/frontend/src/metadata/views/gallery/context-menu/index.js index 395ba5c8ec..c4a01da335 100644 --- a/frontend/src/metadata/views/gallery/context-menu/index.js +++ b/frontend/src/metadata/views/gallery/context-menu/index.js @@ -2,16 +2,11 @@ import React, { useMemo, useCallback, useState } from 'react'; import PropTypes from 'prop-types'; import ContextMenu from '../../../components/context-menu'; import ModalPortal from '../../../../components/modal-portal'; -import toaster from '../../../../components/toast'; -import ZipDownloadDialog from '../../../../components/dialog/zip-download-dialog'; import CopyDirent from '../../../../components/dialog/copy-dirent-dialog'; import PeoplesDialog from '../../../components/dialog/peoples-dialog'; -import { gettext, useGoFileserver, fileServerRoot } from '../../../../utils/constants'; -import { getRowById } from '../../../../components/sf-table/utils/table'; -import { downloadFile } from '../../../utils/file'; -import metadataAPI from '../../../api'; -import { Utils } from '../../../../utils/utils'; +import { gettext } from '../../../../utils/constants'; import { Dirent } from '../../../../models'; +import { useDownloadFile } from '../../../../hooks/download-file'; const CONTEXT_MENU_KEY = { DOWNLOAD: 'download', @@ -22,11 +17,12 @@ const CONTEXT_MENU_KEY = { ADD_PHOTO_TO_GROUPS: 'add_photo_to_groups', }; -const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, addFolder, onRemoveImage, onAddImage, onSetPeoplePhoto }) => { - const [isZipDialogOpen, setIsZipDialogOpen] = useState(false); +const GalleryContextMenu = ({ selectedImages, onDelete, onDuplicate, addFolder, onRemoveImage, onAddImage, onSetPeoplePhoto }) => { const [isCopyDialogOpen, setIsCopyDialogOpen] = useState(false); const [isPeoplesDialogShow, setPeoplesDialogShow] = useState(false); + const { handelDownload: handelDownloadAPI } = useDownloadFile(); + const repoID = window.sfMetadataContext.getSetting('repoID'); const checkCanDeleteRow = window.sfMetadataContext.checkCanDeleteRow(); const canDuplicateRow = window.sfMetadataContext.canDuplicateRow(); @@ -54,10 +50,6 @@ const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, a return validOptions; }, [checkCanDeleteRow, canDuplicateRow, canRemovePhotoFromPeople, canAddPhotoToPeople, selectedImages, onDuplicate, onDelete, onRemoveImage, onAddImage, canSetPeoplePhoto, onSetPeoplePhoto]); - const closeZipDialog = () => { - setIsZipDialogOpen(false); - }; - const toggleCopyDialog = useCallback(() => { setIsCopyDialogOpen(!isCopyDialogOpen); }, [isCopyDialogOpen]); @@ -69,28 +61,12 @@ const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, a const handleDownload = useCallback(() => { if (!selectedImages.length) return; - if (selectedImages.length === 1) { - const image = selectedImages[0]; - const record = getRowById(metadata, image.id); - downloadFile(repoID, record); - return; - } - if (!useGoFileserver) { - setIsZipDialogOpen(true); - return; - } - const dirents = selectedImages.map(image => { - const value = image.parentDir === '/' ? image.name : `${image.parentDir}/${image.name}`; - return value; + const direntList = selectedImages.map(image => { + const name = image.parentDir === '/' ? image.name : `${image.parentDir}/${image.name}`; + return { name }; }); - metadataAPI.zipDownload(repoID, '/', dirents).then((res) => { - const zipToken = res.data['zip_token']; - location.href = `${fileServerRoot}zip/${zipToken}`; - }).catch(error => { - const errMessage = Utils.getErrorMsg(error); - toaster.danger(errMessage); - }); - }, [repoID, metadata, selectedImages]); + handelDownloadAPI('/', direntList); + }, [handelDownloadAPI, selectedImages]); const handleOptionClick = useCallback(option => { switch (option.value) { @@ -135,16 +111,6 @@ const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, a ignoredTriggerElements={['.metadata-gallery-image-item', '.metadata-gallery-grid-image']} onOptionClick={handleOptionClick} /> - {isZipDialogOpen && ( - - image.parentDir === '/' ? image.name : `${image.parentDir}/${image.name}`)} - toggleDialog={closeZipDialog} - /> - - )} {isCopyDialogOpen && ( { const [isRenameDialogShow, setIsRenameDialogShow] = useState(false); - const [isZipDialogOpen, setIsZipDialogOpen] = useState(false); const { metadata } = useMetadataView(); + const { handelDownload: handelDownloadAPI } = useDownloadFile(); const selectedRecord = useMemo(() => getRowById(metadata, selectedCard), [metadata, selectedCard]); const isDir = useMemo(() => checkIsDir(selectedRecord), [selectedRecord]); @@ -53,10 +50,6 @@ const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => { return validOptions; }, [isDir, checkCanDeleteRow, canModifyRow]); - const closeZipDialog = useCallback(() => { - setIsZipDialogOpen(false); - }, []); - const openRenameDialog = useCallback(() => { setIsRenameDialogShow(true); }, []); @@ -74,24 +67,9 @@ const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => { }); }, [metadata, selectedCard, onRename]); - const handelDownload = useCallback((record) => { - if (!isDir) { - downloadFile(repoID, record); - return; - } - if (!useGoFileserver) { - setIsZipDialogOpen(true); - return; - } - const fileName = getFileNameFromRecord(record); - metadataAPI.zipDownload(repoID, parentDir, [fileName]).then((res) => { - const zipToken = res.data['zip_token']; - location.href = `${fileServerRoot}zip/${zipToken}`; - }).catch(error => { - const errMessage = Utils.getErrorMsg(error); - toaster.danger(errMessage); - }); - }, [repoID, isDir, parentDir]); + const handelDownload = useCallback(() => { + handelDownloadAPI(parentDir, [{ name: oldName, is_dir: isDir }]); + }, [handelDownloadAPI, parentDir, oldName, isDir]); const handleOptionClick = useCallback((option) => { if (!selectedCard) return; @@ -140,9 +118,6 @@ const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => { onCancel={() => setIsRenameDialogShow(false)} /> )} - {isZipDialogOpen && ( - - )} ); }; diff --git a/frontend/src/models/dirent.js b/frontend/src/models/dirent.js index 4f5f103242..99734e5d1c 100644 --- a/frontend/src/models/dirent.js +++ b/frontend/src/models/dirent.js @@ -65,6 +65,7 @@ class Dirent { name: this.name, mtime: this.mtime, type: this.type, + is_dir: this.type !== 'file', size: this.size, modifier_name: this.modifier_name, modifier_email: this.modifier_email, diff --git a/frontend/src/pages/lib-content-view/lib-content-view.js b/frontend/src/pages/lib-content-view/lib-content-view.js index c3c44e365d..3a8e3fb31e 100644 --- a/frontend/src/pages/lib-content-view/lib-content-view.js +++ b/frontend/src/pages/lib-content-view/lib-content-view.js @@ -23,7 +23,7 @@ import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dire import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog'; import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type'; import { PRIVATE_FILE_TYPE, DIRENT_DETAIL_SHOW_KEY, TREE_PANEL_STATE_KEY, RECENTLY_USED_LIST_KEY } from '../../constants'; -import { MetadataStatusProvider } from '../../hooks'; +import { MetadataStatusProvider, DownloadFileProvider } from '../../hooks'; import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks'; import { TagsProvider } from '../../tag/hooks'; import { LIST_MODE, METADATA_MODE, TAGS_MODE } from '../../components/dir-view-mode/constants'; @@ -2356,239 +2356,242 @@ class LibContentView extends React.Component { const detailDirent = currentDirent || currentNode?.object || null; return ( - - - - - -
-
- {this.state.currentRepoInfo.status === 'read-only' && -
- {gettext('This library has been set to read-only by admin and cannot be updated.')} -
- } -
-
- {isDirentSelected ? ( - currentMode === TAGS_MODE || currentMode === METADATA_MODE ? ( - + + + + + + +
+
+ {this.state.currentRepoInfo.status === 'read-only' && +
+ {gettext('This library has been set to read-only by admin and cannot be updated.')} +
+ } +
+
+ {isDirentSelected ? ( + currentMode === TAGS_MODE || currentMode === METADATA_MODE ? ( + + ) : ( + + ) ) : ( - - ) - ) : ( - + {isDesktop && +
+ +
+ } +
+
+ {this.state.pathExist ? + + : +
{gettext('Folder does not exist.')}
+ } + {!isCustomPermission && this.state.isDirentDetailShow && ( + )}
- {isDesktop && -
- -
- } -
-
- {this.state.pathExist ? - - : -
{gettext('Folder does not exist.')}
- } - {!isCustomPermission && this.state.isDirentDetailShow && ( - - )}
+ {canUpload && this.state.pathExist && !this.state.isViewFile && ![METADATA_MODE, TAGS_MODE].includes(this.state.currentMode) && ( + this.uploader = uploader} + dragAndDrop={true} + path={this.state.path} + repoID={this.props.repoID} + direntList={this.state.direntList} + onFileUploadSuccess={this.onFileUploadSuccess} + isCustomPermission={isCustomPermission} + /> + )}
- {canUpload && this.state.pathExist && !this.state.isViewFile && ![METADATA_MODE, TAGS_MODE].includes(this.state.currentMode) && ( - this.uploader = uploader} - dragAndDrop={true} - path={this.state.path} - repoID={this.props.repoID} - direntList={this.state.direntList} - onFileUploadSuccess={this.onFileUploadSuccess} - isCustomPermission={isCustomPermission} + {isCopyMoveProgressDialogShow && ( + )} -
- {isCopyMoveProgressDialogShow && ( - - )} - {isDeleteFolderDialogOpen && ( - - )} - - - -
-
-
-
-
+ {isDeleteFolderDialogOpen && ( + + )} + + + + + + + + +
); } }