From 30ef11022487364256656efee3cee92db2c839b2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 29 Oct 2022 20:05:53 +0200 Subject: [PATCH] Fix upload progress not communicating processing phase in web UI (#19530) --- app/javascript/mastodon/actions/compose.js | 21 +++++++++++++------ .../compose/components/upload_form.js | 3 +-- .../compose/components/upload_progress.js | 16 ++++++++++---- .../containers/upload_progress_container.js | 1 + app/javascript/mastodon/reducers/compose.js | 6 +++++- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 42d4ad8dff..e29b88a50f 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -25,11 +25,13 @@ export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'; export const COMPOSE_DIRECT = 'COMPOSE_DIRECT'; export const COMPOSE_MENTION = 'COMPOSE_MENTION'; export const COMPOSE_RESET = 'COMPOSE_RESET'; -export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'; -export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'; -export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL'; -export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS'; -export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'; + +export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'; +export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS'; +export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL'; +export const COMPOSE_UPLOAD_PROGRESS = 'COMPOSE_UPLOAD_PROGRESS'; +export const COMPOSE_UPLOAD_PROCESSING = 'COMPOSE_UPLOAD_PROCESSING'; +export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'; export const THUMBNAIL_UPLOAD_REQUEST = 'THUMBNAIL_UPLOAD_REQUEST'; export const THUMBNAIL_UPLOAD_SUCCESS = 'THUMBNAIL_UPLOAD_SUCCESS'; @@ -268,13 +270,16 @@ export function uploadCompose(files) { if (status === 200) { dispatch(uploadComposeSuccess(data, f)); } else if (status === 202) { + dispatch(uploadComposeProcessing()); + let tryCount = 1; + const poll = () => { api(getState).get(`/api/v1/media/${data.id}`).then(response => { if (response.status === 200) { dispatch(uploadComposeSuccess(response.data, f)); } else if (response.status === 206) { - let retryAfter = (Math.log2(tryCount) || 1) * 1000; + const retryAfter = (Math.log2(tryCount) || 1) * 1000; tryCount += 1; setTimeout(() => poll(), retryAfter); } @@ -289,6 +294,10 @@ export function uploadCompose(files) { }; }; +export const uploadComposeProcessing = () => ({ + type: COMPOSE_UPLOAD_PROCESSING, +}); + export const uploadThumbnail = (id, file) => (dispatch, getState) => { dispatch(uploadThumbnailRequest()); diff --git a/app/javascript/mastodon/features/compose/components/upload_form.js b/app/javascript/mastodon/features/compose/components/upload_form.js index c6eac554e6..9ff2aa0fa6 100644 --- a/app/javascript/mastodon/features/compose/components/upload_form.js +++ b/app/javascript/mastodon/features/compose/components/upload_form.js @@ -4,7 +4,6 @@ import UploadProgressContainer from '../containers/upload_progress_container'; import ImmutablePureComponent from 'react-immutable-pure-component'; import UploadContainer from '../containers/upload_container'; import SensitiveButtonContainer from '../containers/sensitive_button_container'; -import { FormattedMessage } from 'react-intl'; export default class UploadForm extends ImmutablePureComponent { @@ -17,7 +16,7 @@ export default class UploadForm extends ImmutablePureComponent { return (
- } /> +
{mediaIds.map(id => ( diff --git a/app/javascript/mastodon/features/compose/components/upload_progress.js b/app/javascript/mastodon/features/compose/components/upload_progress.js index b0bfe0c9a1..cabf520fd9 100644 --- a/app/javascript/mastodon/features/compose/components/upload_progress.js +++ b/app/javascript/mastodon/features/compose/components/upload_progress.js @@ -3,27 +3,35 @@ import PropTypes from 'prop-types'; import Motion from '../../ui/util/optional_motion'; import spring from 'react-motion/lib/spring'; import Icon from 'mastodon/components/icon'; +import { FormattedMessage } from 'react-intl'; export default class UploadProgress extends React.PureComponent { static propTypes = { active: PropTypes.bool, progress: PropTypes.number, - icon: PropTypes.string.isRequired, - message: PropTypes.node.isRequired, + isProcessing: PropTypes.bool, }; render () { - const { active, progress, icon, message } = this.props; + const { active, progress, isProcessing } = this.props; if (!active) { return null; } + let message; + + if (isProcessing) { + message = ; + } else { + message = ; + } + return (
- +
diff --git a/app/javascript/mastodon/features/compose/containers/upload_progress_container.js b/app/javascript/mastodon/features/compose/containers/upload_progress_container.js index 0cfee96daa..b18c76a43f 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_progress_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_progress_container.js @@ -4,6 +4,7 @@ import UploadProgress from '../components/upload_progress'; const mapStateToProps = state => ({ active: state.getIn(['compose', 'is_uploading']), progress: state.getIn(['compose', 'progress']), + isProcessing: state.getIn(['compose', 'is_processing']), }); export default connect(mapStateToProps)(UploadProgress); diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 7aac87b5c4..e4601e4715 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -14,6 +14,7 @@ import { COMPOSE_UPLOAD_FAIL, COMPOSE_UPLOAD_UNDO, COMPOSE_UPLOAD_PROGRESS, + COMPOSE_UPLOAD_PROCESSING, THUMBNAIL_UPLOAD_REQUEST, THUMBNAIL_UPLOAD_SUCCESS, THUMBNAIL_UPLOAD_FAIL, @@ -136,6 +137,7 @@ function appendMedia(state, media, file) { } map.update('media_attachments', list => list.push(media)); map.set('is_uploading', false); + map.set('is_processing', false); map.set('resetFileKey', Math.floor((Math.random() * 0x10000))); map.set('idempotencyKey', uuid()); map.update('pending_media_attachments', n => n - 1); @@ -354,10 +356,12 @@ export default function compose(state = initialState, action) { return state.set('is_changing_upload', false); case COMPOSE_UPLOAD_REQUEST: return state.set('is_uploading', true).update('pending_media_attachments', n => n + 1); + case COMPOSE_UPLOAD_PROCESSING: + return state.set('is_processing', true); case COMPOSE_UPLOAD_SUCCESS: return appendMedia(state, fromJS(action.media), action.file); case COMPOSE_UPLOAD_FAIL: - return state.set('is_uploading', false).update('pending_media_attachments', n => n - 1); + return state.set('is_uploading', false).set('is_processing', false).update('pending_media_attachments', n => n - 1); case COMPOSE_UPLOAD_UNDO: return removeMedia(state, action.media_id); case COMPOSE_UPLOAD_PROGRESS: