Fix WebUI allowing to upload more items than the limit (#12300)

Until this patch, drag'n'drop and copy-paste allowed to start uploading as
long as the number of *finished* uploads was below the limit.
pull/12323/head
ThibG 2019-11-07 08:07:03 +01:00 committed by Eugen Rochko
parent 7cdb8c10e9
commit 66684c489c
3 changed files with 10 additions and 6 deletions

View File

@ -205,10 +205,11 @@ export function uploadCompose(files) {
return function (dispatch, getState) { return function (dispatch, getState) {
const uploadLimit = 4; const uploadLimit = 4;
const media = getState().getIn(['compose', 'media_attachments']); const media = getState().getIn(['compose', 'media_attachments']);
const pending = getState().getIn(['compose', 'pending_media_attachments']);
const progress = new Array(files.length).fill(0); const progress = new Array(files.length).fill(0);
let total = Array.from(files).reduce((a, v) => a + v.size, 0); let total = Array.from(files).reduce((a, v) => a + v.size, 0);
if (files.length + media.size > uploadLimit) { if (files.length + media.size + pending > uploadLimit) {
dispatch(showAlert(undefined, messages.uploadErrorLimit)); dispatch(showAlert(undefined, messages.uploadErrorLimit));
return; return;
} }
@ -235,7 +236,7 @@ export function uploadCompose(files) {
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total)); dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
}, },
}).then(({ data }) => dispatch(uploadComposeSuccess(data, f))); }).then(({ data }) => dispatch(uploadComposeSuccess(data, f)));
}).catch(error => dispatch(uploadComposeFail(error))); }).catch(error => dispatch(uploadComposeFail(error, true)));
}; };
}; };
}; };
@ -266,10 +267,11 @@ export function changeUploadComposeSuccess(media) {
}; };
}; };
export function changeUploadComposeFail(error) { export function changeUploadComposeFail(error, decrement = false) {
return { return {
type: COMPOSE_UPLOAD_CHANGE_FAIL, type: COMPOSE_UPLOAD_CHANGE_FAIL,
error: error, error: error,
decrement: decrement,
skipLoading: true, skipLoading: true,
}; };
}; };

View File

@ -3,7 +3,7 @@ import UploadButton from '../components/upload_button';
import { uploadCompose } from '../../../actions/compose'; import { uploadCompose } from '../../../actions/compose';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))), disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))),
unavailable: state.getIn(['compose', 'poll']) !== null, unavailable: state.getIn(['compose', 'poll']) !== null,
resetFileKey: state.getIn(['compose', 'resetFileKey']), resetFileKey: state.getIn(['compose', 'resetFileKey']),
}); });

View File

@ -61,6 +61,7 @@ const initialState = ImmutableMap({
is_uploading: false, is_uploading: false,
progress: 0, progress: 0,
media_attachments: ImmutableList(), media_attachments: ImmutableList(),
pending_media_attachments: 0,
poll: null, poll: null,
suggestion_token: null, suggestion_token: null,
suggestions: ImmutableList(), suggestions: ImmutableList(),
@ -114,6 +115,7 @@ function appendMedia(state, media, file) {
map.set('is_uploading', false); map.set('is_uploading', false);
map.set('resetFileKey', Math.floor((Math.random() * 0x10000))); map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
map.set('idempotencyKey', uuid()); map.set('idempotencyKey', uuid());
map.update('pending_media_attachments', n => n - 1);
if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) { if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
map.set('sensitive', true); map.set('sensitive', true);
@ -322,11 +324,11 @@ export default function compose(state = initialState, action) {
case COMPOSE_UPLOAD_CHANGE_FAIL: case COMPOSE_UPLOAD_CHANGE_FAIL:
return state.set('is_changing_upload', false); return state.set('is_changing_upload', false);
case COMPOSE_UPLOAD_REQUEST: case COMPOSE_UPLOAD_REQUEST:
return state.set('is_uploading', true); return state.set('is_uploading', true).update('pending_media_attachments', n => n + 1);
case COMPOSE_UPLOAD_SUCCESS: case COMPOSE_UPLOAD_SUCCESS:
return appendMedia(state, fromJS(action.media), action.file); return appendMedia(state, fromJS(action.media), action.file);
case COMPOSE_UPLOAD_FAIL: case COMPOSE_UPLOAD_FAIL:
return state.set('is_uploading', false); return state.set('is_uploading', false).update('pending_media_attachments', n => action.decrement ? n - 1 : n);
case COMPOSE_UPLOAD_UNDO: case COMPOSE_UPLOAD_UNDO:
return removeMedia(state, action.media_id); return removeMedia(state, action.media_id);
case COMPOSE_UPLOAD_PROGRESS: case COMPOSE_UPLOAD_PROGRESS: