1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-28 08:06:56 +00:00

Merge branch '7.0'

This commit is contained in:
lian
2020-01-06 16:25:55 +08:00
16 changed files with 118 additions and 1482 deletions

View File

@@ -494,13 +494,10 @@ class DirentListItem extends React.Component {
}
renderItemOperation = () => {
let { dirent, selectedDirentList } = this.props;
let { dirent, currentRepoInfo, selectedDirentList } = this.props;
// no need to check whether show shareBtn or not.
// according to specification below, shareBtn aways show.
// check for "generate uploadlink" or other tabs should put inside the shareDialog.
// https://dev.seafile.com/seahub/lib/d6f300e7-bb2b-4722-b83e-cf45e370bfbc/file/seaf-server%20%E5%8A%9F%E8%83%BD%E8%AE%BE%E8%AE%A1/%E6%9D%83%E9%99%90%E7%9B%B8%E5%85%B3/%E8%B5%84%E6%96%99%E5%BA%93%E6%9D%83%E9%99%90%E8%A7%84%E8%8C%83.md
// let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, dirent.permission, dirent);
let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, dirent.permission, dirent);
return (
<Fragment>
@@ -514,9 +511,11 @@ class DirentListItem extends React.Component {
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
</li>
)}
<li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li>
{showShareBtn && (
<li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li>
)}
{dirent.permission === 'rw' && (
<li className="operation-group-item">
<i className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onItemDelete}></i>
@@ -546,7 +545,7 @@ class DirentListItem extends React.Component {
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
</li>
)}
{(
{showShareBtn && (
<li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li>

View File

@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import Resumablejs from '@seafile/resumablejs';
import MD5 from 'MD5';
import { enableResumableFileUpload, resumableUploadFileBlockSize } from '../../utils/constants';
import { enableResumableFileUpload, resumableUploadFileBlockSize, maxUploadFileSize } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants';
@@ -18,13 +18,11 @@ const propTypes = {
chunkSize: PropTypes.number,
withCredentials: PropTypes.bool,
maxFiles: PropTypes.number,
maxFileSize: PropTypes.number,
testMethod: PropTypes.string,
testChunks: PropTypes.number,
simultaneousUploads: PropTypes.number,
fileParameterName: PropTypes.string,
maxFilesErrorCallback: PropTypes.func,
maxFileSizeErrorCallback: PropTypes.func,
minFileSizeErrorCallback: PropTypes.func,
fileTypeErrorCallback: PropTypes.func,
dragAndDrop: PropTypes.bool.isRequired,
@@ -39,6 +37,7 @@ class FileUploader extends React.Component {
this.state = {
retryFileList: [],
uploadFileList: [],
forbidUploadFileList: [],
totalProgress: 0,
isUploadProgressDialogShow: false,
isUploadRemindDialogShow: false,
@@ -64,7 +63,7 @@ class FileUploader extends React.Component {
query: this.setQuery || {},
fileType: this.props.filetypes,
maxFiles: this.props.maxFiles,
maxFileSize: this.props.maxFileSize,
maxFileSize: maxUploadFileSize * 1000 * 1000 || undefined,
testMethod: this.props.testMethod || 'post',
testChunks: this.props.testChunks || false,
headers: this.setHeaders || {},
@@ -105,7 +104,7 @@ class FileUploader extends React.Component {
}
bindCallbackHandler = () => {
let {maxFilesErrorCallback, minFileSizeErrorCallback, maxFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
let {maxFilesErrorCallback, minFileSizeErrorCallback, fileTypeErrorCallback } = this.props;
if (maxFilesErrorCallback) {
this.resumable.opts.maxFilesErrorCallback = this.props.maxFilesErrorCallback;
@@ -115,8 +114,8 @@ class FileUploader extends React.Component {
this.resumable.opts.minFileSizeErrorCallback = this.props.minFileSizeErrorCallback;
}
if (maxFileSizeErrorCallback) {
this.resumable.opts.maxFileSizeErrorCallback = this.props.maxFileSizeErrorCallback;
if (this.maxFileSizeErrorCallback) {
this.resumable.opts.maxFileSizeErrorCallback = this.maxFileSizeErrorCallback;
}
if (fileTypeErrorCallback) {
@@ -142,6 +141,12 @@ class FileUploader extends React.Component {
this.resumable.on('dragstart', this.onDragStart.bind(this));
}
maxFileSizeErrorCallback = (file) => {
let { forbidUploadFileList } = this.state;
forbidUploadFileList.push(file);
this.setState({forbidUploadFileList: forbidUploadFileList});
}
onChunkingComplete = (resumableFile) => {
let allFilesUploaded = this.state.allFilesUploaded;
@@ -229,7 +234,13 @@ class FileUploader extends React.Component {
}
filesAddedComplete = (resumable, files) => {
// single file uploading can check repetition, because custom dialog conn't prevent program execution;
let { forbidUploadFileList } = this.state;
if (forbidUploadFileList.length > 0 && files.length === 0) {
this.setState({
isUploadProgressDialogShow: true,
totalProgress: 100
});
}
}
setUploadFileList = () => {
@@ -377,7 +388,16 @@ class FileUploader extends React.Component {
if (!message) {
error = gettext('Network error');
} else {
error = message;
// eg: '{"error": "Internal error" \n }'
let errorMessage = message.replace(/\n/g, '');
errorMessage = JSON.parse(errorMessage);
error = errorMessage.error;
if (error === 'File locked by others.') {
error = gettext('File Locked by others.');
}
if (error === 'Internal error.') {
error = gettext('Internal error.');
}
}
let uploadFileList = this.state.uploadFileList.map(item => {
@@ -481,7 +501,7 @@ class FileUploader extends React.Component {
this.resumable.files = [];
// reset upload link loaded
this.isUploadLinkLoaded = false;
this.setState({isUploadProgressDialogShow: false, uploadFileList: []});
this.setState({isUploadProgressDialogShow: false, uploadFileList: [], forbidUploadFileList: []});
Utils.registerGlobalVariable('uploader', 'isUploadProgressDialogShow', false);
}
@@ -667,6 +687,7 @@ class FileUploader extends React.Component {
<UploadProgressDialog
retryFileList={this.state.retryFileList}
uploadFileList={this.state.uploadFileList}
forbidUploadFileList={this.state.forbidUploadFileList}
totalProgress={this.state.totalProgress}
uploadBitrate={this.state.uploadBitrate}
allFilesUploaded={this.state.allFilesUploaded}

View File

@@ -0,0 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { gettext, maxUploadFileSize } from '../../utils/constants';
const propTypes = {
file: PropTypes.object,
};
class ForbidUploadListItem extends React.Component {
render() {
let { file } = this.props;
let msg = gettext('Please upload files less than {placeholder}M').replace('{placeholder}', maxUploadFileSize);
return (
<tr className="file-upload-item">
<td className="upload-name">
<div className="ellipsis">{file.name}</div>
</td>
<td colSpan={3} className="error">{msg}</td>
</tr>
);
}
}
ForbidUploadListItem.propTypes = propTypes;
export default ForbidUploadListItem;

View File

@@ -1,14 +1,16 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { gettext } from '../../utils/constants';
import UploadListItem from './upload-list-item';
import { Utils } from '../../utils/utils';
import UploadListItem from './upload-list-item';
import ForbidUploadListItem from './forbid-upload-list-item';
const propTypes = {
uploadBitrate: PropTypes.number.isRequired,
totalProgress: PropTypes.number.isRequired,
retryFileList: PropTypes.array.isRequired,
uploadFileList: PropTypes.array.isRequired,
forbidUploadFileList: PropTypes.array.isRequired,
onCloseUploadDialog: PropTypes.func.isRequired,
onCancelAllUploading: PropTypes.func.isRequired,
onUploadCancel: PropTypes.func.isRequired,
@@ -94,6 +96,11 @@ class UploadProgressDialog extends React.Component {
}
</td>
</tr>
{
this.props.forbidUploadFileList.map((file, index) => {
return (<ForbidUploadListItem key={index} file={file} />);
})
}
{
this.props.uploadFileList.map((resumableFile, index) => {
return (