v2 Media API: poll attachments for completion

https://github.com/mastodon/mastodon/pull/13210
merge-requests/795/head
Alex Gleason 3 years ago
parent 07f1e4cc18
commit c6067dbccb
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -11,7 +11,7 @@ import { defineMessages } from 'react-intl';
import { openModal, closeModal } from './modal'; import { openModal, closeModal } from './modal';
import { getSettings } from './settings'; import { getSettings } from './settings';
import { getFeatures } from 'soapbox/utils/features'; import { getFeatures } from 'soapbox/utils/features';
import { uploadMedia } from './media'; import { uploadMedia, fetchMedia, updateMedia } from './media';
import { isLoggedIn } from 'soapbox/utils/auth'; import { isLoggedIn } from 'soapbox/utils/auth';
import { createStatus } from './statuses'; import { createStatus } from './statuses';
import snackbar from 'soapbox/actions/snackbar'; import snackbar from 'soapbox/actions/snackbar';
@ -249,13 +249,14 @@ export function submitComposeFail(error) {
export function uploadCompose(files) { export function uploadCompose(files) {
return function(dispatch, getState) { return function(dispatch, getState) {
if (!isLoggedIn(getState)) return; if (!isLoggedIn(getState)) return;
const uploadLimit = getFeatures(getState().get('instance')).attachmentLimit; const instance = getState().get('instance');
const { attachmentLimit } = getFeatures(instance);
const media = getState().getIn(['compose', 'media_attachments']); const media = getState().getIn(['compose', '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 > attachmentLimit) {
dispatch(showAlert(undefined, messages.uploadErrorLimit, 'error')); dispatch(showAlert(undefined, messages.uploadErrorLimit, 'error'));
return; return;
} }
@ -263,7 +264,7 @@ export function uploadCompose(files) {
dispatch(uploadComposeRequest()); dispatch(uploadComposeRequest());
for (const [i, f] of Array.from(files).entries()) { for (const [i, f] of Array.from(files).entries()) {
if (media.size + i > uploadLimit - 1) break; if (media.size + i > attachmentLimit - 1) break;
// FIXME: Don't define function in loop // FIXME: Don't define function in loop
/* eslint-disable no-loop-func */ /* eslint-disable no-loop-func */
@ -279,8 +280,25 @@ export function uploadCompose(files) {
}; };
return dispatch(uploadMedia(data, onUploadProgress)) return dispatch(uploadMedia(data, onUploadProgress))
.then(({ data }) => dispatch(uploadComposeSuccess(data))); .then(({ status, data }) => {
// If server-side processing of the media attachment has not completed yet,
// poll the server until it is, before showing the media attachment as uploaded
if (status === 200) {
dispatch(uploadComposeSuccess(data, f));
} else if (status === 202) {
const poll = () => {
dispatch(fetchMedia(data.id)).then(({ status, data }) => {
if (status === 200) {
dispatch(uploadComposeSuccess(data, f));
} else if (status === 206) {
setTimeout(() => poll(), 1000);
}
}).catch(error => dispatch(uploadComposeFail(error)));
};
poll();
}
});
}).catch(error => dispatch(uploadComposeFail(error))); }).catch(error => dispatch(uploadComposeFail(error)));
/* eslint-enable no-loop-func */ /* eslint-enable no-loop-func */
} }
@ -293,7 +311,7 @@ export function changeUploadCompose(id, params) {
dispatch(changeUploadComposeRequest()); dispatch(changeUploadComposeRequest());
api(getState).put(`/api/v1/media/${id}`, params).then(response => { dispatch(updateMedia(id, params)).then(response => {
dispatch(changeUploadComposeSuccess(response.data)); dispatch(changeUploadComposeSuccess(response.data));
}).catch(error => { }).catch(error => {
dispatch(changeUploadComposeFail(id, error)); dispatch(changeUploadComposeFail(id, error));

@ -3,6 +3,18 @@ import { getFeatures } from 'soapbox/utils/features';
const noOp = () => {}; const noOp = () => {};
export function fetchMedia(mediaId) {
return (dispatch, getState) => {
return api(getState).get(`/api/v1/media/${mediaId}`);
};
}
export function updateMedia(mediaId, params) {
return (dispatch, getState) => {
return api(getState).put(`/api/v1/media/${mediaId}`, params);
};
}
export function uploadMediaV1(data, onUploadProgress = noOp) { export function uploadMediaV1(data, onUploadProgress = noOp) {
return (dispatch, getState) => { return (dispatch, getState) => {
return api(getState).post('/api/v1/media', data, { return api(getState).post('/api/v1/media', data, {

Loading…
Cancel
Save