commit: 036dd98abb1fe6ae1d25ff0f3ecffe4dd9a79ea3
parent: 7901f9f63e156732ab10154c34f3c2d188471a9d
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Fri, 2 Mar 2018 07:00:04 +0100
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
Diffstat:
7 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
@@ -283,8 +283,9 @@ export default class MediaGallery extends React.PureComponent {
if (width) {
style.height = width / this.props.media.getIn([0, 'meta', 'small', 'aspect']);
}
+ } else if (width) {
+ style.height = width / (16/9);
} else {
- // crop the image
style.height = height;
}
@@ -309,7 +310,7 @@ export default class MediaGallery extends React.PureComponent {
if (this.isStandaloneEligible()) {
children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} />;
} 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} />);
}
}
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
@@ -184,6 +184,7 @@ export default class Status extends ImmutablePureComponent {
src={video.get('url')}
width={239}
height={110}
+ inline
sensitive={status.get('sensitive')}
onOpenVideo={this.handleOpenVideo}
/>
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -57,6 +57,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
src={video.get('url')}
width={300}
height={150}
+ inline
onOpenVideo={this.handleOpenVideo}
sensitive={status.get('sensitive')}
/>
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
@@ -97,6 +97,7 @@ export default class Video extends React.PureComponent {
onOpenVideo: PropTypes.func,
onCloseVideo: PropTypes.func,
detailed: PropTypes.bool,
+ inline: PropTypes.bool,
intl: PropTypes.object.isRequired,
};
@@ -105,6 +106,7 @@ export default class Video extends React.PureComponent {
duration: 0,
paused: true,
dragging: false,
+ containerWidth: false,
fullscreen: false,
hovered: false,
muted: false,
@@ -113,6 +115,12 @@ export default class Video extends React.PureComponent {
setPlayerRef = c => {
this.player = c;
+
+ if (c) {
+ this.setState({
+ containerWidth: c.offsetWidth,
+ });
+ }
}
setVideoRef = c => {
@@ -246,12 +254,23 @@ export default class Video extends React.PureComponent {
}
render () {
- const { preview, src, width, height, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props;
- const { currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
+ const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, detailed } = this.props;
+ const { containerWidth, currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
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 (
- <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
ref={this.setVideoRef}
src={src}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
@@ -4365,7 +4365,7 @@ a.status-card {
&.inline {
video {
- object-fit: cover;
+ object-fit: contain;
position: relative;
top: 50%;
transform: translateY(-50%);
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
@@ -22,7 +22,7 @@
- if !status.media_attachments.empty?
- if status.media_attachments.first.video?
- 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
%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
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
@@ -23,6 +23,6 @@
- unless status.media_attachments.empty?
- if status.media_attachments.first.video?
- 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
%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 }) }}