From 6cb3514d64ec24b164484f4eb84363b96746d5d6 Mon Sep 17 00:00:00 2001 From: Jakub Mendyk Date: Thu, 23 Aug 2018 14:17:35 +0200 Subject: [PATCH] Add ability to change an instance default theme from the administration panel (#7092) (#8381) * Add default_settings class method to ScopedSettings ScopedSettings was extended to use value of unscoped setting instead of only using defaults set in config/settings.yml for selected settings. This adds possibility for admins to set default values of users' settings, for example default theme (as requested in #7092). * Add ability to change an instance default theme Closes #7092 --- app/controllers/admin/settings_controller.rb | 1 + app/controllers/application_controller.rb | 2 +- app/lib/settings/scoped_settings.rb | 15 +++++++-- app/models/form/admin_settings.rb | 2 ++ app/views/admin/settings/edit.html.haml | 1 + .../application_controller_spec.rb | 33 +++++++++++++++++++ 6 files changed, 51 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 3234b194f..23e0444d0 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -16,6 +16,7 @@ module Admin timeline_preview show_staff_badge bootstrap_timeline_accounts + theme thumbnail hero min_invite_role diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index eafe27047..7ddd26ec0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -95,7 +95,7 @@ class ApplicationController < ActionController::Base end def current_theme - return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme + return Setting.theme unless Themes.instance.names.include? current_user&.setting_theme current_user.setting_theme end diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb index de4af3009..5ee30825d 100644 --- a/app/lib/settings/scoped_settings.rb +++ b/app/lib/settings/scoped_settings.rb @@ -2,6 +2,10 @@ module Settings class ScopedSettings + DEFAULTING_TO_UNSCOPED = %w( + theme + ).freeze + def initialize(object) @object = object end @@ -50,15 +54,22 @@ module Settings Rails.cache.fetch(Setting.cache_key(key, @object)) do db_val = thing_scoped.find_by(var: key.to_s) if db_val - default_value = Setting.default_settings[key] + default_value = ScopedSettings.default_settings[key] return default_value.with_indifferent_access.merge!(db_val.value) if default_value.is_a?(Hash) db_val.value else - Setting.default_settings[key] + ScopedSettings.default_settings[key] end end end + class << self + def default_settings + defaulting = DEFAULTING_TO_UNSCOPED.map { |k| [k, Setting[k]] }.to_h + Setting.default_settings.merge!(defaulting) + end + end + protected def thing_scoped diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 010cf7fc3..db46cda7b 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -30,6 +30,8 @@ class Form::AdminSettings :show_staff_badge=, :bootstrap_timeline_accounts, :bootstrap_timeline_accounts=, + :theme, + :theme=, :min_invite_role, :min_invite_role=, :activity_api_enabled, diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index fda6b00f4..b5aa176a2 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -15,6 +15,7 @@ %hr/ .fields-group + = f.input :theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false = f.input :thumbnail, as: :file, wrapper: :with_block_label, label: t('admin.settings.thumbnail.title'), hint: t('admin.settings.thumbnail.desc_html') = f.input :hero, as: :file, wrapper: :with_block_label, label: t('admin.settings.hero.title'), hint: t('admin.settings.hero.desc_html') diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index c6c78d3f7..d158625e6 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -92,6 +92,39 @@ describe ApplicationController, type: :controller do end end + describe 'helper_method :current_theme' do + it 'returns "default" when theme wasn\'t changed in admin settings' do + allow(Setting).to receive(:default_settings).and_return({'theme' => 'default'}) + + expect(controller.view_context.current_theme).to eq 'default' + end + + it 'returns instances\'s theme when user is not signed in' do + allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + + expect(controller.view_context.current_theme).to eq 'contrast' + end + + it 'returns instances\'s default theme when user didn\'t set theme' do + current_user = Fabricate(:user) + sign_in current_user + + allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + + expect(controller.view_context.current_theme).to eq 'contrast' + end + + it 'returns user\'s theme when it is set' do + current_user = Fabricate(:user) + current_user.settings['theme'] = 'mastodon-light' + sign_in current_user + + allow(Setting).to receive(:[]).with('theme').and_return 'contrast' + + expect(controller.view_context.current_theme).to eq 'mastodon-light' + end + end + context 'ActionController::RoutingError' do subject do routes.draw { get 'routing_error' => 'anonymous#routing_error' }