mirror of
https://github.com/discourse/discourse.git
synced 2026-08-09 21:45:25 +08:00
Since we have been using the upcoming change system
more heavily, we noticed that notifications for available changes
(i.e. changes that have been added at promotion status - 1 OR
changes that recently reached promotion status - 1) are crowding
the admin's notifications a lot.
To address this, we already allowed admins to opt out of these
in 0c46a2e805 . However, we also
want to reduce the cadence of these notifications for admins who do want
to opt out completely.
This commit changes upcoming change available notifications to be
collected & sent in a weekly job, rather than in the job that runs
every 20 minutes & logs added/status changed events.
This weekly job will also handle consolidating existing unread upcoming
change available notifications, and making sure that we do not send
N new notifications per change when an admin has no existing unread
notification.
Upcoming change promoted notifications will still happen "instantly"
88 lines
2.6 KiB
Ruby
Vendored
88 lines
2.6 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
# Intended to be called from UpcomingChanges::Track service,
|
|
# not standalone.
|
|
#
|
|
# Lookup any previous event_type: status_changed (5) events for the change
|
|
# * If there are none, create one for the current status
|
|
class UpcomingChanges::Action::TrackStatusChanges < Service::ActionBase
|
|
# Every admin user that are not bots
|
|
option :all_admins
|
|
|
|
# All changes that were added at the same time, we
|
|
# create a special status changed event for these with
|
|
# no previous value.
|
|
option :added_changes
|
|
|
|
# All changes that were removed at the same time, we don't care about
|
|
# their statuses anymore.
|
|
option :removed_changes
|
|
|
|
def call
|
|
status_changes = {}
|
|
|
|
SiteSetting.upcoming_change_site_settings.each do |change_name|
|
|
if no_previous_status_event?(change_name)
|
|
UpcomingChangeEvent.create!(
|
|
event_type: :status_changed,
|
|
upcoming_change_name: change_name,
|
|
event_data: {
|
|
previous_value: nil,
|
|
new_value: UpcomingChanges.change_status(change_name),
|
|
},
|
|
)
|
|
status_changes[change_name] = {
|
|
previous_value: "N/A",
|
|
new_value: UpcomingChanges.change_status(change_name),
|
|
}
|
|
next
|
|
end
|
|
|
|
next if added_changes.include?(change_name)
|
|
next if removed_changes.include?(change_name)
|
|
|
|
previous_status = previous_status_for(change_name)
|
|
current_status = UpcomingChanges.change_status(change_name)
|
|
|
|
if status_changed?(previous_status, current_status)
|
|
UpcomingChangeEvent.create!(
|
|
event_type: :status_changed,
|
|
upcoming_change_name: change_name,
|
|
event_data: {
|
|
previous_value: previous_status,
|
|
new_value: current_status,
|
|
},
|
|
)
|
|
status_changes[change_name] = { previous_value: previous_status, new_value: current_status }
|
|
end
|
|
end
|
|
|
|
UpcomingChanges.clear_caches!
|
|
DiscourseUpdates.clear_latest_new_feature_created_at_cache
|
|
|
|
status_changes
|
|
end
|
|
|
|
private
|
|
|
|
def previous_status_events
|
|
@previous_status_events ||= UpcomingChangeEvent.status_changed.to_a
|
|
end
|
|
|
|
def no_previous_status_event?(change_name)
|
|
previous_status_events.none? { |event| event.upcoming_change_name == change_name.to_s }
|
|
end
|
|
|
|
def previous_status_for(change_name)
|
|
previous_status_events
|
|
.select { |event| event.upcoming_change_name == change_name.to_s }
|
|
.last
|
|
.event_data[
|
|
"new_value"
|
|
]
|
|
end
|
|
|
|
def status_changed?(previous_status, current_status)
|
|
previous_status&.to_sym != current_status
|
|
end
|
|
end
|