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:
@@ -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',
|
||||
};
|
||||
|
@@ -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}
|
||||
|
@@ -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
|
||||
|
@@ -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>
|
||||
);
|
||||
|
@@ -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 &&
|
||||
|
83
frontend/src/hooks/download-file.js
Normal file
83
frontend/src/hooks/download-file.js
Normal 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;
|
||||
};
|
||||
|
@@ -1 +1,2 @@
|
||||
export { MetadataStatusProvider, useMetadataStatus } from './metadata-status';
|
||||
export { DownloadFileProvider } from './download-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;
|
||||
};
|
||||
|
@@ -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
|
||||
|
@@ -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}/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@@ -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,
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user