diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb index 38bb5d1d0..e6a4bdbc0 100644 --- a/app/controllers/api/v1/accounts/conversations_controller.rb +++ b/app/controllers/api/v1/accounts/conversations_controller.rb @@ -126,11 +126,10 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro # 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. # Always update immediately if there are unread messages to maintain accurate read/unread state. - 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? + has_unread = assignee? ? @conversation.assignee_unread_messages.any? : @conversation.unread_messages.any? # No unread messages - apply throttling to limit DB writes - return unless should_update_last_seen? + return if !has_unread && !should_update_last_seen? dispatch_messages_read_event if assignee? diff --git a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue index fca692d0d..0297d64fe 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ConversationCard.vue @@ -161,11 +161,17 @@ const showLabelsSection = computed(() => { return props.chat.labels?.length > 0 || hasSlaPolicyId.value; }); +const messagePreviewPaddingClass = computed(() => { + return [ + !props.compact && hasUnread.value ? 'ltr:pr-4 rtl:pl-4' : '', + props.compact && hasUnread.value ? 'ltr:pr-6 rtl:pl-6' : '', + ]; +}); + const messagePreviewClass = computed(() => { return [ hasUnread.value ? 'font-medium text-n-slate-12' : 'text-n-slate-11', - !props.compact && hasUnread.value ? 'ltr:pr-4 rtl:pl-4' : '', - props.compact && hasUnread.value ? 'ltr:pr-6 rtl:pl-6' : '', + ...messagePreviewPaddingClass.value, ]; }); @@ -370,7 +376,7 @@ const deleteConversation = () => { v-else-if="isAnyoneTyping" key="typing-preview" class="text-green-500 text-sm font-medium my-0 mx-2 leading-6 h-6 flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap" - :class="messagePreviewClass" + :class="messagePreviewPaddingClass" > {{ typingPreviewText }}

diff --git a/app/services/whatsapp/baileys_handlers/concerns/individual_contact_message_handler.rb b/app/services/whatsapp/baileys_handlers/concerns/individual_contact_message_handler.rb index 113adf193..19df6c7f4 100644 --- a/app/services/whatsapp/baileys_handlers/concerns/individual_contact_message_handler.rb +++ b/app/services/whatsapp/baileys_handlers/concerns/individual_contact_message_handler.rb @@ -1,6 +1,7 @@ module Whatsapp::BaileysHandlers::Concerns::IndividualContactMessageHandler extend ActiveSupport::Concern include Whatsapp::BaileysHandlers::Concerns::MessageCreationHandler + include Events::Types private @@ -30,11 +31,25 @@ module Whatsapp::BaileysHandlers::Concerns::IndividualContactMessageHandler set_conversation handle_create_message + dispatch_incoming_typing_off end ensure clear_message_source_id_from_redis if @lock_acquired end + def dispatch_incoming_typing_off + return unless incoming? + return unless @conversation && @contact + + Rails.configuration.dispatcher.dispatch( + CONVERSATION_TYPING_OFF, + Time.zone.now, + conversation: @conversation, + user: @contact, + is_private: false + ) + end + def set_contact phone = extract_from_jid(type: 'pn') source_id = extract_from_jid(type: 'lid')