Add support for standard GIFs (under 200 KB)
parent
cd042a4ee3
commit
2cc2089534
|
@ -58,6 +58,9 @@ class Item extends React.PureComponent {
|
||||||
handleMouseEnter = (e) => {
|
handleMouseEnter = (e) => {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.play();
|
e.target.play();
|
||||||
|
} else if (this.hoverToPlayClassicGif()) {
|
||||||
|
const { attachment } = this.props;
|
||||||
|
e.target.src = attachment.get('url');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +68,9 @@ class Item extends React.PureComponent {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.pause();
|
e.target.pause();
|
||||||
e.target.currentTime = 0;
|
e.target.currentTime = 0;
|
||||||
|
} else if (this.hoverToPlayClassicGif()) {
|
||||||
|
const { attachment } = this.props;
|
||||||
|
e.target.src = attachment.get('preview_url');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +79,14 @@ class Item extends React.PureComponent {
|
||||||
return !autoPlayGif && attachment.get('type') === 'gifv';
|
return !autoPlayGif && attachment.get('type') === 'gifv';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hoverToPlayClassicGif () {
|
||||||
|
const { attachment } = this.props;
|
||||||
|
return !autoPlayGif && (
|
||||||
|
attachment.get('type') === 'image' &&
|
||||||
|
attachment.get('url').split('.').pop().startsWith('gif')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
handleClick = (e) => {
|
handleClick = (e) => {
|
||||||
const { index, onClick } = this.props;
|
const { index, onClick } = this.props;
|
||||||
|
|
||||||
|
@ -80,6 +94,9 @@ class Item extends React.PureComponent {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.pause();
|
e.target.pause();
|
||||||
e.target.currentTime = 0;
|
e.target.currentTime = 0;
|
||||||
|
} else if (this.hoverToPlayClassicGif()) {
|
||||||
|
const { attachment } = this.props;
|
||||||
|
e.target.src = attachment.get('preview_url');
|
||||||
}
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onClick(index);
|
onClick(index);
|
||||||
|
@ -199,25 +216,54 @@ class Item extends React.PureComponent {
|
||||||
const x = ((focusX / 2) + .5) * 100;
|
const x = ((focusX / 2) + .5) * 100;
|
||||||
const y = ((focusY / -2) + .5) * 100;
|
const y = ((focusY / -2) + .5) * 100;
|
||||||
|
|
||||||
thumbnail = (
|
const isGif = originalUrl.split('.').pop().startsWith('gif');
|
||||||
<a
|
const autoPlay = !isIOS() && autoPlayGif;
|
||||||
className='media-gallery__item-thumbnail'
|
|
||||||
href={attachment.get('remote_url') || originalUrl}
|
if (isGif && !autoPlay) {
|
||||||
onClick={this.handleClick}
|
thumbnail = (
|
||||||
target='_blank'
|
<a
|
||||||
>
|
className='media-gallery__item-thumbnail'
|
||||||
<img
|
href={attachment.get('remote_url') || originalUrl}
|
||||||
className={letterbox ? 'letterbox' : null}
|
onClick={this.handleClick}
|
||||||
src={previewUrl}
|
target='_blank'
|
||||||
srcSet={srcSet}
|
>
|
||||||
sizes={sizes}
|
<img
|
||||||
alt={attachment.get('description')}
|
className={letterbox ? 'letterbox' : null}
|
||||||
title={attachment.get('description')}
|
src={previewUrl}
|
||||||
style={{ objectPosition: letterbox ? null : `${x}% ${y}%` }}
|
sizes={sizes}
|
||||||
onLoad={this.handleImageLoad}
|
alt={attachment.get('description')}
|
||||||
/>
|
title={attachment.get('description')}
|
||||||
</a>
|
style={{ objectPosition: letterbox ? null : `${x}% ${y}%` }}
|
||||||
);
|
onMouseEnter={this.handleMouseEnter}
|
||||||
|
onMouseLeave={this.handleMouseLeave}
|
||||||
|
onMouseDown={this.handleMouseDown}
|
||||||
|
onLoad={this.handleImageLoad}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span className='media-gallery__gifv__label'>GIF</span>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
thumbnail = (
|
||||||
|
<a
|
||||||
|
className='media-gallery__item-thumbnail'
|
||||||
|
href={attachment.get('remote_url') || originalUrl}
|
||||||
|
onClick={this.handleClick}
|
||||||
|
target='_blank'
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
className={letterbox ? 'letterbox' : null}
|
||||||
|
src={previewUrl}
|
||||||
|
srcSet={srcSet}
|
||||||
|
sizes={sizes}
|
||||||
|
alt={attachment.get('description')}
|
||||||
|
title={attachment.get('description')}
|
||||||
|
style={{ objectPosition: letterbox ? null : `${x}% ${y}%` }}
|
||||||
|
onLoad={this.handleImageLoad}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
} else if (attachment.get('type') === 'gifv') {
|
} else if (attachment.get('type') === 'gifv') {
|
||||||
const autoPlay = !isIOS() && autoPlayGif;
|
const autoPlay = !isIOS() && autoPlayGif;
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,12 @@ class MediaAttachment < ApplicationRecord
|
||||||
},
|
},
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
|
GIF_THUMB_FORMAT = {
|
||||||
|
format: 'png',
|
||||||
|
pixels: 160_000, # 400x400px
|
||||||
|
file_geometry_parser: FastGeometryParser,
|
||||||
|
}.freeze
|
||||||
|
|
||||||
AUDIO_STYLES = {
|
AUDIO_STYLES = {
|
||||||
small: {
|
small: {
|
||||||
format: 'png',
|
format: 'png',
|
||||||
|
@ -121,6 +127,7 @@ class MediaAttachment < ApplicationRecord
|
||||||
|
|
||||||
IMAGE_LIMIT = 8.megabytes
|
IMAGE_LIMIT = 8.megabytes
|
||||||
VIDEO_LIMIT = 40.megabytes
|
VIDEO_LIMIT = 40.megabytes
|
||||||
|
GIF_LIMIT = ENV.fetch('MAX_GIF_SIZE', 200).to_i.kilobytes
|
||||||
|
|
||||||
belongs_to :account, inverse_of: :media_attachments, optional: true
|
belongs_to :account, inverse_of: :media_attachments, optional: true
|
||||||
belongs_to :status, inverse_of: :media_attachments, optional: true
|
belongs_to :status, inverse_of: :media_attachments, optional: true
|
||||||
|
@ -193,10 +200,17 @@ class MediaAttachment < ApplicationRecord
|
||||||
|
|
||||||
def file_styles(f)
|
def file_styles(f)
|
||||||
if f.instance.file_content_type == 'image/gif'
|
if f.instance.file_content_type == 'image/gif'
|
||||||
{
|
if f.instance.file_file_size > GIF_LIMIT
|
||||||
small: IMAGE_STYLES[:small],
|
{
|
||||||
original: VIDEO_FORMAT,
|
small: IMAGE_STYLES[:small],
|
||||||
}
|
original: VIDEO_FORMAT,
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
small: GIF_THUMB_FORMAT,
|
||||||
|
original: IMAGE_STYLES[:original],
|
||||||
|
}
|
||||||
|
end
|
||||||
elsif IMAGE_MIME_TYPES.include? f.instance.file_content_type
|
elsif IMAGE_MIME_TYPES.include? f.instance.file_content_type
|
||||||
IMAGE_STYLES
|
IMAGE_STYLES
|
||||||
elsif AUDIO_CONVERTIBLE_MIME_TYPES.include?(f.instance.file_content_type)
|
elsif AUDIO_CONVERTIBLE_MIME_TYPES.include?(f.instance.file_content_type)
|
||||||
|
@ -218,7 +232,11 @@ class MediaAttachment < ApplicationRecord
|
||||||
|
|
||||||
def file_processors(f)
|
def file_processors(f)
|
||||||
if f.file_content_type == 'image/gif'
|
if f.file_content_type == 'image/gif'
|
||||||
[:gif_transcoder, :blurhash_transcoder]
|
if f.file_file_size > GIF_LIMIT
|
||||||
|
[:gif_transcoder, :blurhash_transcoder]
|
||||||
|
else
|
||||||
|
[:lazy_thumbnail, :blurhash_transcoder]
|
||||||
|
end
|
||||||
elsif VIDEO_MIME_TYPES.include? f.file_content_type
|
elsif VIDEO_MIME_TYPES.include? f.file_content_type
|
||||||
[:video_transcoder, :blurhash_transcoder]
|
[:video_transcoder, :blurhash_transcoder]
|
||||||
elsif AUDIO_MIME_TYPES.include? f.file_content_type
|
elsif AUDIO_MIME_TYPES.include? f.file_content_type
|
||||||
|
|
|
@ -20,7 +20,7 @@ module Paperclip
|
||||||
private
|
private
|
||||||
|
|
||||||
def needs_convert?
|
def needs_convert?
|
||||||
needs_different_geometry? || needs_different_format? || needs_metadata_stripping?
|
options[:force_convert] == true || needs_different_geometry? || needs_different_format? || needs_metadata_stripping?
|
||||||
end
|
end
|
||||||
|
|
||||||
def needs_different_geometry?
|
def needs_different_geometry?
|
||||||
|
|
Loading…
Reference in New Issue