[Glitch] Fix not being able to open audio modal in web UI
Port a8c471fcc043b61aa10cf8f849dfb552db7381d3 to glitch-soc Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
		
							parent
							
								
									f29f8caccb
								
							
						
					
					
						commit
						d973a90bcc
					
				
							
								
								
									
										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) => {
 | 
			
		||||
    this.props.onOpenVideo(this.props.status.get('id'), media, options);
 | 
			
		||||
  handleOpenVideo = (options) => {
 | 
			
		||||
    const { status } = this.props;
 | 
			
		||||
    this.props.onOpenVideo(status.get('id'), status.getIn(['media_attachments', 0]), options);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleOpenMedia = (media, index) => {
 | 
			
		||||
 | 
			
		||||
@ -68,8 +68,8 @@ export default class DetailedStatus extends ImmutablePureComponent {
 | 
			
		||||
    e.stopPropagation();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleOpenVideo = (media, options) => {
 | 
			
		||||
    this.props.onOpenVideo(media, options);
 | 
			
		||||
  handleOpenVideo = (options) => {
 | 
			
		||||
    this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), options);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _measureHeight (heightJustChanged) {
 | 
			
		||||
 | 
			
		||||
@ -4,12 +4,10 @@ import PropTypes from 'prop-types';
 | 
			
		||||
import Audio from 'flavours/glitch/features/audio';
 | 
			
		||||
import { connect } from 'react-redux';
 | 
			
		||||
import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
			
		||||
import { FormattedMessage } from 'react-intl';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import Icon from 'flavours/glitch/components/icon';
 | 
			
		||||
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
 | 
			
		||||
 | 
			
		||||
const mapStateToProps = (state, { status }) => ({
 | 
			
		||||
  account: state.getIn(['accounts', status.get('account')]),
 | 
			
		||||
const mapStateToProps = (state, { statusId }) => ({
 | 
			
		||||
  accountStaticAvatar: state.getIn(['accounts', state.getIn(['statuses', statusId, 'account']), 'avatar_static']),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default @connect(mapStateToProps)
 | 
			
		||||
@ -17,27 +15,21 @@ class AudioModal extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    media: ImmutablePropTypes.map.isRequired,
 | 
			
		||||
    status: ImmutablePropTypes.map,
 | 
			
		||||
    statusId: PropTypes.string.isRequired,
 | 
			
		||||
    accountStaticAvatar: PropTypes.string.isRequired,
 | 
			
		||||
    options: PropTypes.shape({
 | 
			
		||||
      autoPlay: PropTypes.bool,
 | 
			
		||||
    }),
 | 
			
		||||
    account: ImmutablePropTypes.map,
 | 
			
		||||
    onClose: PropTypes.func.isRequired,
 | 
			
		||||
    onChangeBackgroundColor: PropTypes.func.isRequired,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static contextTypes = {
 | 
			
		||||
    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 () {
 | 
			
		||||
    const { media, status, account } = this.props;
 | 
			
		||||
    const { media, accountStaticAvatar, statusId, onClose } = this.props;
 | 
			
		||||
    const options = this.props.options || {};
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
@ -48,7 +40,7 @@ class AudioModal extends ImmutablePureComponent {
 | 
			
		||||
            alt={media.get('description')}
 | 
			
		||||
            duration={media.getIn(['meta', 'original', 'duration'], 0)}
 | 
			
		||||
            height={150}
 | 
			
		||||
            poster={media.get('preview_url') || account.get('avatar_static')}
 | 
			
		||||
            poster={media.get('preview_url') || accountStaticAvatar}
 | 
			
		||||
            backgroundColor={media.getIn(['meta', 'colors', 'background'])}
 | 
			
		||||
            foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
 | 
			
		||||
            accentColor={media.getIn(['meta', 'colors', 'accent'])}
 | 
			
		||||
@ -56,11 +48,9 @@ class AudioModal extends ImmutablePureComponent {
 | 
			
		||||
          />
 | 
			
		||||
        </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 className='media-modal__overlay'>
 | 
			
		||||
          {statusId && <Footer statusId={statusId} withOpenButton onClose={onClose} />}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ import ImageLoader from './image_loader';
 | 
			
		||||
import Icon from 'flavours/glitch/components/icon';
 | 
			
		||||
import GIFV from 'flavours/glitch/components/gifv';
 | 
			
		||||
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
 | 
			
		||||
import { getAverageFromBlurhash } from 'flavours/glitch/blurhash';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  close: { id: 'lightbox.close', defaultMessage: 'Close' },
 | 
			
		||||
@ -18,111 +19,6 @@ const messages = defineMessages({
 | 
			
		||||
  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
 | 
			
		||||
class MediaModal extends ImmutablePureComponent {
 | 
			
		||||
 | 
			
		||||
@ -234,7 +130,7 @@ class MediaModal extends ImmutablePureComponent {
 | 
			
		||||
    const blurhash = media.getIn([index, 'blurhash']);
 | 
			
		||||
 | 
			
		||||
    if (blurhash) {
 | 
			
		||||
      const backgroundColor = decodeRGB(decode83(blurhash.slice(2, 6)));
 | 
			
		||||
      const backgroundColor = getAverageFromBlurhash(blurhash);
 | 
			
		||||
      onChangeBackgroundColor(backgroundColor);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import Video from 'flavours/glitch/features/video';
 | 
			
		||||
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 {
 | 
			
		||||
 | 
			
		||||
@ -19,10 +21,21 @@ export default class VideoModal extends ImmutablePureComponent {
 | 
			
		||||
      defaultVolume: PropTypes.number,
 | 
			
		||||
    }),
 | 
			
		||||
    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 () {
 | 
			
		||||
    const { media, onClose } = this.props;
 | 
			
		||||
    const { media, statusId, onClose } = this.props;
 | 
			
		||||
    const options = this.props.options || {};
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
@ -41,6 +54,10 @@ export default class VideoModal extends ImmutablePureComponent {
 | 
			
		||||
            alt={media.get('description')}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div className='media-modal__overlay'>
 | 
			
		||||
          {statusId && <Footer statusId={statusId} withOpenButton onClose={onClose} />}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
import { fromJS, is } from 'immutable';
 | 
			
		||||
import { is } from 'immutable';
 | 
			
		||||
import { throttle, debounce } from 'lodash';
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { isFullscreen, requestFullscreen, exitFullscreen } from 'flavours/glitch/util/fullscreen';
 | 
			
		||||
@ -509,25 +509,13 @@ class Video extends React.PureComponent {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleOpenVideo = () => {
 | 
			
		||||
    const { src, preview, width, height, alt } = this.props;
 | 
			
		||||
    this.video.pause();
 | 
			
		||||
 | 
			
		||||
    const media = fromJS({
 | 
			
		||||
      type: 'video',
 | 
			
		||||
      url: src,
 | 
			
		||||
      preview_url: preview,
 | 
			
		||||
      description: alt,
 | 
			
		||||
      width,
 | 
			
		||||
      height,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const options = {
 | 
			
		||||
    this.props.onOpenVideo({
 | 
			
		||||
      startTime: this.video.currentTime,
 | 
			
		||||
      autoPlay: !this.state.paused,
 | 
			
		||||
      defaultVolume: this.state.volume,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    this.video.pause();
 | 
			
		||||
    this.props.onOpenVideo(media, options);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleCloseVideo = () => {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user