@bcc-code/vue-bcc-chat-ui 6.5.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/assets/index-B_y7vs2y.js +12519 -0
  2. package/dist/assets/index-uEhSMl7W.css +1 -0
  3. package/dist/assets/primeicons-C6QP2o4f.woff2 +0 -0
  4. package/dist/assets/primeicons-DMOk5skT.eot +0 -0
  5. package/dist/assets/primeicons-Dr5RGzOO.svg +345 -0
  6. package/dist/assets/primeicons-MpK4pl85.ttf +0 -0
  7. package/dist/assets/primeicons-WjwUDZjB.woff +0 -0
  8. package/dist/assets/web-Cp3vw--c.js +1 -0
  9. package/dist/assets/web-DSc1BjG7.js +1 -0
  10. package/dist/index.html +13 -0
  11. package/package.json +42 -51
  12. package/README.md +0 -89
  13. package/dist/App.vue.d.ts +0 -2
  14. package/dist/chat/accessToken.d.ts +0 -3
  15. package/dist/chat/bccuiExtension.d.ts +0 -7
  16. package/dist/chat/cacheScope.d.ts +0 -13
  17. package/dist/chat/captionedAttachment.d.ts +0 -7
  18. package/dist/chat/captionedAttachmentExtension.d.ts +0 -7
  19. package/dist/chat/cometChatPatches.d.ts +0 -3
  20. package/dist/chat/connection.d.ts +0 -14
  21. package/dist/chat/data.d.ts +0 -24
  22. package/dist/chat/environment.d.ts +0 -3
  23. package/dist/chat/index.d.ts +0 -453
  24. package/dist/chat/logger.d.ts +0 -12
  25. package/dist/chat/login.d.ts +0 -14
  26. package/dist/chat/message.d.ts +0 -15
  27. package/dist/chat/replyExtension.d.ts +0 -26
  28. package/dist/chat/replyStyle.d.ts +0 -30
  29. package/dist/chat/rescheduleExtension.d.ts +0 -22
  30. package/dist/chat/scheduledMessage.d.ts +0 -4
  31. package/dist/chat/styleFix.d.ts +0 -14
  32. package/dist/chat/theme.d.ts +0 -408
  33. package/dist/chat/translations.d.ts +0 -3
  34. package/dist/chat/types.d.ts +0 -123
  35. package/dist/chat/uiKit.d.ts +0 -10
  36. package/dist/component-overrides/BccBubbleWrapper.vue.d.ts +0 -156
  37. package/dist/component-overrides/CometChatMessageListOverride.vue.d.ts +0 -2
  38. package/dist/components/BccAttachmentBox.vue.d.ts +0 -29
  39. package/dist/components/BccAttachmentPreview.vue.d.ts +0 -23
  40. package/dist/components/BccChatMessageBubble.vue.d.ts +0 -99
  41. package/dist/components/BccChatMessageList.vue.d.ts +0 -82
  42. package/dist/components/BccChatMessages.vue.d.ts +0 -33
  43. package/dist/components/BccChatSendButton.vue.d.ts +0 -4
  44. package/dist/components/BccCometChatFullScreenViewer.vue.d.ts +0 -24
  45. package/dist/components/BccFileBubble.vue.d.ts +0 -70
  46. package/dist/components/BccImageBubble.vue.d.ts +0 -27
  47. package/dist/components/BccReplyBox.vue.d.ts +0 -36
  48. package/dist/components/BccReplyPreview.vue.d.ts +0 -30
  49. package/dist/components/BccScheduledMessageIcon.vue.d.ts +0 -2
  50. package/dist/components/BccScheduledMessageModal.vue.d.ts +0 -31
  51. package/dist/components/BccScheduledMessages.vue.d.ts +0 -25
  52. package/dist/components/BccScheduledSendButton.vue.d.ts +0 -14
  53. package/dist/index.d.ts +0 -4
  54. package/dist/main.d.ts +0 -1
  55. package/dist/offline/cometChatAPIInterceptor.d.ts +0 -2
  56. package/dist/offline/cometChatWSInterceptor.d.ts +0 -2
  57. package/dist/offline/connectivity.d.ts +0 -5
  58. package/dist/offline/failedSendingRetry.d.ts +0 -4
  59. package/dist/offline/index.d.ts +0 -10
  60. package/dist/offline/offlineStoreLocalStorage.d.ts +0 -32
  61. package/dist/offline/types.d.ts +0 -69
  62. package/dist/vite.svg +0 -1
  63. package/dist/vue-bcc-chat-ui.css +0 -1
  64. package/dist/vue-bcc-chat-ui.js +0 -86486
  65. package/dist/vue-bcc-chat-ui.js.map +0 -1
  66. package/src/components/BccAttachmentBox.vue +0 -133
  67. package/src/components/BccAttachmentPreview.vue +0 -57
  68. package/src/components/BccChatMessageBubble.vue +0 -219
  69. package/src/components/BccChatMessageList.vue +0 -488
  70. package/src/components/BccChatMessages.vue +0 -212
  71. package/src/components/BccChatSendButton.vue +0 -91
  72. package/src/components/BccCometChatFullScreenViewer.vue +0 -118
  73. package/src/components/BccFileBubble.vue +0 -137
  74. package/src/components/BccImageBubble.vue +0 -75
  75. package/src/components/BccReplyBox.vue +0 -141
  76. package/src/components/BccReplyPreview.vue +0 -113
  77. package/src/components/BccScheduledMessageIcon.vue +0 -65
  78. package/src/components/BccScheduledMessageModal.vue +0 -70
  79. package/src/components/BccScheduledMessages.vue +0 -125
  80. package/src/components/BccScheduledSendButton.vue +0 -118
