@tencentcloud/ai-desk-customer-vue 1.5.6 → 1.5.9
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.
- package/CHANGELOG.md +18 -0
- package/assets/feedback_dislike_after.svg +1 -1
- package/assets/feedback_dislike_before.svg +2 -9
- package/assets/feedback_dislike_hover.svg +2 -9
- package/assets/feedback_like_after.svg +2 -13
- package/assets/feedback_like_before.svg +2 -9
- package/assets/feedback_like_hover.svg +2 -9
- package/components/CustomerServiceChat/chat-header/index-web.vue +19 -12
- package/components/CustomerServiceChat/feedback-modal/index.vue +391 -0
- package/components/CustomerServiceChat/index-web.vue +34 -1
- package/components/CustomerServiceChat/message-input/message-input-editor-web.vue +0 -1
- package/components/CustomerServiceChat/message-input/message-input-quote/index.vue +0 -3
- package/components/CustomerServiceChat/message-input-toolbar/index-web.vue +4 -2
- package/components/CustomerServiceChat/message-list/bottom-quick-order/index.vue +0 -1
- package/components/CustomerServiceChat/message-list/index-web.vue +92 -62
- package/components/CustomerServiceChat/message-list/message-elements/feedback-button.vue +96 -251
- package/components/CustomerServiceChat/message-list/message-elements/message-bubble-web.vue +51 -16
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-concurrency-limit.vue +0 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-ivr-form/form-branch.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-branch/branch-pc.vue +0 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-mobile.vue +34 -29
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-multi-form/form-pc.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-order.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-product-card.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-rating/message-rating-star.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-stream.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/message-transfer-with-desc.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-desk-elements/styles/common.scss +0 -2
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-layout-web.vue +16 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-desk/message-plugin-web.vue +18 -0
- package/components/CustomerServiceChat/message-list/message-elements/message-quote/index-web.vue +0 -3
- package/components/CustomerServiceChat/message-list/message-elements/message-text.vue +26 -19
- package/components/CustomerServiceChat/message-list/message-elements/message-timestamp.vue +0 -1
- package/components/CustomerServiceChat/message-list/message-elements/read-status/index.vue +4 -2
- package/components/CustomerServiceChat/message-list/scroll-button/index.vue +8 -4
- package/components/CustomerServiceChat/message-list/style/web.scss +0 -2
- package/components/CustomerServiceChat/message-toolbar-button/index.vue +13 -9
- package/components/CustomerServiceChat/message-toolbar-button/toolbar-button-end-human-service.vue +1 -1
- package/components/CustomerServiceChat/style/common.scss +4 -0
- package/components/CustomerServiceChat/style/web.scss +2 -1
- package/components/common/BottomPopup/style/h5.scss +0 -1
- package/components/common/Dialog/style/color.scss +0 -1
- package/components/common/Toast/index-web.vue +1 -1
- package/constant.ts +3 -2
- package/locales/en/aidesk.ts +18 -15
- package/locales/fil/aidesk.ts +17 -15
- package/locales/id/aidesk.ts +17 -15
- package/locales/ja/aidesk.ts +17 -15
- package/locales/ms/aidesk.ts +17 -15
- package/locales/ru/aidesk.ts +17 -15
- package/locales/th/aidesk.ts +17 -15
- package/locales/vi/aidesk.ts +17 -15
- package/locales/zh_cn/aidesk.ts +17 -14
- package/locales/zh_tw/aidesk.ts +17 -15
- package/package.json +1 -1
- package/server.ts +5 -4
- package/utils/index.ts +6 -0
- package/utils/utils.ts +42 -0
- package/assets/customer_avatar.png +0 -0
|
@@ -24,9 +24,13 @@
|
|
|
24
24
|
:bottomQuickOrder="props.bottomQuickOrder"
|
|
25
25
|
:showBottomQuickOrder="showBottomQuickOrder"
|
|
26
26
|
@closeBottomQuickOrder="closeBottomQuickOrder"
|
|
27
|
+
:enableFeedback="props.enableFeedback"
|
|
28
|
+
:enableAINote="props.enableAINote"
|
|
29
|
+
@like="onLike"
|
|
30
|
+
@dislike="onDislike"
|
|
27
31
|
/>
|
|
28
32
|
<MessageToolbarButton
|
|
29
|
-
v-if="!isH5 || (!Boolean(quoteMessage) && !showBottomQuickOrder)"
|
|
33
|
+
v-if="props.toolbarButtonList && (!isH5 || (!Boolean(quoteMessage) && !showBottomQuickOrder))"
|
|
30
34
|
:toolbarButtonList="props.toolbarButtonList"
|
|
31
35
|
/>
|
|
32
36
|
<MessageInputToolbar
|
|
@@ -82,6 +86,11 @@
|
|
|
82
86
|
/>
|
|
83
87
|
</div>
|
|
84
88
|
</div>
|
|
89
|
+
<FeedbackModal
|
|
90
|
+
ref="feedbackModalRef"
|
|
91
|
+
v-show="showFeedbackModal"
|
|
92
|
+
@close="() => { showFeedbackModal = false }"
|
|
93
|
+
/>
|
|
85
94
|
</div>
|
|
86
95
|
</div>
|
|
87
96
|
</template>
|
|
@@ -110,6 +119,7 @@ import { Toast, TOAST_TYPE } from '../common/Toast/index-web';
|
|
|
110
119
|
import state from '../../utils/state.js';
|
|
111
120
|
import { switchReadStatus,isNonEmptyObject } from '../../utils/utils';
|
|
112
121
|
import { getCountryForTimezone } from 'countries-and-timezones';
|
|
122
|
+
import FeedbackModal from './feedback-modal/index.vue';
|
|
113
123
|
const { ref, onMounted, onUnmounted, computed } = vue;
|
|
114
124
|
|
|
115
125
|
interface IProps {
|
|
@@ -134,6 +144,9 @@ interface IProps {
|
|
|
134
144
|
bottomQuickOrder?: QuickOrderModel;
|
|
135
145
|
enableMultilingual?: number;
|
|
136
146
|
langList?: Array<string>;
|
|
147
|
+
enableFeedback?: number;
|
|
148
|
+
enableAINote?: number;
|
|
149
|
+
enableURLDetection?: number;
|
|
137
150
|
}
|
|
138
151
|
|
|
139
152
|
const emits = defineEmits(['closeChat']);
|
|
@@ -151,6 +164,8 @@ const quoteMessage = ref<IMessageModel>();
|
|
|
151
164
|
const showBottomQuickOrder = ref(false);
|
|
152
165
|
const currentLanguage = ref('');
|
|
153
166
|
const languageForShowList = ref<Array<string>>([]);
|
|
167
|
+
const feedbackModalRef = ref();
|
|
168
|
+
const showFeedbackModal = ref(false);
|
|
154
169
|
let timezone = '';
|
|
155
170
|
let countryID = '';
|
|
156
171
|
const props = withDefaults(defineProps<IProps>(), {
|
|
@@ -171,7 +186,10 @@ const props = withDefaults(defineProps<IProps>(), {
|
|
|
171
186
|
userNickName: '',
|
|
172
187
|
showTyping: 0,
|
|
173
188
|
enableMultilingual: 0,
|
|
189
|
+
enableFeedback: 0,
|
|
190
|
+
enableAINote: 1,
|
|
174
191
|
langList: () => [],
|
|
192
|
+
enableURLDetection: 0,
|
|
175
193
|
});
|
|
176
194
|
|
|
177
195
|
const loginCustomerUIKit = () => {
|
|
@@ -283,6 +301,10 @@ const setShowTyping = () => {
|
|
|
283
301
|
state.set('showTyping', props.showTyping);
|
|
284
302
|
}
|
|
285
303
|
|
|
304
|
+
const setEnableURLDetection = () => {
|
|
305
|
+
state.set('enableURLDetection', props.enableURLDetection);
|
|
306
|
+
}
|
|
307
|
+
|
|
286
308
|
try {
|
|
287
309
|
const userContext = TUILogin.getContext();
|
|
288
310
|
if (userContext.userID == '' && props.SDKAppID !==0 && props.userID !=='' && props.userSig !==''){
|
|
@@ -295,6 +317,7 @@ try {
|
|
|
295
317
|
setAvatarNickName();
|
|
296
318
|
setShowReadStatus();
|
|
297
319
|
setShowTyping();
|
|
320
|
+
setEnableURLDetection();
|
|
298
321
|
getTimeZoneAndCountry();
|
|
299
322
|
if (isNonEmptyObject(props.bottomQuickOrder)) {
|
|
300
323
|
showBottomQuickOrder.value = true;
|
|
@@ -437,6 +460,7 @@ function changeLanguage(languageCode: string) {
|
|
|
437
460
|
Log.l(`multilingual: change language to ${languageCode}`);
|
|
438
461
|
TUITranslateService.changeLanguage(languageCode).then(() => {
|
|
439
462
|
currentLanguage.value = languageCode;
|
|
463
|
+
state.set('currentLanguage', languageCode);
|
|
440
464
|
try {
|
|
441
465
|
localStorage.setItem('AIDesk_language', languageCode);
|
|
442
466
|
} catch {
|
|
@@ -458,6 +482,15 @@ function activeConversation() {
|
|
|
458
482
|
},
|
|
459
483
|
});
|
|
460
484
|
}
|
|
485
|
+
|
|
486
|
+
function onLike(messageInfo: Object) {
|
|
487
|
+
feedbackModalRef.value.onLike(messageInfo);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function onDislike(messageInfo: Object) {
|
|
491
|
+
showFeedbackModal.value = true;
|
|
492
|
+
feedbackModalRef.value.onDislike(messageInfo);
|
|
493
|
+
}
|
|
461
494
|
</script>
|
|
462
495
|
|
|
463
496
|
<style scoped lang="scss" src="./style/index.scss">
|
|
@@ -171,7 +171,6 @@ function onQuoteMessageUpdated(options?: {
|
|
|
171
171
|
overflow: hidden;
|
|
172
172
|
text-overflow: ellipsis;
|
|
173
173
|
white-space: nowrap;
|
|
174
|
-
font-family: PingFangSC-Regular;
|
|
175
174
|
}
|
|
176
175
|
}
|
|
177
176
|
.input-quote-content-h5 {
|
|
@@ -198,13 +197,11 @@ function onQuoteMessageUpdated(options?: {
|
|
|
198
197
|
overflow: hidden;
|
|
199
198
|
text-overflow: ellipsis;
|
|
200
199
|
white-space: nowrap;
|
|
201
|
-
font-family: PingFangSC-Regular;
|
|
202
200
|
}
|
|
203
201
|
|
|
204
202
|
.input-quote-sender-h5 {
|
|
205
203
|
font-size: 10px;
|
|
206
204
|
color:#00000080;
|
|
207
|
-
font-family: PingFangSC-Regular;
|
|
208
205
|
}
|
|
209
206
|
}
|
|
210
207
|
|
|
@@ -148,8 +148,10 @@ const onCurrentConversationUpdate = (conversation: IConversationModel) => {
|
|
|
148
148
|
= currentConversation?.value?.type === TUIChatEngine.TYPES.CONV_GROUP;
|
|
149
149
|
};
|
|
150
150
|
|
|
151
|
-
const onInHumanServiceUpdate = (value: boolean) => {
|
|
152
|
-
|
|
151
|
+
const onInHumanServiceUpdate = (data: {conversationID: string, value: boolean}) => {
|
|
152
|
+
if (data && data.conversationID === currentConversation.value.conversationID) {
|
|
153
|
+
isInHumanService.value = data.value;
|
|
154
|
+
}
|
|
153
155
|
};
|
|
154
156
|
|
|
155
157
|
const insertEmoji = (emojiObj: object) => {
|
|
@@ -49,6 +49,10 @@
|
|
|
49
49
|
@handleH5LongPress="handleH5LongPress"
|
|
50
50
|
@heightChanged="onHeightChanged"
|
|
51
51
|
@messageSent="onMessageSent"
|
|
52
|
+
:enableFeedback="props.enableFeedback"
|
|
53
|
+
:enableAINote="props.enableAINote"
|
|
54
|
+
@like="onLike"
|
|
55
|
+
@dislike="onDislike"
|
|
52
56
|
/>
|
|
53
57
|
<div
|
|
54
58
|
v-else
|
|
@@ -66,14 +70,19 @@
|
|
|
66
70
|
:isAudioPlayed="Boolean(audioPlayedMapping[item.ID])"
|
|
67
71
|
:blinkMessageIDList="blinkMessageIDList"
|
|
68
72
|
:messageItem="JSON.parse(JSON.stringify(item))"
|
|
73
|
+
:enableFeedback="props.enableFeedback"
|
|
74
|
+
:enableAINote="props.enableAINote"
|
|
69
75
|
@blinkMessage="blinkMessage"
|
|
70
76
|
@resendMessage="resendMessage(item)"
|
|
77
|
+
@like="onLike"
|
|
78
|
+
@dislike="onDislike"
|
|
71
79
|
>
|
|
72
80
|
<template #messageElement>
|
|
73
81
|
<MessageThinking v-if="isThinkingMessage(item)"/>
|
|
74
82
|
<MessageText
|
|
75
83
|
v-else-if="item.type === TYPES.MSG_TEXT"
|
|
76
84
|
:content="item.getMessageContent()"
|
|
85
|
+
:flow="item.flow"
|
|
77
86
|
/>
|
|
78
87
|
<ProgressMessage
|
|
79
88
|
v-else-if="item.type === TYPES.MSG_IMAGE"
|
|
@@ -151,6 +160,7 @@
|
|
|
151
160
|
<ScrollButton
|
|
152
161
|
ref="scrollButtonInstanceRef"
|
|
153
162
|
@scrollToLatestMessage="scrollToLatestMessage"
|
|
163
|
+
@scrollNearToBottom="scrollNearToBottom"
|
|
154
164
|
/>
|
|
155
165
|
<Dialog
|
|
156
166
|
v-if="reSendDialogShow"
|
|
@@ -226,11 +236,13 @@ import {
|
|
|
226
236
|
isEnabledMessageReadReceiptGlobal,
|
|
227
237
|
deepCopy,
|
|
228
238
|
isNonEmptyObject,
|
|
239
|
+
updateCustomStore,
|
|
229
240
|
} from '../../../utils/utils';
|
|
230
241
|
import { isMessageInvisible, isThinkingMessage, isThinkingMessageOverTime, JSONToObject, isTransferMessageWithoutDesc } from '../../../utils/index';
|
|
231
242
|
import { isCustomerConversation } from '../../../index';
|
|
232
243
|
import { CUSTOM_MESSAGE_SRC } from '../../../constant';
|
|
233
244
|
import { QuickOrderModel } from '../../../interface';
|
|
245
|
+
import Log from '../../../utils/logger';
|
|
234
246
|
|
|
235
247
|
interface ScrollConfig {
|
|
236
248
|
scrollToMessage?: IMessageModel;
|
|
@@ -244,15 +256,21 @@ interface ScrollConfig {
|
|
|
244
256
|
interface IProps {
|
|
245
257
|
bottomQuickOrder?: QuickOrderModel;
|
|
246
258
|
showBottomQuickOrder: boolean;
|
|
259
|
+
enableFeedback: number;
|
|
260
|
+
enableAINote: number;
|
|
247
261
|
}
|
|
248
262
|
const props = withDefaults(defineProps<IProps>(), {
|
|
249
263
|
showBottomQuickOrder: false,
|
|
264
|
+
enableFeedback: 0,
|
|
265
|
+
enableAINote: 1,
|
|
250
266
|
});
|
|
251
267
|
|
|
252
268
|
interface IEmits {
|
|
253
269
|
(key: 'closeInputToolBar'): void;
|
|
254
270
|
(key: 'handleEditor', message: IMessageModel, type: string): void;
|
|
255
271
|
(key: 'closeBottomQuickOrder'): void;
|
|
272
|
+
(key: 'like', messageInfo: Object): void;
|
|
273
|
+
(key: 'dislike', messageInfo: Object): void;
|
|
256
274
|
}
|
|
257
275
|
|
|
258
276
|
const emits = defineEmits<IEmits>();
|
|
@@ -354,29 +372,32 @@ function onNewMessageList(list: IMessageModel[]) {
|
|
|
354
372
|
list.forEach((message:IMessageModel) => {
|
|
355
373
|
if (message.type === TUIChatEngine.TYPES.MSG_CUSTOM) {
|
|
356
374
|
const data = JSONToObject(message.payload.data);
|
|
375
|
+
const conversationID = message.conversationID;
|
|
357
376
|
if (data) {
|
|
358
377
|
if (data.src === CUSTOM_MESSAGE_SRC.BOT_STATUS) {
|
|
378
|
+
updateCustomStore("canEndConversation", { conversationID, value: true });
|
|
359
379
|
if (data.content.content === 'inBot') {
|
|
360
|
-
|
|
380
|
+
updateCustomStore("isInHumanService", { conversationID, value: false });
|
|
361
381
|
}
|
|
362
382
|
} else if (data.src === CUSTOM_MESSAGE_SRC.SEAT_STATUS) {
|
|
383
|
+
updateCustomStore("canEndConversation", { conversationID, value: true });
|
|
363
384
|
if (data.content.command === "updateSeatStatus") {
|
|
364
385
|
if (data.content.content === 'inSeat') {
|
|
365
|
-
|
|
386
|
+
updateCustomStore("isInHumanService", { conversationID, value: true });
|
|
366
387
|
} else if (data.content.content === 'outSeat') {
|
|
367
|
-
|
|
388
|
+
updateCustomStore("isInHumanService", { conversationID, value: false });
|
|
368
389
|
}
|
|
369
390
|
}
|
|
370
391
|
} else if (data.src === CUSTOM_MESSAGE_SRC.TYPING_STATE) {
|
|
371
392
|
if (data.typingStatus === 1) {
|
|
372
|
-
|
|
393
|
+
updateCustomStore("isTyping", { conversationID, value: true });
|
|
373
394
|
} else {
|
|
374
|
-
|
|
395
|
+
updateCustomStore("isTyping", { conversationID, value: false });
|
|
375
396
|
}
|
|
376
397
|
} else if (data.src === CUSTOM_MESSAGE_SRC.NO_SEAT_ONLINE || data.src === CUSTOM_MESSAGE_SRC.TIMEOUT || data.src === CUSTOM_MESSAGE_SRC.END) {
|
|
377
|
-
|
|
378
|
-
} else if (data.src === CUSTOM_MESSAGE_SRC.
|
|
379
|
-
TUIStore.update(StoreName.CUSTOM, "
|
|
398
|
+
updateCustomStore("canEndConversation", { conversationID, value: false });
|
|
399
|
+
} else if (data.src === CUSTOM_MESSAGE_SRC.GET_FEEDBACK_MENU) {
|
|
400
|
+
TUIStore.update(StoreName.CUSTOM, "feedbackTags", data.content.menu);
|
|
380
401
|
}
|
|
381
402
|
}
|
|
382
403
|
}
|
|
@@ -385,6 +406,7 @@ function onNewMessageList(list: IMessageModel[]) {
|
|
|
385
406
|
|
|
386
407
|
async function onMessageListUpdated(list: IMessageModel[]) {
|
|
387
408
|
if (!isCustomerConversation(currentConversationID.value)) {
|
|
409
|
+
Log.w(`Messages filtered as they are not customer service messages. currentConversationID: ${currentConversationID.value}`);
|
|
388
410
|
return;
|
|
389
411
|
}
|
|
390
412
|
observer?.disconnect();
|
|
@@ -441,9 +463,7 @@ async function onMessageListUpdated(list: IMessageModel[]) {
|
|
|
441
463
|
await scrollToPosition({ scrollToBottom: true });
|
|
442
464
|
}
|
|
443
465
|
currentLastMessage.value = Object.assign({}, newLastMessage);
|
|
444
|
-
|
|
445
|
-
nextTick(() => bindIntersectionObserver());
|
|
446
|
-
}
|
|
466
|
+
nextTick(() => bindIntersectionObserver());
|
|
447
467
|
}
|
|
448
468
|
|
|
449
469
|
function isCurrentListInBottomPosition() {
|
|
@@ -682,6 +702,13 @@ async function scrollToLatestMessage() {
|
|
|
682
702
|
}
|
|
683
703
|
scrollButtonInstanceRef.value?.hideScrollButton();
|
|
684
704
|
beforeHistoryGetScrollHeight.value = 0;
|
|
705
|
+
// 滚动到底部的时候,及时检查是否要上报已读回执
|
|
706
|
+
bindIntersectionObserver();
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
function scrollNearToBottom() {
|
|
710
|
+
// 滚动到底部的时候,及时检查是否要上报已读回执
|
|
711
|
+
bindIntersectionObserver();
|
|
685
712
|
}
|
|
686
713
|
|
|
687
714
|
const handelScrollListScroll = throttle(
|
|
@@ -693,67 +720,62 @@ const handelScrollListScroll = throttle(
|
|
|
693
720
|
);
|
|
694
721
|
|
|
695
722
|
async function bindIntersectionObserver() {
|
|
696
|
-
if (
|
|
697
|
-
!messageList.value
|
|
698
|
-
|| !messageListRef.value
|
|
699
|
-
|| messageList.value.length === 0
|
|
700
|
-
) {
|
|
723
|
+
if (!messageList.value || !messageListRef.value || messageList.value.length === 0) {
|
|
701
724
|
return;
|
|
702
725
|
}
|
|
703
726
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
msgDom: HTMLElement;
|
|
708
|
-
msgModel: IMessageModel | undefined;
|
|
709
|
-
}
|
|
710
|
-
> = {};
|
|
727
|
+
if (!isEnabledMessageReadReceiptGlobal()) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
711
730
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
731
|
+
const mappingFromIDToMessage: Record<string, { msgDom: HTMLElement; msgModel: IMessageModel | undefined; }> = {};
|
|
732
|
+
|
|
733
|
+
if (observer) {
|
|
734
|
+
observer.disconnect();
|
|
735
|
+
}
|
|
736
|
+
observer = new IntersectionObserver((entries) => {
|
|
737
|
+
entries.forEach((entry) => {
|
|
738
|
+
const { isIntersecting, target } = entry;
|
|
739
|
+
if (isIntersecting) {
|
|
740
|
+
const { msgDom, msgModel } = mappingFromIDToMessage[target.id];
|
|
741
|
+
if (msgModel) {
|
|
742
|
+
const { readReceiptInfo, ID, payload } = msgModel;
|
|
743
|
+
if (!readReceiptInfo.isPeerRead && !sentReceiptMessageIDSet.has(ID)) {
|
|
724
744
|
TUIChatService.sendMessageReadReceipt([msgModel]);
|
|
725
|
-
sentReceiptMessageIDSet.add(
|
|
726
|
-
|
|
745
|
+
sentReceiptMessageIDSet.add(ID);
|
|
746
|
+
Log.l(`Receipt sent. ID:${ID} payload:${JSON.stringify(payload)}`);
|
|
747
|
+
if (observer) {
|
|
748
|
+
observer.unobserve(msgDom);
|
|
749
|
+
}
|
|
727
750
|
}
|
|
728
751
|
}
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
);
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
}, {
|
|
755
|
+
root: messageListRef.value,
|
|
756
|
+
threshold: 0.3, // 超过1/4可见时触发,提高灵敏度
|
|
757
|
+
});
|
|
736
758
|
|
|
737
|
-
const arrayOfMessageLi
|
|
738
|
-
= messageListRef.value?.querySelectorAll('.message-li');
|
|
759
|
+
const arrayOfMessageLi = messageListRef.value?.querySelectorAll('.message-li');
|
|
739
760
|
if (arrayOfMessageLi) {
|
|
740
|
-
for (let i = 0; i <
|
|
761
|
+
for (let i = 0, length = arrayOfMessageLi.length; i < length; i++) {
|
|
741
762
|
const messageElement = arrayOfMessageLi[i] as HTMLElement;
|
|
742
|
-
const matchingMessage = messageList.value.find(
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
)
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
&&
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
763
|
+
const matchingMessage = messageList.value.find((message: IMessageModel) => {
|
|
764
|
+
// replace tui-
|
|
765
|
+
return messageElement.id.slice(4) === message.ID;
|
|
766
|
+
});
|
|
767
|
+
if (matchingMessage) {
|
|
768
|
+
const { needReadReceipt, readReceiptInfo, flow } = matchingMessage;
|
|
769
|
+
// 收到的消息需要已读回执,但我尚未发送
|
|
770
|
+
if (needReadReceipt && flow === 'in' && !readReceiptInfo.isPeerRead) {
|
|
771
|
+
mappingFromIDToMessage[messageElement.id] = {
|
|
772
|
+
msgDom: messageElement,
|
|
773
|
+
msgModel: matchingMessage,
|
|
774
|
+
};
|
|
775
|
+
if (observer) {
|
|
776
|
+
observer.observe(messageElement);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
757
779
|
}
|
|
758
780
|
}
|
|
759
781
|
}
|
|
@@ -794,6 +816,14 @@ function sendBottomQuickOrder() {
|
|
|
794
816
|
closeBottomQuickOrder();
|
|
795
817
|
}
|
|
796
818
|
|
|
819
|
+
function onLike(messageInfo: Object) {
|
|
820
|
+
emits('like', messageInfo);
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
function onDislike(messageInfo: Object) {
|
|
824
|
+
emits('dislike', messageInfo);
|
|
825
|
+
};
|
|
826
|
+
|
|
797
827
|
defineExpose({
|
|
798
828
|
scrollToLatestMessage,
|
|
799
829
|
});
|