about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2019-11-07 08:07:03 +0100
committerEugen Rochko <eugen@zeonfederated.com>2019-11-07 09:07:03 +0200
commit66684c489c3c0bde752d107b02fc3bd6cbcacf04 (patch)
tree9ea05359ce7c47899520a69f7dd11a5067d1a20a /app
parent7cdb8c10e97fe9e22411efef4986e6393247e0ee (diff)
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.
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/actions/compose.js8
-rw-r--r--app/javascript/mastodon/features/compose/containers/upload_button_container.js2
-rw-r--r--app/javascript/mastodon/reducers/compose.js6
3 files changed, 10 insertions, 6 deletions
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index 8e7906c73..727f02718 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -205,10 +205,11 @@ export function uploadCompose(files) {
   return function (dispatch, getState) {
     const uploadLimit = 4;
     const media  = getState().getIn(['compose', 'media_attachments']);
+    const pending  = getState().getIn(['compose', 'pending_media_attachments']);
     const progress = new Array(files.length).fill(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));
       return;
     }
@@ -235,7 +236,7 @@ export function uploadCompose(files) {
             dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
           },
         }).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 {
     type: COMPOSE_UPLOAD_CHANGE_FAIL,
     error: error,
+    decrement: decrement,
     skipLoading: true,
   };
 };
diff --git a/app/javascript/mastodon/features/compose/containers/upload_button_container.js b/app/javascript/mastodon/features/compose/containers/upload_button_container.js
index 1471e628b..221b98e31 100644
--- a/app/javascript/mastodon/features/compose/containers/upload_button_container.js
+++ b/app/javascript/mastodon/features/compose/containers/upload_button_container.js
@@ -3,7 +3,7 @@ import UploadButton from '../components/upload_button';
 import { uploadCompose } from '../../../actions/compose';
 
 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,
   resetFileKey: state.getIn(['compose', 'resetFileKey']),
 });
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index b5dc81703..4c3342ccc 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -61,6 +61,7 @@ const initialState = ImmutableMap({
   is_uploading: false,
   progress: 0,
   media_attachments: ImmutableList(),
+  pending_media_attachments: 0,
   poll: null,
   suggestion_token: null,
   suggestions: ImmutableList(),
@@ -114,6 +115,7 @@ function appendMedia(state, media, file) {
     map.set('is_uploading', false);
     map.set('resetFileKey', Math.floor((Math.random() * 0x10000)));
     map.set('idempotencyKey', uuid());
+    map.update('pending_media_attachments', n => n - 1);
 
     if (prevSize === 0 && (state.get('default_sensitive') || state.get('spoiler'))) {
       map.set('sensitive', true);
@@ -322,11 +324,11 @@ export default function compose(state = initialState, action) {
   case COMPOSE_UPLOAD_CHANGE_FAIL:
     return state.set('is_changing_upload', false);
   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:
     return appendMedia(state, fromJS(action.media), action.file);
   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:
     return removeMedia(state, action.media_id);
   case COMPOSE_UPLOAD_PROGRESS: