1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-24 04:48:03 +00:00

refactor: download (#7388)

* refactor: download

* feat: update code

* feat: rebase bug

* feat: rebase bug

---------

Co-authored-by: 杨国璇 <ygx@Hello-word.local>
Co-authored-by: 杨国璇 <ygx@192.168.1.9>
Co-authored-by: 杨国璇 <ygx@MacBookPro.lan>
This commit is contained in:
杨国璇
2025-05-29 16:20:20 +08:00
committed by GitHub
parent d7b10849da
commit 12840046cd
12 changed files with 346 additions and 476 deletions

View File

@@ -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',
};

View File

@@ -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 &&
<ModalPortal>
<ZipDownloadDialog
repoID={this.props.repoID}
path={this.props.path}
target={this.state.downloadItems}
toggleDialog={this.closeZipDialog}
/>
</ModalPortal>
}
{this.state.isCopyDialogShow &&
<CopyDirentDialog
path={this.props.path}

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import classnames from 'classnames';
import dayjs from 'dayjs';
import { DropdownItem } from 'reactstrap';
import { gettext, siteRoot, mediaUrl, username, useGoFileserver, fileServerRoot, enableVideoThumbnail, enablePDFThumbnail } from '../../utils/constants';
import { gettext, siteRoot, mediaUrl, username, enableVideoThumbnail, enablePDFThumbnail } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import { seafileAPI } from '../../utils/seafile-api';
import URLDecorator from '../../utils/url-decorator';
@@ -14,11 +14,12 @@ import ModalPortal from '../modal-portal';
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 LibSubFolderPermissionDialog from '../dialog/lib-sub-folder-permission-dialog';
import FileAccessLog from '../dialog/file-access-log';
import toaster from '../toast';
import MobileItemMenu from '../../components/mobile-item-menu';
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
import { Dirent } from '../../models';
import '../../css/dirent-list-item.css';
@@ -27,6 +28,7 @@ const propTypes = {
repoID: PropTypes.string.isRequired,
isItemFreezed: PropTypes.bool.isRequired,
dirent: PropTypes.object.isRequired,
eventBus: PropTypes.object.isRequired,
onItemClick: PropTypes.func.isRequired,
freezeItem: PropTypes.func.isRequired,
unfreezeItem: PropTypes.func.isRequired,
@@ -80,7 +82,6 @@ class DirentListItem extends React.Component {
dirent,
isOperationShow: false,
highlight: false,
isZipDialogOpen: false,
isFileAccessLogDialogOpen: false,
isMoveDialogShow: false,
isCopyDialogShow: false,
@@ -524,36 +525,10 @@ class DirentListItem extends React.Component {
onItemDownload = (e) => {
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 {
/>
</ModalPortal>
}
{this.state.isZipDialogOpen &&
<ModalPortal>
<ZipDownloadDialog
repoID={this.props.repoID}
path={this.props.path}
target={this.state.dirent.name}
toggleDialog={this.closeZipDialog}
/>
</ModalPortal>
}
{this.state.isShareDialogShow &&
<ModalPortal>
<ShareDialog

View File

@@ -1,16 +1,14 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { siteRoot, gettext, username, enableSeadoc, thumbnailSizeForOriginal, thumbnailDefaultSize, fileServerRoot, enableWhiteboard, useGoFileserver, enableExcalidraw } from '../../utils/constants';
import { siteRoot, gettext, username, enableSeadoc, thumbnailSizeForOriginal, thumbnailDefaultSize, fileServerRoot, enableWhiteboard, enableExcalidraw } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import TextTranslation from '../../utils/text-translation';
import URLDecorator from '../../utils/url-decorator';
import toaster from '../toast';
import ModalPortal from '../modal-portal';
import CreateFile from '../dialog/create-file-dialog';
import CreateFolder from '../dialog/create-folder-dialog';
import ImageDialog from '../dialog/image-dialog';
import ZipDownloadDialog from '../dialog/zip-download-dialog';
import MoveDirentDialog from '../dialog/move-dirent-dialog';
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
import DirentListItem from './dirent-list-item';
@@ -22,6 +20,7 @@ import EmptyTip from '../empty-tip';
import imageAPI from '../../utils/image-api';
import { seafileAPI } from '../../utils/seafile-api';
import FixedWidthTable from '../common/fixed-width-table';
import { Dirent } from '../../models';
const propTypes = {
path: PropTypes.string.isRequired,
@@ -76,7 +75,6 @@ class DirentListView extends React.Component {
isCreateFolderDialogShow: false,
isMoveDialogShow: false,
isCopyDialogShow: false,
isProgressDialogShow: false,
downloadItems: [],
isMultipleOperation: true,
activeDirent: null,
@@ -329,38 +327,9 @@ class DirentListView 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;
}
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 &&
<ZipDownloadDialog
repoID={this.props.repoID}
path={this.props.path}
target={this.state.downloadItems}
toggleDialog={this.onCloseZipDownloadDialog}
/>
}
</Fragment>
</div>
);

View File

@@ -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 &&
<ModalPortal>
<ZipDownloadDialog
repoID={this.props.repoID}
path={this.props.path}
target={this.props.selectedDirentList.map(dirent => dirent.name)}
toggleDialog={this.closeZipDialog}
/>
</ModalPortal>
}
{this.state.showLibContentViewDialogs && (
<Fragment>
{this.state.showShareDialog &&

View File

@@ -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 (
<DownloadFileContext.Provider value={{ eventBus, handelDownload }}>
{children}
{isZipDialogOpen && (
<ModalPortal>
<ZipDownloadDialog
repoID={repoID}
path={pathRef.current}
target={direntListRef.current}
toggleDialog={cancelDownload}
/>
</ModalPortal>
)}
</DownloadFileContext.Provider>
);
};
export const useDownloadFile = () => {
const context = useContext(DownloadFileContext);
if (!context) {
throw new Error('\'DownloadFileContext\' is null');
}
return context;
};

View File

@@ -1 +1,2 @@
export { MetadataStatusProvider, useMetadataStatus } from './metadata-status';
export { DownloadFileProvider } from './download-file';

View File

@@ -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;
};

View File

@@ -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 && (
<ModalPortal>
<ZipDownloadDialog
repoID={repoID}
path="/"
target={selectedImages.map(image => image.parentDir === '/' ? image.name : `${image.parentDir}/${image.name}`)}
toggleDialog={closeZipDialog}
/>
</ModalPortal>
)}
{isCopyDialogOpen && (
<ModalPortal>
<CopyDirent

View File

@@ -2,17 +2,14 @@ import React, { useCallback, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import ContextMenu from '../../../components/context-menu';
import RenameDialog from '../../../components/dialog/rename-dialog';
import ZipDownloadDialog from '../../../../components/dialog/zip-download-dialog';
import { getRowById } from '../../../../components/sf-table/utils/table';
import { checkIsDir } from '../../../utils/row';
import { getFileNameFromRecord, getParentDirFromRecord } from '../../../utils/cell';
import { gettext, useGoFileserver, fileServerRoot } from '../../../../utils/constants';
import { openInNewTab, openParentFolder, downloadFile } from '../../../utils/file';
import { gettext } from '../../../../utils/constants';
import { openInNewTab, openParentFolder } from '../../../utils/file';
import { useMetadataView } from '../../../hooks/metadata-view';
import { PRIVATE_COLUMN_KEY } from '../../../constants';
import { Utils } from '../../../../utils/utils';
import toaster from '../../../../components/toast';
import metadataAPI from '../../../api';
import { useDownloadFile } from '../../../../hooks/download-file';
const CONTEXT_MENU_KEY = {
OPEN_IN_NEW_TAB: 'open_in_new_tab',
@@ -24,9 +21,9 @@ const CONTEXT_MENU_KEY = {
const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => {
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 && (
<ZipDownloadDialog repoID={repoID} path={parentDir} target={[oldName]} toggleDialog={closeZipDialog}/>
)}
</>
);
};

View File

@@ -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,

View File

@@ -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,6 +2356,7 @@ class LibContentView extends React.Component {
const detailDirent = currentDirent || currentNode?.object || null;
return (
<DownloadFileProvider repoID={repoID} eventBus={this.props.eventBus}>
<DndProvider backend={HTML5Backend}>
<MetadataStatusProvider repoID={repoID} repoInfo={currentRepoInfo} hideMetadataView={this.hideMetadataView} statusCallback={this.metadataStatusCallback} >
<TagsProvider repoID={repoID} currentPath={path} repoInfo={currentRepoInfo} selectTagsView={this.onTreeNodeClick} tagsChangedCallback={this.tagsChangedCallback} >
@@ -2380,6 +2381,7 @@ class LibContentView extends React.Component {
) : (
<SelectedDirentsToolbar
repoID={this.props.repoID}
eventBus={this.props.eventBus}
path={this.state.path}
userPerm={userPerm}
repoEncrypted={this.state.repoEncrypted}
@@ -2589,6 +2591,7 @@ class LibContentView extends React.Component {
</TagsProvider>
</MetadataStatusProvider>
</DndProvider>
</DownloadFileProvider>
);
}
}