Skip to content

Commit 13589e6

Browse files
committed
(feat) add message selection
1 parent 04a4f9d commit 13589e6

File tree

12 files changed

+304
-82
lines changed

12 files changed

+304
-82
lines changed

demo/src/ChatContainer.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
:rooms-loaded="roomsLoaded"
5151
:room-actions="roomActions"
5252
:menu-actions="menuActions"
53+
:message-selection-actions="messageSelectionActions"
5354
:room-message="roomMessage"
5455
:templates-text="templatesText"
5556
@fetch-more-rooms="fetchMoreRooms"
@@ -62,6 +63,7 @@
6263
@add-room="addRoom"
6364
@room-action-handler="menuActionHandler"
6465
@menu-action-handler="menuActionHandler"
66+
@message-selection-action-handler="messageSelectionActionHandler"
6567
@send-message-reaction="sendMessageReaction"
6668
@typing-message="typingMessage"
6769
@toggle-rooms-list="$emit('show-demo-options', $event.opened)"
@@ -138,6 +140,7 @@ export default {
138140
{ name: 'removeUser', title: 'Remove User' },
139141
{ name: 'deleteRoom', title: 'Delete Room' }
140142
],
143+
messageSelectionActions: [{ name: 'deleteMessages', title: 'Delete' }],
141144
styles: { container: { borderRadius: '4px' } },
142145
templatesText: [
143146
{
@@ -687,6 +690,15 @@ export default {
687690
}
688691
},
689692
693+
messageSelectionActionHandler({ action, messages, roomId }) {
694+
switch (action.name) {
695+
case 'deleteMessages':
696+
messages.forEach(message => {
697+
this.deleteMessage({ message, roomId })
698+
})
699+
}
700+
},
701+
690702
async sendMessageReaction({ reaction, remove, messageId, roomId }) {
691703
firestoreService.updateMessageReactions(
692704
roomId,

src/lib/ChatWindow.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
:messages-loaded="messagesLoaded"
3939
:menu-actions="menuActions"
4040
:message-actions="messageActions"
41+
:message-selection-actions="messageSelectionActions"
4142
:auto-scroll="autoScroll"
4243
:show-send-icon="showSendIcon"
4344
:show-files="showFiles"
@@ -74,6 +75,7 @@
7475
@open-failed-message="openFailedMessage"
7576
@menu-action-handler="menuActionHandler"
7677
@message-action-handler="messageActionHandler"
78+
@message-selection-action-handler="messageSelectionActionHandler"
7779
@send-message-reaction="sendMessageReaction"
7880
@typing-message="typingMessage"
7981
@textarea-action-handler="textareaActionHandler"
@@ -137,9 +139,11 @@ export default {
137139
default: () => [
138140
{ name: 'replyMessage', title: 'Reply' },
139141
{ name: 'editMessage', title: 'Edit Message', onlyMe: true },
140-
{ name: 'deleteMessage', title: 'Delete Message', onlyMe: true }
142+
{ name: 'deleteMessage', title: 'Delete Message', onlyMe: true },
143+
{ name: 'selectMessages', title: 'Select' }
141144
]
142145
},
146+
messageSelectionActions: { type: Array, default: () => [] },
143147
autoScroll: {
144148
type: Object,
145149
default: () => {
@@ -214,7 +218,8 @@ export default {
214218
'textarea-action-handler',
215219
'fetch-more-rooms',
216220
'add-room',
217-
'room-action-handler'
221+
'room-action-handler',
222+
'message-selection-action-handler'
218223
],
219224
220225
data() {
@@ -400,6 +405,12 @@ export default {
400405
roomId: this.room.roomId
401406
})
402407
},
408+
messageSelectionActionHandler(ev) {
409+
this.$emit('message-selection-action-handler', {
410+
...ev,
411+
roomId: this.room.roomId
412+
})
413+
},
403414
sendMessageReaction(messageReaction) {
404415
this.$emit('send-message-reaction', {
405416
...messageReaction,

src/lib/Message/Message.scss

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
font-weight: 500;
1919
text-transform: uppercase;
2020
color: var(--chat-message-color-date);
21-
background: var(--chat-message-bg-color-date);
21+
background-color: var(--chat-message-bg-color-date);
2222
}
2323

2424
.vac-card-system {
2525
max-width: 250px;
2626
padding: 8px 4px;
2727
color: var(--chat-message-color-system);
28-
background: var(--chat-message-bg-color-system);
28+
background-color: var(--chat-message-bg-color-system);
2929
}
3030

3131
.vac-line-new {
@@ -120,7 +120,7 @@
120120
}
121121

122122
.vac-message-card {
123-
background: var(--chat-message-bg-color);
123+
background-color: var(--chat-message-bg-color);
124124
color: var(--chat-message-color);
125125
border-radius: 8px;
126126
font-size: 14px;
@@ -141,14 +141,19 @@
141141
}
142142

143143
.vac-message-current {
144-
background: var(--chat-message-bg-color-me) !important;
144+
background-color: var(--chat-message-bg-color-me) !important;
145145
}
146146

147147
.vac-message-deleted {
148148
color: var(--chat-message-color-deleted) !important;
149149
font-size: 13px !important;
150150
font-style: italic !important;
151-
background: var(--chat-message-bg-color-deleted) !important;
151+
background-color: var(--chat-message-bg-color-deleted) !important;
152+
}
153+
154+
.vac-message-selected {
155+
background-color: var(--chat-message-bg-color-selected) !important;
156+
transition: background-color 0.2s;
152157
}
153158

154159
.vac-icon-deleted {

src/lib/Message/Message.vue

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
v-else
2727
class="vac-message-box"
2828
:class="{ 'vac-offset-current': message.senderId === currentUserId }"
29+
@click="selectMessage"
2930
>
3031
<slot name="message" v-bind="{ message }">
3132
<div
@@ -48,7 +49,9 @@
4849
:class="{
4950
'vac-message-highlight': isMessageHover,
5051
'vac-message-current': message.senderId === currentUserId,
51-
'vac-message-deleted': message.deleted
52+
'vac-message-deleted': message.deleted,
53+
'vac-item-clickable': messageSelectionEnabled,
54+
'vac-message-selected': isMessageSelected
5255
}"
5356
@mouseover="onHoverMessage"
5457
@mouseleave="onLeaveMessage"
@@ -102,6 +105,7 @@
102105
:room-users="roomUsers"
103106
:text-formatting="textFormatting"
104107
:link-options="linkOptions"
108+
:message-selection-enabled="messageSelectionEnabled"
105109
@open-file="openFile"
106110
>
107111
<template v-for="(i, name) in $scopedSlots" #[name]="data">
@@ -248,7 +252,9 @@ export default {
248252
textFormatting: { type: Object, required: true },
249253
linkOptions: { type: Object, required: true },
250254
hideOptions: { type: Boolean, required: true },
251-
usernameOptions: { type: Object, required: true }
255+
usernameOptions: { type: Object, required: true },
256+
messageSelectionEnabled: { type: Boolean, required: true },
257+
selectedMessages: { type: Array, default: () => [] }
252258
},
253259
254260
emits: [
@@ -258,7 +264,9 @@ export default {
258264
'open-user-tag',
259265
'open-failed-message',
260266
'message-action-handler',
261-
'send-message-reaction'
267+
'send-message-reaction',
268+
'select-message',
269+
'unselect-message'
262270
],
263271
264272
data() {
@@ -321,6 +329,14 @@ export default {
321329
return this.messages.some(
322330
message => message.senderId !== this.currentUserId && message.avatar
323331
)
332+
},
333+
isMessageSelected() {
334+
return (
335+
this.messageSelectionEnabled &&
336+
!!this.selectedMessages.find(
337+
message => message._id === this.message._id
338+
)
339+
)
324340
}
325341
},
326342
@@ -338,6 +354,9 @@ export default {
338354
obj.index < res.index ? obj : res
339355
)
340356
}
357+
},
358+
messageSelectionEnabled() {
359+
this.resetMessageHover()
341360
}
342361
},
343362
@@ -353,14 +372,22 @@ export default {
353372
354373
methods: {
355374
onHoverMessage() {
356-
this.messageHover = true
357-
if (this.canEditMessage()) this.hoverMessageId = this.message._id
375+
if (!this.messageSelectionEnabled) {
376+
this.messageHover = true
377+
if (this.canEditMessage()) this.hoverMessageId = this.message._id
378+
}
358379
},
359380
canEditMessage() {
360381
return !this.message.deleted
361382
},
362383
onLeaveMessage() {
363-
if (!this.optionsOpened && !this.emojiOpened) this.messageHover = false
384+
if (!this.messageSelectionEnabled) {
385+
if (!this.optionsOpened && !this.emojiOpened) this.messageHover = false
386+
this.hoverMessageId = null
387+
}
388+
},
389+
resetMessageHover() {
390+
this.messageHover = false
364391
this.hoverMessageId = null
365392
},
366393
openFile(file) {
@@ -370,8 +397,7 @@ export default {
370397
this.$emit('open-user-tag', { user })
371398
},
372399
messageActionHandler(action) {
373-
this.messageHover = false
374-
this.hoverMessageId = null
400+
this.resetMessageHover()
375401
376402
setTimeout(() => {
377403
this.$emit('message-action-handler', { action, message: this.message })
@@ -384,6 +410,15 @@ export default {
384410
remove: reaction && reaction.indexOf(this.currentUserId) !== -1
385411
})
386412
this.messageHover = false
413+
},
414+
selectMessage() {
415+
if (this.messageSelectionEnabled) {
416+
if (this.isMessageSelected) {
417+
this.$emit('unselect-message', this.message._id)
418+
} else {
419+
this.$emit('select-message', this.message)
420+
}
421+
}
387422
}
388423
}
389424
}

src/lib/Message/MessageFiles/MessageFile/MessageFile.vue

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class="vac-message-image-container"
77
@mouseover="imageHover = true"
88
@mouseleave="imageHover = false"
9-
@click.stop="openFile('preview')"
9+
@click="openFile($event, 'preview')"
1010
>
1111
<progress-bar
1212
v-if="file.progress >= 0"
@@ -36,18 +36,21 @@
3636
}"
3737
>
3838
<transition name="vac-fade-image">
39-
<div v-if="imageHover && !isImageLoading" class="vac-image-buttons">
39+
<div
40+
v-if="!messageSelectionEnabled && imageHover && !isImageLoading"
41+
class="vac-image-buttons"
42+
>
4043
<div
4144
class="vac-svg-button vac-button-view"
42-
@click.stop="openFile('preview')"
45+
@click="openFile($event, 'preview')"
4346
>
4447
<slot name="eye-icon">
4548
<svg-icon name="eye" />
4649
</slot>
4750
</div>
4851
<div
4952
class="vac-svg-button vac-button-download"
50-
@click.stop="openFile('download')"
53+
@click="openFile($event, 'download')"
5154
>
5255
<slot name="document-icon">
5356
<svg-icon name="document" />
@@ -61,7 +64,7 @@
6164
<div
6265
v-else-if="isVideo"
6366
class="vac-video-container"
64-
@click.stop.prevent="openFile('preview')"
67+
@click.prevent="openFile('preview')"
6568
>
6669
<progress-bar v-if="file.progress >= 0" :progress="file.progress" />
6770
<video width="100%" height="100%" controls>
@@ -86,7 +89,8 @@ export default {
8689
currentUserId: { type: [String, Number], required: true },
8790
message: { type: Object, required: true },
8891
file: { type: Object, required: true },
89-
index: { type: Number, required: true }
92+
index: { type: Number, required: true },
93+
messageSelectionEnabled: { type: Boolean, required: true }
9094
},
9195
9296
emits: ['open-file'],
@@ -139,8 +143,11 @@ export default {
139143
image.src = this.file.url
140144
image.addEventListener('load', () => (this.imageLoading = false))
141145
},
142-
openFile(action) {
143-
this.$emit('open-file', { file: this.file, action })
146+
openFile(event, action) {
147+
if (!this.messageSelectionEnabled) {
148+
event.stopPropagation()
149+
this.$emit('open-file', { file: this.file, action })
150+
}
144151
}
145152
}
146153
}

src/lib/Message/MessageFiles/MessageFiles.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
:current-user-id="currentUserId"
77
:message="message"
88
:index="idx"
9+
:message-selection-enabled="messageSelectionEnabled"
910
@open-file="$emit('open-file', $event)"
1011
>
1112
<template v-for="(i, name) in $scopedSlots" #[name]="data">
@@ -71,7 +72,8 @@ export default {
7172
message: { type: Object, required: true },
7273
roomUsers: { type: Array, required: true },
7374
textFormatting: { type: Object, required: true },
74-
linkOptions: { type: Object, required: true }
75+
linkOptions: { type: Object, required: true },
76+
messageSelectionEnabled: { type: Boolean, required: true }
7577
},
7678
7779
emits: ['open-file', 'open-user-tag'],

0 commit comments

Comments
 (0)