mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-24 12:58:34 +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',
|
TAGS_DATA: 'tags_data',
|
||||||
SELECT_TAG: 'select_tag',
|
SELECT_TAG: 'select_tag',
|
||||||
UPDATE_SELECTED_TAG: 'update_selected_tag',
|
UPDATE_SELECTED_TAG: 'update_selected_tag',
|
||||||
|
|
||||||
|
// download file
|
||||||
|
DOWNLOAD_FILE: 'download_file',
|
||||||
};
|
};
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
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 { Utils } from '../../utils/utils';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
import URLDecorator from '../../utils/url-decorator';
|
||||||
@@ -14,7 +14,6 @@ import TextTranslation from '../../utils/text-translation';
|
|||||||
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
||||||
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
||||||
import ShareDialog from '../dialog/share-dialog';
|
import ShareDialog from '../dialog/share-dialog';
|
||||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
|
||||||
import Rename from '../../components/dialog/rename-dirent';
|
import Rename from '../../components/dialog/rename-dirent';
|
||||||
import CreateFile from '../dialog/create-file-dialog';
|
import CreateFile from '../dialog/create-file-dialog';
|
||||||
import CreateFolder from '../dialog/create-folder-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 FileAccessLog from '../dialog/file-access-log';
|
||||||
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
import { EVENT_BUS_TYPE } from '../common/event-bus-type';
|
||||||
import EmptyTip from '../empty-tip';
|
import EmptyTip from '../empty-tip';
|
||||||
|
import { Dirent } from '../../models';
|
||||||
|
|
||||||
import '../../css/grid-view.css';
|
import '../../css/grid-view.css';
|
||||||
|
|
||||||
@@ -78,7 +78,6 @@ class DirentGridView extends React.Component {
|
|||||||
isShareDialogShow: false,
|
isShareDialogShow: false,
|
||||||
isMoveDialogShow: false,
|
isMoveDialogShow: false,
|
||||||
isCopyDialogShow: false,
|
isCopyDialogShow: false,
|
||||||
isZipDialogOpen: false,
|
|
||||||
isRenameDialogShow: false,
|
isRenameDialogShow: false,
|
||||||
isCreateFolderDialogShow: false,
|
isCreateFolderDialogShow: false,
|
||||||
isCreateFileDialogShow: false,
|
isCreateFileDialogShow: false,
|
||||||
@@ -458,39 +457,10 @@ class DirentGridView extends React.Component {
|
|||||||
return path === '/' ? path + dirent.name : path + '/' + dirent.name;
|
return path === '/' ? path + dirent.name : path + '/' + dirent.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
closeZipDialog = () => {
|
|
||||||
this.setState({
|
|
||||||
isZipDialogOpen: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onItemsDownload = () => {
|
onItemsDownload = () => {
|
||||||
let { path, repoID, selectedDirentList } = this.props;
|
const { path, selectedDirentList, eventBus } = this.props;
|
||||||
if (selectedDirentList.length === 1 && !selectedDirentList[0].isDir()) {
|
const direntList = selectedDirentList.map(dirent => dirent instanceof Dirent ? dirent.toJson() : dirent);
|
||||||
let direntPath = Utils.joinPath(path, selectedDirentList[0].name);
|
eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList);
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onCreateFolderToggle = () => {
|
onCreateFolderToggle = () => {
|
||||||
@@ -999,16 +969,6 @@ class DirentGridView extends React.Component {
|
|||||||
onAddFolder={this.props.onAddFolder}
|
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 &&
|
{this.state.isCopyDialogShow &&
|
||||||
<CopyDirentDialog
|
<CopyDirentDialog
|
||||||
path={this.props.path}
|
path={this.props.path}
|
||||||
|
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { DropdownItem } from 'reactstrap';
|
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 { Utils } from '../../utils/utils';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
import URLDecorator from '../../utils/url-decorator';
|
||||||
@@ -14,11 +14,12 @@ import ModalPortal from '../modal-portal';
|
|||||||
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
||||||
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
||||||
import ShareDialog from '../dialog/share-dialog';
|
import ShareDialog from '../dialog/share-dialog';
|
||||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
|
||||||
import LibSubFolderPermissionDialog from '../dialog/lib-sub-folder-permission-dialog';
|
import LibSubFolderPermissionDialog from '../dialog/lib-sub-folder-permission-dialog';
|
||||||
import FileAccessLog from '../dialog/file-access-log';
|
import FileAccessLog from '../dialog/file-access-log';
|
||||||
import toaster from '../toast';
|
import toaster from '../toast';
|
||||||
import MobileItemMenu from '../../components/mobile-item-menu';
|
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';
|
import '../../css/dirent-list-item.css';
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ const propTypes = {
|
|||||||
repoID: PropTypes.string.isRequired,
|
repoID: PropTypes.string.isRequired,
|
||||||
isItemFreezed: PropTypes.bool.isRequired,
|
isItemFreezed: PropTypes.bool.isRequired,
|
||||||
dirent: PropTypes.object.isRequired,
|
dirent: PropTypes.object.isRequired,
|
||||||
|
eventBus: PropTypes.object.isRequired,
|
||||||
onItemClick: PropTypes.func.isRequired,
|
onItemClick: PropTypes.func.isRequired,
|
||||||
freezeItem: PropTypes.func.isRequired,
|
freezeItem: PropTypes.func.isRequired,
|
||||||
unfreezeItem: PropTypes.func.isRequired,
|
unfreezeItem: PropTypes.func.isRequired,
|
||||||
@@ -80,7 +82,6 @@ class DirentListItem extends React.Component {
|
|||||||
dirent,
|
dirent,
|
||||||
isOperationShow: false,
|
isOperationShow: false,
|
||||||
highlight: false,
|
highlight: false,
|
||||||
isZipDialogOpen: false,
|
|
||||||
isFileAccessLogDialogOpen: false,
|
isFileAccessLogDialogOpen: false,
|
||||||
isMoveDialogShow: false,
|
isMoveDialogShow: false,
|
||||||
isCopyDialogShow: false,
|
isCopyDialogShow: false,
|
||||||
@@ -524,36 +525,10 @@ class DirentListItem extends React.Component {
|
|||||||
onItemDownload = (e) => {
|
onItemDownload = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.nativeEvent.stopImmediatePropagation();
|
e.nativeEvent.stopImmediatePropagation();
|
||||||
let dirent = this.state.dirent;
|
const { path, eventBus } = this.props;
|
||||||
let repoID = this.props.repoID;
|
const { dirent } = this.state;
|
||||||
let direntPath = this.getDirentPath(dirent);
|
const direntList = dirent instanceof Dirent ? [dirent.toJson()] : [dirent];
|
||||||
if (dirent.type === 'dir') {
|
eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList);
|
||||||
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
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
getDirentPath = (dirent) => {
|
getDirentPath = (dirent) => {
|
||||||
@@ -973,16 +948,6 @@ class DirentListItem extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</ModalPortal>
|
</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 &&
|
{this.state.isShareDialogShow &&
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<ShareDialog
|
<ShareDialog
|
||||||
|
@@ -1,16 +1,14 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
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 { Utils } from '../../utils/utils';
|
||||||
import TextTranslation from '../../utils/text-translation';
|
import TextTranslation from '../../utils/text-translation';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
|
||||||
import toaster from '../toast';
|
import toaster from '../toast';
|
||||||
import ModalPortal from '../modal-portal';
|
import ModalPortal from '../modal-portal';
|
||||||
import CreateFile from '../dialog/create-file-dialog';
|
import CreateFile from '../dialog/create-file-dialog';
|
||||||
import CreateFolder from '../dialog/create-folder-dialog';
|
import CreateFolder from '../dialog/create-folder-dialog';
|
||||||
import ImageDialog from '../dialog/image-dialog';
|
import ImageDialog from '../dialog/image-dialog';
|
||||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
|
||||||
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
||||||
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
||||||
import DirentListItem from './dirent-list-item';
|
import DirentListItem from './dirent-list-item';
|
||||||
@@ -22,6 +20,7 @@ import EmptyTip from '../empty-tip';
|
|||||||
import imageAPI from '../../utils/image-api';
|
import imageAPI from '../../utils/image-api';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import FixedWidthTable from '../common/fixed-width-table';
|
import FixedWidthTable from '../common/fixed-width-table';
|
||||||
|
import { Dirent } from '../../models';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
@@ -76,7 +75,6 @@ class DirentListView extends React.Component {
|
|||||||
isCreateFolderDialogShow: false,
|
isCreateFolderDialogShow: false,
|
||||||
isMoveDialogShow: false,
|
isMoveDialogShow: false,
|
||||||
isCopyDialogShow: false,
|
isCopyDialogShow: false,
|
||||||
isProgressDialogShow: false,
|
|
||||||
downloadItems: [],
|
downloadItems: [],
|
||||||
isMultipleOperation: true,
|
isMultipleOperation: true,
|
||||||
activeDirent: null,
|
activeDirent: null,
|
||||||
@@ -329,38 +327,9 @@ class DirentListView extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onItemsDownload = () => {
|
onItemsDownload = () => {
|
||||||
let { path, repoID, selectedDirentList } = this.props;
|
const { path, selectedDirentList, eventBus } = this.props;
|
||||||
if (selectedDirentList.length) {
|
const direntList = selectedDirentList.map(dirent => dirent instanceof Dirent ? dirent.toJson() : dirent);
|
||||||
if (selectedDirentList.length === 1 && !selectedDirentList[0].isDir()) {
|
eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList);
|
||||||
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 });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// common contextmenu handle
|
// common contextmenu handle
|
||||||
@@ -813,6 +782,7 @@ class DirentListView extends React.Component {
|
|||||||
path={this.props.path}
|
path={this.props.path}
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
currentRepoInfo={this.props.currentRepoInfo}
|
currentRepoInfo={this.props.currentRepoInfo}
|
||||||
|
eventBus={this.props.eventBus}
|
||||||
isAdmin={this.isAdmin}
|
isAdmin={this.isAdmin}
|
||||||
isRepoOwner={this.isRepoOwner}
|
isRepoOwner={this.isRepoOwner}
|
||||||
repoEncrypted={this.repoEncrypted}
|
repoEncrypted={this.repoEncrypted}
|
||||||
@@ -941,14 +911,6 @@ class DirentListView extends React.Component {
|
|||||||
onAddFolder={this.props.onAddFolder}
|
onAddFolder={this.props.onAddFolder}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
{this.state.isProgressDialogShow &&
|
|
||||||
<ZipDownloadDialog
|
|
||||||
repoID={this.props.repoID}
|
|
||||||
path={this.props.path}
|
|
||||||
target={this.state.downloadItems}
|
|
||||||
toggleDialog={this.onCloseZipDownloadDialog}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -1,12 +1,11 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
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 { Utils } from '../../utils/utils';
|
||||||
import { seafileAPI } from '../../utils/seafile-api';
|
import { seafileAPI } from '../../utils/seafile-api';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
import URLDecorator from '../../utils/url-decorator';
|
||||||
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
import MoveDirentDialog from '../dialog/move-dirent-dialog';
|
||||||
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
import CopyDirentDialog from '../dialog/copy-dirent-dialog';
|
||||||
import ZipDownloadDialog from '../dialog/zip-download-dialog';
|
|
||||||
import ShareDialog from '../dialog/share-dialog';
|
import ShareDialog from '../dialog/share-dialog';
|
||||||
import Rename from '../dialog/rename-dirent';
|
import Rename from '../dialog/rename-dirent';
|
||||||
import LibSubFolderPermissionDialog from '../dialog/lib-sub-folder-permission-dialog';
|
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 ItemDropdownMenu from '../dropdown-menu/item-dropdown-menu';
|
||||||
import toaster from '../toast';
|
import toaster from '../toast';
|
||||||
import FileAccessLog from '../dialog/file-access-log';
|
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';
|
import '../../css/selected-dirents-toolbar.css';
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ const propTypes = {
|
|||||||
repoID: PropTypes.string.isRequired,
|
repoID: PropTypes.string.isRequired,
|
||||||
repoEncrypted: PropTypes.bool.isRequired,
|
repoEncrypted: PropTypes.bool.isRequired,
|
||||||
selectedDirentList: PropTypes.array.isRequired,
|
selectedDirentList: PropTypes.array.isRequired,
|
||||||
|
eventBus: PropTypes.object.isRequired,
|
||||||
onItemsMove: PropTypes.func.isRequired,
|
onItemsMove: PropTypes.func.isRequired,
|
||||||
onItemsCopy: PropTypes.func.isRequired,
|
onItemsCopy: PropTypes.func.isRequired,
|
||||||
onItemsDelete: PropTypes.func.isRequired,
|
onItemsDelete: PropTypes.func.isRequired,
|
||||||
@@ -45,7 +47,6 @@ class SelectedDirentsToolbar extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isZipDialogOpen: false,
|
|
||||||
isFileAccessLogDialogOpen: false,
|
isFileAccessLogDialogOpen: false,
|
||||||
isMoveDialogShow: false,
|
isMoveDialogShow: false,
|
||||||
isCopyDialogShow: false,
|
isCopyDialogShow: false,
|
||||||
@@ -71,38 +72,9 @@ class SelectedDirentsToolbar extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onItemsDownload = () => {
|
onItemsDownload = () => {
|
||||||
let { path, repoID, selectedDirentList } = this.props;
|
const { path, selectedDirentList, eventBus } = this.props;
|
||||||
if (selectedDirentList.length) {
|
const direntList = selectedDirentList.map(dirent => dirent instanceof Dirent ? dirent.toJson() : dirent);
|
||||||
if (selectedDirentList.length === 1 && !selectedDirentList[0].isDir()) {
|
eventBus.dispatch(EVENT_BUS_TYPE.DOWNLOAD_FILE, path, direntList);
|
||||||
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
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
checkDuplicatedName = (newName) => {
|
checkDuplicatedName = (newName) => {
|
||||||
@@ -433,16 +405,6 @@ class SelectedDirentsToolbar extends React.Component {
|
|||||||
onAddFolder={this.props.onAddFolder}
|
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 && (
|
{this.state.showLibContentViewDialogs && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{this.state.showShareDialog &&
|
{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 { MetadataStatusProvider, useMetadataStatus } from './metadata-status';
|
||||||
|
export { DownloadFileProvider } from './download-file';
|
||||||
|
@@ -2,7 +2,6 @@ import { getFileNameFromRecord, getParentDirFromRecord } from './cell';
|
|||||||
import { checkIsDir } from './row';
|
import { checkIsDir } from './row';
|
||||||
import { Utils } from '../../utils/utils';
|
import { Utils } from '../../utils/utils';
|
||||||
import { siteRoot } from '../../utils/constants';
|
import { siteRoot } from '../../utils/constants';
|
||||||
import URLDecorator from '../../utils/url-decorator';
|
|
||||||
|
|
||||||
const FILE_TYPE = {
|
const FILE_TYPE = {
|
||||||
FOLDER: 'folder',
|
FOLDER: 'folder',
|
||||||
@@ -116,13 +115,3 @@ export const openParentFolder = (record) => {
|
|||||||
const url = window.location.origin + window.location.pathname + Utils.encodePath(parentDir);
|
const url = window.location.origin + window.location.pathname + Utils.encodePath(parentDir);
|
||||||
window.open(url, '_blank');
|
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 PropTypes from 'prop-types';
|
||||||
import ContextMenu from '../../../components/context-menu';
|
import ContextMenu from '../../../components/context-menu';
|
||||||
import ModalPortal from '../../../../components/modal-portal';
|
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 CopyDirent from '../../../../components/dialog/copy-dirent-dialog';
|
||||||
import PeoplesDialog from '../../../components/dialog/peoples-dialog';
|
import PeoplesDialog from '../../../components/dialog/peoples-dialog';
|
||||||
import { gettext, useGoFileserver, fileServerRoot } from '../../../../utils/constants';
|
import { gettext } 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 { Dirent } from '../../../../models';
|
import { Dirent } from '../../../../models';
|
||||||
|
import { useDownloadFile } from '../../../../hooks/download-file';
|
||||||
|
|
||||||
const CONTEXT_MENU_KEY = {
|
const CONTEXT_MENU_KEY = {
|
||||||
DOWNLOAD: 'download',
|
DOWNLOAD: 'download',
|
||||||
@@ -22,11 +17,12 @@ const CONTEXT_MENU_KEY = {
|
|||||||
ADD_PHOTO_TO_GROUPS: 'add_photo_to_groups',
|
ADD_PHOTO_TO_GROUPS: 'add_photo_to_groups',
|
||||||
};
|
};
|
||||||
|
|
||||||
const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, addFolder, onRemoveImage, onAddImage, onSetPeoplePhoto }) => {
|
const GalleryContextMenu = ({ selectedImages, onDelete, onDuplicate, addFolder, onRemoveImage, onAddImage, onSetPeoplePhoto }) => {
|
||||||
const [isZipDialogOpen, setIsZipDialogOpen] = useState(false);
|
|
||||||
const [isCopyDialogOpen, setIsCopyDialogOpen] = useState(false);
|
const [isCopyDialogOpen, setIsCopyDialogOpen] = useState(false);
|
||||||
const [isPeoplesDialogShow, setPeoplesDialogShow] = useState(false);
|
const [isPeoplesDialogShow, setPeoplesDialogShow] = useState(false);
|
||||||
|
|
||||||
|
const { handelDownload: handelDownloadAPI } = useDownloadFile();
|
||||||
|
|
||||||
const repoID = window.sfMetadataContext.getSetting('repoID');
|
const repoID = window.sfMetadataContext.getSetting('repoID');
|
||||||
const checkCanDeleteRow = window.sfMetadataContext.checkCanDeleteRow();
|
const checkCanDeleteRow = window.sfMetadataContext.checkCanDeleteRow();
|
||||||
const canDuplicateRow = window.sfMetadataContext.canDuplicateRow();
|
const canDuplicateRow = window.sfMetadataContext.canDuplicateRow();
|
||||||
@@ -54,10 +50,6 @@ const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, a
|
|||||||
return validOptions;
|
return validOptions;
|
||||||
}, [checkCanDeleteRow, canDuplicateRow, canRemovePhotoFromPeople, canAddPhotoToPeople, selectedImages, onDuplicate, onDelete, onRemoveImage, onAddImage, canSetPeoplePhoto, onSetPeoplePhoto]);
|
}, [checkCanDeleteRow, canDuplicateRow, canRemovePhotoFromPeople, canAddPhotoToPeople, selectedImages, onDuplicate, onDelete, onRemoveImage, onAddImage, canSetPeoplePhoto, onSetPeoplePhoto]);
|
||||||
|
|
||||||
const closeZipDialog = () => {
|
|
||||||
setIsZipDialogOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleCopyDialog = useCallback(() => {
|
const toggleCopyDialog = useCallback(() => {
|
||||||
setIsCopyDialogOpen(!isCopyDialogOpen);
|
setIsCopyDialogOpen(!isCopyDialogOpen);
|
||||||
}, [isCopyDialogOpen]);
|
}, [isCopyDialogOpen]);
|
||||||
@@ -69,28 +61,12 @@ const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, a
|
|||||||
|
|
||||||
const handleDownload = useCallback(() => {
|
const handleDownload = useCallback(() => {
|
||||||
if (!selectedImages.length) return;
|
if (!selectedImages.length) return;
|
||||||
if (selectedImages.length === 1) {
|
const direntList = selectedImages.map(image => {
|
||||||
const image = selectedImages[0];
|
const name = image.parentDir === '/' ? image.name : `${image.parentDir}/${image.name}`;
|
||||||
const record = getRowById(metadata, image.id);
|
return { name };
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
metadataAPI.zipDownload(repoID, '/', dirents).then((res) => {
|
handelDownloadAPI('/', direntList);
|
||||||
const zipToken = res.data['zip_token'];
|
}, [handelDownloadAPI, selectedImages]);
|
||||||
location.href = `${fileServerRoot}zip/${zipToken}`;
|
|
||||||
}).catch(error => {
|
|
||||||
const errMessage = Utils.getErrorMsg(error);
|
|
||||||
toaster.danger(errMessage);
|
|
||||||
});
|
|
||||||
}, [repoID, metadata, selectedImages]);
|
|
||||||
|
|
||||||
const handleOptionClick = useCallback(option => {
|
const handleOptionClick = useCallback(option => {
|
||||||
switch (option.value) {
|
switch (option.value) {
|
||||||
@@ -135,16 +111,6 @@ const GalleryContextMenu = ({ metadata, selectedImages, onDelete, onDuplicate, a
|
|||||||
ignoredTriggerElements={['.metadata-gallery-image-item', '.metadata-gallery-grid-image']}
|
ignoredTriggerElements={['.metadata-gallery-image-item', '.metadata-gallery-grid-image']}
|
||||||
onOptionClick={handleOptionClick}
|
onOptionClick={handleOptionClick}
|
||||||
/>
|
/>
|
||||||
{isZipDialogOpen && (
|
|
||||||
<ModalPortal>
|
|
||||||
<ZipDownloadDialog
|
|
||||||
repoID={repoID}
|
|
||||||
path="/"
|
|
||||||
target={selectedImages.map(image => image.parentDir === '/' ? image.name : `${image.parentDir}/${image.name}`)}
|
|
||||||
toggleDialog={closeZipDialog}
|
|
||||||
/>
|
|
||||||
</ModalPortal>
|
|
||||||
)}
|
|
||||||
{isCopyDialogOpen && (
|
{isCopyDialogOpen && (
|
||||||
<ModalPortal>
|
<ModalPortal>
|
||||||
<CopyDirent
|
<CopyDirent
|
||||||
|
@@ -2,17 +2,14 @@ import React, { useCallback, useMemo, useState } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import ContextMenu from '../../../components/context-menu';
|
import ContextMenu from '../../../components/context-menu';
|
||||||
import RenameDialog from '../../../components/dialog/rename-dialog';
|
import RenameDialog from '../../../components/dialog/rename-dialog';
|
||||||
import ZipDownloadDialog from '../../../../components/dialog/zip-download-dialog';
|
|
||||||
import { getRowById } from '../../../../components/sf-table/utils/table';
|
import { getRowById } from '../../../../components/sf-table/utils/table';
|
||||||
import { checkIsDir } from '../../../utils/row';
|
import { checkIsDir } from '../../../utils/row';
|
||||||
import { getFileNameFromRecord, getParentDirFromRecord } from '../../../utils/cell';
|
import { getFileNameFromRecord, getParentDirFromRecord } from '../../../utils/cell';
|
||||||
import { gettext, useGoFileserver, fileServerRoot } from '../../../../utils/constants';
|
import { gettext } from '../../../../utils/constants';
|
||||||
import { openInNewTab, openParentFolder, downloadFile } from '../../../utils/file';
|
import { openInNewTab, openParentFolder } from '../../../utils/file';
|
||||||
import { useMetadataView } from '../../../hooks/metadata-view';
|
import { useMetadataView } from '../../../hooks/metadata-view';
|
||||||
import { PRIVATE_COLUMN_KEY } from '../../../constants';
|
import { PRIVATE_COLUMN_KEY } from '../../../constants';
|
||||||
import { Utils } from '../../../../utils/utils';
|
import { useDownloadFile } from '../../../../hooks/download-file';
|
||||||
import toaster from '../../../../components/toast';
|
|
||||||
import metadataAPI from '../../../api';
|
|
||||||
|
|
||||||
const CONTEXT_MENU_KEY = {
|
const CONTEXT_MENU_KEY = {
|
||||||
OPEN_IN_NEW_TAB: 'open_in_new_tab',
|
OPEN_IN_NEW_TAB: 'open_in_new_tab',
|
||||||
@@ -24,9 +21,9 @@ const CONTEXT_MENU_KEY = {
|
|||||||
|
|
||||||
const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => {
|
const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => {
|
||||||
const [isRenameDialogShow, setIsRenameDialogShow] = useState(false);
|
const [isRenameDialogShow, setIsRenameDialogShow] = useState(false);
|
||||||
const [isZipDialogOpen, setIsZipDialogOpen] = useState(false);
|
|
||||||
|
|
||||||
const { metadata } = useMetadataView();
|
const { metadata } = useMetadataView();
|
||||||
|
const { handelDownload: handelDownloadAPI } = useDownloadFile();
|
||||||
|
|
||||||
const selectedRecord = useMemo(() => getRowById(metadata, selectedCard), [metadata, selectedCard]);
|
const selectedRecord = useMemo(() => getRowById(metadata, selectedCard), [metadata, selectedCard]);
|
||||||
const isDir = useMemo(() => checkIsDir(selectedRecord), [selectedRecord]);
|
const isDir = useMemo(() => checkIsDir(selectedRecord), [selectedRecord]);
|
||||||
@@ -53,10 +50,6 @@ const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => {
|
|||||||
return validOptions;
|
return validOptions;
|
||||||
}, [isDir, checkCanDeleteRow, canModifyRow]);
|
}, [isDir, checkCanDeleteRow, canModifyRow]);
|
||||||
|
|
||||||
const closeZipDialog = useCallback(() => {
|
|
||||||
setIsZipDialogOpen(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const openRenameDialog = useCallback(() => {
|
const openRenameDialog = useCallback(() => {
|
||||||
setIsRenameDialogShow(true);
|
setIsRenameDialogShow(true);
|
||||||
}, []);
|
}, []);
|
||||||
@@ -74,24 +67,9 @@ const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => {
|
|||||||
});
|
});
|
||||||
}, [metadata, selectedCard, onRename]);
|
}, [metadata, selectedCard, onRename]);
|
||||||
|
|
||||||
const handelDownload = useCallback((record) => {
|
const handelDownload = useCallback(() => {
|
||||||
if (!isDir) {
|
handelDownloadAPI(parentDir, [{ name: oldName, is_dir: isDir }]);
|
||||||
downloadFile(repoID, record);
|
}, [handelDownloadAPI, parentDir, oldName, isDir]);
|
||||||
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 handleOptionClick = useCallback((option) => {
|
const handleOptionClick = useCallback((option) => {
|
||||||
if (!selectedCard) return;
|
if (!selectedCard) return;
|
||||||
@@ -140,9 +118,6 @@ const KanbanContextMenu = ({ selectedCard, onDelete, onRename }) => {
|
|||||||
onCancel={() => setIsRenameDialogShow(false)}
|
onCancel={() => setIsRenameDialogShow(false)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isZipDialogOpen && (
|
|
||||||
<ZipDownloadDialog repoID={repoID} path={parentDir} target={[oldName]} toggleDialog={closeZipDialog}/>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -65,6 +65,7 @@ class Dirent {
|
|||||||
name: this.name,
|
name: this.name,
|
||||||
mtime: this.mtime,
|
mtime: this.mtime,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
|
is_dir: this.type !== 'file',
|
||||||
size: this.size,
|
size: this.size,
|
||||||
modifier_name: this.modifier_name,
|
modifier_name: this.modifier_name,
|
||||||
modifier_email: this.modifier_email,
|
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 DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
|
||||||
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
|
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 { 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 { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
|
||||||
import { TagsProvider } from '../../tag/hooks';
|
import { TagsProvider } from '../../tag/hooks';
|
||||||
import { LIST_MODE, METADATA_MODE, TAGS_MODE } from '../../components/dir-view-mode/constants';
|
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;
|
const detailDirent = currentDirent || currentNode?.object || null;
|
||||||
return (
|
return (
|
||||||
|
<DownloadFileProvider repoID={repoID} eventBus={this.props.eventBus}>
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
<MetadataStatusProvider repoID={repoID} repoInfo={currentRepoInfo} hideMetadataView={this.hideMetadataView} statusCallback={this.metadataStatusCallback} >
|
<MetadataStatusProvider repoID={repoID} repoInfo={currentRepoInfo} hideMetadataView={this.hideMetadataView} statusCallback={this.metadataStatusCallback} >
|
||||||
<TagsProvider repoID={repoID} currentPath={path} repoInfo={currentRepoInfo} selectTagsView={this.onTreeNodeClick} tagsChangedCallback={this.tagsChangedCallback} >
|
<TagsProvider repoID={repoID} currentPath={path} repoInfo={currentRepoInfo} selectTagsView={this.onTreeNodeClick} tagsChangedCallback={this.tagsChangedCallback} >
|
||||||
@@ -2380,6 +2381,7 @@ class LibContentView extends React.Component {
|
|||||||
) : (
|
) : (
|
||||||
<SelectedDirentsToolbar
|
<SelectedDirentsToolbar
|
||||||
repoID={this.props.repoID}
|
repoID={this.props.repoID}
|
||||||
|
eventBus={this.props.eventBus}
|
||||||
path={this.state.path}
|
path={this.state.path}
|
||||||
userPerm={userPerm}
|
userPerm={userPerm}
|
||||||
repoEncrypted={this.state.repoEncrypted}
|
repoEncrypted={this.state.repoEncrypted}
|
||||||
@@ -2589,6 +2591,7 @@ class LibContentView extends React.Component {
|
|||||||
</TagsProvider>
|
</TagsProvider>
|
||||||
</MetadataStatusProvider>
|
</MetadataStatusProvider>
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
|
</DownloadFileProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user