Fix audio attachments opening in video modal from media tab in web UI (#12056)
Fix video attachments having a GIF label in media tab in web UI
This commit is contained in:
		
							parent
							
								
									9184522cb4
								
							
						
					
					
						commit
						c9b8ba50f8
					
				|  | @ -119,6 +119,7 @@ export default class MediaItem extends ImmutablePureComponent { | ||||||
|       ); |       ); | ||||||
|     } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) { |     } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) { | ||||||
|       const autoPlay = !isIOS() && autoPlayGif; |       const autoPlay = !isIOS() && autoPlayGif; | ||||||
|  |       const label    = attachment.get('type') === 'video' ? <Icon id='play' /> : 'GIF'; | ||||||
| 
 | 
 | ||||||
|       thumbnail = ( |       thumbnail = ( | ||||||
|         <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}> |         <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}> | ||||||
|  | @ -135,7 +136,7 @@ export default class MediaItem extends ImmutablePureComponent { | ||||||
|             muted |             muted | ||||||
|           /> |           /> | ||||||
| 
 | 
 | ||||||
|           <span className='media-gallery__gifv__label'>GIF</span> |           <span className='media-gallery__gifv__label'>{label}</span> | ||||||
|         </div> |         </div> | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -100,8 +100,10 @@ class AccountGallery extends ImmutablePureComponent { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleOpenMedia = attachment => { |   handleOpenMedia = attachment => { | ||||||
|     if (['video', 'audio'].includes(attachment.get('type'))) { |     if (attachment.get('type') === 'video') { | ||||||
|       this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') })); |       this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') })); | ||||||
|  |     } else if (attachment.get('type') === 'audio') { | ||||||
|  |       this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status') })); | ||||||
|     } else { |     } else { | ||||||
|       const media = attachment.getIn(['status', 'media_attachments']); |       const media = attachment.getIn(['status', 'media_attachments']); | ||||||
|       const index = media.findIndex(x => x.get('id') === attachment.get('id')); |       const index = media.findIndex(x => x.get('id') === attachment.get('id')); | ||||||
|  |  | ||||||
|  | @ -0,0 +1,76 @@ | ||||||
|  | import React from 'react'; | ||||||
|  | import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
|  | import PropTypes from 'prop-types'; | ||||||
|  | import Audio from 'mastodon/features/audio'; | ||||||
|  | import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||||
|  | import { FormattedMessage } from 'react-intl'; | ||||||
|  | import { previewState } from './video_modal'; | ||||||
|  | import classNames from 'classnames'; | ||||||
|  | import Icon from 'mastodon/components/icon'; | ||||||
|  | 
 | ||||||
|  | export default class AudioModal extends ImmutablePureComponent { | ||||||
|  | 
 | ||||||
|  |   static propTypes = { | ||||||
|  |     media: ImmutablePropTypes.map.isRequired, | ||||||
|  |     status: ImmutablePropTypes.map, | ||||||
|  |     onClose: PropTypes.func.isRequired, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   static contextTypes = { | ||||||
|  |     router: PropTypes.object, | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   componentDidMount () { | ||||||
|  |     if (this.context.router) { | ||||||
|  |       const history = this.context.router.history; | ||||||
|  | 
 | ||||||
|  |       history.push(history.location.pathname, previewState); | ||||||
|  | 
 | ||||||
|  |       this.unlistenHistory = history.listen(() => { | ||||||
|  |         this.props.onClose(); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   componentWillUnmount () { | ||||||
|  |     if (this.context.router) { | ||||||
|  |       this.unlistenHistory(); | ||||||
|  | 
 | ||||||
|  |       if (this.context.router.history.location.state === previewState) { | ||||||
|  |         this.context.router.history.goBack(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   handleStatusClick = e => { | ||||||
|  |     if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { | ||||||
|  |       e.preventDefault(); | ||||||
|  |       this.context.router.history.push(`/statuses/${this.props.status.get('id')}`); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   render () { | ||||||
|  |     const { media, status } = this.props; | ||||||
|  | 
 | ||||||
|  |     return ( | ||||||
|  |       <div className='modal-root__modal audio-modal'> | ||||||
|  |         <div className='audio-modal__container'> | ||||||
|  |           <Audio | ||||||
|  |             src={media.get('url')} | ||||||
|  |             alt={media.get('description')} | ||||||
|  |             duration={media.getIn(['meta', 'original', 'duration'], 0)} | ||||||
|  |             height={135} | ||||||
|  |             preload | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|  | 
 | ||||||
|  |         {status && ( | ||||||
|  |           <div className={classNames('media-modal__meta')}> | ||||||
|  |             <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a> | ||||||
|  |           </div> | ||||||
|  |         )} | ||||||
|  |       </div> | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -228,7 +228,7 @@ class MediaModal extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|           {status && ( |           {status && ( | ||||||
|             <div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}> |             <div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}> | ||||||
|               <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a> |               <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a> | ||||||
|             </div> |             </div> | ||||||
|           )} |           )} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ import ActionsModal from './actions_modal'; | ||||||
| import MediaModal from './media_modal'; | import MediaModal from './media_modal'; | ||||||
| import VideoModal from './video_modal'; | import VideoModal from './video_modal'; | ||||||
| import BoostModal from './boost_modal'; | import BoostModal from './boost_modal'; | ||||||
|  | import AudioModal from './audio_modal'; | ||||||
| import ConfirmationModal from './confirmation_modal'; | import ConfirmationModal from './confirmation_modal'; | ||||||
| import FocalPointModal from './focal_point_modal'; | import FocalPointModal from './focal_point_modal'; | ||||||
| import { | import { | ||||||
|  | @ -23,6 +24,7 @@ import { | ||||||
| const MODAL_COMPONENTS = { | const MODAL_COMPONENTS = { | ||||||
|   'MEDIA': () => Promise.resolve({ default: MediaModal }), |   'MEDIA': () => Promise.resolve({ default: MediaModal }), | ||||||
|   'VIDEO': () => Promise.resolve({ default: VideoModal }), |   'VIDEO': () => Promise.resolve({ default: VideoModal }), | ||||||
|  |   'AUDIO': () => Promise.resolve({ default: AudioModal }), | ||||||
|   'BOOST': () => Promise.resolve({ default: BoostModal }), |   'BOOST': () => Promise.resolve({ default: BoostModal }), | ||||||
|   'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }), |   'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }), | ||||||
|   'MUTE': MuteModal, |   'MUTE': MuteModal, | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ import PropTypes from 'prop-types'; | ||||||
| import Video from 'mastodon/features/video'; | import Video from 'mastodon/features/video'; | ||||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||||
| import { FormattedMessage } from 'react-intl'; | import { FormattedMessage } from 'react-intl'; | ||||||
|  | import classNames from 'classnames'; | ||||||
|  | import Icon from 'mastodon/components/icon'; | ||||||
| 
 | 
 | ||||||
| export const previewState = 'previewVideoModal'; | export const previewState = 'previewVideoModal'; | ||||||
| 
 | 
 | ||||||
|  | @ -52,22 +54,25 @@ export default class VideoModal extends ImmutablePureComponent { | ||||||
|   render () { |   render () { | ||||||
|     const { media, status, time, onClose } = this.props; |     const { media, status, time, onClose } = this.props; | ||||||
| 
 | 
 | ||||||
|     const link = status && <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>; |  | ||||||
| 
 |  | ||||||
|     return ( |     return ( | ||||||
|       <div className='modal-root__modal video-modal'> |       <div className='modal-root__modal video-modal'> | ||||||
|         <div> |         <div className='video-modal__container'> | ||||||
|           <Video |           <Video | ||||||
|             preview={media.get('preview_url')} |             preview={media.get('preview_url')} | ||||||
|             blurhash={media.get('blurhash')} |             blurhash={media.get('blurhash')} | ||||||
|             src={media.get('url')} |             src={media.get('url')} | ||||||
|             startTime={time} |             startTime={time} | ||||||
|             onCloseVideo={onClose} |             onCloseVideo={onClose} | ||||||
|             link={link} |  | ||||||
|             detailed |             detailed | ||||||
|             alt={media.get('description')} |             alt={media.get('description')} | ||||||
|           /> |           /> | ||||||
|         </div> |         </div> | ||||||
|  | 
 | ||||||
|  |         {status && ( | ||||||
|  |           <div className={classNames('media-modal__meta')}> | ||||||
|  |             <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a> | ||||||
|  |           </div> | ||||||
|  |         )} | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -4271,10 +4271,13 @@ a.status-card.compact:hover { | ||||||
|   z-index: 9999; |   z-index: 9999; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .video-modal { | .video-modal__container { | ||||||
|   max-width: 100vw; |   max-width: 100vw; | ||||||
|   max-height: 100vh; |   max-height: 100vh; | ||||||
|   position: relative; | } | ||||||
|  | 
 | ||||||
|  | .audio-modal__container { | ||||||
|  |   width: 50vw; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .media-modal { | .media-modal { | ||||||
|  | @ -4374,6 +4377,7 @@ a.status-card.compact:hover { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   a { |   a { | ||||||
|  |     pointer-events: auto; | ||||||
|     text-decoration: none; |     text-decoration: none; | ||||||
|     font-weight: 500; |     font-weight: 500; | ||||||
|     color: $ui-secondary-color; |     color: $ui-secondary-color; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue