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:
		
							parent
							
								
									7901f9f63e
								
							
						
					
					
						commit
						036dd98abb
					
				
					 7 changed files with 30 additions and 8 deletions
				
			
		| 
						 | 
					@ -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} />);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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}
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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')}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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%);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 }) }}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue