0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-05 15:18:34 +08:00
discourse/config/initializers/015-track-upcoming-change-toggle.rb
Martin Brennan 4de06a006b
FIX: Do not notify new sites or plugins enabled of old upcoming changes (#42045)
For upcoming changes, we were having a problem where we
were notifying admins of upcoming changes in brand new sites.
A previous fix 2e5afb46e2f5c0547bc298b2bd1a9c39e813dc17 tried
to remedy this, but since it relies on the `new_site?` method, which
isn't true after 1 hour, the next time the scheduled notifications are
run for an admin they will be sent them even if their site is relatively
new.

This commit attempts to conclusively fix the issue by inserting
upcoming change `admins_notified_automatic_promotion` and
`admins_notified_available_change` events via `BackfillNotifiedEvents`
for changes that exist in particular statuses when the site is first
created. These events will have `event_data: {"backfilled" => true}`
to distinguish them from others.

It also fixes an adjacent issue where an admin was notified of a
plugin's upcoming changes as soon as they enable the plugin,
which isn't useful as the intent of upcoming changes is to notify
of changes for things the admin has already been using.

**Before this change, on brand new site with current upcoming change
state**

<img width="401" height="429" alt="image"
src="https://github.com/user-attachments/assets/a89cd641-59aa-4c48-a57c-9692021df176"
/>

**After this change**

No notification to show :) But when I moved an upcoming change to `beta`
it showed
the notification for the enabled upcoming change correctly:

<img width="378" height="174" alt="image"
src="https://github.com/user-attachments/assets/20e4096f-e83f-4c06-970d-a9b43561b12e"
/>
2026-07-30 09:51:08 +10:00

64 lines
2.8 KiB
Ruby
Vendored

# frozen_string_literal: true
Rails.application.config.after_initialize { UpcomingChanges.clear_caches! }
#
# Similar to 014-track-setting-changes.rb, we can react to upcoming changes
# being enabled/or disabled here for more complicated scenarios, where
# we are not just changing UI or behaviour when the state of the underlying
# setting is changed.
#
# We need to do this separately from 014-track-setting-changes.rb because
# we don't actually change the underlying setting value in the database
# when an upcoming change is automatically promoted. See UpcomingChanges::NotifyPromotions
# for further context.
#
# We do also send these events when admins manually opt-in or opt-out of an upcoming change
# via the UI and the UpcomingChanges::Toggle service.
DiscourseEvent.on(:upcoming_change_enabled) do |setting_name|
# Respond to event here, e.g. if setting_name == :enable_form_templates do X.
if setting_name == :enable_horizon_high_context_topic_cards
Themes::Action::HorizonHighContextTopicCardsToggled.call(enabled: true)
elsif setting_name == :remove_and_replace_uncategorized
SiteSetting::Action::RemoveAndReplaceUncategorizedToggled.call(enabled: true)
end
end
DiscourseEvent.on(:upcoming_change_disabled) do |setting_name|
# Respond to event here, e.g. if setting_name == :enable_form_templates do X.
if setting_name == :enable_horizon_high_context_topic_cards
Themes::Action::HorizonHighContextTopicCardsToggled.call(enabled: false)
elsif setting_name == :remove_and_replace_uncategorized
SiteSetting::Action::RemoveAndReplaceUncategorizedToggled.call(enabled: false)
end
end
# A plugin's settings are registered whether or not it is enabled, so its upcoming
# changes have been accumulating in the audit trail all along, only
# ConditionalDisplay was holding their notifications back. Enabling the plugin would
# otherwise release that whole back-catalogue at once, which is noise. The admin just
# opted into the plugin, they did not have anything change out from under them, so they
# don't need to have a flood of notifications.
#
# Treat it the same way as a new site and mark those changes as already notified
# about. Promotion itself still happens, so :upcoming_change_enabled fires as usual.
DiscourseEvent.on(:site_setting_changed) do |name, _old_value, new_value|
next if !new_value
plugin_name = SiteSetting.plugins[name]
next if plugin_name.blank?
plugin = Discourse.plugins_by_name[plugin_name]
next if plugin&.enabled_site_setting&.to_sym != name.to_sym
all_plugin_upcoming_changes =
SiteSetting.upcoming_change_site_settings.select do |change_name|
SiteSetting.plugins[change_name] == plugin_name
end
next if all_plugin_upcoming_changes.blank?
UpcomingChanges::Action::BackfillNotifiedEvents.call(
upcoming_change_names: all_plugin_upcoming_changes,
)
end