Responsively enforce 16:9 ratio on all media thumbnails in web UI (#6590)

* Responsively enforce 16:9 ratio on all media thumbnails in web UI

Also change video player behaviour to "contain" rather than
"cover" videos that don't fit the ratio, unlike images and GIFs,
it's expected that a video is shown fully.

* Fix spacing issues and remove floor

* Remove floor
This commit is contained in:
Eugen Rochko 2018-03-02 07:00:04 +01:00 committed by GitHub
parent a91ef56e80
commit 8c85fd26bb
7 changed files with 30 additions and 8 deletions

View file

@ -283,8 +283,9 @@ export default class MediaGallery extends React.PureComponent {
if (width) { if (width) {
style.height = width / this.props.media.getIn([0, 'meta', 'small', 'aspect']); style.height = width / this.props.media.getIn([0, 'meta', 'small', 'aspect']);
} }
} else if (width) {
style.height = width / (16/9);
} else { } else {
// crop the image
style.height = height; style.height = height;
} }
@ -309,7 +310,7 @@ export default class MediaGallery extends React.PureComponent {
if (this.isStandaloneEligible()) { if (this.isStandaloneEligible()) {
children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} />; children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} />;
} else { } else {
children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} containerWidth={width} containerHeight={height} />); children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} containerWidth={width} containerHeight={style.height} />);
} }
} }

View file

@ -184,6 +184,7 @@ export default class Status extends ImmutablePureComponent {
src={video.get('url')} src={video.get('url')}
width={239} width={239}
height={110} height={110}
inline
sensitive={status.get('sensitive')} sensitive={status.get('sensitive')}
onOpenVideo={this.handleOpenVideo} onOpenVideo={this.handleOpenVideo}
/> />

View file

@ -57,6 +57,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
src={video.get('url')} src={video.get('url')}
width={300} width={300}
height={150} height={150}
inline
onOpenVideo={this.handleOpenVideo} onOpenVideo={this.handleOpenVideo}
sensitive={status.get('sensitive')} sensitive={status.get('sensitive')}
/> />

View file

@ -97,6 +97,7 @@ export default class Video extends React.PureComponent {
onOpenVideo: PropTypes.func, onOpenVideo: PropTypes.func,
onCloseVideo: PropTypes.func, onCloseVideo: PropTypes.func,
detailed: PropTypes.bool, detailed: PropTypes.bool,
inline: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
@ -105,6 +106,7 @@ export default class Video extends React.PureComponent {
duration: 0, duration: 0,
paused: true, paused: true,
dragging: false, dragging: false,
containerWidth: false,
fullscreen: false, fullscreen: false,
hovered: false, hovered: false,
muted: false, muted: false,
@ -113,6 +115,12 @@ export default class Video extends React.PureComponent {
setPlayerRef = c => { setPlayerRef = c => {
this.player = c; this.player = c;
if (c) {
this.setState({
containerWidth: c.offsetWidth,
});
}
} }
setVideoRef = c => { setVideoRef = c => {
@ -246,12 +254,23 @@ export default class Video extends React.PureComponent {
} }
render () { render () {
const { preview, src, width, height, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props; const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props;
const { currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; const { containerWidth, currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
const progress = (currentTime / duration) * 100; const progress = (currentTime / duration) * 100;
const playerStyle = {};
let { width, height } = this.props;
if (inline && containerWidth) {
width = containerWidth;
height = containerWidth / (16/9);
playerStyle.width = width;
playerStyle.height = height;
}
return ( return (
<div className={classNames('video-player', { inactive: !revealed, detailed, inline: width && height && !fullscreen, fullscreen })} style={{ width, height }} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> <div className={classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen })} style={playerStyle} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
<video <video
ref={this.setVideoRef} ref={this.setVideoRef}
src={src} src={src}

View file

@ -4365,7 +4365,7 @@ a.status-card {
&.inline { &.inline {
video { video {
object-fit: cover; object-fit: contain;
position: relative; position: relative;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);

View file

@ -22,7 +22,7 @@
- if !status.media_attachments.empty? - if !status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first
%div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true) }} %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 670, height: 380, detailed: true, inline: true) }}
- else - else
%div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }} %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}
- elsif status.preview_cards.first - elsif status.preview_cards.first

View file

@ -23,6 +23,6 @@
- unless status.media_attachments.empty? - unless status.media_attachments.empty?
- if status.media_attachments.first.video? - if status.media_attachments.first.video?
- video = status.media_attachments.first - video = status.media_attachments.first
%div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343) }} %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true) }}
- else - else
%div{ data: { component: 'MediaGallery', props: Oj.dump(height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }} %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}