@phonghq/go-chat 1.0.55 → 1.0.57
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/dist/assets/icons/call/IconClock.vue.d.ts +2 -0
- package/dist/assets/icons/call/IconClock.vue.js +22 -0
- package/dist/chat/App.vue.js +24 -7
- package/dist/chat/page/home/ChatList.vue.d.ts +4 -0
- package/dist/chat/page/home/ChatList.vue.js +12 -5
- package/dist/chat/page/home/ChatMessage.vue.d.ts +1 -0
- package/dist/chat/page/home/ChatMessage.vue.js +27 -7
- package/dist/chat/page/home/ChatMessageItem.vue.js +31 -16
- package/dist/chat/page/home/DropZone.vue.d.ts +13 -0
- package/dist/chat/page/home/DropZone.vue.js +130 -0
- package/dist/chat/page/home/Home.vue.d.ts +1 -0
- package/dist/chat/page/home/Home.vue.js +71 -20
- package/dist/chat/page/home/HomeHeader.vue.js +7 -5
- package/dist/chat/page/home/InputChat.vue.js +139 -70
- package/dist/chat/page/home/PhoneNumpad.vue.js +2 -0
- package/dist/components/chat/call/Calling.vue.js +76 -70
- package/dist/components/chat/call/TimeLeft.vue.d.ts +5 -0
- package/dist/components/chat/call/TimeLeft.vue.js +59 -0
- package/dist/composable/useInitData.js +2 -2
- package/dist/composable/useListConversations.d.ts +2 -0
- package/dist/composable/useListConversations.js +50 -11
- package/dist/composable/usePlivo.d.ts +1 -0
- package/dist/composable/usePlivo.js +31 -9
- package/dist/constant/mqtt.d.ts +1 -0
- package/dist/constant/mqtt.js +2 -0
- package/dist/go-chat.es.js +40714 -40469
- package/dist/go-chat.umd.js +23 -23
- package/dist/plugins/mqtt.js +5 -7
- package/dist/style.css +1 -1
- package/dist/types/chat/auth.d.ts +0 -1
- package/dist/types/chat/call.d.ts +1 -0
- package/dist/types/chat/call.js +1 -0
- package/dist/types/chat/global.d.ts +1 -0
- package/dist/types/message.d.ts +1 -0
- package/dist/utils/chat/store/auth.d.ts +0 -2
- package/dist/utils/chat/store/auth.js +7 -7
- package/dist/utils/chat/store/conversation.js +1 -1
- package/dist/utils/chat/store/message.d.ts +4 -0
- package/dist/utils/chat/store/message.js +4 -0
- package/dist/views/home/phone-numpad/PhoneNumpad.vue.js +3 -0
- package/package.json +1 -1
|
@@ -16,35 +16,37 @@ import IconMic from '../../../assets/icons/call/IconMic.vue';
|
|
|
16
16
|
import { useDebounce } from '../../../utils/debounce';
|
|
17
17
|
import { phoneNumberFormat } from '../../../utils/string-helper';
|
|
18
18
|
import { handleMedialPermissionError, showPageError } from '../../../utils/chat/page-error';
|
|
19
|
+
import RingAudio from '../../../assets/sound/telephone-2.mp3';
|
|
20
|
+
import TimeLeft from '../../../components/chat/call/TimeLeft.vue';
|
|
19
21
|
const props = withDefaults(defineProps(), {
|
|
20
22
|
responsive: 'window'
|
|
21
23
|
});
|
|
22
24
|
const emit = defineEmits();
|
|
23
25
|
const handlePlivoCallBack = (status, data) => {
|
|
26
|
+
callStatus.value = status;
|
|
24
27
|
if (status == PLIVO_CALL_STATUS.RINGING) {
|
|
28
|
+
handleInComingCall(data);
|
|
29
|
+
}
|
|
30
|
+
else if (status == PLIVO_CALL_STATUS.CHECK_USER_OFFER) {
|
|
25
31
|
getUserOffer(data?.phone ?? '');
|
|
26
|
-
callStatus.value = PLIVO_CALL_STATUS.RINGING;
|
|
27
|
-
open();
|
|
28
32
|
}
|
|
29
33
|
else if (status == PLIVO_CALL_STATUS.CONNECT_FAILED || status == PLIVO_CALL_STATUS.NO_ANSWER) {
|
|
30
34
|
endCall();
|
|
31
|
-
callStatus.value = status;
|
|
32
35
|
}
|
|
33
36
|
else if (status == PLIVO_CALL_STATUS.CALL_END) {
|
|
34
37
|
errorMessage.value = data?.message ?? '';
|
|
35
38
|
const closeModal = data?.reason == 'ORIGINATOR_CANCEL';
|
|
36
39
|
endCall({ closeModal });
|
|
37
|
-
callStatus.value = status;
|
|
38
40
|
}
|
|
39
41
|
else if (status == PLIVO_CALL_STATUS.CALL_START) {
|
|
40
|
-
|
|
42
|
+
audioRef.value?.pause();
|
|
41
43
|
startTimer();
|
|
42
44
|
}
|
|
43
45
|
else if (status == PLIVO_CALL_STATUS.MEDIA_PERMISSION_FAIL) {
|
|
44
46
|
handleMedialPermissionError();
|
|
45
47
|
}
|
|
46
48
|
};
|
|
47
|
-
const { plivoLogin, plivoCallAnswer, plivoCall, plivoEndCall, plivoCallSwishMute, plivoCallSwishSpeaker } = usePlivo(handlePlivoCallBack);
|
|
49
|
+
const { plivoLogin, plivoCallAnswer, plivoCall, plivoEndCall, plivoCallSwishMute, plivoCallSwishSpeaker, checkTimeLimit } = usePlivo(handlePlivoCallBack);
|
|
48
50
|
const STATUS_LABEL = computed(() => {
|
|
49
51
|
return {
|
|
50
52
|
[PLIVO_CALL_STATUS.CONNECTING]: 'Connecting...',
|
|
@@ -57,7 +59,8 @@ const STATUS_LABEL = computed(() => {
|
|
|
57
59
|
[PLIVO_CALL_STATUS.CANCEL]: '',
|
|
58
60
|
[PLIVO_CALL_STATUS.TIME_OUT]: '',
|
|
59
61
|
[PLIVO_CALL_STATUS.BUSY]: '',
|
|
60
|
-
[PLIVO_CALL_STATUS.MEDIA_PERMISSION_FAIL]: ''
|
|
62
|
+
[PLIVO_CALL_STATUS.MEDIA_PERMISSION_FAIL]: '',
|
|
63
|
+
[PLIVO_CALL_STATUS.CHECK_USER_OFFER]: ''
|
|
61
64
|
};
|
|
62
65
|
});
|
|
63
66
|
const label = computed(() => STATUS_LABEL.value[callStatus.value] ?? '');
|
|
@@ -68,8 +71,10 @@ const disable = ref(false);
|
|
|
68
71
|
const errorMessage = ref('');
|
|
69
72
|
const record_link = ref('');
|
|
70
73
|
const drawerVisibleRef = ref(null);
|
|
74
|
+
const audioRef = ref(null);
|
|
71
75
|
const userRemoter = ref(null);
|
|
72
76
|
const isMute = ref(false);
|
|
77
|
+
const limitTime = ref(0);
|
|
73
78
|
let timer = null;
|
|
74
79
|
let timeOut = null;
|
|
75
80
|
let refreshTokenTimeOut = null;
|
|
@@ -78,7 +83,7 @@ let callType = 'call';
|
|
|
78
83
|
let uuidEnd = '';
|
|
79
84
|
onMounted(async () => {
|
|
80
85
|
try {
|
|
81
|
-
if (dataProfile.value?.
|
|
86
|
+
if (dataProfile.value?.phone) {
|
|
82
87
|
const token = await getPlivoAccessToken();
|
|
83
88
|
await plivoLogin({ token });
|
|
84
89
|
setTimeout(refreshToken, 15 * 60 * 1000);
|
|
@@ -101,9 +106,13 @@ function startTimer() {
|
|
|
101
106
|
let sec = 0;
|
|
102
107
|
timer = setInterval(() => {
|
|
103
108
|
sec++;
|
|
109
|
+
limitTime.value = limitTime.value - 1;
|
|
104
110
|
const m = String(Math.floor(sec / 60)).padStart(2, '0');
|
|
105
111
|
const s = String(sec % 60).padStart(2, '0');
|
|
106
112
|
duration.value = `${m}:${s}`;
|
|
113
|
+
if (!limitTime.value || limitTime.value <= 0) {
|
|
114
|
+
handleTimeLimitError();
|
|
115
|
+
}
|
|
107
116
|
}, 1000);
|
|
108
117
|
}
|
|
109
118
|
function endCall(option) {
|
|
@@ -111,6 +120,7 @@ function endCall(option) {
|
|
|
111
120
|
drawerVisible.value = false;
|
|
112
121
|
drawerVisibleRef.value?.close();
|
|
113
122
|
}
|
|
123
|
+
audioRef.value?.pause();
|
|
114
124
|
handleEmitEndCall(userRemoter.value, callType);
|
|
115
125
|
plivoEndCall(callStatus.value);
|
|
116
126
|
callStatus.value = PLIVO_CALL_STATUS.CALL_END;
|
|
@@ -150,6 +160,16 @@ const refreshToken = async () => {
|
|
|
150
160
|
console.log(e);
|
|
151
161
|
}
|
|
152
162
|
};
|
|
163
|
+
const handleInComingCall = (data) => {
|
|
164
|
+
limitTime.value = data?.limit_time ?? 0;
|
|
165
|
+
if (limitTime.value <= 0) {
|
|
166
|
+
handleTimeLimitError();
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
emit('userCalling', userRemoter.value);
|
|
170
|
+
audioRef.value?.play();
|
|
171
|
+
open();
|
|
172
|
+
};
|
|
153
173
|
const open = () => {
|
|
154
174
|
drawerVisible.value = true;
|
|
155
175
|
disable.value = true;
|
|
@@ -169,6 +189,11 @@ const startCall = async (data) => {
|
|
|
169
189
|
callStatus.value = PLIVO_CALL_STATUS.CONNECTING;
|
|
170
190
|
userRemoter.value = data;
|
|
171
191
|
open();
|
|
192
|
+
limitTime.value = await checkTimeLimit();
|
|
193
|
+
if (!limitTime.value || limitTime.value <= 0) {
|
|
194
|
+
handleTimeLimitError();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
172
197
|
callType = 'call';
|
|
173
198
|
await plivoCall(data.phone);
|
|
174
199
|
callStatus.value = PLIVO_CALL_STATUS.CALLING;
|
|
@@ -194,7 +219,6 @@ const getUserOffer = async (phone) => {
|
|
|
194
219
|
let res = null;
|
|
195
220
|
try {
|
|
196
221
|
userRemoter.value = { phone, username: '' };
|
|
197
|
-
emit('userCalling', userRemoter.value);
|
|
198
222
|
let data = {
|
|
199
223
|
phone: formatPhone10number(phone, '1'),
|
|
200
224
|
client_id: dataProfile.value?.tenant_id ?? ''
|
|
@@ -209,56 +233,14 @@ const getUserOffer = async (phone) => {
|
|
|
209
233
|
phone: res?.phone ? '1' + res?.phone : phone
|
|
210
234
|
};
|
|
211
235
|
userRemoter.value = user;
|
|
212
|
-
if (callStatus.value !== PLIVO_CALL_STATUS.CALL_END) {
|
|
236
|
+
if (callStatus.value !== PLIVO_CALL_STATUS.CALL_END && callStatus.value !== PLIVO_CALL_STATUS.CHECK_USER_OFFER) {
|
|
213
237
|
emit('userCalling', userRemoter.value);
|
|
214
238
|
}
|
|
215
239
|
};
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// if (message?.data?.status == PLIVO_CALL_STATUS.RINGING) {
|
|
221
|
-
// if (message?.data?.to_number == dataProfile.value?.phone) {
|
|
222
|
-
// callStatus.value = PLIVO_CALL_STATUS.RINGING
|
|
223
|
-
// dataWebSK = {
|
|
224
|
-
// from: message.data.from_number,
|
|
225
|
-
// to: message.data.to_number
|
|
226
|
-
// }
|
|
227
|
-
// getUserOffer(message.data.from_number)
|
|
228
|
-
// handleCallAnswer(message)
|
|
229
|
-
// open()
|
|
230
|
-
// }
|
|
231
|
-
// } else if (message?.data?.status == PLIVO_CALL_STATUS.CALL_START) {
|
|
232
|
-
// try {
|
|
233
|
-
// await startIncomingCall(message?.data?.call_uuid)
|
|
234
|
-
// startTimer()
|
|
235
|
-
// callStatus.value = PLIVO_CALL_STATUS.CALL_START
|
|
236
|
-
// } catch (e) {
|
|
237
|
-
// console.log(e)
|
|
238
|
-
// endCall()
|
|
239
|
-
// }
|
|
240
|
-
// } else if (message?.data?.status == PLIVO_CALL_STATUS.CALL_END) {
|
|
241
|
-
// endCall()
|
|
242
|
-
// } else if (
|
|
243
|
-
// message?.data?.status == PLIVO_CALL_STATUS.CONNECT_FAILED ||
|
|
244
|
-
// message?.data?.status == PLIVO_CALL_STATUS.NO_ANSWER
|
|
245
|
-
// ) {
|
|
246
|
-
// endCall()
|
|
247
|
-
// callStatus.value = message?.data?.status
|
|
248
|
-
// } else {
|
|
249
|
-
// // console.log(message)
|
|
250
|
-
// da = false
|
|
251
|
-
// // handleMedia(message)
|
|
252
|
-
// }
|
|
253
|
-
// } else if (message?.event == 'record_uploaded') {
|
|
254
|
-
// if (uuidEnd == message?.data?.call_uuid) {
|
|
255
|
-
// record_link.value = message?.data?.recording_url
|
|
256
|
-
// }
|
|
257
|
-
// }
|
|
258
|
-
//
|
|
259
|
-
// // if (da){
|
|
260
|
-
// // } else console.log('-----------------', message)
|
|
261
|
-
// }
|
|
240
|
+
const handleTimeLimitError = () => {
|
|
241
|
+
errorMessage.value = 'Call time limit reached. This call has ended.';
|
|
242
|
+
endCall();
|
|
243
|
+
};
|
|
262
244
|
const exportRecordFile = async () => {
|
|
263
245
|
downloadRecord(record_link.value);
|
|
264
246
|
};
|
|
@@ -321,6 +303,16 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
321
303
|
...{ class: "flex flex-col items-center justify-center h-full relative bg-white" },
|
|
322
304
|
...{ style: {} },
|
|
323
305
|
});
|
|
306
|
+
/** @type {[typeof TimeLeft, ]} */ ;
|
|
307
|
+
// @ts-ignore
|
|
308
|
+
const __VLS_10 = __VLS_asFunctionalComponent(TimeLeft, new TimeLeft({
|
|
309
|
+
time: (__VLS_ctx.limitTime),
|
|
310
|
+
}));
|
|
311
|
+
const __VLS_11 = __VLS_10({
|
|
312
|
+
time: (__VLS_ctx.limitTime),
|
|
313
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_10));
|
|
314
|
+
// @ts-ignore
|
|
315
|
+
[limitTime,];
|
|
324
316
|
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
325
317
|
...{ class: "h-40 w-40 call-avatar mb-8" },
|
|
326
318
|
});
|
|
@@ -329,7 +321,7 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
329
321
|
});
|
|
330
322
|
/** @type {[typeof Avatar, ]} */ ;
|
|
331
323
|
// @ts-ignore
|
|
332
|
-
const
|
|
324
|
+
const __VLS_14 = __VLS_asFunctionalComponent(Avatar, new Avatar({
|
|
333
325
|
...{ class: "bg-white z-[2]" },
|
|
334
326
|
src: (__VLS_ctx.userRemoter?.avatar ?? ''),
|
|
335
327
|
id: (__VLS_ctx.userRemoter?.id ?? ''),
|
|
@@ -337,14 +329,14 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
337
329
|
name: (__VLS_ctx.userRemoter?.username),
|
|
338
330
|
size: "xxl",
|
|
339
331
|
}));
|
|
340
|
-
const
|
|
332
|
+
const __VLS_15 = __VLS_14({
|
|
341
333
|
...{ class: "bg-white z-[2]" },
|
|
342
334
|
src: (__VLS_ctx.userRemoter?.avatar ?? ''),
|
|
343
335
|
id: (__VLS_ctx.userRemoter?.id ?? ''),
|
|
344
336
|
color: (__VLS_ctx.userRemoter?.color),
|
|
345
337
|
name: (__VLS_ctx.userRemoter?.username),
|
|
346
338
|
size: "xxl",
|
|
347
|
-
}, ...__VLS_functionalComponentArgsRest(
|
|
339
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_14));
|
|
348
340
|
// @ts-ignore
|
|
349
341
|
[userRemoter, userRemoter, userRemoter, userRemoter,];
|
|
350
342
|
if (__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.RINGING || __VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALLING) {
|
|
@@ -371,7 +363,10 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
371
363
|
[userRemoter, userRemoter, phoneNumberFormat,];
|
|
372
364
|
__VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
|
|
373
365
|
...{ class: "text-gray-400 mt-1" },
|
|
366
|
+
...{ class: ({ 'text-2xl font-semibold': __VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_START }) },
|
|
374
367
|
});
|
|
368
|
+
// @ts-ignore
|
|
369
|
+
[callStatus, PLIVO_CALL_STATUS,];
|
|
375
370
|
(__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_START ? __VLS_ctx.duration : __VLS_ctx.STATUS_LABEL[__VLS_ctx.callStatus]);
|
|
376
371
|
// @ts-ignore
|
|
377
372
|
[callStatus, callStatus, PLIVO_CALL_STATUS, duration, STATUS_LABEL,];
|
|
@@ -391,8 +386,8 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
391
386
|
[record_link, exportRecordFile,];
|
|
392
387
|
/** @type {[typeof IconSoundDownload, ]} */ ;
|
|
393
388
|
// @ts-ignore
|
|
394
|
-
const
|
|
395
|
-
const
|
|
389
|
+
const __VLS_18 = __VLS_asFunctionalComponent(IconSoundDownload, new IconSoundDownload({}));
|
|
390
|
+
const __VLS_19 = __VLS_18({}, ...__VLS_functionalComponentArgsRest(__VLS_18));
|
|
396
391
|
}
|
|
397
392
|
if (__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_START) {
|
|
398
393
|
// @ts-ignore
|
|
@@ -409,12 +404,12 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
409
404
|
});
|
|
410
405
|
/** @type {[typeof IconMic, ]} */ ;
|
|
411
406
|
// @ts-ignore
|
|
412
|
-
const
|
|
407
|
+
const __VLS_22 = __VLS_asFunctionalComponent(IconMic, new IconMic({
|
|
413
408
|
mute: (__VLS_ctx.isMute),
|
|
414
409
|
}));
|
|
415
|
-
const
|
|
410
|
+
const __VLS_23 = __VLS_22({
|
|
416
411
|
mute: (__VLS_ctx.isMute),
|
|
417
|
-
}, ...__VLS_functionalComponentArgsRest(
|
|
412
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_22));
|
|
418
413
|
// @ts-ignore
|
|
419
414
|
[isMute,];
|
|
420
415
|
}
|
|
@@ -433,8 +428,8 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
433
428
|
});
|
|
434
429
|
/** @type {[typeof IconClose, ]} */ ;
|
|
435
430
|
// @ts-ignore
|
|
436
|
-
const
|
|
437
|
-
const
|
|
431
|
+
const __VLS_26 = __VLS_asFunctionalComponent(IconClose, new IconClose({}));
|
|
432
|
+
const __VLS_27 = __VLS_26({}, ...__VLS_functionalComponentArgsRest(__VLS_26));
|
|
438
433
|
}
|
|
439
434
|
if (__VLS_ctx.callStatus != __VLS_ctx.PLIVO_CALL_STATUS.CALL_END) {
|
|
440
435
|
// @ts-ignore
|
|
@@ -451,8 +446,8 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
451
446
|
});
|
|
452
447
|
/** @type {[typeof IconPhoneCancel, ]} */ ;
|
|
453
448
|
// @ts-ignore
|
|
454
|
-
const
|
|
455
|
-
const
|
|
449
|
+
const __VLS_30 = __VLS_asFunctionalComponent(IconPhoneCancel, new IconPhoneCancel({}));
|
|
450
|
+
const __VLS_31 = __VLS_30({}, ...__VLS_functionalComponentArgsRest(__VLS_30));
|
|
456
451
|
}
|
|
457
452
|
if (__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.RINGING) {
|
|
458
453
|
// @ts-ignore
|
|
@@ -465,14 +460,23 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
465
460
|
[answer,];
|
|
466
461
|
/** @type {[typeof IconPhone, ]} */ ;
|
|
467
462
|
// @ts-ignore
|
|
468
|
-
const
|
|
469
|
-
const
|
|
463
|
+
const __VLS_34 = __VLS_asFunctionalComponent(IconPhone, new IconPhone({}));
|
|
464
|
+
const __VLS_35 = __VLS_34({}, ...__VLS_functionalComponentArgsRest(__VLS_34));
|
|
470
465
|
}
|
|
471
466
|
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
472
467
|
...{ class: "flex items-center justify-center gap-8 mt-10" },
|
|
473
468
|
});
|
|
474
469
|
}
|
|
475
470
|
var __VLS_2;
|
|
471
|
+
__VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
|
|
472
|
+
ref: "audioRef",
|
|
473
|
+
src: (__VLS_ctx.RingAudio),
|
|
474
|
+
loop: true,
|
|
475
|
+
preload: "auto",
|
|
476
|
+
});
|
|
477
|
+
/** @type {typeof __VLS_ctx.audioRef} */ ;
|
|
478
|
+
// @ts-ignore
|
|
479
|
+
[RingAudio, audioRef,];
|
|
476
480
|
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
477
481
|
/** @type {__VLS_StyleScopedClasses['flex-col']} */ ;
|
|
478
482
|
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
@@ -505,6 +509,8 @@ var __VLS_2;
|
|
|
505
509
|
/** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
|
|
506
510
|
/** @type {__VLS_StyleScopedClasses['text-gray-400']} */ ;
|
|
507
511
|
/** @type {__VLS_StyleScopedClasses['mt-1']} */ ;
|
|
512
|
+
/** @type {__VLS_StyleScopedClasses['text-2xl']} */ ;
|
|
513
|
+
/** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
|
|
508
514
|
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
509
515
|
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
510
516
|
/** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
time: number;
|
|
3
|
+
};
|
|
4
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
export default _default;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
import IconClock from '../../../assets/icons/call/IconClock.vue';
|
|
4
|
+
const props = withDefaults(defineProps(), {});
|
|
5
|
+
const emit = defineEmits();
|
|
6
|
+
const limitTimeLabel = computed(() => {
|
|
7
|
+
const m2 = Math.floor(props.time / 60);
|
|
8
|
+
const s2 = props.time % 60;
|
|
9
|
+
return `${m2.toString().padStart(2, '0')}:${s2.toString().padStart(2, '0')}`;
|
|
10
|
+
});
|
|
11
|
+
debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
|
|
12
|
+
const __VLS_defaults = {};
|
|
13
|
+
const __VLS_ctx = {
|
|
14
|
+
...{},
|
|
15
|
+
...{},
|
|
16
|
+
...{},
|
|
17
|
+
...{},
|
|
18
|
+
...{},
|
|
19
|
+
};
|
|
20
|
+
let __VLS_elements;
|
|
21
|
+
let __VLS_components;
|
|
22
|
+
let __VLS_directives;
|
|
23
|
+
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
24
|
+
...{ class: "text-sm rounded-lg px-3 py-1.5 border border-chat-primary border-[2px] bg-[#eff6ff] absolute top-6 left-6 text-chat-primary flex items-center gap-1" },
|
|
25
|
+
});
|
|
26
|
+
/** @type {[typeof IconClock, ]} */ ;
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
const __VLS_0 = __VLS_asFunctionalComponent(IconClock, new IconClock({
|
|
29
|
+
...{ class: "w-4 h-4" },
|
|
30
|
+
}));
|
|
31
|
+
const __VLS_1 = __VLS_0({
|
|
32
|
+
...{ class: "w-4 h-4" },
|
|
33
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_0));
|
|
34
|
+
(__VLS_ctx.limitTimeLabel);
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
[limitTimeLabel,];
|
|
37
|
+
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
|
|
38
|
+
/** @type {__VLS_StyleScopedClasses['rounded-lg']} */ ;
|
|
39
|
+
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
|
|
40
|
+
/** @type {__VLS_StyleScopedClasses['py-1.5']} */ ;
|
|
41
|
+
/** @type {__VLS_StyleScopedClasses['border']} */ ;
|
|
42
|
+
/** @type {__VLS_StyleScopedClasses['border-chat-primary']} */ ;
|
|
43
|
+
/** @type {__VLS_StyleScopedClasses['border-[2px]']} */ ;
|
|
44
|
+
/** @type {__VLS_StyleScopedClasses['bg-[#eff6ff]']} */ ;
|
|
45
|
+
/** @type {__VLS_StyleScopedClasses['absolute']} */ ;
|
|
46
|
+
/** @type {__VLS_StyleScopedClasses['top-6']} */ ;
|
|
47
|
+
/** @type {__VLS_StyleScopedClasses['left-6']} */ ;
|
|
48
|
+
/** @type {__VLS_StyleScopedClasses['text-chat-primary']} */ ;
|
|
49
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
50
|
+
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
51
|
+
/** @type {__VLS_StyleScopedClasses['gap-1']} */ ;
|
|
52
|
+
/** @type {__VLS_StyleScopedClasses['w-4']} */ ;
|
|
53
|
+
/** @type {__VLS_StyleScopedClasses['h-4']} */ ;
|
|
54
|
+
const __VLS_export = (await import('vue')).defineComponent({
|
|
55
|
+
__typeEmits: {},
|
|
56
|
+
__typeProps: {},
|
|
57
|
+
props: {},
|
|
58
|
+
});
|
|
59
|
+
export default {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ref } from 'vue';
|
|
2
2
|
import { sdkInit } from '../plugins/sdk';
|
|
3
|
-
import {
|
|
3
|
+
import { dataProfile, getProfile, loginLink } from '../utils/chat/store/auth';
|
|
4
4
|
import { routerPush } from '../utils/chat/chat-router';
|
|
5
5
|
import { PAGE } from '../constant/general';
|
|
6
6
|
import { connectMqtt, subscribeToTopic, unsubscribeFromTopic } from '../plugins/mqtt';
|
|
@@ -36,7 +36,7 @@ export function useInitData() {
|
|
|
36
36
|
const initData = async (props, responsive) => {
|
|
37
37
|
await getProfile();
|
|
38
38
|
if (dataProfile.value?.user_type == 'tenant') {
|
|
39
|
-
await checkTenantPhoneOnGapInsight()
|
|
39
|
+
// await checkTenantPhoneOnGapInsight()
|
|
40
40
|
}
|
|
41
41
|
unsubscribeFromTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
|
|
42
42
|
subscribeToTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
|
|
@@ -47,6 +47,8 @@ export declare const useListConversations: (is_unknown: number, is_tenant: boole
|
|
|
47
47
|
getData: (data?: IParamGetConversation, option?: {
|
|
48
48
|
reset?: boolean;
|
|
49
49
|
hideLoading?: boolean;
|
|
50
|
+
page?: number;
|
|
51
|
+
is_mqtt?: boolean;
|
|
50
52
|
}) => Promise<void>;
|
|
51
53
|
handleReadMessage: (receiver_id: any) => void;
|
|
52
54
|
getDataCache: () => boolean;
|
|
@@ -5,6 +5,7 @@ import { dataProfile } from '../utils/chat/store/auth';
|
|
|
5
5
|
import { useDebounce } from '../utils/debounce';
|
|
6
6
|
import { getConversation } from '../utils/chat/store/conversation';
|
|
7
7
|
import { readMessages } from '../utils/chat/store/message';
|
|
8
|
+
import dayjs from 'dayjs';
|
|
8
9
|
import { useDigibot } from '../composable/useDigibot';
|
|
9
10
|
import { getCache, setCache } from '../utils/chat/cache';
|
|
10
11
|
const { digibotData, digibotId } = useDigibot();
|
|
@@ -19,10 +20,17 @@ export const useListConversations = (is_unknown, is_tenant) => {
|
|
|
19
20
|
const isLoadingSearch = ref(false);
|
|
20
21
|
onMounted(() => {
|
|
21
22
|
handleConnectMqtt();
|
|
23
|
+
document.addEventListener('visibilitychange', handleVisibilitychange);
|
|
22
24
|
});
|
|
23
25
|
onUnmounted(() => {
|
|
26
|
+
document.removeEventListener('visibilitychange', handleVisibilitychange);
|
|
24
27
|
handleDisconnectMqtt;
|
|
25
28
|
});
|
|
29
|
+
const handleVisibilitychange = () => {
|
|
30
|
+
if (document.visibilityState === 'visible') {
|
|
31
|
+
getDataMqtt();
|
|
32
|
+
}
|
|
33
|
+
};
|
|
26
34
|
const handleDisconnectMqtt = () => {
|
|
27
35
|
TOPIC_HOME.forEach((item) => {
|
|
28
36
|
unsubscribeFromTopic(item + dataProfile.value?.id);
|
|
@@ -57,25 +65,28 @@ export const useListConversations = (is_unknown, is_tenant) => {
|
|
|
57
65
|
};
|
|
58
66
|
const mqttMessageHandler = (topic, data) => {
|
|
59
67
|
if ((data.is_unknown ?? 0) == is_unknown || (!is_tenant && is_unknown == 0)) {
|
|
60
|
-
|
|
68
|
+
getDataMqttDebounce();
|
|
61
69
|
if (topic ===
|
|
62
70
|
TOPIC_HOME[0] + dataProfile.value?.id
|
|
63
|
-
|
|
64
|
-
) {
|
|
71
|
+
|| topic === TOPIC_HOME[1] + dataProfile.value?.id) {
|
|
65
72
|
const index = listConversations.value.findIndex((item) => item.id === data.id);
|
|
66
73
|
const hasChatBox = listConversations.value.findIndex((item) => item.id === digibotId);
|
|
67
74
|
if (index != -1) {
|
|
68
75
|
data.username = listConversations.value[index].username ?? '';
|
|
76
|
+
data.color = listConversations.value[index].color ?? '';
|
|
77
|
+
data.avatar = listConversations.value[index].avatar ?? '';
|
|
78
|
+
data.receiver_id = listConversations.value[index].receiver_id;
|
|
69
79
|
listConversations.value.splice(index, 1);
|
|
70
80
|
}
|
|
71
81
|
if (hasChatBox > -1) {
|
|
72
82
|
listConversations.value.splice(1, 0, data);
|
|
73
83
|
}
|
|
74
84
|
else {
|
|
85
|
+
data.receiver_id = data.receiver_id != dataProfile.value?.id ? data.receiver_id : data.sender_id;
|
|
75
86
|
listConversations.value.unshift(data);
|
|
76
87
|
}
|
|
77
88
|
}
|
|
78
|
-
if (topic === TOPIC_HOME[
|
|
89
|
+
if (topic === TOPIC_HOME[2] + dataProfile.value?.id) {
|
|
79
90
|
if (data.is_unknown == is_unknown) {
|
|
80
91
|
const index = listConversations.value.findIndex((item) => item.id === data.id);
|
|
81
92
|
if (index != -1) {
|
|
@@ -96,19 +107,31 @@ export const useListConversations = (is_unknown, is_tenant) => {
|
|
|
96
107
|
// }
|
|
97
108
|
}
|
|
98
109
|
};
|
|
99
|
-
const
|
|
100
|
-
|
|
110
|
+
const getDataMqttDebounce = useDebounce(() => {
|
|
111
|
+
getDataMqtt();
|
|
101
112
|
}, 5000);
|
|
102
113
|
const getData = async (data, option) => {
|
|
103
114
|
try {
|
|
104
115
|
if (!is_tenant && is_unknown == 1)
|
|
105
116
|
return;
|
|
106
117
|
params.value = { ...params.value, ...(data ?? {}) };
|
|
107
|
-
const is_unknown_value = is_tenant ? is_unknown : undefined;
|
|
108
118
|
if (option?.reset) {
|
|
109
119
|
params.value.page = 1;
|
|
110
120
|
}
|
|
111
|
-
const
|
|
121
|
+
const is_unknown_value = is_tenant ? is_unknown : undefined;
|
|
122
|
+
const page_request = option?.page ?? params.value.page;
|
|
123
|
+
const res = await getConversation({
|
|
124
|
+
...params.value,
|
|
125
|
+
is_unknown: is_unknown_value,
|
|
126
|
+
page: page_request
|
|
127
|
+
});
|
|
128
|
+
if (page_request <= 1 && !params.value?.search) {
|
|
129
|
+
setCache(STORAGE_KEY + is_unknown, res.items);
|
|
130
|
+
}
|
|
131
|
+
if (option?.is_mqtt) {
|
|
132
|
+
mergeChats(res?.items);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
112
135
|
if (option?.reset) {
|
|
113
136
|
listConversations.value = [];
|
|
114
137
|
if (is_unknown == 0 && dataProfile.value?.user_type == 'tenant')
|
|
@@ -118,9 +141,6 @@ export const useListConversations = (is_unknown, is_tenant) => {
|
|
|
118
141
|
listConversations.value.push(...(res?.items ?? []));
|
|
119
142
|
params.value.page = res?._meta?.currentPage || 1;
|
|
120
143
|
pageCount.value = res?._meta?.pageCount || 1;
|
|
121
|
-
if (params.value.page <= 1) {
|
|
122
|
-
setCache(STORAGE_KEY + is_unknown, listConversations.value);
|
|
123
|
-
}
|
|
124
144
|
}
|
|
125
145
|
catch (error) {
|
|
126
146
|
console.error(error);
|
|
@@ -128,6 +148,25 @@ export const useListConversations = (is_unknown, is_tenant) => {
|
|
|
128
148
|
finally {
|
|
129
149
|
}
|
|
130
150
|
};
|
|
151
|
+
const mergeChats = (newChats) => {
|
|
152
|
+
const map = new Map();
|
|
153
|
+
listConversations.value.forEach((c) => {
|
|
154
|
+
map.set(c.id, c);
|
|
155
|
+
});
|
|
156
|
+
newChats.forEach((c) => {
|
|
157
|
+
map.set(c.id, {
|
|
158
|
+
...(map.get(c.id) ?? {}),
|
|
159
|
+
...c
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
listConversations.value = Array.from(map.values()).sort((a, b) => dayjs(b.updated_at).valueOf() - dayjs(a.updated_at).valueOf());
|
|
163
|
+
};
|
|
164
|
+
const getDataMqtt = async () => {
|
|
165
|
+
let page = params.value.page;
|
|
166
|
+
for (let i = 1; i <= page; i++) {
|
|
167
|
+
await getData(undefined, { page: i, is_mqtt: true });
|
|
168
|
+
}
|
|
169
|
+
};
|
|
131
170
|
const getDataCache = () => {
|
|
132
171
|
const cache_data = getCache(STORAGE_KEY + is_unknown);
|
|
133
172
|
if (cache_data.data) {
|
|
@@ -10,4 +10,5 @@ export declare function usePlivo(callback: (status: PlivoCallStatusType, data?:
|
|
|
10
10
|
plivoEndCall: (status: PlivoCallStatusType) => void;
|
|
11
11
|
plivoCallSwishMute: (isMute: boolean) => void;
|
|
12
12
|
plivoCallSwishSpeaker: (id: any) => void;
|
|
13
|
+
checkTimeLimit: () => Promise<number>;
|
|
13
14
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PLIVO_CALL_STATUS } from '../types/chat/call';
|
|
2
2
|
import { createSipAccount } from '../utils/chat/store/call';
|
|
3
3
|
import { dataProfile } from '../utils/chat/store/auth';
|
|
4
|
+
import { getPhoneTimeLimit } from '../utils/chat/store/message';
|
|
4
5
|
export function usePlivo(callback) {
|
|
5
6
|
var options = {
|
|
6
7
|
debug: 'ALL',
|
|
@@ -40,13 +41,14 @@ export function usePlivo(callback) {
|
|
|
40
41
|
const payload = JSON.parse(atob(data.token.split('.')[1]));
|
|
41
42
|
await createSipAccount({
|
|
42
43
|
sip_username: `${payload.sub}_${payload.iss}`,
|
|
43
|
-
did_number: dataProfile.value?.
|
|
44
|
+
did_number: dataProfile.value?.phone ?? ''
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
// await plivoBrowserSdk?.client?.tokenLogin(payload.sub ?? '', token)
|
|
47
48
|
// await plivoBrowserSdk?.client?.login('webcall003079673454891827', '123456abcA!')
|
|
48
49
|
// await plivoBrowserSdk?.client?.login(payload.sub , null, token)
|
|
49
50
|
await plivoBrowserSdk?.client?.loginWithAccessToken(data.token);
|
|
51
|
+
plivoBrowserSdk?.client?.setRingTone(false);
|
|
50
52
|
// await plivoBrowserSdk?.client?.on?.(payload)
|
|
51
53
|
// console.log('Registered with token')
|
|
52
54
|
}
|
|
@@ -57,13 +59,20 @@ export function usePlivo(callback) {
|
|
|
57
59
|
const handleLoginFailed = (e) => {
|
|
58
60
|
console.log('Login failed', e);
|
|
59
61
|
};
|
|
60
|
-
const handleIncomingCall = (call) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
const handleIncomingCall = async (call) => {
|
|
63
|
+
try {
|
|
64
|
+
const data = {
|
|
65
|
+
phone: _getPhone(call.src)
|
|
66
|
+
};
|
|
67
|
+
callback(PLIVO_CALL_STATUS.CHECK_USER_OFFER, data);
|
|
68
|
+
const limit_time = await checkTimeLimit();
|
|
69
|
+
plivoBrowserSdk?.client?.setRingTone(true);
|
|
70
|
+
callback(PLIVO_CALL_STATUS.RINGING, { ...data, limit_time });
|
|
71
|
+
CallUuid = call?.callUUID;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
callback(PLIVO_CALL_STATUS.CALL_END);
|
|
75
|
+
}
|
|
67
76
|
};
|
|
68
77
|
const handleCallRemoteRinging = (callInfo) => {
|
|
69
78
|
CallUuid = callInfo.callUUID;
|
|
@@ -125,7 +134,7 @@ export function usePlivo(callback) {
|
|
|
125
134
|
plivoBrowserSdk?.client?.unmute?.();
|
|
126
135
|
};
|
|
127
136
|
const plivoCall = async (phone) => {
|
|
128
|
-
plivoBrowserSdk
|
|
137
|
+
plivoBrowserSdk?.client?.call('+' + phone, { number_phone: phone });
|
|
129
138
|
await _waitEventOrTimeout(5000);
|
|
130
139
|
};
|
|
131
140
|
const plivoEndCall = (status) => {
|
|
@@ -135,6 +144,7 @@ export function usePlivo(callback) {
|
|
|
135
144
|
else if (status == PLIVO_CALL_STATUS.CALL_START || status == PLIVO_CALL_STATUS.CALLING) {
|
|
136
145
|
plivoBrowserSdk?.client?.hangup?.();
|
|
137
146
|
}
|
|
147
|
+
plivoBrowserSdk?.client?.setRingTone(false);
|
|
138
148
|
};
|
|
139
149
|
const handleCallFailed = (data, callInfo) => {
|
|
140
150
|
console.log('handleCallFailed', data);
|
|
@@ -158,6 +168,17 @@ export function usePlivo(callback) {
|
|
|
158
168
|
alert(id);
|
|
159
169
|
plivoBrowserSdk?.client?.audio?.set?.(id);
|
|
160
170
|
};
|
|
171
|
+
const checkTimeLimit = async () => {
|
|
172
|
+
// await sleep()
|
|
173
|
+
const res = await getPhoneTimeLimit({
|
|
174
|
+
tenant_id: dataProfile.value?.tenant_id ?? '',
|
|
175
|
+
phone: dataProfile.value?.phone ?? ''
|
|
176
|
+
});
|
|
177
|
+
return res;
|
|
178
|
+
};
|
|
179
|
+
const sleep = () => {
|
|
180
|
+
return new Promise(resolve => setTimeout(resolve, 2000));
|
|
181
|
+
};
|
|
161
182
|
return {
|
|
162
183
|
plivoLogin,
|
|
163
184
|
plivoCallAnswer,
|
|
@@ -166,5 +187,6 @@ export function usePlivo(callback) {
|
|
|
166
187
|
plivoEndCall,
|
|
167
188
|
plivoCallSwishMute,
|
|
168
189
|
plivoCallSwishSpeaker,
|
|
190
|
+
checkTimeLimit
|
|
169
191
|
};
|
|
170
192
|
}
|
package/dist/constant/mqtt.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const TOPIC_DETAIL_CHAT = "chat/message/";
|
|
2
2
|
export declare const TOPIC_DETAIL_CALL = "call/message/";
|
|
3
|
+
export declare const TOPIC_PLIVO_CALL = "message-call/";
|
|
3
4
|
export declare const TOPIC_PLIVO_SMS = "sms-inbound/";
|
|
4
5
|
export declare const TOPIC_STATUS_USER: string;
|
|
5
6
|
export declare const TOPIC_HOME: string[];
|
package/dist/constant/mqtt.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export const TOPIC_DETAIL_CHAT = 'chat/message/';
|
|
2
2
|
export const TOPIC_DETAIL_CALL = 'call/message/';
|
|
3
|
+
export const TOPIC_PLIVO_CALL = 'message-call/';
|
|
3
4
|
export const TOPIC_PLIVO_SMS = 'sms-inbound/';
|
|
4
5
|
export const TOPIC_STATUS_USER = 'user/status/';
|
|
5
6
|
export const TOPIC_HOME = [
|
|
6
7
|
// 'chat/conversation/update/',
|
|
7
8
|
// 'chat/conversation/read_message/',
|
|
8
9
|
// 'chat/conversation/update_list/',
|
|
10
|
+
'chat/conversation/update/message-call/',
|
|
9
11
|
'chat/conversation/update/sms-inbound/',
|
|
10
12
|
'chat/conversation/read_message/',
|
|
11
13
|
];
|