discourse/plugins/chat/lib/chat/notification_consolidation_extension.rb
David Battersby 997fbc9757
FEATURE: Add ability to watch chat threads (#28639)
This change introduces a new thread notification level allowing users to get notified when someone replies to the thread.

Users who watch a thread will get a green notification on the chat icon and a user notification (blue). User notifications are consolidated based on thread id to prevent cluttering the original users notification area.

---------

Co-authored-by: Régis Hanol <regis@hanol.fr>
2024-09-02 16:45:55 +04:00

64 lines
2.3 KiB
Ruby

# frozen_string_literal: true
module Chat
module NotificationConsolidationExtension
CONSOLIDATION_THRESHOLD = 1
def self.watched_thread_message_plan
Notifications::ConsolidateNotifications.new(
from: Notification.types[:chat_watched_thread],
to: Notification.types[:chat_watched_thread],
threshold: CONSOLIDATION_THRESHOLD,
unconsolidated_query_blk:
Proc.new do |notifications, data|
notifications.where("data::json ->> 'consolidated' IS NULL").where(
"data::json ->> 'chat_thread_id' = ?",
data[:chat_thread_id].to_s,
)
end,
consolidated_query_blk:
Proc.new do |notifications, data|
notifications.where("(data::json ->> 'consolidated')::bool").where(
"data::json ->> 'chat_thread_id' = ?",
data[:chat_thread_id].to_s,
)
end,
).set_mutations(
set_data_blk:
lambda do |notification|
data = notification.data_hash
last_watched_thread_notification =
Notification
.where(user_id: notification.user_id)
.order("notifications.id DESC")
.where("data::json ->> 'chat_thread_id' = ?", data[:chat_thread_id].to_s)
.where(notification_type: Notification.types[:chat_watched_thread])
.first
return data if !last_watched_thread_notification
consolidated_data = last_watched_thread_notification.data_hash
if data[:last_read_message_id].to_i <= consolidated_data[:chat_message_id].to_i
data[:chat_message_id] = consolidated_data[:chat_message_id]
end
if !consolidated_data[:username2] && data[:username] != consolidated_data[:username]
data.merge(
username2: consolidated_data[:username],
user_ids: consolidated_data[:user_ids].concat(data[:user_ids]),
)
else
data.merge(
username: consolidated_data[:username],
username2: consolidated_data[:username2],
user_ids: (consolidated_data[:user_ids].concat(data[:user_ids])).uniq,
)
end
end,
)
end
end
end