Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions src/assets/styles/components/_chat.scss
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ $scroll-bar-width: 4px;
margin-top: unset; // resets margins of `.v-row + .v-row`
}

&--grouped {
margin-bottom: 4px;
}

&--grouped-left {
margin-bottom: 4px;
}

&--right {
float: right;
}
Expand All @@ -126,11 +134,34 @@ $scroll-bar-width: 4px;
&__message {
display: flex;
flex-direction: row;
padding-top: 8px;
padding-bottom: 8px;
padding-left: 16px;
padding-right: 16px;
border-radius: 8px;
padding: 8px 16px;
border-radius: 16px;
position: relative;

&::after {
content: "";
position: absolute;
bottom: 0;
width: 0;
height: 0;
border: 22px solid transparent;
}
}

&__message-container:not(&__message-container--right):not(&__message-container--grouped-left) .a-chat__message::after {
left: -6px;
border-right-color: white;
border-left: 0;
border-bottom: 0;
transform: rotate(-15deg);
}

&__message-container--right:not(&__message-container--grouped) .a-chat__message::after {
right: -6px;
border-left-color: white;
border-right: 0;
border-bottom: 0;
transform: rotate(15deg);
}

&__message-actions-icon {
Expand Down Expand Up @@ -532,6 +563,14 @@ $scroll-bar-width: 4px;
}
}

&__message-container--right:not(&__message-container--grouped) .a-chat__message::after {
border-left-color: map.get(colors.$adm-colors, 'black3');
}

&__message-container:not(&__message-container--right):not(&__message-container--grouped-left) .a-chat__message::after {
border-right-color: map.get(colors.$adm-colors, 'black3');
}

&__message-actions-icon {
background-image: linear-gradient(
45deg,
Expand Down
6 changes: 5 additions & 1 deletion src/components/AChat/AChatAttachment/AChatAttachment.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
:class="{
'a-chat__message-container--right': isStringEqualCI(transaction.senderId, userId),
'a-chat__message-container--transition': elementLeftOffset === 0,
'a-chat__message-container--disable-max-width': disableMaxWidth
'a-chat__message-container--disable-max-width': disableMaxWidth,
'a-chat__message-container--grouped':
!transaction.showBubble && isStringEqualCI(transaction.senderId, userId),
'a-chat__message-container--grouped-left':
!transaction.showBubble && !isStringEqualCI(transaction.senderId, userId)
}"
v-touch="{
move: onMove,
Expand Down
8 changes: 6 additions & 2 deletions src/components/AChat/AChatMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
:class="{
'a-chat__message-container--right': isStringEqualCI(transaction.senderId, userId),
'a-chat__message-container--transition': elementLeftOffset === 0,
'a-chat__message-container--disable-max-width': disableMaxWidth
'a-chat__message-container--disable-max-width': disableMaxWidth,
'a-chat__message-container--grouped':
!transaction.showBubble && isStringEqualCI(transaction.senderId, userId),
'a-chat__message-container--grouped-left':
!transaction.showBubble && !isStringEqualCI(transaction.senderId, userId)
}"
v-touch="{
move: onMove,
Expand All @@ -24,7 +28,7 @@
:data-id="dataId"
>
<div class="a-chat__message-card">
<div class="a-chat__message-card-header mt-1">
<div v-if="transaction.showTime" class="a-chat__message-card-header mt-1">
<div v-if="transaction.status === 'CONFIRMED'" class="a-chat__blockchain-status">
&#x26AD;
</div>
Expand Down
6 changes: 5 additions & 1 deletion src/components/AChat/AChatTransaction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
:class="{
'a-chat__message-container--right': isStringEqualCI(transaction.senderId, userId),
'a-chat__message-container--transition': elementLeftOffset === 0,
'a-chat__message-container--disable-max-width': disableMaxWidth
'a-chat__message-container--disable-max-width': disableMaxWidth,
'a-chat__message-container--grouped':
!transaction.showBubble && isStringEqualCI(transaction.senderId, userId),
'a-chat__message-container--grouped-left':
!transaction.showBubble && !isStringEqualCI(transaction.senderId, userId)
}"
v-touch="{
move: onMove,
Expand Down
44 changes: 42 additions & 2 deletions src/components/Chat/Chat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<free-tokens-dialog v-model="isShowFreeTokensDialog" />
<a-chat
ref="chatRef"
:messages="messages"
:messages="groupedMessages"
:show-new-chat-placeholder="showNewChatPlaceholder"
:partners="partners"
:partner-id="partnerId"
Expand Down Expand Up @@ -276,7 +276,13 @@ import { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, ref, wat
import Visibility from 'visibilityjs'
import copyToClipboard from 'copy-to-clipboard'

import { Cryptos, Fees, UPLOAD_MAX_FILE_COUNT, UPLOAD_MAX_FILE_SIZE } from '@/lib/constants'
import {
Cryptos,
Fees,
UPLOAD_MAX_FILE_COUNT,
UPLOAD_MAX_FILE_SIZE,
CHAT_MESSAGE_BUBBLE_TIME_OFFSET
} from '@/lib/constants'
import EmojiPicker from '@/components/EmojiPicker.vue'

import { mdiChevronDown } from '@mdi/js'
Expand Down Expand Up @@ -395,6 +401,40 @@ const isNewChat = computed(() => store.getters['chat/isNewChat'](props.partnerId
const shouldDisableInput = computed(
() => isGettingPublicKey.value || isKeyMissing.value || !store.state.publicKeys[props.partnerId]
)
const groupedMessages = computed(() => {
if (!messages.value.length) return []

const result: NormalizedChatMessageTransaction[] = []
let group: NormalizedChatMessageTransaction[] = []

messages.value.forEach((msg: NormalizedChatMessageTransaction, index: number) => {
const prevMsg = messages.value[index - 1]
const nextMsg = messages.value[index + 1]

const isSameGroupAsPrev =
prevMsg &&
msg.senderId === prevMsg.senderId &&
msg.timestamp - prevMsg.timestamp < CHAT_MESSAGE_BUBBLE_TIME_OFFSET
const isSameGroupAsNext =
nextMsg &&
msg.senderId === nextMsg.senderId &&
nextMsg.timestamp - msg.timestamp < CHAT_MESSAGE_BUBBLE_TIME_OFFSET

msg.showTime = !isSameGroupAsPrev

msg.showBubble = false

group.push(msg)

if (!isSameGroupAsNext) {
group[group.length - 1].showBubble = true
result.push(...group)
group = []
}
})

return result
})

const getPartnerName = (address: string) => {
const name: string = store.getters['partners/displayName'](address) || ''
Expand Down
2 changes: 2 additions & 0 deletions src/lib/chat/helpers/normalizeMessage.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export type NormalizedChatMessageTransaction = Pick<
asset: any // @todo types
localFiles?: LocalFile[] // in case of attachments
readonly?: boolean
showBubble?: boolean
showTime?: boolean
}

export function normalizeMessage(
Expand Down
5 changes: 5 additions & 0 deletions src/lib/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ export const REACT_EMOJIS = {
PARTY_POPPER: '🎉'
} as const

/**
* Time offset for grouping messages in the chat
**/
export const CHAT_MESSAGE_BUBBLE_TIME_OFFSET = 30000

/** Validation errors for the chat message */
export const VALIDATION_ERRORS = {
EmptyMessage: 'EMPTY_MESSAGE',
Expand Down