diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index 110debd6e5..0a5c14cca7 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -54,6 +54,7 @@ class Settings::PreferencesController < Settings::BaseController :setting_aggregate_reblogs, :setting_show_application, :setting_advanced_layout, + :setting_use_blurhash, notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account), interactions: %i(must_be_follower must_be_following must_be_following_dm) ) diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index 77bac61eec..9cd71b7c99 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -6,7 +6,7 @@ import IconButton from './icon_button'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { isIOS } from '../is_mobile'; import classNames from 'classnames'; -import { autoPlayGif, displayMedia } from '../initial_state'; +import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state'; import { decode } from 'blurhash'; const messages = defineMessages({ @@ -81,6 +81,8 @@ class Item extends React.PureComponent { } _decode () { + if (!useBlurhash) return; + const hash = this.props.attachment.get('blurhash'); const pixels = decode(hash, 32, 32); diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js index b0c4085277..0acdd198d5 100644 --- a/app/javascript/mastodon/features/video/index.js +++ b/app/javascript/mastodon/features/video/index.js @@ -5,7 +5,7 @@ import { fromJS, is } from 'immutable'; import { throttle } from 'lodash'; import classNames from 'classnames'; import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen'; -import { displayMedia } from '../../initial_state'; +import { displayMedia, useBlurhash } from '../../initial_state'; import Icon from 'mastodon/components/icon'; import { decode } from 'blurhash'; @@ -298,6 +298,8 @@ class Video extends React.PureComponent { } _decode () { + if (!useBlurhash) return; + const hash = this.props.blurhash; const pixels = decode(hash, 32, 32); diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 125508c234..f0f131ff58 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -20,5 +20,6 @@ export const mascot = getMeta('mascot'); export const profile_directory = getMeta('profile_directory'); export const isStaff = getMeta('is_staff'); export const forceSingleColumn = !getMeta('advanced_layout'); +export const useBlurhash = getMeta('use_blurhash'); export default initialState; diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index bf2e5a962f..aaf95cc198 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -34,6 +34,7 @@ class UserSettingsDecorator user.settings['aggregate_reblogs'] = aggregate_reblogs_preference if change?('setting_aggregate_reblogs') user.settings['show_application'] = show_application_preference if change?('setting_show_application') user.settings['advanced_layout'] = advanced_layout_preference if change?('setting_advanced_layout') + user.settings['use_blurhash'] = use_blurhash_preference if change?('setting_use_blurhash') end def merged_notification_emails @@ -112,6 +113,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_advanced_layout' end + def use_blurhash_preference + boolean_cast_setting 'setting_use_blurhash' + end + def boolean_cast_setting(key) ActiveModel::Type::Boolean.new.cast(settings[key]) end diff --git a/app/models/user.rb b/app/models/user.rb index 50873dd013..3a4b415dd6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -106,7 +106,7 @@ class User < ApplicationRecord delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :delete_modal, :reduce_motion, :system_font_ui, :noindex, :theme, :display_media, :hide_network, :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, - :advanced_layout, to: :settings, prefix: :setting, allow_nil: false + :advanced_layout, :use_blurhash, to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code attr_writer :external diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 8daf36e0a5..54f99d570e 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -32,6 +32,7 @@ class InitialStateSerializer < ActiveModel::Serializer store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers store[:reduce_motion] = object.current_account.user.setting_reduce_motion store[:advanced_layout] = object.current_account.user.setting_advanced_layout + store[:use_blurhash] = object.current_account.user.setting_use_blurhash store[:is_staff] = object.current_account.user.staff? end diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index 10f0092647..c138828017 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -34,6 +34,9 @@ .fields-group = f.input :setting_display_media, collection: ['default', 'show_all', 'hide_all'],label_method: lambda { |item| t("simple_form.hints.defaults.setting_display_media_#{item}") }, hint: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label + .fields-group + = f.input :setting_use_blurhash, as: :boolean, wrapper: :with_label + .fields-group = f.input :setting_expand_spoilers, as: :boolean, wrapper: :with_label diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 4602f9cd9d..75cbec9de5 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -34,6 +34,7 @@ en: setting_hide_network: Who you follow and who follows you will not be shown on your profile setting_noindex: Affects your public profile and status pages setting_show_application: The application you use to toot will be displayed in the detailed view of your toots + setting_use_blurhash: Gradients are based on the colors of the hidden visuals but obfuscate any details username: Your username will be unique on %{domain} whole_word: When the keyword or phrase is alphanumeric only, it will only be applied if it matches the whole word featured_tag: @@ -109,6 +110,7 @@ en: setting_system_font_ui: Use system's default font setting_theme: Site theme setting_unfollow_modal: Show confirmation dialog before unfollowing someone + setting_use_blurhash: Show colorful gradients for hidden media severity: Severity type: Import type username: Username diff --git a/config/settings.yml b/config/settings.yml index 805624d3e1..ad71b6008f 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -32,6 +32,7 @@ defaults: &defaults theme: 'default' aggregate_reblogs: true advanced_layout: false + use_blurhash: true notification_emails: follow: false reblog: false