Add image processing and generate blurhash for server thumbnail (#19348)
Remove separate server hero setting
This commit is contained in:
		| @@ -22,7 +22,6 @@ class Form::AdminSettings | ||||
|     custom_css | ||||
|     profile_directory | ||||
|     thumbnail | ||||
|     hero | ||||
|     mascot | ||||
|     trends | ||||
|     trendable_by_default | ||||
| @@ -49,7 +48,6 @@ class Form::AdminSettings | ||||
|  | ||||
|   UPLOAD_KEYS = %i( | ||||
|     thumbnail | ||||
|     hero | ||||
|     mascot | ||||
|   ).freeze | ||||
|  | ||||
|   | ||||
| @@ -12,10 +12,35 @@ | ||||
| #  meta              :json | ||||
| #  created_at        :datetime         not null | ||||
| #  updated_at        :datetime         not null | ||||
| #  blurhash          :string | ||||
| # | ||||
|  | ||||
| class SiteUpload < ApplicationRecord | ||||
|   has_attached_file :file | ||||
|   include Attachmentable | ||||
|  | ||||
|   STYLES = { | ||||
|     thumbnail: { | ||||
|       '@1x': { | ||||
|         format: 'png', | ||||
|         geometry: '1200x630#', | ||||
|         file_geometry_parser: FastGeometryParser, | ||||
|         blurhash: { | ||||
|           x_comp: 4, | ||||
|           y_comp: 4, | ||||
|         }.freeze, | ||||
|       }, | ||||
|  | ||||
|       '@2x': { | ||||
|         format: 'png', | ||||
|         geometry: '2400x1260#', | ||||
|         file_geometry_parser: FastGeometryParser, | ||||
|       }.freeze, | ||||
|     }.freeze, | ||||
|  | ||||
|     mascot: {}.freeze, | ||||
|   }.freeze | ||||
|  | ||||
|   has_attached_file :file, styles: ->(file) { STYLES[file.instance.var.to_sym] }, convert_options: { all: '-coalesce -strip' }, processors: [:lazy_thumbnail, :blurhash_transcoder, :type_corrector] | ||||
|  | ||||
|   validates_attachment_content_type :file, content_type: /\Aimage\/.*\z/ | ||||
|   validates :file, presence: true | ||||
|   | ||||
| @@ -84,10 +84,6 @@ class InstancePresenter < ActiveModelSerializers::Model | ||||
|     @thumbnail ||= Rails.cache.fetch('site_uploads/thumbnail') { SiteUpload.find_by(var: 'thumbnail') } | ||||
|   end | ||||
|  | ||||
|   def hero | ||||
|     @hero ||= Rails.cache.fetch('site_uploads/hero') { SiteUpload.find_by(var: 'hero') } | ||||
|   end | ||||
|  | ||||
|   def mascot | ||||
|     @mascot ||= Rails.cache.fetch('site_uploads/mascot') { SiteUpload.find_by(var: 'mascot') } | ||||
|   end | ||||
|   | ||||
| @@ -17,7 +17,20 @@ class REST::InstanceSerializer < ActiveModel::Serializer | ||||
|   has_many :rules, serializer: REST::RuleSerializer | ||||
|  | ||||
|   def thumbnail | ||||
|     object.thumbnail ? full_asset_url(object.thumbnail.file.url) : full_pack_url('media/images/preview.png') | ||||
|     if object.thumbnail | ||||
|       { | ||||
|         url: full_asset_url(object.thumbnail.file.url(:'@1x')), | ||||
|         blurhash: object.thumbnail.blurhash, | ||||
|         versions: { | ||||
|           '@1x': full_asset_url(object.thumbnail.file.url(:'@1x')), | ||||
|           '@2x': full_asset_url(object.thumbnail.file.url(:'@2x')), | ||||
|         }, | ||||
|       } | ||||
|     else | ||||
|       { | ||||
|         url: full_pack_url('media/images/preview.png'), | ||||
|       } | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def usage | ||||
|   | ||||
| @@ -33,7 +33,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer | ||||
|   end | ||||
|  | ||||
|   def thumbnail | ||||
|     instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url) : full_pack_url('media/images/preview.png') | ||||
|     instance_presenter.thumbnail ? full_asset_url(instance_presenter.thumbnail.file.url(:'@1x')) : full_pack_url('media/images/preview.png') | ||||
|   end | ||||
|  | ||||
|   def stats | ||||
|   | ||||
| @@ -34,8 +34,6 @@ | ||||
|   .fields-row | ||||
|     .fields-row__column.fields-row__column-6.fields-group | ||||
|       = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: site_upload_delete_hint(t('admin.settings.thumbnail.desc_html'), :thumbnail) | ||||
|     .fields-row__column.fields-row__column-6.fields-group | ||||
|       = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: site_upload_delete_hint(t('admin.settings.hero.desc_html'), :hero) | ||||
|  | ||||
|   .fields-row | ||||
|     .fields-row__column.fields-row__column-6.fields-group | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| .hero-widget | ||||
|   .hero-widget__img | ||||
|     = image_tag @instance_presenter.hero&.file&.url || @instance_presenter.thumbnail&.file&.url || asset_pack_path('media/images/preview.png'), alt: @instance_presenter.title | ||||
|     = image_tag @instance_presenter.thumbnail&.file&.url(:'@1x') || asset_pack_path('media/images/preview.png'), alt: @instance_presenter.title | ||||
|  | ||||
|   .hero-widget__text | ||||
|     %p= @instance_presenter.description.html_safe.presence || t('about.about_mastodon_html') | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| = opengraph 'og:type', 'website' | ||||
| = opengraph 'og:title', @instance_presenter.title | ||||
| = opengraph 'og:description', description | ||||
| = opengraph 'og:image', full_asset_url(thumbnail&.file&.url || asset_pack_path('media/images/preview.png', protocol: :request)) | ||||
| = opengraph 'og:image', full_asset_url(thumbnail&.file&.url(:'@1x') || asset_pack_path('media/images/preview.png', protocol: :request)) | ||||
| = opengraph 'og:image:width', thumbnail ? thumbnail.meta['width'] : '1200' | ||||
| = opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630' | ||||
| = opengraph 'twitter:card', 'summary_large_image' | ||||
|   | ||||
| @@ -735,9 +735,6 @@ en: | ||||
|         users: To logged-in local users | ||||
|       domain_blocks_rationale: | ||||
|         title: Show rationale | ||||
|       hero: | ||||
|         desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to server thumbnail | ||||
|         title: Hero image | ||||
|       mascot: | ||||
|         desc_html: Displayed on multiple pages. At least 293×205px recommended. When not set, falls back to default mascot | ||||
|         title: Mascot image | ||||
|   | ||||
| @@ -0,0 +1,5 @@ | ||||
| class AddBlurhashToSiteUploads < ActiveRecord::Migration[6.1] | ||||
|   def change | ||||
|     add_column :site_uploads, :blurhash, :string | ||||
|   end | ||||
| end | ||||
| @@ -10,7 +10,7 @@ | ||||
| # | ||||
| # It's strongly recommended that you check this file into your version control system. | ||||
|  | ||||
| ActiveRecord::Schema.define(version: 2022_10_06_061337) do | ||||
| ActiveRecord::Schema.define(version: 2022_10_12_181003) do | ||||
|  | ||||
|   # These are extensions that must be enabled in order to support this database | ||||
|   enable_extension "plpgsql" | ||||
| @@ -866,6 +866,7 @@ ActiveRecord::Schema.define(version: 2022_10_06_061337) do | ||||
|     t.json "meta" | ||||
|     t.datetime "created_at", null: false | ||||
|     t.datetime "updated_at", null: false | ||||
|     t.string "blurhash" | ||||
|     t.index ["var"], name: "index_site_uploads_on_var", unique: true | ||||
|   end | ||||
|  | ||||
|   | ||||
| @@ -99,13 +99,6 @@ describe InstancePresenter do | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   describe '#hero' do | ||||
|     it 'returns SiteUpload' do | ||||
|       hero = Fabricate(:site_upload, var: 'hero') | ||||
|       expect(instance_presenter.hero).to eq(hero) | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   describe '#mascot' do | ||||
|     it 'returns SiteUpload' do | ||||
|       mascot = Fabricate(:site_upload, var: 'mascot') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user