[Glitch] Fix not being able to open audio modal in web UI
Port de8c539b7b to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
			
			
This commit is contained in:
		
							parent
							
								
									f1c5ce7cea
								
							
						
					
					
						commit
						49b205ad89
					
				
					 7 changed files with 152 additions and 148 deletions
				
			
		
							
								
								
									
										112
									
								
								app/javascript/flavours/glitch/blurhash.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								app/javascript/flavours/glitch/blurhash.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,112 @@ | ||||||
|  | const DIGIT_CHARACTERS = [ | ||||||
|  |   '0', | ||||||
|  |   '1', | ||||||
|  |   '2', | ||||||
|  |   '3', | ||||||
|  |   '4', | ||||||
|  |   '5', | ||||||
|  |   '6', | ||||||
|  |   '7', | ||||||
|  |   '8', | ||||||
|  |   '9', | ||||||
|  |   'A', | ||||||
|  |   'B', | ||||||
|  |   'C', | ||||||
|  |   'D', | ||||||
|  |   'E', | ||||||
|  |   'F', | ||||||
|  |   'G', | ||||||
|  |   'H', | ||||||
|  |   'I', | ||||||
|  |   'J', | ||||||
|  |   'K', | ||||||
|  |   'L', | ||||||
|  |   'M', | ||||||
|  |   'N', | ||||||
|  |   'O', | ||||||
|  |   'P', | ||||||
|  |   'Q', | ||||||
|  |   'R', | ||||||
|  |   'S', | ||||||
|  |   'T', | ||||||
|  |   'U', | ||||||
|  |   'V', | ||||||
|  |   'W', | ||||||
|  |   'X', | ||||||
|  |   'Y', | ||||||
|  |   'Z', | ||||||
|  |   'a', | ||||||
|  |   'b', | ||||||
|  |   'c', | ||||||
|  |   'd', | ||||||
|  |   'e', | ||||||
|  |   'f', | ||||||
|  |   'g', | ||||||
|  |   'h', | ||||||
|  |   'i', | ||||||
|  |   'j', | ||||||
|  |   'k', | ||||||
|  |   'l', | ||||||
|  |   'm', | ||||||
|  |   'n', | ||||||
|  |   'o', | ||||||
|  |   'p', | ||||||
|  |   'q', | ||||||
|  |   'r', | ||||||
|  |   's', | ||||||
|  |   't', | ||||||
|  |   'u', | ||||||
|  |   'v', | ||||||
|  |   'w', | ||||||
|  |   'x', | ||||||
|  |   'y', | ||||||
|  |   'z', | ||||||
|  |   '#', | ||||||
|  |   '$', | ||||||
|  |   '%', | ||||||
|  |   '*', | ||||||
|  |   '+', | ||||||
|  |   ',', | ||||||
|  |   '-', | ||||||
|  |   '.', | ||||||
|  |   ':', | ||||||
|  |   ';', | ||||||
|  |   '=', | ||||||
|  |   '?', | ||||||
|  |   '@', | ||||||
|  |   '[', | ||||||
|  |   ']', | ||||||
|  |   '^', | ||||||
|  |   '_', | ||||||
|  |   '{', | ||||||
|  |   '|', | ||||||
|  |   '}', | ||||||
|  |   '~', | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | export const decode83 = (str) => { | ||||||
|  |   let value = 0; | ||||||
|  |   let c, digit; | ||||||
|  | 
 | ||||||
|  |   for (let i = 0; i < str.length; i++) { | ||||||
|  |     c = str[i]; | ||||||
|  |     digit = DIGIT_CHARACTERS.indexOf(c); | ||||||
|  |     value = value * 83 + digit; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return value; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const intToRGB = int => ({ | ||||||
|  |   r: Math.max(0, (int >> 16)), | ||||||
|  |   g: Math.max(0, (int >> 8) & 255), | ||||||
|  |   b: Math.max(0, (int & 255)), | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | export const getAverageFromBlurhash = blurhash => { | ||||||
|  |   if (!blurhash) { | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return intToRGB(decode83(blurhash.slice(2, 6))); | ||||||
|  | }; | ||||||
|  | @ -378,8 +378,9 @@ class Status extends ImmutablePureComponent { | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   handleOpenVideo = (media, options) => { |   handleOpenVideo = (options) => { | ||||||
|     this.props.onOpenVideo(this.props.status.get('id'), media, options); |     const { status } = this.props; | ||||||
|  |     this.props.onOpenVideo(status.get('id'), status.getIn(['media_attachments', 0]), options); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleOpenMedia = (media, index) => { |   handleOpenMedia = (media, index) => { | ||||||
|  |  | ||||||
|  | @ -68,8 +68,8 @@ export default class DetailedStatus extends ImmutablePureComponent { | ||||||
|     e.stopPropagation(); |     e.stopPropagation(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleOpenVideo = (media, options) => { |   handleOpenVideo = (options) => { | ||||||
|     this.props.onOpenVideo(media, options); |     this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   _measureHeight (heightJustChanged) { |   _measureHeight (heightJustChanged) { | ||||||
|  |  | ||||||
|  | @ -4,12 +4,10 @@ import PropTypes from 'prop-types'; | ||||||
| import Audio from 'flavours/glitch/features/audio'; | import Audio from 'flavours/glitch/features/audio'; | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||||
| import { FormattedMessage } from 'react-intl'; | import Footer from 'flavours/glitch/features/picture_in_picture/components/footer'; | ||||||
| import classNames from 'classnames'; |  | ||||||
| import Icon from 'flavours/glitch/components/icon'; |  | ||||||
| 
 | 
 | ||||||
| const mapStateToProps = (state, { status }) => ({ | const mapStateToProps = (state, { statusId }) => ({ | ||||||
|   account: state.getIn(['accounts', status.get('account')]), |   accountStaticAvatar: state.getIn(['accounts', state.getIn(['statuses', statusId, 'account']), 'avatar_static']), | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default @connect(mapStateToProps) | export default @connect(mapStateToProps) | ||||||
|  | @ -17,27 +15,21 @@ class AudioModal extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|   static propTypes = { |   static propTypes = { | ||||||
|     media: ImmutablePropTypes.map.isRequired, |     media: ImmutablePropTypes.map.isRequired, | ||||||
|     status: ImmutablePropTypes.map, |     statusId: PropTypes.string.isRequired, | ||||||
|  |     accountStaticAvatar: PropTypes.string.isRequired, | ||||||
|     options: PropTypes.shape({ |     options: PropTypes.shape({ | ||||||
|       autoPlay: PropTypes.bool, |       autoPlay: PropTypes.bool, | ||||||
|     }), |     }), | ||||||
|     account: ImmutablePropTypes.map, |  | ||||||
|     onClose: PropTypes.func.isRequired, |     onClose: PropTypes.func.isRequired, | ||||||
|  |     onChangeBackgroundColor: PropTypes.func.isRequired, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   static contextTypes = { |   static contextTypes = { | ||||||
|     router: PropTypes.object, |     router: PropTypes.object, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   handleStatusClick = e => { |  | ||||||
|     if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { |  | ||||||
|       e.preventDefault(); |  | ||||||
|       this.context.router.history.push(`/statuses/${this.props.status.get('id')}`); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   render () { |   render () { | ||||||
|     const { media, status, account } = this.props; |     const { media, accountStaticAvatar, statusId, onClose } = this.props; | ||||||
|     const options = this.props.options || {}; |     const options = this.props.options || {}; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|  | @ -48,7 +40,7 @@ class AudioModal extends ImmutablePureComponent { | ||||||
|             alt={media.get('description')} |             alt={media.get('description')} | ||||||
|             duration={media.getIn(['meta', 'original', 'duration'], 0)} |             duration={media.getIn(['meta', 'original', 'duration'], 0)} | ||||||
|             height={150} |             height={150} | ||||||
|             poster={media.get('preview_url') || account.get('avatar_static')} |             poster={media.get('preview_url') || accountStaticAvatar} | ||||||
|             backgroundColor={media.getIn(['meta', 'colors', 'background'])} |             backgroundColor={media.getIn(['meta', 'colors', 'background'])} | ||||||
|             foregroundColor={media.getIn(['meta', 'colors', 'foreground'])} |             foregroundColor={media.getIn(['meta', 'colors', 'foreground'])} | ||||||
|             accentColor={media.getIn(['meta', 'colors', 'accent'])} |             accentColor={media.getIn(['meta', 'colors', 'accent'])} | ||||||
|  | @ -56,11 +48,9 @@ class AudioModal extends ImmutablePureComponent { | ||||||
|           /> |           /> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         {status && ( |         <div className='media-modal__overlay'> | ||||||
|           <div className={classNames('media-modal__meta')}> |           {statusId && <Footer statusId={statusId} withOpenButton onClose={onClose} />} | ||||||
|             <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a> |         </div> | ||||||
|           </div> |  | ||||||
|         )} |  | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ import ImageLoader from './image_loader'; | ||||||
| import Icon from 'flavours/glitch/components/icon'; | import Icon from 'flavours/glitch/components/icon'; | ||||||
| import GIFV from 'flavours/glitch/components/gifv'; | import GIFV from 'flavours/glitch/components/gifv'; | ||||||
| import Footer from 'flavours/glitch/features/picture_in_picture/components/footer'; | import Footer from 'flavours/glitch/features/picture_in_picture/components/footer'; | ||||||
|  | import { getAverageFromBlurhash } from 'flavours/glitch/blurhash'; | ||||||
| 
 | 
 | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   close: { id: 'lightbox.close', defaultMessage: 'Close' }, |   close: { id: 'lightbox.close', defaultMessage: 'Close' }, | ||||||
|  | @ -18,111 +19,6 @@ const messages = defineMessages({ | ||||||
|   next: { id: 'lightbox.next', defaultMessage: 'Next' }, |   next: { id: 'lightbox.next', defaultMessage: 'Next' }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const digitCharacters = [ |  | ||||||
|   '0', |  | ||||||
|   '1', |  | ||||||
|   '2', |  | ||||||
|   '3', |  | ||||||
|   '4', |  | ||||||
|   '5', |  | ||||||
|   '6', |  | ||||||
|   '7', |  | ||||||
|   '8', |  | ||||||
|   '9', |  | ||||||
|   'A', |  | ||||||
|   'B', |  | ||||||
|   'C', |  | ||||||
|   'D', |  | ||||||
|   'E', |  | ||||||
|   'F', |  | ||||||
|   'G', |  | ||||||
|   'H', |  | ||||||
|   'I', |  | ||||||
|   'J', |  | ||||||
|   'K', |  | ||||||
|   'L', |  | ||||||
|   'M', |  | ||||||
|   'N', |  | ||||||
|   'O', |  | ||||||
|   'P', |  | ||||||
|   'Q', |  | ||||||
|   'R', |  | ||||||
|   'S', |  | ||||||
|   'T', |  | ||||||
|   'U', |  | ||||||
|   'V', |  | ||||||
|   'W', |  | ||||||
|   'X', |  | ||||||
|   'Y', |  | ||||||
|   'Z', |  | ||||||
|   'a', |  | ||||||
|   'b', |  | ||||||
|   'c', |  | ||||||
|   'd', |  | ||||||
|   'e', |  | ||||||
|   'f', |  | ||||||
|   'g', |  | ||||||
|   'h', |  | ||||||
|   'i', |  | ||||||
|   'j', |  | ||||||
|   'k', |  | ||||||
|   'l', |  | ||||||
|   'm', |  | ||||||
|   'n', |  | ||||||
|   'o', |  | ||||||
|   'p', |  | ||||||
|   'q', |  | ||||||
|   'r', |  | ||||||
|   's', |  | ||||||
|   't', |  | ||||||
|   'u', |  | ||||||
|   'v', |  | ||||||
|   'w', |  | ||||||
|   'x', |  | ||||||
|   'y', |  | ||||||
|   'z', |  | ||||||
|   '#', |  | ||||||
|   '$', |  | ||||||
|   '%', |  | ||||||
|   '*', |  | ||||||
|   '+', |  | ||||||
|   ',', |  | ||||||
|   '-', |  | ||||||
|   '.', |  | ||||||
|   ':', |  | ||||||
|   ';', |  | ||||||
|   '=', |  | ||||||
|   '?', |  | ||||||
|   '@', |  | ||||||
|   '[', |  | ||||||
|   ']', |  | ||||||
|   '^', |  | ||||||
|   '_', |  | ||||||
|   '{', |  | ||||||
|   '|', |  | ||||||
|   '}', |  | ||||||
|   '~', |  | ||||||
| ]; |  | ||||||
| 
 |  | ||||||
| const decode83 = (str) => { |  | ||||||
|   let value = 0; |  | ||||||
|   let c, digit; |  | ||||||
| 
 |  | ||||||
|   for (let i = 0; i < str.length; i++) { |  | ||||||
|     c = str[i]; |  | ||||||
|     digit = digitCharacters.indexOf(c); |  | ||||||
|     value = value * 83 + digit; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   return value; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| const decodeRGB = int => ({ |  | ||||||
|   r: Math.max(0, (int >> 16)), |  | ||||||
|   g: Math.max(0, (int >> 8) & 255), |  | ||||||
|   b: Math.max(0, (int & 255)), |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| export default @injectIntl | export default @injectIntl | ||||||
| class MediaModal extends ImmutablePureComponent { | class MediaModal extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|  | @ -234,7 +130,7 @@ class MediaModal extends ImmutablePureComponent { | ||||||
|     const blurhash = media.getIn([index, 'blurhash']); |     const blurhash = media.getIn([index, 'blurhash']); | ||||||
| 
 | 
 | ||||||
|     if (blurhash) { |     if (blurhash) { | ||||||
|       const backgroundColor = decodeRGB(decode83(blurhash.slice(2, 6))); |       const backgroundColor = getAverageFromBlurhash(blurhash); | ||||||
|       onChangeBackgroundColor(backgroundColor); |       onChangeBackgroundColor(backgroundColor); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import Video from 'flavours/glitch/features/video'; | import Video from 'flavours/glitch/features/video'; | ||||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||||
|  | import Footer from 'flavours/glitch/features/picture_in_picture/components/footer'; | ||||||
|  | import { getAverageFromBlurhash } from 'flavours/glitch/blurhash'; | ||||||
| 
 | 
 | ||||||
| export default class VideoModal extends ImmutablePureComponent { | export default class VideoModal extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|  | @ -19,10 +21,21 @@ export default class VideoModal extends ImmutablePureComponent { | ||||||
|       defaultVolume: PropTypes.number, |       defaultVolume: PropTypes.number, | ||||||
|     }), |     }), | ||||||
|     onClose: PropTypes.func.isRequired, |     onClose: PropTypes.func.isRequired, | ||||||
|  |     onChangeBackgroundColor: PropTypes.func.isRequired, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   componentDidMount () { | ||||||
|  |     const { media, onChangeBackgroundColor, onClose } = this.props; | ||||||
|  | 
 | ||||||
|  |     const backgroundColor = getAverageFromBlurhash(media.get('blurhash')); | ||||||
|  | 
 | ||||||
|  |     if (backgroundColor) { | ||||||
|  |       onChangeBackgroundColor(backgroundColor); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { media, onClose } = this.props; |     const { media, statusId, onClose } = this.props; | ||||||
|     const options = this.props.options || {}; |     const options = this.props.options || {}; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|  | @ -41,6 +54,10 @@ export default class VideoModal extends ImmutablePureComponent { | ||||||
|             alt={media.get('description')} |             alt={media.get('description')} | ||||||
|           /> |           /> | ||||||
|         </div> |         </div> | ||||||
|  | 
 | ||||||
|  |         <div className='media-modal__overlay'> | ||||||
|  |           {statusId && <Footer statusId={statusId} withOpenButton onClose={onClose} />} | ||||||
|  |         </div> | ||||||
|       </div> |       </div> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; | ||||||
| import { fromJS, is } from 'immutable'; | import { is } from 'immutable'; | ||||||
| import { throttle, debounce } from 'lodash'; | import { throttle, debounce } from 'lodash'; | ||||||
| import classNames from 'classnames'; | import classNames from 'classnames'; | ||||||
| import { isFullscreen, requestFullscreen, exitFullscreen } from 'flavours/glitch/util/fullscreen'; | import { isFullscreen, requestFullscreen, exitFullscreen } from 'flavours/glitch/util/fullscreen'; | ||||||
|  | @ -509,25 +509,13 @@ class Video extends React.PureComponent { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleOpenVideo = () => { |   handleOpenVideo = () => { | ||||||
|     const { src, preview, width, height, alt } = this.props; |     this.video.pause(); | ||||||
| 
 | 
 | ||||||
|     const media = fromJS({ |     this.props.onOpenVideo({ | ||||||
|       type: 'video', |  | ||||||
|       url: src, |  | ||||||
|       preview_url: preview, |  | ||||||
|       description: alt, |  | ||||||
|       width, |  | ||||||
|       height, |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     const options = { |  | ||||||
|       startTime: this.video.currentTime, |       startTime: this.video.currentTime, | ||||||
|       autoPlay: !this.state.paused, |       autoPlay: !this.state.paused, | ||||||
|       defaultVolume: this.state.volume, |       defaultVolume: this.state.volume, | ||||||
|     }; |     }); | ||||||
| 
 |  | ||||||
|     this.video.pause(); |  | ||||||
|     this.props.onOpenVideo(media, options); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleCloseVideo = () => { |   handleCloseVideo = () => { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue