diff options
author | multiple creatures <dev@multiple-creature.party> | 2019-04-12 13:58:30 -0500 |
---|---|---|
committer | multiple creatures <dev@multiple-creature.party> | 2019-05-21 03:16:21 -0500 |
commit | 2cc20895349b2668be4f09beae1b92e8b2254079 (patch) | |
tree | 88644e8ffc4ecae2a5c8a1cc911ef5f6cecbb104 | |
parent | cd042a4ee30c46b117d74a182e14846a1d62540b (diff) |
Add support for standard GIFs (under 200 KB)
-rw-r--r-- | app/javascript/flavours/glitch/components/media_gallery.js | 84 | ||||
-rw-r--r-- | app/models/media_attachment.rb | 28 | ||||
-rw-r--r-- | lib/paperclip/lazy_thumbnail.rb | 2 |
3 files changed, 89 insertions, 25 deletions
diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index 3478766d2..62ef1da5e 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -58,6 +58,9 @@ class Item extends React.PureComponent { handleMouseEnter = (e) => { if (this.hoverToPlay()) { 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()) { e.target.pause(); 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'; } + hoverToPlayClassicGif () { + const { attachment } = this.props; + return !autoPlayGif && ( + attachment.get('type') === 'image' && + attachment.get('url').split('.').pop().startsWith('gif') + ); + } + handleClick = (e) => { const { index, onClick } = this.props; @@ -80,6 +94,9 @@ class Item extends React.PureComponent { if (this.hoverToPlay()) { e.target.pause(); e.target.currentTime = 0; + } else if (this.hoverToPlayClassicGif()) { + const { attachment } = this.props; + e.target.src = attachment.get('preview_url'); } e.preventDefault(); onClick(index); @@ -199,25 +216,54 @@ class Item extends React.PureComponent { const x = ((focusX / 2) + .5) * 100; const y = ((focusY / -2) + .5) * 100; - 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> - ); + const isGif = originalUrl.split('.').pop().startsWith('gif'); + const autoPlay = !isIOS() && autoPlayGif; + + if (isGif && !autoPlay) { + 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} + sizes={sizes} + alt={attachment.get('description')} + title={attachment.get('description')} + 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') { const autoPlay = !isIOS() && autoPlayGif; diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 8d3a656ae..2bc81dc6f 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -54,6 +54,12 @@ class MediaAttachment < ApplicationRecord }, }.freeze + GIF_THUMB_FORMAT = { + format: 'png', + pixels: 160_000, # 400x400px + file_geometry_parser: FastGeometryParser, + }.freeze + AUDIO_STYLES = { small: { format: 'png', @@ -121,6 +127,7 @@ class MediaAttachment < ApplicationRecord IMAGE_LIMIT = 8.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 :status, inverse_of: :media_attachments, optional: true @@ -193,10 +200,17 @@ class MediaAttachment < ApplicationRecord def file_styles(f) if f.instance.file_content_type == 'image/gif' - { - small: IMAGE_STYLES[:small], - original: VIDEO_FORMAT, - } + if f.instance.file_file_size > GIF_LIMIT + { + 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 IMAGE_STYLES elsif AUDIO_CONVERTIBLE_MIME_TYPES.include?(f.instance.file_content_type) @@ -218,7 +232,11 @@ class MediaAttachment < ApplicationRecord def file_processors(f) 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 [:video_transcoder, :blurhash_transcoder] elsif AUDIO_MIME_TYPES.include? f.file_content_type diff --git a/lib/paperclip/lazy_thumbnail.rb b/lib/paperclip/lazy_thumbnail.rb index 542c17fb2..5992e76d8 100644 --- a/lib/paperclip/lazy_thumbnail.rb +++ b/lib/paperclip/lazy_thumbnail.rb @@ -20,7 +20,7 @@ module Paperclip private 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 def needs_different_geometry? |