Use StillImage on media items and fix autoPlayGif on account gallery

This commit is contained in:
Bárbara de Castro Fernandes 2020-06-09 18:24:31 -03:00
parent 2da584b5ee
commit e19f350111
3 changed files with 41 additions and 79 deletions

View File

@ -11,6 +11,7 @@ import { decode } from 'blurhash';
import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media_aspect_ratio'; import { isPanoramic, isPortrait, isNonConformingRatio, minimumAspectRatio, maximumAspectRatio } from '../utils/media_aspect_ratio';
import { Map as ImmutableMap } from 'immutable'; import { Map as ImmutableMap } from 'immutable';
import { getSettings } from 'soapbox/actions/settings'; import { getSettings } from 'soapbox/actions/settings';
import StillImage from 'soapbox/components/still_image';
const messages = defineMessages({ const messages = defineMessages({
toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' }, toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },
@ -60,8 +61,7 @@ class Item extends React.PureComponent {
hoverToPlay() { hoverToPlay() {
const { attachment, autoPlayGif } = this.props; const { attachment, autoPlayGif } = this.props;
return !autoPlayGif && return !autoPlayGif && attachment.get('type') === 'gifv';
(attachment.get('type') === 'gifv' || attachment.getIn(['pleroma', 'mime_type']) === 'image/gif');
} }
handleClick = (e) => { handleClick = (e) => {
@ -72,7 +72,7 @@ class Item extends React.PureComponent {
e.preventDefault(); e.preventDefault();
} else { } else {
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (!this.canvas && this.hoverToPlay()) { if (this.hoverToPlay()) {
e.target.pause(); e.target.pause();
e.target.currentTime = 0; e.target.currentTime = 0;
} }
@ -112,23 +112,12 @@ class Item extends React.PureComponent {
this.canvas = c; this.canvas = c;
} }
setImageRef = i => {
this.image = i;
}
handleImageLoad = () => { handleImageLoad = () => {
this.setState({ loaded: true }); this.setState({ loaded: true });
if (this.hoverToPlay()) {
const image = this.image;
const canvas = this.canvas;
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
canvas.getContext('2d').drawImage(image, 0, 0);
}
} }
render() { render() {
const { attachment, standalone, displayWidth, visible, dimensions, autoPlayGif } = this.props; const { attachment, standalone, visible, dimensions, autoPlayGif } = this.props;
let width = 100; let width = 100;
let height = '100%'; let height = '100%';
@ -162,39 +151,17 @@ class Item extends React.PureComponent {
); );
} else if (attachment.get('type') === 'image') { } else if (attachment.get('type') === 'image') {
const previewUrl = attachment.get('preview_url'); const previewUrl = attachment.get('preview_url');
const previewWidth = attachment.getIn(['meta', 'small', 'width']);
const originalUrl = attachment.get('url'); const originalUrl = attachment.get('url');
const originalWidth = attachment.getIn(['meta', 'original', 'width']);
const hasSize = typeof originalWidth === 'number' && typeof previewWidth === 'number';
const srcSet = hasSize ? `${originalUrl} ${originalWidth}w, ${previewUrl} ${previewWidth}w` : null;
const sizes = hasSize && (displayWidth > 0) ? `${displayWidth * (width / 100)}px` : null;
const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100;
thumbnail = ( thumbnail = (
<a <a
className={classNames('media-gallery__item-thumbnail', { 'media-gallery__item-thumbnail--play-on-hover': this.hoverToPlay() })} className='media-gallery__item-thumbnail'
href={attachment.get('remote_url') || originalUrl} href={attachment.get('remote_url') || originalUrl}
onClick={this.handleClick} onClick={this.handleClick}
target='_blank' target='_blank'
> >
<img <StillImage src={previewUrl} alt={attachment.get('description')} />
src={previewUrl}
srcSet={srcSet}
sizes={sizes}
alt={attachment.get('description')}
title={attachment.get('description')}
style={{ objectPosition: `${x}% ${y}%` }}
onLoad={this.handleImageLoad}
ref={this.setImageRef}
/>
{this.hoverToPlay() && <canvas ref={this.setCanvasRef} style={{ objectPosition: `${x}% ${y}%` }} />}
</a> </a>
); );
} else if (attachment.get('type') === 'gifv') { } else if (attachment.get('type') === 'gifv') {

View File

@ -8,6 +8,7 @@ import classNames from 'classnames';
import { decode } from 'blurhash'; import { decode } from 'blurhash';
import { isIOS } from 'soapbox/is_mobile'; import { isIOS } from 'soapbox/is_mobile';
import { getSettings } from 'soapbox/actions/settings'; import { getSettings } from 'soapbox/actions/settings';
import StillImage from 'soapbox/components/still_image';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
autoPlayGif: getSettings(state).get('autoPlayGif'), autoPlayGif: getSettings(state).get('autoPlayGif'),
@ -113,12 +114,10 @@ class MediaItem extends ImmutablePureComponent {
const y = ((focusY / -2) + .5) * 100; const y = ((focusY / -2) + .5) * 100;
thumbnail = ( thumbnail = (
<img <StillImage
src={attachment.get('preview_url')} src={attachment.get('preview_url')}
alt={attachment.get('description')} alt={attachment.get('description')}
title={attachment.get('description')}
style={{ objectPosition: `${x}% ${y}%` }} style={{ objectPosition: `${x}% ${y}%` }}
onLoad={this.handleImageLoad}
/> />
); );
} else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) { } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {

View File

@ -28,47 +28,26 @@
z-index: 1; z-index: 1;
&, &,
img, .still-image {
canvas {
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
img, .still-image--play-on-hover::before {
canvas { content: 'GIF';
object-fit: cover; position: absolute;
} color: var(--primary-text-color);
background: var(--foreground-color);
&--play-on-hover { bottom: 6px;
&::before { left: 6px;
content: 'GIF'; padding: 2px 6px;
position: absolute; border-radius: 2px;
color: var(--primary-text-color); font-size: 11px;
background: var(--foreground-color); font-weight: 600;
bottom: 6px; pointer-events: none;
left: 6px; opacity: 0.9;
padding: 2px 6px; transition: opacity 0.1s ease;
border-radius: 2px; line-height: 18px;
font-size: 11px;
font-weight: 600;
pointer-events: none;
opacity: 0.9;
transition: opacity 0.1s ease;
line-height: 18px;
}
img {
position: absolute;
}
img,
&:hover::before {
visibility: hidden;
}
&:hover img {
visibility: visible;
}
} }
} }
@ -82,6 +61,23 @@
z-index: 0; z-index: 0;
background: var(--background-color); background: var(--background-color);
.still-image--play-on-hover::before {
content: 'GIF';
position: absolute;
color: var(--primary-text-color);
background: var(--foreground-color);
bottom: 6px;
left: 6px;
padding: 2px 6px;
border-radius: 2px;
font-size: 11px;
font-weight: 600;
pointer-events: none;
opacity: 0.9;
transition: opacity 0.1s ease;
line-height: 18px;
}
&--hidden { &--hidden {
display: none; display: none;
} }