Add image processing and generate blurhash for server thumbnail (#19348)
Remove separate server hero setting
This commit is contained in:
parent
7afc6a630c
commit
b04633a961
|
@ -22,7 +22,6 @@ class Form::AdminSettings
|
||||||
custom_css
|
custom_css
|
||||||
profile_directory
|
profile_directory
|
||||||
thumbnail
|
thumbnail
|
||||||
hero
|
|
||||||
mascot
|
mascot
|
||||||
trends
|
trends
|
||||||
trendable_by_default
|
trendable_by_default
|
||||||
|
@ -49,7 +48,6 @@ class Form::AdminSettings
|
||||||
|
|
||||||
UPLOAD_KEYS = %i(
|
UPLOAD_KEYS = %i(
|
||||||
thumbnail
|
thumbnail
|
||||||
hero
|
|
||||||
mascot
|
mascot
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,35 @@
|
||||||
# meta :json
|
# meta :json
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
|
# blurhash :string
|
||||||
#
|
#
|
||||||
|
|
||||||
class SiteUpload < ApplicationRecord
|
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_attachment_content_type :file, content_type: /\Aimage\/.*\z/
|
||||||
validates :file, presence: true
|
validates :file, presence: true
|
||||||
|
|
|
@ -84,10 +84,6 @@ class InstancePresenter < ActiveModelSerializers::Model
|
||||||
@thumbnail ||= Rails.cache.fetch('site_uploads/thumbnail') { SiteUpload.find_by(var: 'thumbnail') }
|
@thumbnail ||= Rails.cache.fetch('site_uploads/thumbnail') { SiteUpload.find_by(var: 'thumbnail') }
|
||||||
end
|
end
|
||||||
|
|
||||||
def hero
|
|
||||||
@hero ||= Rails.cache.fetch('site_uploads/hero') { SiteUpload.find_by(var: 'hero') }
|
|
||||||
end
|
|
||||||
|
|
||||||
def mascot
|
def mascot
|
||||||
@mascot ||= Rails.cache.fetch('site_uploads/mascot') { SiteUpload.find_by(var: 'mascot') }
|
@mascot ||= Rails.cache.fetch('site_uploads/mascot') { SiteUpload.find_by(var: 'mascot') }
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,20 @@ class REST::InstanceSerializer < ActiveModel::Serializer
|
||||||
has_many :rules, serializer: REST::RuleSerializer
|
has_many :rules, serializer: REST::RuleSerializer
|
||||||
|
|
||||||
def thumbnail
|
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
|
end
|
||||||
|
|
||||||
def usage
|
def usage
|
||||||
|
|
|
@ -33,7 +33,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def thumbnail
|
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
|
end
|
||||||
|
|
||||||
def stats
|
def stats
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
.fields-row
|
.fields-row
|
||||||
.fields-row__column.fields-row__column-6.fields-group
|
.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)
|
= 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
|
||||||
.fields-row__column.fields-row__column-6.fields-group
|
.fields-row__column.fields-row__column-6.fields-group
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.hero-widget
|
.hero-widget
|
||||||
.hero-widget__img
|
.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
|
.hero-widget__text
|
||||||
%p= @instance_presenter.description.html_safe.presence || t('about.about_mastodon_html')
|
%p= @instance_presenter.description.html_safe.presence || t('about.about_mastodon_html')
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
= opengraph 'og:type', 'website'
|
= opengraph 'og:type', 'website'
|
||||||
= opengraph 'og:title', @instance_presenter.title
|
= opengraph 'og:title', @instance_presenter.title
|
||||||
= opengraph 'og:description', description
|
= 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:width', thumbnail ? thumbnail.meta['width'] : '1200'
|
||||||
= opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
|
= opengraph 'og:image:height', thumbnail ? thumbnail.meta['height'] : '630'
|
||||||
= opengraph 'twitter:card', 'summary_large_image'
|
= opengraph 'twitter:card', 'summary_large_image'
|
||||||
|
|
|
@ -735,9 +735,6 @@ en:
|
||||||
users: To logged-in local users
|
users: To logged-in local users
|
||||||
domain_blocks_rationale:
|
domain_blocks_rationale:
|
||||||
title: Show 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:
|
mascot:
|
||||||
desc_html: Displayed on multiple pages. At least 293×205px recommended. When not set, falls back to default mascot
|
desc_html: Displayed on multiple pages. At least 293×205px recommended. When not set, falls back to default mascot
|
||||||
title: Mascot image
|
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.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -866,6 +866,7 @@ ActiveRecord::Schema.define(version: 2022_10_06_061337) do
|
||||||
t.json "meta"
|
t.json "meta"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
|
t.string "blurhash"
|
||||||
t.index ["var"], name: "index_site_uploads_on_var", unique: true
|
t.index ["var"], name: "index_site_uploads_on_var", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -99,13 +99,6 @@ describe InstancePresenter do
|
||||||
end
|
end
|
||||||
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
|
describe '#mascot' do
|
||||||
it 'returns SiteUpload' do
|
it 'returns SiteUpload' do
|
||||||
mascot = Fabricate(:site_upload, var: 'mascot')
|
mascot = Fabricate(:site_upload, var: 'mascot')
|
||||||
|
|
Reference in New Issue