@@ -1,488 +0,0 @@
1
- <script setup lang="ts">
2
- import { CometChat, Group, GroupMember } from "@cometchat/chat-sdk-javascript";
3
- import { CometChatMessageEvents, MessageStatus } from "@cometchat/uikit-resources";
4
- import {
5
- PropType,
6
- Ref,
7
- onBeforeUnmount,
8
- onMounted,
9
- onUnmounted,
10
- provide,
11
- ref,
12
- watch,
13
- watchEffect,
14
- } from "vue";
15
- import chat from "../chat";
16
- import { connect, disconnect } from "../chat/connection";
17
- import { getGroupMembersInfo } from "../chat/data";
18
- import logger from "../chat/logger";
19
- import { loggedIn } from "../chat/login";
20
- import { watchAndApplyStyle } from "../chat/styleFix";
21
- import { ChatInstance, ParticipantInfo } from "../chat/types";
22
- import { offlineStore } from "../offline";
23
- import { onlineMode, onlineStatus } from "../offline/connectivity";
24
- import BccChatMessages from "./BccChatMessages.vue";
25
- import BccScheduledMessages from "./BccScheduledMessages.vue";
26
- const props = defineProps({
27
- chatUid: { type: String, required: true },
28
- senderDisplayName: { type: String, required: false },
29
- hideDeletedMessages: { type: Boolean, required: false, default: false },
30
- groupMessageGetter: {
31
- type: Function as PropType<(guid: string, query: string) => Promise<any>>,
32
- required: false,
33
- },
34
- loadMessageId: { type: String, required: false, default: "" },
35
- displayNoMessagesText: { type: Boolean, required: false, default: true },
36
- });
37
-
38
- const componentId = ref(
39
- `component-${Math.random().toString(36).substring(2, 11)}`
40
- );
41
- const chatGroup = ref<Group>();
42
- const chatGroupNotFound = ref(false);
43
-
44
- const isChatMessagesEmpty = ref(false);
45
-
46
- const emit = defineEmits(['groupMembersFetched']);
47
- const groupMembers = ref<ParticipantInfo[]>();
48
-
49
- const chatInstance: Ref<ChatInstance> = ref({
50
- componentId: componentId,
51
- replyToMessage: null,
52
- captionedAttachment: null,
53
- decoyAttachment: null,
54
- showScheduledMessagesChat: false,
55
- showAlert: false,
56
- showRescheduleAlert: false,
57
- userInput: null,
58
- rescheduleInfo: null
59
- });
60
-
61
- provide("chatInstance", chatInstance);
62
-
63
- const localLoadMessageId = ref(props.loadMessageId);
64
- watch(() => props.loadMessageId, (newVal) => {
65
- localLoadMessageId.value = newVal;
66
- });
67
-
68
- const onMessageSend = CometChatMessageEvents.ccMessageSent.subscribe(({ message, status }) => {
69
- if (status !== MessageStatus.inprogress) {
70
- return
71
- }
72
-
73
- let metadata: any = (message as any)?.getMetadata() || {};
74
- let scope: string | undefined = chatGroup.value?.getScope();
75
-
76
- if (chatInstance.value.replyToMessage) {
77
- metadata.replyToMessageId = chatInstance.value.replyToMessage?.getId();
78
- chatInstance.value.replyToMessage = null;
79
- }
80
-
81
- if (props.senderDisplayName && scope == "moderator") {
82
- metadata.senderDisplayName = props.senderDisplayName
83
- }
84
-
85
- const muid = window.crypto.randomUUID();
86
- message.setMuid(muid);
87
- const tags = (message as any).getTags() ?? [];
88
- tags.push(muid);
89
- (message as any).setTags(tags);
90
- (message as any).setMetadata(metadata);
91
- isChatMessagesEmpty.value = false;
92
- });
93
-
94
- watch([loggedIn, chat.onlineStatus, () => props.chatUid, chat.initialized, () => props.groupMessageGetter, chat.scrollToMessageId, localLoadMessageId], async ([_loggedIn, _online, _chatUid, _initialized, _groupMessageGetter, _scrollToMessageId, _localLoadMessageId]) => {
95
- logger.debug("ChatMessageList watch changed", { chatUid: _chatUid, loggedIn: _loggedIn, online: _online, initialized: _initialized });
96
- try {
97
- if (_loggedIn && _chatUid && _initialized) {
98
- chatGroupNotFound.value = false;
99
- const [_, group] = await Promise.all([
100
- connect(componentId.value),
101
- chat.getGroup(props.chatUid)
102
- ])
103
- chatGroup.value = group ?? undefined;
104
- chatGroupNotFound.value = group === undefined;
105
-
106
- if (_groupMessageGetter && !chatGroup.value?.getHasJoined()) {
107
- chat.updateGetGroupMessages(_groupMessageGetter)
108
- }
109
-
110
- if (_scrollToMessageId) {
111
- chat.scrollToMessage(_scrollToMessageId);
112
- }
113
-
114
- if (_localLoadMessageId) {
115
- chat.loadMessageId.value = _localLoadMessageId;
116
- localLoadMessageId.value = "";
117
- }
118
-
119
- isChatMessagesEmpty.value = false;
120
-
121
- if (chatGroup.value) {
122
-
123
- let isChannel = (chatGroup.value.getMetadata() as any).isChannel;
124
-
125
- watchAndApplyStyle(".bcc-chat-message-list-wrapper", [
126
- {
127
- selector: ".cc-messagebubble-wrapper__container",
128
- style: {
129
- "max-width": isChannel ? "95%" : "80%"
130
- }
131
- }
132
- ])
133
-
134
- // Allow some time for messages to load before displaying "no messages"
135
- setTimeout(() => {
136
- if (offlineStore.getGroupMessages(_chatUid, {
137
- per_page: 1,
138
- affix: 'prepend'
139
- }).total === 0) {
140
- isChatMessagesEmpty.value = true;
141
- } else {
142
- isChatMessagesEmpty.value = false;
143
- }
144
- }, 1500);
145
-
146
- if (!isChannel) {
147
- getGroupMembersInfo(_chatUid).then((participants) => groupMembers.value = participants);
148
- } else {
149
- groupMembers.value = [];
150
- }
151
- }
152
- await chat.clearGroupChatCount(props.chatUid);
153
- } else if (chatGroup.value) {
154
- chatGroup.value = undefined;
155
- }
156
- } catch (error) {
157
- logger.error("Error in ChatMessageList watch", { error, chatUid: _chatUid, loggedIn: _loggedIn, online: _online, initialized: _initialized });
158
- }
159
- }, { immediate: true });
160
-
161
- watchEffect(() => {
162
- if (groupMembers.value && groupMembers.value.length) {
163
- emit('groupMembersFetched', groupMembers.value);
164
- } else {
165
- emit('groupMembersFetched', []);
166
- }
167
- })
168
-
169
- onMounted(() => {
170
- logger.debug("Mounting chat", { chatUid: props.chatUid });
171
- setTimeout(() => {
172
- if (!chatGroup.value && !chatGroupNotFound.value) {
173
- logger.error("Chat not loaded after 5 seconds", { chatUid: props.chatUid, connected: chat.connected.value, loggedIn: loggedIn.value, onlineMode: onlineMode.value, onlineStatus: onlineStatus.value, initialized: chat.initialized.value });
174
- } else {
175
- logger.debug("Chat successfully loaded", { chatUid: props.chatUid, connected: chat.connected.value, loggedIn: loggedIn.value, onlineMode: onlineMode.value, onlineStatus: onlineStatus.value, initialized: chat.initialized.value });
176
- }
177
- }, 5000);
178
- watchAndApplyStyle(".bcc-chat-message-list-wrapper", [
179
- {
180
- selector: ".cc__text",
181
- style: { color: "var(--cc__text-color)" },
182
- shadowDomSelector: "cometchat-text-bubble",
183
- },
184
- {
185
- selector: ".cc__preview__subtitle",
186
- style: {
187
- "overflow": "hidden",
188
- "display": "-webkit-box",
189
- "-webkit-box-orient": "vertical",
190
- "-webkit-line-clamp": "1",
191
- "word-break": "break-all"
192
- },
193
- shadowDomSelector: "cometchat-preview",
194
- },
195
- {
196
- selector: ".cc__polldata",
197
- style: { color: "var(--cc__primary150)" },
198
- shadowDomSelector: "create-poll"
199
- },
200
- {
201
- selector: ".cc__pollsbubble__option",
202
- style: {
203
- backgroundColor: "var(--cc__background)",
204
- },
205
- shadowDomSelector: "polls-bubble"
206
- },
207
- ]);
208
-
209
-
210
- CometChat.addGroupListener("groupListener", new CometChat.GroupListener({
211
- onGroupMemberScopeChanged: (_action: any, changedUser: GroupMember, newScope: any, _oldScope: any, _changedGroup: GroupMember) => {
212
- handleGroupMemberChanges(changedUser, "update", newScope);
213
- },
214
- onGroupMemberKicked: (_action: any, changedUser: GroupMember, _Ye: any, _group: any) => {
215
- handleGroupMemberChanges(changedUser, "remove");
216
- },
217
- onGroupMemberBanned: (_action: any, user: GroupMember, _Ye: any, _group: any) => {
218
- handleGroupMemberChanges(user, "remove");
219
- },
220
- onGroupMemberUnbanned: (_action: any, user: GroupMember, _Ye: any, _group: any) => {
221
- handleGroupMemberChanges(user, "add");
222
- },
223
- onMemberAddedToGroup: (_action: any, user: GroupMember, _Ye: any, _group: any) => {
224
- handleGroupMemberChanges(user, "add");
225
- },
226
- onGroupMemberLeft: (_action: any, user: GroupMember, _group: any) => {
227
- handleGroupMemberChanges(user, "remove");
228
- },
229
- onGroupMemberJoined: (_action: any, user: GroupMember, _group: any) => {
230
- handleGroupMemberChanges(user, "add");
231
- }
232
- }))
233
- });
234
-
235
- onBeforeUnmount(() => {
236
- onMessageSend.unsubscribe();
237
- })
238
-
239
- onUnmounted(async () => {
240
- await disconnect(componentId.value);
241
- });
242
-
243
- function handleGroupMemberChanges(changedUser: GroupMember, action: string, newScope?: string) {
244
- let participant: ParticipantInfo = {
245
- uid: changedUser.getUid(),
246
- displayName: changedUser.getName(),
247
- avatar: changedUser.getAvatar(),
248
- role: newScope ? newScope : CometChat.GROUP_MEMBER_SCOPE.PARTICIPANT
249
- }
250
-
251
- if (action === "add" && !existsInGroup(changedUser.getUid())) {
252
- groupMembers.value?.push(participant)
253
- }
254
-
255
- if (action === "remove" && existsInGroup(changedUser.getUid())) {
256
- groupMembers.value = groupMembers.value?.filter(participant => participant.uid !== changedUser.getUid());
257
- }
258
-
259
- if (action === "update" && existsInGroup(changedUser.getUid())) {
260
- groupMembers.value = groupMembers.value?.map(p => p.uid === changedUser.getUid() ? { ...p, ...participant } : p);
261
- }
262
- }
263
-
264
- function existsInGroup(uid: string): boolean {
265
- return groupMembers.value?.some(p => p.uid === uid) ?? false;
266
- }
267
-
268
- function closeScheduledMessage() {
269
- chatInstance.value.captionedAttachment = null
270
- chatInstance.value.replyToMessage = null
271
- chatInstance.value.scheduledMessageChat = undefined
272
- chatInstance.value.showScheduledMessagesChat = false;
273
- }
274
-
275
- </script>
276
-
277
- <template>
278
- <div class="bcc-chat-message-list-wrapper" :class="componentId">
279
- <BccScheduledMessages v-if="chatGroup && chatInstance.showScheduledMessagesChat"
280
- class="bcc-scheduled-message-list" :chatGroup="chatInstance.scheduledMessageChat!"
281
- :originalChatUid="props.chatUid" @close="closeScheduledMessage()" />
282
-
283
- <BccChatMessages v-else-if="chatGroup" :chatGroup="chatGroup"
284
- :hide-deleted-messages="props.hideDeletedMessages" :chatUid="props.chatUid" />
285
-
286
- <div v-else class="bcc-chat-message-list-offline">
287
- <span v-if="chat.onlineStatus.value === 'offline'">
288
- Waiting for network...
289
- </span>
290
- <span v-else-if="!chat.connected.value">
291
- Connecting...
292
- </span>
293
- <span v-else-if="chatGroupNotFound">
294
- Chat not found...
295
- </span>
296
- <span v-else-if="!chatGroup">
297
- Loading chat...
298
- </span>
299
- <span v-else>
300
- Loading...
301
- </span>
302
- </div>
303
-
304
- <div v-if="isChatMessagesEmpty && chatGroup && !chatInstance.showScheduledMessagesChat" class="bcc-chat-message-list-offline pointer-events-none">
305
- <slot name="no-messages">
306
- <span>No messages have been sent yet</span>
307
- </slot>
308
- </div>
309
- </div>
310
- </template>
311
-
312
- <style lang="scss">
313
- .bcc-chat-message-list-wrapper {
314
- position: relative;
315
- height: 100%;
316
- }
317
-
318
- /*
319
- primary: my bubble
320
- accent: message bar text
321
- accent100: message bar and widget buttons bg, others bubble
322
- accent200: horizontal line on message bar
323
- accent500: icons on message bar
324
- accent600: dates and date separator and popup icons
325
- accent700: avatar background, widget buttons text
326
- accent900: text in avatar
327
- */
328
-
329
- .bcc-chat-message-list {
330
- --cc__primary: #cfeac8;
331
- --cc__primary150: #004e48;
332
- --cc__background: #f3faf7;
333
- --cc__secondary: white;
334
- --cc__accent: #004e48;
335
- --cc__accent50: rgba(62, 142, 117, 0.04);
336
- --cc__accent100: #ffffff;
337
- --cc__accent200: rgba(62, 142, 117, 0.15);
338
- --cc__accent300: rgba(62, 142, 117, 0.24);
339
- --cc__accent400: rgba(62, 142, 117, 0.33);
340
- --cc__accent500: rgba(62, 142, 117, 0.46);
341
- --cc__accent600: #004e48;
342
- --cc__accent700: #254a40;
343
- --cc__accent800: rgba(62, 142, 117, 0.82);
344
- --cc__accent900: #f3faf7;
345
- --cc__text-color: #000;
346
- --cc__link-color: #57639e;
347
- }
348
-
349
- :root.dark .bcc-chat-message-list {
350
- --cc__primary: #57639e;
351
- --cc__primary150: #57639e;
352
- --cc__background: hsl(230, 25%, 15%);
353
- --cc__secondary: #111827;
354
- --cc__accent: #758abc;
355
- --cc__accent50: rgba(98, 116, 174, 0.24);
356
- --cc__accent100: linear-gradient(45deg, #05070b 0%, #0c111c 100%);
357
- --cc__accent200: rgba(98, 116, 174, 0.35);
358
- --cc__accent300: rgba(98, 116, 174, 0.44);
359
- --cc__accent400: rgba(98, 116, 174, 0.53);
360
- --cc__accent500: rgba(98, 116, 174, 0.66);
361
- --cc__accent600: #758abc;
362
- --cc__accent700: #6274ae;
363
- --cc__accent800: rgba(98, 116, 174, 0.92);
364
- --cc__accent900: #090A0B;
365
- --cc__text-color: #fff;
366
- --cc__link-color: #cfeac8;
367
- }
368
-
369
- .bcc-chat-message-list {
370
- height: 100%;
371
-
372
- /* 1. Wrapper for Messages component */
373
- .cc-messages-wrapper {
374
-
375
- /* 1.1 Messages component */
376
- .cc-messages-wrapper__messages {
377
-
378
- /* 1.1.1 Wrapper for Messages List */
379
- .cc-messages-wrapper__messages-list {
380
- height: 100%;
381
- }
382
-
383
- /* 1.1.2 Wrapper for Messages Composer */
384
- .cc-messagecomposer-wrapper {
385
- //padding: 0; //Use to remove side padding on composer
386
- }
387
-
388
- /* 1.1.3 Wrapper for Messages Composer Header View */
389
- .cc-messagecomposer-wrapper__headerview {
390
- max-height: 100%;
391
- margin-bottom: 5px;
392
- }
393
- }
394
-
395
- .cc-messagebubble-wrapper__content {
396
- max-width: 100%;
397
- }
398
-
399
- .cc-messagebubble-wrapper__content>div>.bcc-message-wrapper.has-text.has-image+div>div>div:not([class]) {
400
- justify-content: flex-end !important;
401
- padding: 0px 8px 8px !important;
402
- margin-top: -5px !important;
403
- height: unset !important;
404
- border-radius: unset !important;
405
- line-height: unset !important;
406
- position: unset !important;
407
- margin-right: unset !important;
408
- background: unset !important;
409
- }
410
- }
411
-
412
- .cc-messagebubble-wrapper__container {
413
- max-width: 80%;
414
- }
415
-
416
- .cc-messagebubble-wrapper__messageoptions {
417
- border-radius: 8px;
418
-
419
- .cc-context-menu__top-menu {
420
- border: 1px var(--cc__secondary) solid !important;
421
- }
422
- }
423
-
424
-
425
- /* 2. Message for Messages Composer when offline */
426
- .bcc-chat-message-composer-offline {
427
- position: relative;
428
- bottom: 38px;
429
- text-align: center;
430
- //height: 96px;
431
- width: 100%;
432
- //backdrop-filter: blur(4px);
433
- font: 500 11px sans-serif;
434
-
435
- /* 2.1 Text of Messages Composer offline view */
436
- span {
437
- width: 150px;
438
- display: inline;
439
- padding: 4px 6px;
440
- color: var(--cc__text-color);
441
- background: var(--cc__primary);
442
- border-radius: 8px;
443
- }
444
- }
445
-
446
- /* Hide send button when offline */
447
- &.offline .messageinput__primaryactions,
448
- &.offline .messageinput__auxiliaryactions,
449
- &.offline .messageinput__secondaryactions {
450
- opacity: 0.2;
451
- }
452
-
453
- }
454
-
455
- .bcc-chat-message-list-offline {
456
- position: absolute;
457
- top: 0;
458
- bottom: 0;
459
- left: 0;
460
- right: 0;
461
- display: flex;
462
- justify-content: center;
463
- align-items: center;
464
- font: 700 22px sans-serif;
465
- color: #bcbcbc;
466
- }
467
-
468
- .cc-messagecomposer__emojikeyboard {
469
- display: none;
470
- }
471
-
472
- // Hide emoji keyboard
473
- .cc-messagecomposer__emojikeyboard {
474
- display: none;
475
- }
476
-
477
- .cc-threadedmessages-wrapper__bubbleview::-webkit-scrollbar,
478
- .cc__message-list::-webkit-scrollbar {
479
- background: transparent;
480
- width: 8px;
481
- }
482
-
483
- .cc-threadedmessages-wrapper__bubbleview::-webkit-scrollbar-thumb,
484
- .cc__message-list::-webkit-scrollbar-thumb {
485
- background: rgb(232, 229, 229);
486
- border-radius: 8px;
487
- }
488
- </style>
@@ -1,212 +0,0 @@
1
- <script setup lang="ts">
2
- import { BccMessage } from "@bcc-code/component-library-vue";
3
- import { Group } from "@cometchat/chat-sdk-javascript";
4
- import { localize } from "@cometchat/uikit-resources";
5
- import { MessageComposerConfiguration } from "@cometchat/uikit-shared";
6
- import { computed, inject, nextTick, onMounted, onUnmounted, Ref, ref, watch, watchEffect } from 'vue';
7
- import chat from "../chat";
8
- import { CometChatMessages } from "../chat/cometChatPatches";
9
- import { sendScheduledMessage } from "../chat/scheduledMessage";
10
- import { ChatInstance } from '../chat/types';
11
- import { getMessageComposerConfiguration, getMessageListConfiguration, getThreadedMessagesConfiguration } from "../chat/uiKit";
12
- import BccAttachmentBox from "./BccAttachmentBox.vue";
13
- import BccChatSendButton from "./BccChatSendButton.vue";
14
- import BccScheduledMessageModal from "./BccScheduledMessageModal.vue";
15
-
16
- const props = defineProps({
17
- chatUid: { type: String, required: true },
18
- chatGroup: { type: Group, required: true },
19
- hideDeletedMessages: { type: Boolean, required: false, default: false }
20
- })
21
-
22
- const isOffline = computed(() => chat.onlineStatus.value === 'offline');
23
-
24
- const chatGroup = ref<Group>();
25
-
26
- const chatInstance = inject<Ref<ChatInstance>>("chatInstance");
27
- const messageComposerConfiguration = getMessageComposerConfiguration(chatInstance);
28
- const messageListConfiguration = getMessageListConfiguration(props.hideDeletedMessages, chatInstance, chatGroup);
29
- const threadedMessagesConfiguration = getThreadedMessagesConfiguration(chatGroup);
30
- threadedMessagesConfiguration.messageComposerConfiguration = getThreadedMessageComposerConfig();
31
-
32
- onMounted(async () => {
33
- chatGroup.value = props.chatGroup
34
- attachEventlisteners();
35
-
36
- messageComposerConfiguration.value.text = chatInstance?.value.userInput ?? '';
37
-
38
- await nextTick();
39
- if (chatInstance?.value.decoyAttachment) {
40
- chatInstance.value.captionedAttachment = chatInstance.value.decoyAttachment
41
- chatInstance.value.decoyAttachment = null
42
- }
43
- })
44
-
45
- onUnmounted(() => {
46
- detachEventlisteners();
47
- })
48
-
49
- watch(() => props.chatGroup,
50
- (group) => {
51
- chatGroup.value = group;
52
- }
53
- );
54
-
55
- watchEffect(() => {
56
- if (chatInstance && chatInstance.value.captionedAttachment) {
57
- messageComposerConfiguration.value.headerView = {
58
- componentName: BccAttachmentBox,
59
- props: {
60
- captionedAttachment: chatInstance.value.captionedAttachment
61
- }
62
- }
63
-
64
- messageComposerConfiguration.value.sendButtonView = {
65
- componentName: BccChatSendButton,
66
- props: {
67
- chatUid: props.chatUid
68
- }
69
- };
70
- detachEventlisteners()
71
- attachEventlisteners()
72
- } else {
73
- if (chatInstance && chatInstance.value.replyToMessage) {
74
- messageComposerConfiguration.value.headerView = {
75
- componentName: "bcc-reply-box",
76
- props: {
77
- replyToMessage: chatInstance.value.replyToMessage,
78
- }
79
- };
80
- } else {
81
- messageComposerConfiguration.value.headerView = undefined;
82
- }
83
- messageComposerConfiguration.value.sendButtonView = undefined;
84
- }
85
- });
86
-
87
- function getThreadedMessageComposerConfig(): MessageComposerConfiguration {
88
- let composerConfig = { ...messageComposerConfiguration.value }
89
- composerConfig.auxilaryButtonView = undefined
90
- return composerConfig;
91
- }
92
-
93
- // Holding functionality temporarily disabled due to some bugs
94
-
95
- function attachEventlisteners() {
96
- const interval = setInterval(() => {
97
- const btns = document.querySelectorAll('.cc-messagecomposer-wrapper__sendbutton');
98
- const sendButton = btns[btns.length - 1]
99
- document.querySelector("body")?.addEventListener("contextmenu", (event) => event.preventDefault());
100
-
101
- if (sendButton) {
102
- sendButton.addEventListener("pointerdown", onMouseDown);
103
- sendButton.addEventListener("pointerup", clearTimer);
104
- sendButton.addEventListener("mouseleave", clearTimer);
105
- sendButton.addEventListener("contextmenu", onContextMenu);
106
- clearInterval(interval)
107
- }
108
- }, 500);
109
- }
110
-
111
- function detachEventlisteners() {
112
- const btns = document.querySelectorAll('.cc-messagecomposer-wrapper__sendbutton');
113
- const sendButton = btns[btns.length - 1]
114
-
115
- if (sendButton) {
116
- sendButton.removeEventListener("pointerdown", onMouseDown);
117
- sendButton.removeEventListener("pointerup", clearTimer);
118
- sendButton.removeEventListener("mouseleave", clearTimer);
119
- sendButton.removeEventListener("contextmenu", onContextMenu);
120
- }
121
- }
122
-
123
- function closeModal() {
124
- showModal.value = false;
125
- }
126
-
127
- const showModal = ref(false);
128
- let timerId: string | number | NodeJS.Timeout | null | undefined;
129
- const duration = 500;
130
- let longPressDetected = false;
131
-
132
- const openPopup = () => {
133
- showModal.value = true;
134
- }
135
-
136
- const onMouseDown = (event: Event) => {
137
- const userInput = document.querySelector<HTMLElement>(".messageinput-input")?.innerText;
138
- event.preventDefault();
139
- event.stopPropagation();
140
- if (userInput) {
141
- // Only handle long press when there is user input
142
- timerId = setTimeout(() => {
143
- longPressDetected = true;
144
- openPopup();
145
- }, duration); // assuming duration is 500ms for long press
146
- }
147
- };
148
-
149
- const showAlert = ref<boolean>(false);
150
-
151
- const onContextMenu = (event: Event) => {
152
- if (longPressDetected) {
153
- // Prevent context menu only when long press is detected
154
- event.preventDefault();
155
- event.stopPropagation();
156
- }
157
- };
158
-
159
- const clearTimer = (event: Event) => {
160
- event.preventDefault();
161
- event.stopPropagation();
162
- if (timerId !== null) {
163
- clearTimeout(timerId);
164
- timerId = null;
165
- }
166
- }
167
-
168
- function scheduleMessage(scheduleDate?: string) {
169
- if (scheduleDate && chatInstance) {
170
- sendScheduledMessage(scheduleDate, props.chatUid, chatInstance).then((msgSuccessful) => {
171
- if (!msgSuccessful) {
172
- showModal.value = false
173
- showAlert.value = true
174
- setTimeout(() => showAlert.value = false, 3000)
175
- }
176
- })
177
- }
178
- }
179
-
180
- function isChannel(): boolean {
181
- return (props.chatGroup.getMetadata() as any)?.isChannel;
182
- }
183
-
184
- function isParticipant(): boolean {
185
- //if not part of the group return true anyway since getScope dosen't exist when not in the group
186
- if (!chatGroup.value?.getHasJoined()) {
187
- return true
188
- }
189
- return chatGroup.value?.getScope() == "participant";
190
- }
191
- </script>
192
-
193
- <template>
194
- <div :class="'bcc-chat-message-list' + (isOffline ? ' offline' : '')">
195
- <CometChatMessages :hideMessageHeader="true" :disableSoundForMessages="true"
196
- :messageComposerConfiguration="messageComposerConfiguration"
197
- :messageListConfiguration="messageListConfiguration"
198
- :threadedMessagesConfiguration="threadedMessagesConfiguration"
199
- :hideMessageComposer="(isParticipant() && isChannel())" :hideDetails="true" :group="chatGroup" />
200
- <div v-if="chat.onlineStatus.value === 'offline' || !chat.connected.value"
201
- class="bcc-chat-message-composer-offline">
202
- <span v-if="isOffline">Waiting for network...</span>
203
- <span v-else>Connecting... </span>
204
- </div>
205
- <BccScheduledMessageModal v-if="showModal" @close="closeModal()" @send="scheduleMessage" :closeOnOutsideClick="false">
206
- </BccScheduledMessageModal>
207
- <BccMessage v-if="showAlert" class="absolute top-0 w-[97%] mx-2 mt-1" icon severity="error"
208
- closable @close="showAlert = false">
209
- {{ localize("ERROR_SENDING_SCHEDULED_MESSAGE") }}
210
- </BccMessage>
211
- </div>
212
- </template>