fix: Message grouping, orientation, spacing, and tooltip

This commit is contained in:
iamsivin
2025-01-24 14:25:29 +05:30
parent b429ce0ad5
commit 11e77e9349
2 changed files with 44 additions and 14 deletions
@@ -97,6 +97,8 @@ import ContextMenu from 'dashboard/modules/conversations/components/MessageConte
// eslint-disable-next-line vue/define-macros-order
const props = defineProps({
id: { type: Number, required: true },
messages: { type: Array, default: () => [] },
index: { type: Number, required: true },
messageType: {
type: Number,
required: true,
@@ -182,17 +184,19 @@ const isMyMessage = computed(() => {
) {
return true;
}
if (props.messageType === MESSAGE_TYPES.ACTIVITY) {
return false;
}
const senderId = props.senderId ?? props.sender?.id;
const senderType = props.senderType ?? props.sender?.type;
if (!senderType || !senderId) {
return false;
return true;
}
return (
senderType.toLowerCase() === SENDER_TYPES.USER.toLowerCase() &&
props.currentUserId === senderId
);
return senderType.toLowerCase() === SENDER_TYPES.USER.toLowerCase();
});
/**
@@ -221,8 +225,8 @@ const flexOrientationClass = computed(() => {
const gridClass = computed(() => {
const map = {
[ORIENTATION.LEFT]: 'grid grid-cols-[24px_1fr]',
[ORIENTATION.RIGHT]: 'grid grid-cols-1fr',
[ORIENTATION.LEFT]: 'grid grid-cols-1fr',
[ORIENTATION.RIGHT]: 'grid grid-cols-[1fr_24px]',
};
return map[orientation.value];
@@ -231,13 +235,13 @@ const gridClass = computed(() => {
const gridTemplate = computed(() => {
const map = {
[ORIENTATION.LEFT]: `
"avatar bubble"
"spacer meta"
`,
[ORIENTATION.RIGHT]: `
"bubble"
"meta"
`,
[ORIENTATION.RIGHT]: `
"bubble avatar"
"meta spacer"
`,
};
return map[orientation.value];
@@ -251,7 +255,7 @@ const shouldGroupWithNext = computed(() => {
const shouldShowAvatar = computed(() => {
if (props.messageType === MESSAGE_TYPES.ACTIVITY) return false;
if (orientation.value === ORIENTATION.RIGHT) return false;
if (orientation.value === ORIENTATION.LEFT) return false;
return true;
});
@@ -361,6 +365,17 @@ const shouldRenderMessage = computed(() => {
);
});
const messageSpacingClass = computed(() => {
// Non-activity messages only need to check groupWithNext
if (props.messageType !== MESSAGE_TYPES.ACTIVITY) {
return props.groupWithNext ? 'mb-1' : 'mb-6';
}
// For activity messages, check if next message exists and is also an activity
const nextMessage = props.messages?.[props.index + 1];
return nextMessage?.messageType === MESSAGE_TYPES.ACTIVITY ? 'mb-2' : 'mb-6';
});
function openContextMenu(e) {
const shouldSkipContextMenu =
e.target?.classList.contains('skip-context-menu') ||
@@ -414,6 +429,11 @@ const avatarInfo = computed(() => {
};
});
const avatarTooltip = computed(() => {
if (avatarInfo.value.name === '') return '';
return `${t('CONVERSATION.SENT_BY')} ${avatarInfo.value.name}`;
});
const setupHighlightTimer = () => {
if (Number(route.query.messageId) !== Number(props.id)) {
return;
@@ -443,10 +463,11 @@ provideMessageContext({
<div
v-if="shouldRenderMessage"
:id="`message${props.id}`"
class="flex w-full message-bubble-container mb-2"
class="flex w-full message-bubble-container"
:data-message-id="props.id"
:class="[
flexOrientationClass,
messageSpacingClass,
{
'group-with-next': shouldGroupWithNext,
'bg-n-alpha-1': showBackgroundHighlight,
@@ -472,6 +493,7 @@ provideMessageContext({
>
<div
v-if="!shouldGroupWithNext && shouldShowAvatar"
v-tooltip.left-end="avatarTooltip"
class="[grid-area:avatar] flex items-end"
>
<Avatar v-bind="avatarInfo" :size="24" />
@@ -74,7 +74,11 @@ const shouldGroupWithNext = (index, searchList) => {
nextMessageType === MESSAGE_TYPES.TEMPLATE &&
currentMessageType === MESSAGE_TYPES.TEMPLATE;
if (!hasSameSender || areBothTemplates) return false;
const areBothActivity =
nextMessageType === MESSAGE_TYPES.ACTIVITY &&
currentMessageType === MESSAGE_TYPES.ACTIVITY;
if (!hasSameSender || areBothTemplates || areBothActivity) return false;
if (currentMessageType !== nextMessageType) return false;
@@ -111,6 +115,8 @@ const getInReplyToMessage = parentMessage => {
<template v-for="(message, index) in read" :key="message.id">
<Message
v-bind="message"
:messages="read"
:index="index"
:is-email-inbox="isAnEmailChannel"
:in-reply-to="getInReplyToMessage(message)"
:group-with-next="shouldGroupWithNext(index, read)"
@@ -123,6 +129,8 @@ const getInReplyToMessage = parentMessage => {
<template v-for="(message, index) in unread" :key="message.id">
<Message
v-bind="message"
:messages="unread"
:index="index"
:in-reply-to="getInReplyToMessage(message)"
:group-with-next="shouldGroupWithNext(index, unread)"
:inbox-supports-reply-to="inboxSupportsReplyTo"