chore: mark conversation notifications as read on visit (#13906)
This commit is contained in:
@@ -116,6 +116,8 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro
|
|||||||
# High-traffic accounts generate excessive DB writes when agents frequently switch between conversations.
|
# High-traffic accounts generate excessive DB writes when agents frequently switch between conversations.
|
||||||
# Throttle last_seen updates to once per hour when there are no unread messages to reduce DB load.
|
# Throttle last_seen updates to once per hour when there are no unread messages to reduce DB load.
|
||||||
# Always update immediately if there are unread messages to maintain accurate read/unread state.
|
# Always update immediately if there are unread messages to maintain accurate read/unread state.
|
||||||
|
# Visiting a conversation should clear any unread inbox notifications for this conversation.
|
||||||
|
Notification::MarkConversationReadService.new(user: Current.user, account: Current.account, conversation: @conversation).perform
|
||||||
return update_last_seen_on_conversation(DateTime.now.utc, true) if assignee? && @conversation.assignee_unread_messages.any?
|
return update_last_seen_on_conversation(DateTime.now.utc, true) if assignee? && @conversation.assignee_unread_messages.any?
|
||||||
return update_last_seen_on_conversation(DateTime.now.utc, false) if !assignee? && @conversation.unread_messages.any?
|
return update_last_seen_on_conversation(DateTime.now.utc, false) if !assignee? && @conversation.unread_messages.any?
|
||||||
|
|
||||||
|
|||||||
25
app/services/notification/mark_conversation_read_service.rb
Normal file
25
app/services/notification/mark_conversation_read_service.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class Notification::MarkConversationReadService
|
||||||
|
pattr_initialize [:user!, :account!, :conversation!]
|
||||||
|
|
||||||
|
def perform
|
||||||
|
return unless user.is_a?(User)
|
||||||
|
|
||||||
|
notifications.find_each do |notification|
|
||||||
|
notification.update!(read_at: read_at)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def notifications
|
||||||
|
user.notifications.where(
|
||||||
|
account: account,
|
||||||
|
primary_actor: conversation,
|
||||||
|
read_at: nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_at
|
||||||
|
@read_at ||= Time.current
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -729,6 +729,23 @@ RSpec.describe 'Conversations API', type: :request do
|
|||||||
expect(conversation.reload.assignee_last_seen_at).not_to be_nil
|
expect(conversation.reload.assignee_last_seen_at).not_to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'marks unread notifications as read when updating last seen' do
|
||||||
|
allow(Rails.configuration.dispatcher).to receive(:dispatch)
|
||||||
|
notification = create(:notification, account: account, user: agent, primary_actor: conversation, read_at: nil)
|
||||||
|
|
||||||
|
post "/api/v1/accounts/#{account.id}/conversations/#{conversation.display_id}/update_last_seen",
|
||||||
|
headers: agent.create_new_auth_token,
|
||||||
|
as: :json
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:success)
|
||||||
|
expect(notification.reload.read_at).to be_present
|
||||||
|
expect(Rails.configuration.dispatcher).to have_received(:dispatch).with(
|
||||||
|
'notification.updated',
|
||||||
|
kind_of(Time),
|
||||||
|
hash_including(notification: have_attributes(id: notification.id))
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
it 'throttles updates within an hour when there are no unread messages' do
|
it 'throttles updates within an hour when there are no unread messages' do
|
||||||
conversation.update!(agent_last_seen_at: 30.minutes.ago)
|
conversation.update!(agent_last_seen_at: 30.minutes.ago)
|
||||||
# Ensure all messages are older than agent_last_seen_at (no unread messages)
|
# Ensure all messages are older than agent_last_seen_at (no unread messages)
|
||||||
|
|||||||
Reference in New Issue
Block a user