iachat/app/javascript/dashboard/components-next/message/MessageMeta.vue
Cayo P. R. Oliveira a760442010
fix: mark message read edge case (#46)
* feat: enhance message_content_attributes to handle reaction messages

* fix: update external_created_at to use raw message timestamp directly

* fix: update readableTime to use externalCreatedAt if available

* feat: enhance timestamp formatting with localization support for pt-BR

* feat: add note to message_content_attributes about external_created_at timestamp

* fix: add missing newline at end of conversation.json files

* test: add additional cases for messageTimestamp formatting

* chore: remove outdated note about external_created_at in message_content_attributes

* refactor: remove out of scope task changes

* feat: add test for setting external_created_at in content_attributes on new message

* fix: use last_seen_at message query conditions only if present

* test: add SQL execution tests for messages_read with last_seen_at conditions

* fix: ensure SQL notifications are unsubscribed after message read events

* refactor: streamline message query in messages_read method

* test: update messages_read specs to test expected behavior

* refactor: simplify readableTime computation by removing unnecessary externalCreatedAt check

* fix: update readableTime computation to use externalCreatedAt if available

* test: enhance messages_read specs to use a consistent event object

* test: refactor spec for creating message with external_created_at in messages.upsert event

* Refactor incoming message specs for clarity and consistency

- Consolidated raw_message and params definitions using let blocks for better readability.
- Updated tests to directly manipulate raw_message and params within individual examples.
- Ensured consistent naming and structure across different message types.
- Improved assertions to reflect changes in message attributes and expectations.

* refactor: streamline messages.update event handling and improve test clarity

* test: refactor messages.upsert event specs to use a consistent timestamp

* test: enhance reaction message handling in incoming_message_baileys_service_spec
2025-05-16 14:13:00 -03:00

137 lines
3.5 KiB
Vue

<script setup>
import { computed } from 'vue';
import { messageTimestamp } from 'shared/helpers/timeHelper';
import MessageStatus from './MessageStatus.vue';
import Icon from 'next/icon/Icon.vue';
import { useInbox } from 'dashboard/composables/useInbox';
import { useMessageContext } from './provider.js';
import { MESSAGE_STATUS, MESSAGE_TYPES } from './constants';
const {
isAFacebookInbox,
isALineChannel,
isAPIInbox,
isASmsInbox,
isATelegramChannel,
isATwilioChannel,
isAWebWidgetInbox,
isAWhatsAppChannel,
isAnEmailChannel,
isAnInstagramChannel,
} = useInbox();
const {
status,
isPrivate,
createdAt,
sourceId,
messageType,
contentAttributes,
} = useMessageContext();
const readableTime = computed(() =>
messageTimestamp(
contentAttributes?.value?.externalCreatedAt ?? createdAt.value,
'LLL d, h:mm a'
)
);
const showStatusIndicator = computed(() => {
if (isPrivate.value) return false;
// Don't show status for failed messages, we already show error message
if (status.value === MESSAGE_STATUS.FAILED) return false;
// Don't show status for deleted messages
if (contentAttributes.value?.deleted) return false;
if (messageType.value === MESSAGE_TYPES.OUTGOING) return true;
if (messageType.value === MESSAGE_TYPES.TEMPLATE) return true;
return false;
});
const isSent = computed(() => {
if (!showStatusIndicator.value) return false;
// Messages will be marked as sent for the Email channel if they have a source ID.
if (isAnEmailChannel.value) return !!sourceId.value;
if (
isAWhatsAppChannel.value ||
isATwilioChannel.value ||
isAFacebookInbox.value ||
isASmsInbox.value ||
isATelegramChannel.value ||
isAnInstagramChannel.value
) {
return sourceId.value && status.value === MESSAGE_STATUS.SENT;
}
// All messages will be mark as sent for the Line channel, as there is no source ID.
if (isALineChannel.value) return true;
return false;
});
const isDelivered = computed(() => {
if (!showStatusIndicator.value) return false;
if (
isAWhatsAppChannel.value ||
isATwilioChannel.value ||
isASmsInbox.value ||
isAFacebookInbox.value
) {
return sourceId.value && status.value === MESSAGE_STATUS.DELIVERED;
}
// All messages marked as delivered for the web widget inbox and API inbox once they are sent.
if (isAWebWidgetInbox.value || isAPIInbox.value) {
return status.value === MESSAGE_STATUS.SENT;
}
if (isALineChannel.value) {
return status.value === MESSAGE_STATUS.DELIVERED;
}
return false;
});
const isRead = computed(() => {
if (!showStatusIndicator.value) return false;
if (
isAWhatsAppChannel.value ||
isATwilioChannel.value ||
isAFacebookInbox.value ||
isAnInstagramChannel.value
) {
return sourceId.value && status.value === MESSAGE_STATUS.READ;
}
if (isAWebWidgetInbox.value || isAPIInbox.value) {
return status.value === MESSAGE_STATUS.READ;
}
return false;
});
const statusToShow = computed(() => {
if (isRead.value) return MESSAGE_STATUS.READ;
if (isDelivered.value) return MESSAGE_STATUS.DELIVERED;
if (isSent.value) return MESSAGE_STATUS.SENT;
return MESSAGE_STATUS.PROGRESS;
});
</script>
<template>
<div class="text-xs flex items-center gap-1.5">
<div class="inline">
<time class="inline">{{ readableTime }}</time>
</div>
<Icon v-if="isPrivate" icon="i-lucide-lock-keyhole" class="size-3" />
<MessageStatus v-if="showStatusIndicator" :status="statusToShow" />
</div>
</template>
`