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
local
Eugen Rochko 6 years ago committed by GitHub
parent 7901f9f63e
commit 036dd98abb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      app/javascript/mastodon/components/media_gallery.js
  2. 1
      app/javascript/mastodon/components/status.js
  3. 1
      app/javascript/mastodon/features/status/components/detailed_status.js
  4. 25
      app/javascript/mastodon/features/video/index.js
  5. 2
      app/javascript/styles/mastodon/components.scss
  6. 2
      app/views/stream_entries/_detailed_status.html.haml
  7. 2
      app/views/stream_entries/_simple_status.html.haml

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

@ -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}
/>

@ -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')}
/>

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

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

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

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

Loading…
Cancel
Save