Fix upload progress not communicating processing phase in web UI (#19530)
This commit is contained in:
		
							parent
							
								
									a449ee8654
								
							
						
					
					
						commit
						30ef110224
					
				
					 5 changed files with 34 additions and 13 deletions
				
			
		|  | @ -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()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 ( | ||||
|       <div className='compose-form__upload-wrapper'> | ||||
|         <UploadProgressContainer icon='upload' message={<FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />} /> | ||||
|         <UploadProgressContainer /> | ||||
| 
 | ||||
|         <div className='compose-form__uploads-wrapper'> | ||||
|           {mediaIds.map(id => ( | ||||
|  |  | |||
|  | @ -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 = <FormattedMessage id='upload_progress.processing' defaultMessage='Processing…' />; | ||||
|     } else { | ||||
|       message = <FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />; | ||||
|     } | ||||
| 
 | ||||
|     return ( | ||||
|       <div className='upload-progress'> | ||||
|         <div className='upload-progress__icon'> | ||||
|           <Icon id={icon} /> | ||||
|           <Icon id='upload' /> | ||||
|         </div> | ||||
| 
 | ||||
|         <div className='upload-progress__message'> | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
		Reference in a new issue