[Glitch] Fix not being able to open audio modal in web UI

Port a8c471fcc0 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
master
Eugen Rochko 2020-12-07 04:29:37 +01:00 committed by Claire
parent f29f8caccb
commit d973a90bcc
7 changed files with 152 additions and 148 deletions

View 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)));
};

View File

@ -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) => {

View File

@ -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) {

View File

@ -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>
); );
} }

View File

@ -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);
} }
} }

View File

@ -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>
); );
} }

View File

@ -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 = () => {