DEV: In development, refresh client when theme changes are made (#22978)

This brings the theme development experience (via the discourse_theme cli) closer to the experience of making javascript changes in Discourse core/plugins via Ember CLI. Whenever a change is made to a non-css theme field, all clients will be instructed to immediately refresh via message-bus.
This commit is contained in:
David Taylor 2023-08-04 11:02:26 +01:00 committed by GitHub
parent 28dc222e2f
commit e76e0ad592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 10 deletions

View File

@ -7,7 +7,7 @@ import { bind } from "discourse-common/utils/decorators";
export default {
initialize(owner) {
this.messageBus = owner.lookup("service:message-bus");
const session = owner.lookup("service:session");
this.session = owner.lookup("service:session");
// Preserve preview_theme_id=## and pp=async-flamegraph parameters across pages
const params = new URLSearchParams(window.location.search);
@ -40,7 +40,7 @@ export default {
this.messageBus.subscribe(
"/file-change",
this.onFileChange,
session.mbLastFileChangeId
this.session.mbLastFileChangeId
);
},
@ -54,6 +54,14 @@ export default {
if (me === "refresh") {
// Refresh if necessary
document.location.reload(true);
} else if (me === "development-mode-theme-changed") {
if (window.location.pathname.startsWith("/admin/customize/themes")) {
// don't refresh users on routes which make theme changes - would be very inconvenient.
// Instead, refresh on their next route navigation.
this.session.requiresRefresh = true;
} else {
document.location.reload(true);
}
} else if (me.new_href && me.target) {
let query = `link[data-target='${me.target}']`;

View File

@ -98,6 +98,9 @@ class Theme < ActiveRecord::Base
changed_colors.clear
changed_schemes.clear
any_non_css_fields_changed =
changed_fields.any? { |f| !(f.basic_scss_field? || f.extra_scss_field?) }
changed_fields.each(&:save!)
changed_fields.clear
@ -126,6 +129,14 @@ class Theme < ActiveRecord::Base
self.theme_setting_requests_refresh = false
end
end
if any_non_css_fields_changed && should_refresh_development_clients?
MessageBus.publish "/file-change", ["development-mode-theme-changed"]
end
end
def should_refresh_development_clients?
Rails.env.development?
end
def update_child_components
@ -513,18 +524,20 @@ class Theme < ActiveRecord::Base
changed_fields << field
end
end
field
else
if value.present? || upload_id.present?
theme_fields.build(
target_id: target_id,
value: value,
name: name,
type_id: type_id,
upload_id: upload_id,
)
field =
theme_fields.build(
target_id: target_id,
value: value,
name: name,
type_id: type_id,
upload_id: upload_id,
)
changed_fields << field
end
end
field
end
def child_theme_ids=(theme_ids)

View File

@ -1093,4 +1093,30 @@ HTML
expect(messages.count).to eq(0)
end
end
describe "development experience" do
it "sends 'development-mode-theme-changed event when non-css fields are updated" do
Theme.any_instance.stubs(:should_refresh_development_clients?).returns(true)
theme.set_field(target: :common, name: :scss, value: "body {background: green;}")
messages =
MessageBus
.track_publish { theme.save! }
.filter { |m| m.channel == "/file-change" }
.map(&:data)
expect(messages).not_to include("development-mode-theme-changed")
theme.set_field(target: :common, name: :header, value: "<p>Hello world</p>")
messages =
MessageBus
.track_publish { theme.save! }
.filter { |m| m.channel == "/file-change" }
.map(&:data)
expect(messages).to include(["development-mode-theme-changed"])
end
end
end