[Glitch] Change media elements to use aspect-ratio rather than compute height themselves
Port 598e63dad2
to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
pull/59/head^2^2
parent
10f5329ddf
commit
a8939e9098
|
@ -358,12 +358,10 @@ class MediaGallery extends React.PureComponent {
|
||||||
|
|
||||||
const computedClass = classNames('media-gallery', { 'full-width': fullwidth });
|
const computedClass = classNames('media-gallery', { 'full-width': fullwidth });
|
||||||
|
|
||||||
if (this.isStandaloneEligible() && width) {
|
if (this.isStandaloneEligible()) { // TODO: cropImages setting
|
||||||
style.height = width / this.props.media.getIn([0, 'meta', 'small', 'aspect']);
|
style.aspectRatio = `${this.props.media.getIn([0, 'meta', 'small', 'aspect'])}`;
|
||||||
} else if (width) {
|
|
||||||
style.height = width / (16/9);
|
|
||||||
} else {
|
} else {
|
||||||
return (<div className={computedClass} ref={this.handleRef} />);
|
style.aspectRatio = '16 / 9';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isStandaloneEligible()) {
|
if (this.isStandaloneEligible()) {
|
||||||
|
|
|
@ -3,62 +3,22 @@ import PropTypes from 'prop-types';
|
||||||
import Icon from 'flavours/glitch/components/icon';
|
import Icon from 'flavours/glitch/components/icon';
|
||||||
import { removePictureInPicture } from 'flavours/glitch/actions/picture_in_picture';
|
import { removePictureInPicture } from 'flavours/glitch/actions/picture_in_picture';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { debounce } from 'lodash';
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
class PictureInPicturePlaceholder extends React.PureComponent {
|
class PictureInPicturePlaceholder extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
width: PropTypes.number,
|
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
|
||||||
width: this.props.width,
|
|
||||||
height: this.props.width && (this.props.width / (16/9)),
|
|
||||||
};
|
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(removePictureInPicture());
|
dispatch(removePictureInPicture());
|
||||||
};
|
};
|
||||||
|
|
||||||
setRef = c => {
|
|
||||||
this.node = c;
|
|
||||||
|
|
||||||
if (this.node) {
|
|
||||||
this._setDimensions();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
_setDimensions () {
|
|
||||||
const width = this.node.offsetWidth;
|
|
||||||
const height = width / (16/9);
|
|
||||||
|
|
||||||
this.setState({ width, height });
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
|
||||||
window.removeEventListener('resize', this.handleResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
|
||||||
if (this.node) {
|
|
||||||
this._setDimensions();
|
|
||||||
}
|
|
||||||
}, 250, {
|
|
||||||
trailing: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { height } = this.state;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={this.setRef} className='picture-in-picture-placeholder' style={{ height }} role='button' tabIndex={0} onClick={this.handleClick}>
|
<div className='picture-in-picture-placeholder' role='button' tabIndex={0} onClick={this.handleClick}>
|
||||||
<Icon id='window-restore' />
|
<Icon id='window-restore' />
|
||||||
<FormattedMessage id='picture_in_picture.restore' defaultMessage='Put it back' />
|
<FormattedMessage id='picture_in_picture.restore' defaultMessage='Put it back' />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -624,7 +624,7 @@ class Status extends ImmutablePureComponent {
|
||||||
attachments = status.get('media_attachments');
|
attachments = status.get('media_attachments');
|
||||||
|
|
||||||
if (pictureInPicture.get('inUse')) {
|
if (pictureInPicture.get('inUse')) {
|
||||||
media.push(<PictureInPicturePlaceholder width={this.props.cachedMediaWidth} />);
|
media.push(<PictureInPicturePlaceholder />);
|
||||||
mediaIcons.push('video-camera');
|
mediaIcons.push('video-camera');
|
||||||
} else if (attachments.size > 0) {
|
} else if (attachments.size > 0) {
|
||||||
if (muted || attachments.some(item => item.get('type') === 'unknown')) {
|
if (muted || attachments.some(item => item.get('type') === 'unknown')) {
|
||||||
|
@ -680,8 +680,6 @@ class Status extends ImmutablePureComponent {
|
||||||
fullwidth={!rootId && settings.getIn(['media', 'fullwidth'])}
|
fullwidth={!rootId && settings.getIn(['media', 'fullwidth'])}
|
||||||
preventPlayback={isCollapsed || !isExpanded}
|
preventPlayback={isCollapsed || !isExpanded}
|
||||||
onOpenVideo={this.handleOpenVideo}
|
onOpenVideo={this.handleOpenVideo}
|
||||||
width={this.props.cachedMediaWidth}
|
|
||||||
cacheWidth={this.props.cacheMediaWidth}
|
|
||||||
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
|
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
|
||||||
visible={this.state.showMedia}
|
visible={this.state.showMedia}
|
||||||
onToggleVisibility={this.handleToggleMediaVisibility}
|
onToggleVisibility={this.handleToggleMediaVisibility}
|
||||||
|
@ -721,8 +719,6 @@ class Status extends ImmutablePureComponent {
|
||||||
onOpenMedia={this.handleOpenMedia}
|
onOpenMedia={this.handleOpenMedia}
|
||||||
card={status.get('card')}
|
card={status.get('card')}
|
||||||
compact
|
compact
|
||||||
cacheWidth={this.props.cacheMediaWidth}
|
|
||||||
defaultWidth={this.props.cachedMediaWidth}
|
|
||||||
sensitive={status.get('sensitive')}
|
sensitive={status.get('sensitive')}
|
||||||
/>,
|
/>,
|
||||||
);
|
);
|
||||||
|
|
|
@ -390,7 +390,7 @@ class Audio extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getRadius () {
|
_getRadius () {
|
||||||
return parseInt(((this.state.height || this.props.height) - (PADDING * this._getScaleCoefficient()) * 2) / 2);
|
return parseInt((this.state.height || this.props.height) / 2 - PADDING * this._getScaleCoefficient());
|
||||||
}
|
}
|
||||||
|
|
||||||
_getScaleCoefficient () {
|
_getScaleCoefficient () {
|
||||||
|
@ -402,7 +402,7 @@ class Audio extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
_getCY() {
|
_getCY() {
|
||||||
return Math.floor(this._getRadius() + (PADDING * this._getScaleCoefficient()));
|
return Math.floor((this.state.height || this.props.height) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getAccentColor () {
|
_getAccentColor () {
|
||||||
|
@ -476,7 +476,7 @@ class Audio extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames('audio-player', { editable, inactive: !revealed })} ref={this.setPlayerRef} style={{ backgroundColor: this._getBackgroundColor(), color: this._getForegroundColor(), height: this.props.fullscreen ? '100%' : (this.state.height || this.props.height) }} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} tabIndex={0} onKeyDown={this.handleKeyDown}>
|
<div className={classNames('audio-player', { editable, inactive: !revealed })} ref={this.setPlayerRef} style={{ backgroundColor: this._getBackgroundColor(), color: this._getForegroundColor(), aspectRatio: '16 / 9' }} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} tabIndex={0} onKeyDown={this.handleKeyDown}>
|
||||||
|
|
||||||
<Blurhash
|
<Blurhash
|
||||||
hash={blurhash}
|
hash={blurhash}
|
||||||
|
@ -521,9 +521,16 @@ class Audio extends React.PureComponent {
|
||||||
{(revealed || editable) && <img
|
{(revealed || editable) && <img
|
||||||
src={this.props.poster}
|
src={this.props.poster}
|
||||||
alt=''
|
alt=''
|
||||||
width={(this._getRadius() - TICK_SIZE) * 2}
|
style={{
|
||||||
height={(this._getRadius() - TICK_SIZE) * 2}
|
position: 'absolute',
|
||||||
style={{ position: 'absolute', left: this._getCX(), top: this._getCY(), transform: 'translate(-50%, -50%)', borderRadius: '50%', pointerEvents: 'none' }}
|
left: '50%',
|
||||||
|
top: '50%',
|
||||||
|
height: `calc(${(100 - 2 * 100 * PADDING / 982)}% - ${TICK_SIZE * 2}px)`,
|
||||||
|
aspectRatio: '1',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
}}
|
||||||
/>}
|
/>}
|
||||||
|
|
||||||
<div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
|
<div className='video-player__seek' onMouseDown={this.handleMouseDown} ref={this.setSeekRef}>
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { decode as decodeIDNA } from 'flavours/glitch/utils/idna';
|
||||||
import Icon from 'flavours/glitch/components/icon';
|
import Icon from 'flavours/glitch/components/icon';
|
||||||
import { useBlurhash } from 'flavours/glitch/initial_state';
|
import { useBlurhash } from 'flavours/glitch/initial_state';
|
||||||
import Blurhash from 'flavours/glitch/components/blurhash';
|
import Blurhash from 'flavours/glitch/components/blurhash';
|
||||||
import { debounce } from 'lodash';
|
|
||||||
|
|
||||||
const getHostname = url => {
|
const getHostname = url => {
|
||||||
const parser = document.createElement('a');
|
const parser = document.createElement('a');
|
||||||
|
@ -45,8 +44,6 @@ export default class Card extends React.PureComponent {
|
||||||
card: ImmutablePropTypes.map,
|
card: ImmutablePropTypes.map,
|
||||||
onOpenMedia: PropTypes.func.isRequired,
|
onOpenMedia: PropTypes.func.isRequired,
|
||||||
compact: PropTypes.bool,
|
compact: PropTypes.bool,
|
||||||
defaultWidth: PropTypes.number,
|
|
||||||
cacheWidth: PropTypes.func,
|
|
||||||
sensitive: PropTypes.bool,
|
sensitive: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +52,6 @@ export default class Card extends React.PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
width: this.props.defaultWidth || 280,
|
|
||||||
previewLoaded: false,
|
previewLoaded: false,
|
||||||
embedded: false,
|
embedded: false,
|
||||||
revealed: !this.props.sensitive,
|
revealed: !this.props.sensitive,
|
||||||
|
@ -78,24 +74,6 @@ export default class Card extends React.PureComponent {
|
||||||
window.removeEventListener('resize', this.handleResize);
|
window.removeEventListener('resize', this.handleResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setDimensions () {
|
|
||||||
const width = this.node.offsetWidth;
|
|
||||||
|
|
||||||
if (this.props.cacheWidth) {
|
|
||||||
this.props.cacheWidth(width);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ width });
|
|
||||||
}
|
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
|
||||||
if (this.node) {
|
|
||||||
this._setDimensions();
|
|
||||||
}
|
|
||||||
}, 250, {
|
|
||||||
trailing: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
handlePhotoClick = () => {
|
handlePhotoClick = () => {
|
||||||
const { card, onOpenMedia } = this.props;
|
const { card, onOpenMedia } = this.props;
|
||||||
|
|
||||||
|
@ -129,10 +107,6 @@ export default class Card extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
|
|
||||||
if (this.node) {
|
|
||||||
this._setDimensions();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
handleImageLoad = () => {
|
handleImageLoad = () => {
|
||||||
|
@ -148,36 +122,31 @@ export default class Card extends React.PureComponent {
|
||||||
renderVideo () {
|
renderVideo () {
|
||||||
const { card } = this.props;
|
const { card } = this.props;
|
||||||
const content = { __html: addAutoPlay(card.get('html')) };
|
const content = { __html: addAutoPlay(card.get('html')) };
|
||||||
const { width } = this.state;
|
|
||||||
const ratio = card.get('width') / card.get('height');
|
|
||||||
const height = width / ratio;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={this.setRef}
|
ref={this.setRef}
|
||||||
className='status-card__image status-card-video'
|
className='status-card__image status-card-video'
|
||||||
dangerouslySetInnerHTML={content}
|
dangerouslySetInnerHTML={content}
|
||||||
style={{ height }}
|
style={{ aspectRatio: `${card.get('width')} / ${card.get('height')}` }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { card, compact } = this.props;
|
const { card, compact } = this.props;
|
||||||
const { width, embedded, revealed } = this.state;
|
const { embedded, revealed } = this.state;
|
||||||
|
|
||||||
if (card === null) {
|
if (card === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
|
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name');
|
||||||
const horizontal = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
|
const horizontal = (!compact && card.get('width') > card.get('height')) || card.get('type') !== 'link' || embedded;
|
||||||
const interactive = card.get('type') !== 'link';
|
const interactive = card.get('type') !== 'link';
|
||||||
const className = classnames('status-card', { horizontal, compact, interactive });
|
const className = classnames('status-card', { horizontal, compact, interactive });
|
||||||
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
const title = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
|
||||||
const language = card.get('language') || '';
|
const language = card.get('language') || '';
|
||||||
const ratio = card.get('width') / card.get('height');
|
|
||||||
const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
|
|
||||||
|
|
||||||
const description = (
|
const description = (
|
||||||
<div className='status-card__content' lang={language}>
|
<div className='status-card__content' lang={language}>
|
||||||
|
@ -187,6 +156,14 @@ export default class Card extends React.PureComponent {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const thumbnailStyle = {
|
||||||
|
visibility: revealed? null : 'hidden',
|
||||||
|
};
|
||||||
|
|
||||||
|
if (horizontal) {
|
||||||
|
thumbnailStyle.aspectRatio = (compact && !embedded) ? '16 / 9' : `${card.get('width')} / ${card.get('height')}`;
|
||||||
|
}
|
||||||
|
|
||||||
let embed = '';
|
let embed = '';
|
||||||
let canvas = (
|
let canvas = (
|
||||||
<Blurhash
|
<Blurhash
|
||||||
|
@ -197,7 +174,7 @@ export default class Card extends React.PureComponent {
|
||||||
dummy={!useBlurhash}
|
dummy={!useBlurhash}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
let thumbnail = <img src={card.get('image')} alt='' style={{ width: horizontal ? width : null, height: horizontal ? height : null, visibility: revealed ? null : 'hidden' }} onLoad={this.handleImageLoad} className='status-card__image-image' />;
|
let thumbnail = <img src={card.get('image')} alt='' style={thumbnailStyle} onLoad={this.handleImageLoad} className='status-card__image-image' />;
|
||||||
let spoilerButton = (
|
let spoilerButton = (
|
||||||
<button type='button' onClick={this.handleReveal} className='spoiler-button__overlay'>
|
<button type='button' onClick={this.handleReveal} className='spoiler-button__overlay'>
|
||||||
<span className='spoiler-button__overlay__label'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
<span className='spoiler-button__overlay__label'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span>
|
||||||
|
|
|
@ -2,7 +2,7 @@ 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 { is } from 'immutable';
|
import { is } from 'immutable';
|
||||||
import { throttle, debounce } from 'lodash';
|
import { throttle } from 'lodash';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
|
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
|
||||||
import { displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
import { displayMedia, useBlurhash } from 'flavours/glitch/initial_state';
|
||||||
|
@ -102,8 +102,6 @@ class Video extends React.PureComponent {
|
||||||
src: PropTypes.string.isRequired,
|
src: PropTypes.string.isRequired,
|
||||||
alt: PropTypes.string,
|
alt: PropTypes.string,
|
||||||
lang: PropTypes.string,
|
lang: PropTypes.string,
|
||||||
width: PropTypes.number,
|
|
||||||
height: PropTypes.number,
|
|
||||||
sensitive: PropTypes.bool,
|
sensitive: PropTypes.bool,
|
||||||
currentTime: PropTypes.number,
|
currentTime: PropTypes.number,
|
||||||
onOpenVideo: PropTypes.func,
|
onOpenVideo: PropTypes.func,
|
||||||
|
@ -112,7 +110,6 @@ class Video extends React.PureComponent {
|
||||||
inline: PropTypes.bool,
|
inline: PropTypes.bool,
|
||||||
editable: PropTypes.bool,
|
editable: PropTypes.bool,
|
||||||
alwaysVisible: PropTypes.bool,
|
alwaysVisible: PropTypes.bool,
|
||||||
cacheWidth: PropTypes.func,
|
|
||||||
visible: PropTypes.bool,
|
visible: PropTypes.bool,
|
||||||
letterbox: PropTypes.bool,
|
letterbox: PropTypes.bool,
|
||||||
fullwidth: PropTypes.bool,
|
fullwidth: PropTypes.bool,
|
||||||
|
@ -138,41 +135,16 @@ class Video extends React.PureComponent {
|
||||||
volume: 0.5,
|
volume: 0.5,
|
||||||
paused: true,
|
paused: true,
|
||||||
dragging: false,
|
dragging: false,
|
||||||
containerWidth: this.props.width,
|
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
hovered: false,
|
hovered: false,
|
||||||
muted: false,
|
muted: false,
|
||||||
revealed: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
|
revealed: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
|
||||||
};
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
|
||||||
if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
|
|
||||||
this.setState({ revealed: nextProps.visible });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setPlayerRef = c => {
|
setPlayerRef = c => {
|
||||||
this.player = c;
|
this.player = c;
|
||||||
|
|
||||||
if (this.player) {
|
|
||||||
this._setDimensions();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_setDimensions () {
|
|
||||||
const width = this.player.offsetWidth;
|
|
||||||
|
|
||||||
if (width && width !== this.state.containerWidth) {
|
|
||||||
if (this.props.cacheWidth) {
|
|
||||||
this.props.cacheWidth(width);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
containerWidth: width,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setVideoRef = c => {
|
setVideoRef = c => {
|
||||||
this.video = c;
|
this.video = c;
|
||||||
|
|
||||||
|
@ -381,12 +353,10 @@ class Video extends React.PureComponent {
|
||||||
document.addEventListener('MSFullscreenChange', this.handleFullscreenChange, true);
|
document.addEventListener('MSFullscreenChange', this.handleFullscreenChange, true);
|
||||||
|
|
||||||
window.addEventListener('scroll', this.handleScroll);
|
window.addEventListener('scroll', this.handleScroll);
|
||||||
window.addEventListener('resize', this.handleResize, { passive: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
window.removeEventListener('scroll', this.handleScroll);
|
window.removeEventListener('scroll', this.handleScroll);
|
||||||
window.removeEventListener('resize', this.handleResize);
|
|
||||||
|
|
||||||
document.removeEventListener('fullscreenchange', this.handleFullscreenChange, true);
|
document.removeEventListener('fullscreenchange', this.handleFullscreenChange, true);
|
||||||
document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange, true);
|
document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange, true);
|
||||||
|
@ -403,26 +373,18 @@ class Video extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
if (this.player && this.player.offsetWidth && this.player.offsetWidth !== this.state.containerWidth && !this.state.fullscreen) {
|
if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
|
||||||
if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
|
this.setState({ revealed: nextProps.visible });
|
||||||
this.setState({
|
|
||||||
containerWidth: this.player.offsetWidth,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate (prevProps) {
|
||||||
if (this.video && this.state.revealed && this.props.preventPlayback && !prevProps.preventPlayback) {
|
if (this.video && this.state.revealed && this.props.preventPlayback && !prevProps.preventPlayback) {
|
||||||
this.video.pause();
|
this.video.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
|
||||||
if (this.player) {
|
|
||||||
this._setDimensions();
|
|
||||||
}
|
|
||||||
}, 250, {
|
|
||||||
trailing: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
handleScroll = throttle(() => {
|
handleScroll = throttle(() => {
|
||||||
if (!this.video) {
|
if (!this.video) {
|
||||||
return;
|
return;
|
||||||
|
@ -540,21 +502,12 @@ class Video extends React.PureComponent {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, lang, letterbox, fullwidth, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
|
const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, lang, letterbox, fullwidth, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
|
||||||
const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
|
const { currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
|
||||||
const progress = Math.min((currentTime / duration) * 100, 100);
|
const progress = Math.min((currentTime / duration) * 100, 100);
|
||||||
const playerStyle = {};
|
const playerStyle = {};
|
||||||
|
|
||||||
const computedClass = classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen, editable, letterbox, 'full-width': fullwidth });
|
if (inline) {
|
||||||
|
playerStyle.aspectRatio = '16 / 9';
|
||||||
let { width, height } = this.props;
|
|
||||||
|
|
||||||
if (inline && containerWidth) {
|
|
||||||
width = containerWidth;
|
|
||||||
height = containerWidth / (16/9);
|
|
||||||
|
|
||||||
playerStyle.height = height;
|
|
||||||
} else if (inline) {
|
|
||||||
return (<div className={computedClass} ref={this.setPlayerRef} tabIndex={0} />);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let preload;
|
let preload;
|
||||||
|
@ -578,7 +531,7 @@ class Video extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
className={computedClass}
|
className={classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen, editable, letterbox, 'full-width': fullwidth })}
|
||||||
style={playerStyle}
|
style={playerStyle}
|
||||||
ref={this.setPlayerRef}
|
ref={this.setPlayerRef}
|
||||||
onMouseEnter={this.handleMouseEnter}
|
onMouseEnter={this.handleMouseEnter}
|
||||||
|
@ -605,8 +558,6 @@ class Video extends React.PureComponent {
|
||||||
aria-label={alt}
|
aria-label={alt}
|
||||||
title={alt}
|
title={alt}
|
||||||
lang={lang}
|
lang={lang}
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
volume={volume}
|
volume={volume}
|
||||||
onClick={this.togglePlay}
|
onClick={this.togglePlay}
|
||||||
onKeyDown={this.handleVideoKeyDown}
|
onKeyDown={this.handleVideoKeyDown}
|
||||||
|
@ -615,6 +566,7 @@ class Video extends React.PureComponent {
|
||||||
onLoadedData={this.handleLoadedData}
|
onLoadedData={this.handleLoadedData}
|
||||||
onProgress={this.handleProgress}
|
onProgress={this.handleProgress}
|
||||||
onVolumeChange={this.handleVolumeChange}
|
onVolumeChange={this.handleVolumeChange}
|
||||||
|
style={{ ...playerStyle, width: '100%' }}
|
||||||
/>}
|
/>}
|
||||||
|
|
||||||
<div className={classNames('spoiler-button', { 'spoiler-button--hidden': revealed || editable })}>
|
<div className={classNames('spoiler-button', { 'spoiler-button--hidden': revealed || editable })}>
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
margin-right: -14px;
|
margin-right: -14px;
|
||||||
width: inherit;
|
width: inherit;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
height: 250px;
|
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -808,6 +808,10 @@ a.status-card {
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-card-video {
|
.status-card-video {
|
||||||
|
// Firefox has a bug where frameborder=0 iframes add some extra blank space
|
||||||
|
// see https://bugzilla.mozilla.org/show_bug.cgi?id=155174
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
iframe {
|
iframe {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -1153,6 +1157,7 @@ a.status-card.compact:hover {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: $darker-text-color;
|
color: $darker-text-color;
|
||||||
|
aspect-ratio: 16 / 9;
|
||||||
|
|
||||||
i {
|
i {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
Loading…
Reference in New Issue