From 2c1a8e59f54e165a5556a2684a962142837a30e1 Mon Sep 17 00:00:00 2001
From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Date: Wed, 29 Jan 2025 22:56:08 +0530
Subject: [PATCH] chore: Next bubble improvements (#10759)
---
.../dashboard/assets/scss/_woot.scss | 20 +++--
.../components-next/avatar/Avatar.vue | 4 +-
.../components-next/message/Message.vue | 50 +++++++----
.../components-next/message/MessageList.vue | 19 ++++-
.../message/bubbles/Activity.vue | 2 +-
.../components-next/message/bubbles/Base.vue | 6 +-
.../message/bubbles/BaseAttachment.vue | 4 +-
.../message/bubbles/Email/Index.vue | 9 +-
.../message/bubbles/Text/Index.vue | 7 +-
.../message/chips/AttachmentChips.vue | 32 +++-----
.../message/chips/AttachmentGrid.vue | 82 +++++++++++++++++++
.../components-next/message/chips/Audio.vue | 26 +++++-
.../components-next/message/chips/File.vue | 17 +++-
.../components-next/message/chips/Image.vue | 35 +++++++-
.../components-next/message/chips/Video.vue | 34 +++++++-
.../components-next/message/provider.js | 2 +-
tailwind.config.js | 3 +
theme/colors.js | 2 +
18 files changed, 283 insertions(+), 71 deletions(-)
create mode 100644 app/javascript/dashboard/components-next/message/chips/AttachmentGrid.vue
diff --git a/app/javascript/dashboard/assets/scss/_woot.scss b/app/javascript/dashboard/assets/scss/_woot.scss
index d736d7b5a..29e3c7c60 100644
--- a/app/javascript/dashboard/assets/scss/_woot.scss
+++ b/app/javascript/dashboard/assets/scss/_woot.scss
@@ -146,17 +146,19 @@
--solid-2: 255 255 255;
--solid-3: 255 255 255;
--solid-active: 255 255 255;
- --solid-amber: 252 232 193;
- --solid-blue: 218 236 255;
+ --solid-amber: 255 228 181;
+ --solid-blue: 182 216 255;
--solid-iris: 230 231 255;
+ --solid-purple: 202 202 255;
+ --solid-red: 255 212 219;
--alpha-1: 67, 67, 67, 0.06;
- --alpha-2: 201, 202, 207, 0.15;
+ --alpha-2: 196, 197, 198, 0.22;
--alpha-3: 255, 255, 255, 0.96;
- --black-alpha-1: 0, 0, 0, 0.12;
+ --black-alpha-1: 0, 0, 0, 0.08;
--black-alpha-2: 0, 0, 0, 0.04;
--border-blue: 39, 129, 246, 0.5;
- --white-alpha: 255, 255, 255, 0.8;
+ --white-alpha: 255, 255, 255, 0.84;
}
.dark {
@@ -240,16 +242,18 @@
--gray-12: 238 238 238;
--background-color: 18 18 19;
+ --text-blue: 126 182 255;
--border-strong: 52 52 52;
--border-weak: 38 38 42;
--solid-1: 23 23 26;
--solid-2: 29 30 36;
--solid-3: 44 45 54;
--solid-active: 53 57 66;
- --solid-amber: 42 37 30;
- --solid-blue: 16 49 91;
+ --solid-amber: 56 50 41;
+ --solid-blue: 4 51 101;
--solid-iris: 38 42 101;
- --text-blue: 126 182 255;
+ --solid-purple: 51 51 107;
+ --solid-red: 78 46 55;
--alpha-1: 36, 36, 36, 0.8;
--alpha-2: 139, 147, 182, 0.15;
diff --git a/app/javascript/dashboard/components-next/avatar/Avatar.vue b/app/javascript/dashboard/components-next/avatar/Avatar.vue
index 65859b1c7..3cf6d3c88 100644
--- a/app/javascript/dashboard/components-next/avatar/Avatar.vue
+++ b/app/javascript/dashboard/components-next/avatar/Avatar.vue
@@ -50,16 +50,16 @@ const AVATAR_COLORS = {
dark: [
['#4B143D', '#FF8DCC'],
['#3F220D', '#FFA366'],
- ['#2A2A2A', '#ADB1B8'],
['#023B37', '#0BD8B6'],
+ ['#2A2A2A', '#ADB1B8'],
['#27264D', '#A19EFF'],
['#1D2E62', '#9EB1FF'],
],
light: [
['#FBDCEF', '#C2298A'],
['#FFE0BB', '#99543A'],
- ['#E8E8E8', '#60646C'],
['#CCF3EA', '#008573'],
+ ['#E8E8E8', '#60646C'],
['#EBEBFE', '#4747C2'],
['#E1E9FF', '#3A5BC7'],
],
diff --git a/app/javascript/dashboard/components-next/message/Message.vue b/app/javascript/dashboard/components-next/message/Message.vue
index df0602a49..150c57f85 100644
--- a/app/javascript/dashboard/components-next/message/Message.vue
+++ b/app/javascript/dashboard/components-next/message/Message.vue
@@ -117,7 +117,7 @@ const props = defineProps({
},
conversationId: { type: Number, required: true },
createdAt: { type: Number, required: true }, // eslint-disable-line vue/no-unused-properties
- currentUserId: { type: Number, required: true },
+ currentUserId: { type: Number, required: true }, // eslint-disable-line vue/no-unused-properties
groupWithNext: { type: Boolean, default: false },
inboxId: { type: Number, default: null }, // eslint-disable-line vue/no-unused-properties
inboxSupportsReplyTo: { type: Object, default: () => ({}) },
@@ -173,7 +173,11 @@ const variant = computed(() => {
return variants[props.messageType] || MESSAGE_VARIANTS.USER;
});
-const isMyMessage = computed(() => {
+const isBotOrAgentMessage = computed(() => {
+ if (props.messageType === MESSAGE_TYPES.ACTIVITY) {
+ return false;
+ }
+
// if an outgoing message is still processing, then it's definitely a
// message sent by the current user
if (
@@ -182,17 +186,15 @@ const isMyMessage = computed(() => {
) {
return true;
}
+
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();
});
/**
@@ -200,7 +202,7 @@ const isMyMessage = computed(() => {
* @returns {import('vue').ComputedRef<'left'|'right'|'center'>} The computed orientation
*/
const orientation = computed(() => {
- if (isMyMessage.value) {
+ if (isBotOrAgentMessage.value) {
return ORIENTATION.RIGHT;
}
@@ -221,8 +223,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 +233,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 +253,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;
});
@@ -414,6 +416,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;
@@ -433,7 +440,7 @@ provideMessageContext({
isPrivate: computed(() => props.private),
variant,
orientation,
- isMyMessage,
+ isBotOrAgentMessage,
shouldGroupWithNext,
});
@@ -443,7 +450,7 @@ provideMessageContext({
@@ -479,7 +487,13 @@ provideMessageContext({
{
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;
@@ -103,6 +107,17 @@ const getInReplyToMessage = parentMessage => {
return replyMessage ? useCamelCase(replyMessage) : null;
};
+
+const getMessageSpacingClass = (message, messages, index) => {
+ // For non-activity messages, use groupWithNext logic
+ if (message.messageType !== MESSAGE_TYPES.ACTIVITY) {
+ return shouldGroupWithNext(index, messages) ? 'mb-1' : 'mb-6';
+ }
+
+ // For activity messages, check next message exists and is also an activity
+ const nextMessage = messages[index + 1];
+ return nextMessage?.messageType === MESSAGE_TYPES.ACTIVITY ? 'mb-2' : 'mb-6';
+};
@@ -116,6 +131,7 @@ const getInReplyToMessage = parentMessage => {
:group-with-next="shouldGroupWithNext(index, read)"
:inbox-supports-reply-to="inboxSupportsReplyTo"
:current-user-id="currentUserId"
+ :class="getMessageSpacingClass(message, read, index)"
data-clarity-mask="True"
/>
@@ -128,6 +144,7 @@ const getInReplyToMessage = parentMessage => {
:inbox-supports-reply-to="inboxSupportsReplyTo"
:current-user-id="currentUserId"
:is-email-inbox="isAnEmailChannel"
+ :class="getMessageSpacingClass(message, unread, index)"
data-clarity-mask="True"
/>
diff --git a/app/javascript/dashboard/components-next/message/bubbles/Activity.vue b/app/javascript/dashboard/components-next/message/bubbles/Activity.vue
index d52286543..4e9300711 100644
--- a/app/javascript/dashboard/components-next/message/bubbles/Activity.vue
+++ b/app/javascript/dashboard/components-next/message/bubbles/Activity.vue
@@ -14,7 +14,7 @@ const readableTime = computed(() =>
diff --git a/app/javascript/dashboard/components-next/message/bubbles/Base.vue b/app/javascript/dashboard/components-next/message/bubbles/Base.vue
index aaf0cb1ba..20c5bbb9f 100644
--- a/app/javascript/dashboard/components-next/message/bubbles/Base.vue
+++ b/app/javascript/dashboard/components-next/message/bubbles/Base.vue
@@ -20,9 +20,9 @@ const varaintBaseMap = {
'bg-n-solid-amber text-n-amber-12 [&_.prosemirror-mention-node]:font-semibold',
[MESSAGE_VARIANTS.USER]: 'bg-n-slate-4 text-n-slate-12',
[MESSAGE_VARIANTS.ACTIVITY]: 'bg-n-alpha-1 text-n-slate-11 text-sm',
- [MESSAGE_VARIANTS.BOT]: 'bg-n-solid-iris text-n-slate-12',
- [MESSAGE_VARIANTS.TEMPLATE]: 'bg-n-solid-iris text-n-slate-12',
- [MESSAGE_VARIANTS.ERROR]: 'bg-n-ruby-4 text-n-ruby-12',
+ [MESSAGE_VARIANTS.BOT]: 'bg-n-solid-purple text-n-slate-12',
+ [MESSAGE_VARIANTS.TEMPLATE]: 'bg-n-solid-purple text-n-slate-12',
+ [MESSAGE_VARIANTS.ERROR]: 'bg-n-solid-red text-n-ruby-12',
[MESSAGE_VARIANTS.EMAIL]: 'w-full',
[MESSAGE_VARIANTS.UNSUPPORTED]:
'bg-n-solid-amber/70 border border-dashed border-n-amber-12 text-n-amber-12',
diff --git a/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue b/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue
index d494de908..832bcd3bc 100644
--- a/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue
+++ b/app/javascript/dashboard/components-next/message/bubbles/BaseAttachment.vue
@@ -60,13 +60,13 @@ const senderName = computed(() => {
:href="action.href"
rel="noreferrer noopener nofollow"
target="_blank"
- class="w-full block bg-n-solid-3 px-4 py-2 rounded-lg text-sm text-center border border-n-container"
+ class="w-full block bg-n-alpha-white px-4 py-2 rounded-lg text-sm text-center border border-n-container"
>
{{ action.label }}