diff --git a/app/models/theme.rb b/app/models/theme.rb index 3f59348d9e2..c7b3def3050 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -94,6 +94,13 @@ class Theme < ActiveRecord::Base clear_cached_settings! DB.after_commit { ColorScheme.hex_cache.clear } notify_theme_change(with_scheme: notify_with_scheme) + + if theme_setting_requests_refresh + DB.after_commit do + Discourse.request_refresh! + self.theme_setting_requests_refresh = false + end + end end def update_child_components @@ -572,6 +579,10 @@ class Theme < ActiveRecord::Base raise Discourse::NotFound unless target_setting target_setting.value = new_value + + if target_setting.requests_refresh? + self.theme_setting_requests_refresh = true + end end def update_translation(translation_key, new_value) @@ -727,6 +738,8 @@ class Theme < ActiveRecord::Base private + attr_accessor :theme_setting_requests_refresh + def to_scss_variable(name, value) escaped = SassC::Script::Value::String.quote(value, sass: true) "$#{name}: unquote(#{escaped});" diff --git a/lib/theme_settings_manager.rb b/lib/theme_settings_manager.rb index 2e905717b7c..c520da5650a 100644 --- a/lib/theme_settings_manager.rb +++ b/lib/theme_settings_manager.rb @@ -37,6 +37,10 @@ class ThemeSettingsManager @opts[:description] # Old method of specifying description. Is now overridden by locale file end + def requests_refresh? + @opts[:refresh] + end + def value=(new_value) ensure_is_valid_value!(new_value) diff --git a/lib/theme_settings_parser.rb b/lib/theme_settings_parser.rb index e12f5d03393..b7b14b81c2e 100644 --- a/lib/theme_settings_parser.rb +++ b/lib/theme_settings_parser.rb @@ -43,6 +43,8 @@ class ThemeSettingsParser opts[:textarea] = !!raw_opts[:textarea] opts[:json_schema] = raw_opts[:json_schema] + opts[:refresh] = !!raw_opts[:refresh] + opts end diff --git a/spec/fixtures/theme_settings/valid_settings.yaml b/spec/fixtures/theme_settings/valid_settings.yaml index 95be277cf32..a6e8e9b6fa1 100644 --- a/spec/fixtures/theme_settings/valid_settings.yaml +++ b/spec/fixtures/theme_settings/valid_settings.yaml @@ -80,3 +80,7 @@ invalid_json_schema_setting: valid_json_schema_setting: default: "" json_schema: '{ "type": "array", "uniqueItems": true, "items": { "type": "object", "properties": { "color": { "type": "string" }, "icon": { "type": "string" } }, "additionalProperties": false } }' + +causes_refresh: + default: "" + refresh: true diff --git a/spec/models/theme_spec.rb b/spec/models/theme_spec.rb index a47571e444b..d5bddee7820 100644 --- a/spec/models/theme_spec.rb +++ b/spec/models/theme_spec.rb @@ -902,4 +902,44 @@ HTML expect(new_digest).to eq(digest) end end + + describe "#update_setting" do + it "requests clients to refresh if `refresh: true`" do + theme.set_field(target: :settings, name: "yaml", value: <<~YAML) + super_feature_enabled: + type: bool + default: false + refresh: true + YAML + + ThemeSetting.create!(theme: theme, data_type: ThemeSetting.types[:bool], name: "super_feature_enabled") + theme.save! + + messages = MessageBus.track_publish do + theme.update_setting(:super_feature_enabled, true) + theme.save! + end.filter { |m| m.channel == "/global/asset-version" } + + expect(messages.count).to eq(1) + end + + it "does not request clients to refresh if `refresh: false`" do + theme.set_field(target: :settings, name: "yaml", value: <<~YAML) + super_feature_enabled: + type: bool + default: false + refresh: false + YAML + + ThemeSetting.create!(theme: theme, data_type: ThemeSetting.types[:bool], name: "super_feature_enabled") + theme.save! + + messages = MessageBus.track_publish do + theme.update_setting(:super_feature_enabled, true) + theme.save! + end.filter { |m| m.channel == "/global/asset-version" } + + expect(messages.count).to eq(0) + end + end end