@phonghq/go-chat 1.0.13 → 1.0.15
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/chat/page/home/ChatMessage.vue.d.ts +1 -0
- package/dist/components/common/drawer/DrawerBase.vue.d.ts +1 -1
- package/dist/components/common/modal/ModalBase.vue.d.ts +1 -1
- package/dist/composable/useCallHelper.d.ts +1 -0
- package/dist/composable/usePlivo.d.ts +9 -0
- package/dist/go-chat.es.js +18932 -20851
- package/dist/go-chat.umd.js +14 -44
- package/dist/plugins/websocket.d.ts +1 -1
- package/dist/style.css +1 -1
- package/dist/test/assets/icons/call/IconMic.vue.js +9 -9
- package/dist/test/chat/App.vue.js +0 -1
- package/dist/test/chat/page/home/ChatMessage.vue.js +8 -5
- package/dist/test/chat/page/home/Home.vue.js +1 -0
- package/dist/test/components/chat/call/Calling.vue.js +150 -106
- package/dist/test/composable/useCallHelper.js +11 -8
- package/dist/test/composable/useInitData.js +5 -5
- package/dist/test/composable/usePlivo.js +138 -0
- package/dist/test/plugins/mqtt.js +0 -3
- package/dist/test/plugins/websocket.js +33 -24
- package/dist/test/types/call.js +10 -1
- package/dist/test/utils/chat/call.js +19 -6
- package/dist/types/call.d.ts +9 -0
- package/dist/utils/chat/call.d.ts +1 -0
- package/package.json +2 -1
- package/dist/composable/TestSound.d.ts +0 -64
- package/dist/router/index.d.ts +0 -2
- package/dist/test/composable/TestSound.js +0 -196
- package/dist/test/router/index.js +0 -39
- package/dist/test/views/NotFound.vue.js +0 -47
- package/dist/test/views/TenantPhone.vue.js +0 -270
- package/dist/views/NotFound.vue.d.ts +0 -2
- package/dist/views/TenantPhone.vue.d.ts +0 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
|
2
2
|
import IconPhone from '../../../assets/icons/call/IconPhone.vue';
|
|
3
3
|
import { dataProfile } from '../../../utils/chat/auth.js';
|
|
4
4
|
import { useCallHelper } from '../../../composable/useCallHelper';
|
|
5
5
|
import IconPhoneCancel from '../../../assets/icons/call/IconPhoneCancel.vue';
|
|
6
|
-
import {
|
|
6
|
+
import { removeHandleWebSK } from '../../../plugins/websocket';
|
|
7
7
|
import { downloadRecord } from '../../../utils/chat/call';
|
|
8
8
|
import DrawerBaseCustom from '../../../components/common/drawer/DrawerBaseCustom.vue';
|
|
9
9
|
import Avatar from '../../../components/chat/customer/Avatar.vue';
|
|
@@ -11,42 +11,59 @@ import { getUserDetailChat } from '../../../utils/chat/user';
|
|
|
11
11
|
import { formatPhone10number } from '../../../utils/chat/phone-string';
|
|
12
12
|
import IconSoundDownload from '../../../assets/icons/call/IconSoundDownload.vue';
|
|
13
13
|
import IconClose from '../../../assets/icons/call/IconClose.vue';
|
|
14
|
-
|
|
14
|
+
import { usePlivo } from '../../../composable/usePlivo';
|
|
15
|
+
import { PLIVO_CALL_STATUS } from '../../../types/call';
|
|
16
|
+
import IconMic from '../../../assets/icons/call/IconMic.vue';
|
|
17
|
+
const { call, end, handleMedia, startIncomingCall, handleCallAnswer, callAnswer, uuid, startPeerConnection } = useCallHelper();
|
|
18
|
+
const handlePlivoCallBack = (status, data) => {
|
|
19
|
+
if (status == PLIVO_CALL_STATUS.RINGING) {
|
|
20
|
+
getUserOffer(data?.phone ?? '');
|
|
21
|
+
callStatus.value = PLIVO_CALL_STATUS.RINGING;
|
|
22
|
+
open();
|
|
23
|
+
}
|
|
24
|
+
else if (status == PLIVO_CALL_STATUS.CONNECT_FAILED || status == PLIVO_CALL_STATUS.NO_ANSWER) {
|
|
25
|
+
endCall();
|
|
26
|
+
callStatus.value = status;
|
|
27
|
+
}
|
|
28
|
+
else if (status == PLIVO_CALL_STATUS.CALL_END) {
|
|
29
|
+
errorMessage.value = data?.message ?? '';
|
|
30
|
+
endCall();
|
|
31
|
+
callStatus.value = status;
|
|
32
|
+
}
|
|
33
|
+
else if (status == PLIVO_CALL_STATUS.CALL_START) {
|
|
34
|
+
callStatus.value = status;
|
|
35
|
+
startTimer();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const { plivoLogin, plivoCallAnswer, plivoCall, plivoEndCall, plivoCallSwishMute } = usePlivo(handlePlivoCallBack);
|
|
15
39
|
const props = withDefaults(defineProps(), {});
|
|
16
40
|
const emit = defineEmits();
|
|
17
|
-
const STATUS = {
|
|
18
|
-
CONNECTING: 'Connecting...',
|
|
19
|
-
CALLING: 'calling',
|
|
20
|
-
RINGING: 'ringing',
|
|
21
|
-
CONNECT_FAILED: 'failed',
|
|
22
|
-
CALL_START: 'in-progress',
|
|
23
|
-
CALL_END: 'completed',
|
|
24
|
-
NO_ANSWER: 'no-answer'
|
|
25
|
-
};
|
|
26
41
|
const STATUS_LABEL = computed(() => {
|
|
27
42
|
return {
|
|
28
|
-
[
|
|
29
|
-
[
|
|
30
|
-
[
|
|
31
|
-
[
|
|
32
|
-
[
|
|
33
|
-
[
|
|
34
|
-
[
|
|
43
|
+
[PLIVO_CALL_STATUS.CONNECTING]: 'Connecting...',
|
|
44
|
+
[PLIVO_CALL_STATUS.CALLING]: 'Calling...',
|
|
45
|
+
[PLIVO_CALL_STATUS.RINGING]: 'Ringing...',
|
|
46
|
+
[PLIVO_CALL_STATUS.CONNECT_FAILED]: errorMessage.value || 'Connect Error',
|
|
47
|
+
[PLIVO_CALL_STATUS.CALL_START]: '',
|
|
48
|
+
[PLIVO_CALL_STATUS.CALL_END]: errorMessage.value || 'Call Ended',
|
|
49
|
+
[PLIVO_CALL_STATUS.NO_ANSWER]: 'No Answer'
|
|
35
50
|
};
|
|
36
51
|
});
|
|
37
|
-
const callStatus = ref(
|
|
52
|
+
const callStatus = ref(PLIVO_CALL_STATUS.CONNECTING);
|
|
38
53
|
const duration = ref('00:00');
|
|
39
54
|
const drawerVisible = ref(false);
|
|
40
55
|
const disable = ref(false);
|
|
41
56
|
const errorMessage = ref('');
|
|
42
57
|
const record_link = ref('');
|
|
43
58
|
const drawerVisibleRef = ref(null);
|
|
59
|
+
const userRemoter = ref(null);
|
|
60
|
+
const isMute = ref(false);
|
|
44
61
|
let timer = null;
|
|
45
62
|
let timeOut = null;
|
|
46
63
|
let callType = 'call';
|
|
47
64
|
let uuidEnd = '';
|
|
48
|
-
onMounted(() => {
|
|
49
|
-
|
|
65
|
+
onMounted(async () => {
|
|
66
|
+
await plivoLogin('');
|
|
50
67
|
});
|
|
51
68
|
onUnmounted(() => {
|
|
52
69
|
removeHandleWebSK('call-message');
|
|
@@ -66,22 +83,17 @@ function startTimer() {
|
|
|
66
83
|
duration.value = `${m}:${s}`;
|
|
67
84
|
}, 1000);
|
|
68
85
|
}
|
|
69
|
-
function toggleMute() {
|
|
70
|
-
alert('Mic toggled');
|
|
71
|
-
}
|
|
72
|
-
function toggleSpeaker() {
|
|
73
|
-
alert('Speaker toggled');
|
|
74
|
-
}
|
|
75
86
|
function endCall(option) {
|
|
76
|
-
callStatus.value
|
|
87
|
+
plivoEndCall(callStatus.value);
|
|
88
|
+
callStatus.value = PLIVO_CALL_STATUS.CALL_END;
|
|
77
89
|
uuidEnd = uuid.value;
|
|
78
|
-
end();
|
|
79
90
|
clearInterval(timer);
|
|
80
91
|
disable.value = false;
|
|
81
92
|
if (option?.closeModal) {
|
|
82
93
|
drawerVisible.value = false;
|
|
83
94
|
drawerVisibleRef.value?.close();
|
|
84
95
|
}
|
|
96
|
+
isMute.value = false;
|
|
85
97
|
duration.value = '00:00';
|
|
86
98
|
if (timer)
|
|
87
99
|
clearInterval(timer);
|
|
@@ -93,36 +105,40 @@ const open = () => {
|
|
|
93
105
|
disable.value = true;
|
|
94
106
|
drawerVisibleRef.value?.open();
|
|
95
107
|
};
|
|
108
|
+
const handleMute = () => {
|
|
109
|
+
plivoCallSwishMute(!isMute.value);
|
|
110
|
+
isMute.value = !isMute.value;
|
|
111
|
+
};
|
|
96
112
|
const startCall = async (data) => {
|
|
97
113
|
try {
|
|
98
|
-
callStatus.value =
|
|
99
|
-
|
|
114
|
+
callStatus.value = PLIVO_CALL_STATUS.CONNECTING;
|
|
115
|
+
userRemoter.value = data;
|
|
100
116
|
open();
|
|
101
117
|
callType = 'call';
|
|
102
|
-
await
|
|
103
|
-
callStatus.value =
|
|
118
|
+
await plivoCall(data.phone);
|
|
119
|
+
callStatus.value = PLIVO_CALL_STATUS.CALLING;
|
|
104
120
|
}
|
|
105
121
|
catch (e) {
|
|
122
|
+
endCall();
|
|
106
123
|
console.log(e);
|
|
107
124
|
errorMessage.value = e?.message || JSON.stringify(e);
|
|
108
|
-
callStatus.value =
|
|
125
|
+
callStatus.value = PLIVO_CALL_STATUS.CONNECT_FAILED;
|
|
109
126
|
}
|
|
110
127
|
};
|
|
111
128
|
const answer = async (message) => {
|
|
112
129
|
try {
|
|
113
|
-
await
|
|
114
|
-
await startIncomingCall(message?.data?.call_uuid);
|
|
115
|
-
callStatus.value = STATUS.CALL_START;
|
|
130
|
+
await plivoCallAnswer();
|
|
116
131
|
}
|
|
117
132
|
catch (e) {
|
|
118
133
|
endCall();
|
|
119
|
-
callStatus.value =
|
|
134
|
+
callStatus.value = PLIVO_CALL_STATUS.CONNECT_FAILED;
|
|
120
135
|
errorMessage.value = e?.message || JSON.stringify(e);
|
|
121
136
|
}
|
|
122
137
|
};
|
|
123
138
|
const getUserOffer = async (phone) => {
|
|
124
139
|
let res = null;
|
|
125
140
|
try {
|
|
141
|
+
userRemoter.value = null;
|
|
126
142
|
let data = {
|
|
127
143
|
phone: formatPhone10number(phone, '1'),
|
|
128
144
|
client_id: dataProfile.value?.tenant_id ?? ''
|
|
@@ -139,55 +155,52 @@ const getUserOffer = async (phone) => {
|
|
|
139
155
|
userRemoter.value = user;
|
|
140
156
|
emit('userCalling', userRemoter.value);
|
|
141
157
|
};
|
|
142
|
-
const handleMqttMessage = async (message) => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
// if (da){
|
|
189
|
-
// } else console.log('-----------------', message)
|
|
190
|
-
};
|
|
158
|
+
// const handleMqttMessage = async (message: any) => {
|
|
159
|
+
// console.log(message)
|
|
160
|
+
// let da = true
|
|
161
|
+
// if (message.event == 'call_update') {
|
|
162
|
+
// if (message?.data?.status == PLIVO_CALL_STATUS.RINGING) {
|
|
163
|
+
// if (message?.data?.to_number == dataProfile.value?.phone) {
|
|
164
|
+
// callStatus.value = PLIVO_CALL_STATUS.RINGING
|
|
165
|
+
// dataWebSK = {
|
|
166
|
+
// from: message.data.from_number,
|
|
167
|
+
// to: message.data.to_number
|
|
168
|
+
// }
|
|
169
|
+
// getUserOffer(message.data.from_number)
|
|
170
|
+
// handleCallAnswer(message)
|
|
171
|
+
// open()
|
|
172
|
+
// }
|
|
173
|
+
// } else if (message?.data?.status == PLIVO_CALL_STATUS.CALL_START) {
|
|
174
|
+
// try {
|
|
175
|
+
// await startIncomingCall(message?.data?.call_uuid)
|
|
176
|
+
// startTimer()
|
|
177
|
+
// callStatus.value = PLIVO_CALL_STATUS.CALL_START
|
|
178
|
+
// } catch (e) {
|
|
179
|
+
// console.log(e)
|
|
180
|
+
// endCall()
|
|
181
|
+
// }
|
|
182
|
+
// } else if (message?.data?.status == PLIVO_CALL_STATUS.CALL_END) {
|
|
183
|
+
// endCall()
|
|
184
|
+
// } else if (
|
|
185
|
+
// message?.data?.status == PLIVO_CALL_STATUS.CONNECT_FAILED ||
|
|
186
|
+
// message?.data?.status == PLIVO_CALL_STATUS.NO_ANSWER
|
|
187
|
+
// ) {
|
|
188
|
+
// endCall()
|
|
189
|
+
// callStatus.value = message?.data?.status
|
|
190
|
+
// } else {
|
|
191
|
+
// // console.log(message)
|
|
192
|
+
// da = false
|
|
193
|
+
// // handleMedia(message)
|
|
194
|
+
// }
|
|
195
|
+
// } else if (message?.event == 'record_uploaded') {
|
|
196
|
+
// if (uuidEnd == message?.data?.call_uuid) {
|
|
197
|
+
// record_link.value = message?.data?.recording_url
|
|
198
|
+
// }
|
|
199
|
+
// }
|
|
200
|
+
//
|
|
201
|
+
// // if (da){
|
|
202
|
+
// // } else console.log('-----------------', message)
|
|
203
|
+
// }
|
|
191
204
|
const exportRecordFile = async () => {
|
|
192
205
|
downloadRecord(record_link.value);
|
|
193
206
|
};
|
|
@@ -280,9 +293,9 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
280
293
|
__VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
|
|
281
294
|
...{ class: "flex items-center justify-center gap-8 mt-10" },
|
|
282
295
|
});
|
|
283
|
-
if (__VLS_ctx.callStatus == __VLS_ctx.
|
|
296
|
+
if (__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.RINGING) {
|
|
284
297
|
// @ts-ignore
|
|
285
|
-
[callStatus,
|
|
298
|
+
[callStatus, PLIVO_CALL_STATUS,];
|
|
286
299
|
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
287
300
|
...{ onClick: (__VLS_ctx.answer) },
|
|
288
301
|
...{ class: "w-16 h-16 bg-[#22C55E] hover:bg-green-600 text-white rounded-full flex items-center justify-center shadow-lg transition" },
|
|
@@ -294,9 +307,9 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
294
307
|
const __VLS_14 = __VLS_asFunctionalComponent(IconPhone, new IconPhone({}));
|
|
295
308
|
const __VLS_15 = __VLS_14({}, ...__VLS_functionalComponentArgsRest(__VLS_14));
|
|
296
309
|
}
|
|
297
|
-
if (__VLS_ctx.record_link && __VLS_ctx.callStatus == __VLS_ctx.
|
|
310
|
+
if (__VLS_ctx.record_link && __VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_END) {
|
|
298
311
|
// @ts-ignore
|
|
299
|
-
[callStatus,
|
|
312
|
+
[callStatus, PLIVO_CALL_STATUS, record_link,];
|
|
300
313
|
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
301
314
|
...{ onClick: (__VLS_ctx.exportRecordFile) },
|
|
302
315
|
href: (__VLS_ctx.record_link),
|
|
@@ -310,12 +323,36 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
310
323
|
const __VLS_18 = __VLS_asFunctionalComponent(IconSoundDownload, new IconSoundDownload({}));
|
|
311
324
|
const __VLS_19 = __VLS_18({}, ...__VLS_functionalComponentArgsRest(__VLS_18));
|
|
312
325
|
}
|
|
313
|
-
if (__VLS_ctx.callStatus == __VLS_ctx.
|
|
326
|
+
if (__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_START) {
|
|
314
327
|
// @ts-ignore
|
|
315
|
-
[callStatus,
|
|
328
|
+
[callStatus, PLIVO_CALL_STATUS,];
|
|
316
329
|
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
317
330
|
...{ onClick: (...[$event]) => {
|
|
318
|
-
if (!(__VLS_ctx.callStatus == __VLS_ctx.
|
|
331
|
+
if (!(__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_START))
|
|
332
|
+
return;
|
|
333
|
+
__VLS_ctx.handleMute();
|
|
334
|
+
// @ts-ignore
|
|
335
|
+
[handleMute,];
|
|
336
|
+
} },
|
|
337
|
+
...{ class: "w-16 h-16 bg-white hover:bg-green-600 text-black rounded-full flex items-center justify-center shadow-lg transition" },
|
|
338
|
+
});
|
|
339
|
+
/** @type {[typeof IconMic, ]} */ ;
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
const __VLS_22 = __VLS_asFunctionalComponent(IconMic, new IconMic({
|
|
342
|
+
mute: (__VLS_ctx.isMute),
|
|
343
|
+
}));
|
|
344
|
+
const __VLS_23 = __VLS_22({
|
|
345
|
+
mute: (__VLS_ctx.isMute),
|
|
346
|
+
}, ...__VLS_functionalComponentArgsRest(__VLS_22));
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
[isMute,];
|
|
349
|
+
}
|
|
350
|
+
if (__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_END) {
|
|
351
|
+
// @ts-ignore
|
|
352
|
+
[callStatus, PLIVO_CALL_STATUS,];
|
|
353
|
+
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
354
|
+
...{ onClick: (...[$event]) => {
|
|
355
|
+
if (!(__VLS_ctx.callStatus == __VLS_ctx.PLIVO_CALL_STATUS.CALL_END))
|
|
319
356
|
return;
|
|
320
357
|
__VLS_ctx.endCall({ closeModal: true });
|
|
321
358
|
// @ts-ignore
|
|
@@ -325,15 +362,15 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
325
362
|
});
|
|
326
363
|
/** @type {[typeof IconClose, ]} */ ;
|
|
327
364
|
// @ts-ignore
|
|
328
|
-
const
|
|
329
|
-
const
|
|
365
|
+
const __VLS_26 = __VLS_asFunctionalComponent(IconClose, new IconClose({}));
|
|
366
|
+
const __VLS_27 = __VLS_26({}, ...__VLS_functionalComponentArgsRest(__VLS_26));
|
|
330
367
|
}
|
|
331
|
-
if (__VLS_ctx.callStatus != __VLS_ctx.
|
|
368
|
+
if (__VLS_ctx.callStatus != __VLS_ctx.PLIVO_CALL_STATUS.CALL_END) {
|
|
332
369
|
// @ts-ignore
|
|
333
|
-
[callStatus,
|
|
370
|
+
[callStatus, PLIVO_CALL_STATUS,];
|
|
334
371
|
__VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
|
|
335
372
|
...{ onClick: (...[$event]) => {
|
|
336
|
-
if (!(__VLS_ctx.callStatus != __VLS_ctx.
|
|
373
|
+
if (!(__VLS_ctx.callStatus != __VLS_ctx.PLIVO_CALL_STATUS.CALL_END))
|
|
337
374
|
return;
|
|
338
375
|
__VLS_ctx.endCall();
|
|
339
376
|
// @ts-ignore
|
|
@@ -343,8 +380,8 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
343
380
|
});
|
|
344
381
|
/** @type {[typeof IconPhoneCancel, ]} */ ;
|
|
345
382
|
// @ts-ignore
|
|
346
|
-
const
|
|
347
|
-
const
|
|
383
|
+
const __VLS_30 = __VLS_asFunctionalComponent(IconPhoneCancel, new IconPhoneCancel({}));
|
|
384
|
+
const __VLS_31 = __VLS_30({}, ...__VLS_functionalComponentArgsRest(__VLS_30));
|
|
348
385
|
}
|
|
349
386
|
__VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
|
|
350
387
|
...{ class: "absolute bottom-6 text-gray-500 text-sm" },
|
|
@@ -354,10 +391,6 @@ const { default: __VLS_8 } = __VLS_2.slots;
|
|
|
354
391
|
[duration,];
|
|
355
392
|
}
|
|
356
393
|
var __VLS_2;
|
|
357
|
-
__VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
|
|
358
|
-
id: "go-chat-local-audio",
|
|
359
|
-
autoplay: true,
|
|
360
|
-
});
|
|
361
394
|
__VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
|
|
362
395
|
id: "go-chat-remote-audio",
|
|
363
396
|
autoplay: true,
|
|
@@ -415,6 +448,17 @@ __VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
|
|
|
415
448
|
/** @type {__VLS_StyleScopedClasses['h-16']} */ ;
|
|
416
449
|
/** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
|
|
417
450
|
/** @type {__VLS_StyleScopedClasses['hover:bg-green-600']} */ ;
|
|
451
|
+
/** @type {__VLS_StyleScopedClasses['text-black']} */ ;
|
|
452
|
+
/** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
|
|
453
|
+
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
454
|
+
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
|
|
455
|
+
/** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
|
|
456
|
+
/** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
|
|
457
|
+
/** @type {__VLS_StyleScopedClasses['transition']} */ ;
|
|
458
|
+
/** @type {__VLS_StyleScopedClasses['w-16']} */ ;
|
|
459
|
+
/** @type {__VLS_StyleScopedClasses['h-16']} */ ;
|
|
460
|
+
/** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
|
|
461
|
+
/** @type {__VLS_StyleScopedClasses['hover:bg-green-600']} */ ;
|
|
418
462
|
/** @type {__VLS_StyleScopedClasses['text-white']} */ ;
|
|
419
463
|
/** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
|
|
420
464
|
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
|
|
@@ -140,7 +140,7 @@ export function useCallHelper() {
|
|
|
140
140
|
sourceCall?.disconnect?.(processorCall);
|
|
141
141
|
stopQueue();
|
|
142
142
|
websocket?.disconnect();
|
|
143
|
-
stream?.
|
|
143
|
+
stream?.getAudioTracks?.()?.forEach((track) => track?.stop());
|
|
144
144
|
if (!uuid)
|
|
145
145
|
return;
|
|
146
146
|
await plivoEndCall(uuid.value);
|
|
@@ -148,6 +148,11 @@ export function useCallHelper() {
|
|
|
148
148
|
};
|
|
149
149
|
const startPeerConnection = async () => {
|
|
150
150
|
try {
|
|
151
|
+
if (!audioCtxCall) {
|
|
152
|
+
audioCtxCall = _getAudioContext();
|
|
153
|
+
}
|
|
154
|
+
if (audioCtxCall.state === 'suspended')
|
|
155
|
+
await audioCtxCall.resume();
|
|
151
156
|
stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
152
157
|
sourceCall = audioCtxCall.createMediaStreamSource(stream);
|
|
153
158
|
processorCall = audioCtxCall.createScriptProcessor(256, 1, 1);
|
|
@@ -168,7 +173,7 @@ export function useCallHelper() {
|
|
|
168
173
|
// socketSend(binaryChunk)
|
|
169
174
|
// websocket.binaryType = "arraybuffer";
|
|
170
175
|
// console.log(binaryChunk)
|
|
171
|
-
websocket.sendDefault(binaryChunk)
|
|
176
|
+
// websocket.sendDefault(binaryChunk)
|
|
172
177
|
}
|
|
173
178
|
};
|
|
174
179
|
sourceCall.connect(processorCall);
|
|
@@ -187,6 +192,9 @@ export function useCallHelper() {
|
|
|
187
192
|
// const float32Data = int16ToFloat32(int16View)
|
|
188
193
|
const floatData = _muLawToFloat32(ulawBytes);
|
|
189
194
|
prebuffer.push(floatData);
|
|
195
|
+
if (prebuffer.length > 3) {
|
|
196
|
+
prebuffer.shift(); // bỏ gói cũ
|
|
197
|
+
}
|
|
190
198
|
};
|
|
191
199
|
async function scheduleNext() {
|
|
192
200
|
try {
|
|
@@ -278,12 +286,6 @@ export function useCallHelper() {
|
|
|
278
286
|
}
|
|
279
287
|
websocket = new WebSocketClient(uuid_request, handleMqttMessage);
|
|
280
288
|
await websocket?.init();
|
|
281
|
-
if (!audioCtxCall) {
|
|
282
|
-
audioCtxCall = _getAudioContext();
|
|
283
|
-
}
|
|
284
|
-
if (audioCtxCall.state === 'suspended')
|
|
285
|
-
await audioCtxCall.resume();
|
|
286
|
-
await startPeerConnection();
|
|
287
289
|
if (running)
|
|
288
290
|
return;
|
|
289
291
|
running = true;
|
|
@@ -330,6 +332,7 @@ export function useCallHelper() {
|
|
|
330
332
|
testPlay,
|
|
331
333
|
handleCallAnswer,
|
|
332
334
|
callAnswer,
|
|
335
|
+
startPeerConnection,
|
|
333
336
|
startIncomingCall,
|
|
334
337
|
uuid
|
|
335
338
|
};
|
|
@@ -6,7 +6,7 @@ import { PAGE } from '../constant/general';
|
|
|
6
6
|
import { subscribeToTopic, unsubscribeFromTopic } from '../plugins/mqtt';
|
|
7
7
|
import { TOPIC_DETAIL_CALL } from '../constant/mqtt';
|
|
8
8
|
import { getWebSocket, initWebSocket } from '../plugins/websocket';
|
|
9
|
-
import router from '../router'
|
|
9
|
+
// import router from '../router'
|
|
10
10
|
//PINIA
|
|
11
11
|
export const isRouterReady = ref(false);
|
|
12
12
|
export function useInitData() {
|
|
@@ -38,10 +38,10 @@ export function useInitData() {
|
|
|
38
38
|
initWebSocket();
|
|
39
39
|
unsubscribeFromTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
|
|
40
40
|
subscribeToTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
|
|
41
|
-
if
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
41
|
+
// if((!res?.phone && res.tenant_id && !props.isLib)) {
|
|
42
|
+
// router.push({name: 'tenant-phone'})
|
|
43
|
+
// }
|
|
44
|
+
if (response == 'mobile') {
|
|
45
45
|
routerPush(PAGE.CHAT_LIST);
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { PLIVO_CALL_STATUS } from '../types/call';
|
|
2
|
+
export function usePlivo(callback) {
|
|
3
|
+
var options = {
|
|
4
|
+
debug: 'ALL',
|
|
5
|
+
permOnClick: true,
|
|
6
|
+
deviceParams: {
|
|
7
|
+
micEnabled: true,
|
|
8
|
+
audioConstraints: { audio: true, video: false }
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var plivoBrowserSdk = null;
|
|
12
|
+
let CallUuid = '';
|
|
13
|
+
let custom_resolve = null;
|
|
14
|
+
let custom_reject = null;
|
|
15
|
+
const plivoLogin = async (token) => {
|
|
16
|
+
token =
|
|
17
|
+
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6InBsaXZvO3Y9MSJ9.eyJqdGkiOiJ0ZXN0MSIsImlzcyI6IlNBTjJZMFpERTRNSkFUTVpZNU5DIiwic3ViIjoid2ViY2FsbDAwMzA3OTY3MzQ1NDg5MTgyNyIsIm5iZiI6MTc2MzY5MzUyNSwiZXhwIjoxNzYzNzc5OTI1LCJncmFudHMiOnsidm9pY2UiOnsiaW5jb21pbmdfYWxsb3ciOnRydWUsIm91dGdvaW5nX2FsbG93Ijp0cnVlfX19.9p4O_xTb4kNhKyDVfK3EemSKBQiHtbKNUZ5iwnSdX1I';
|
|
18
|
+
try {
|
|
19
|
+
if (!plivoBrowserSdk)
|
|
20
|
+
plivoBrowserSdk = new window.Plivo(options);
|
|
21
|
+
plivoBrowserSdk?.client?.on?.('onCallAnswered', (callInfo) => {
|
|
22
|
+
handleCallAnswered(callInfo);
|
|
23
|
+
});
|
|
24
|
+
plivoBrowserSdk?.client?.on?.('onCallTerminated', (hangupInfo, callInfo) => handleCallTerminated(hangupInfo, callInfo));
|
|
25
|
+
plivoBrowserSdk.client.on('onCallFailed', (data, callInfo) => {
|
|
26
|
+
handleCallFailed(data, callInfo);
|
|
27
|
+
});
|
|
28
|
+
plivoBrowserSdk.client.on('onCalling', (data) => console.log('onCallFailed', data));
|
|
29
|
+
plivoBrowserSdk?.client?.on?.('onIncomingCall', (callerID, extraHeaders, callInfo) => {
|
|
30
|
+
handleIncomingCall(callInfo);
|
|
31
|
+
});
|
|
32
|
+
plivoBrowserSdk.client.on('onCallRemoteRinging', (data) => handleCallRemoteRinging(data));
|
|
33
|
+
// plivoBrowserSdk?.client?.on?.('onReady', () => console.log('Ready'))
|
|
34
|
+
// plivoBrowserSdk?.client?.on?.('onLoginFailed', () => console.log('Login failed'))
|
|
35
|
+
// plivoBrowserSdk?.client?.on?.('remoteAudioStatus', () => console.log('remoteAudioStatus'))
|
|
36
|
+
await plivoBrowserSdk?.client?.login('webcall003079673454891827', '123456abcA!');
|
|
37
|
+
const speaker = document.getElementById("go-chat-remote-audio");
|
|
38
|
+
if (speaker)
|
|
39
|
+
plivoBrowserSdk?.client?.setAudioElement(speaker);
|
|
40
|
+
console.log('Registered with token');
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.log('Login error: ' + err);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const handleIncomingCall = (call) => {
|
|
47
|
+
const data = {
|
|
48
|
+
phone: _getPhone(call.src)
|
|
49
|
+
};
|
|
50
|
+
console.log(call);
|
|
51
|
+
callback(PLIVO_CALL_STATUS.RINGING, data);
|
|
52
|
+
CallUuid = call?.callUUID;
|
|
53
|
+
};
|
|
54
|
+
const handleCallRemoteRinging = (callInfo) => {
|
|
55
|
+
CallUuid = callInfo.callUUID;
|
|
56
|
+
callback(PLIVO_CALL_STATUS.CALLING);
|
|
57
|
+
custom_resolve?.();
|
|
58
|
+
};
|
|
59
|
+
const handleCallAnswered = (call) => {
|
|
60
|
+
if (call.callUUID == CallUuid) {
|
|
61
|
+
custom_resolve?.();
|
|
62
|
+
callback(PLIVO_CALL_STATUS.CALL_START);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const handleCallTerminated = (data, callInfo) => {
|
|
66
|
+
if (CallUuid === callInfo.callUUID) {
|
|
67
|
+
callback(PLIVO_CALL_STATUS.CALL_END, { message: data?.reason });
|
|
68
|
+
CallUuid = '';
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const _getPhone = (text, dial = '1') => {
|
|
72
|
+
let result = text.replace(/[^0-9]/g, '');
|
|
73
|
+
return result?.startsWith(dial) ? result.slice(dial.toString().length) : result;
|
|
74
|
+
};
|
|
75
|
+
const _waitEventOrTimeout = (timeoutMs = 3000) => {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
custom_resolve = null;
|
|
78
|
+
const timer = setTimeout(() => {
|
|
79
|
+
reject('Time out error!');
|
|
80
|
+
custom_resolve = null;
|
|
81
|
+
custom_reject = null;
|
|
82
|
+
}, timeoutMs);
|
|
83
|
+
custom_resolve = () => {
|
|
84
|
+
resolve(true);
|
|
85
|
+
custom_resolve = null;
|
|
86
|
+
clearTimeout(timer);
|
|
87
|
+
};
|
|
88
|
+
custom_reject = (data) => {
|
|
89
|
+
reject(data);
|
|
90
|
+
custom_reject = null;
|
|
91
|
+
clearTimeout(timer);
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const plivoCallAnswer = async () => {
|
|
96
|
+
plivoBrowserSdk?.client?.answer?.(CallUuid);
|
|
97
|
+
await _waitEventOrTimeout(3000);
|
|
98
|
+
};
|
|
99
|
+
const plivoCallReject = () => {
|
|
100
|
+
plivoBrowserSdk?.client?.reject?.(CallUuid);
|
|
101
|
+
};
|
|
102
|
+
const plivoCallIgnore = () => {
|
|
103
|
+
if (CallUuid)
|
|
104
|
+
plivoBrowserSdk?.client?.ignore?.(CallUuid);
|
|
105
|
+
};
|
|
106
|
+
const plivoCallSwishMute = (isMute) => {
|
|
107
|
+
plivoBrowserSdk?.client?.mute();
|
|
108
|
+
if (isMute)
|
|
109
|
+
plivoBrowserSdk?.client?.mute?.();
|
|
110
|
+
else
|
|
111
|
+
plivoBrowserSdk?.client?.unmute?.();
|
|
112
|
+
};
|
|
113
|
+
const plivoCall = async (phone) => {
|
|
114
|
+
plivoBrowserSdk.client.call('+' + phone, { number_phone: phone });
|
|
115
|
+
await _waitEventOrTimeout(5000);
|
|
116
|
+
};
|
|
117
|
+
const plivoEndCall = (status) => {
|
|
118
|
+
if (status == PLIVO_CALL_STATUS.RINGING) {
|
|
119
|
+
plivoBrowserSdk?.client?.reject?.(CallUuid);
|
|
120
|
+
}
|
|
121
|
+
else if (status == PLIVO_CALL_STATUS.CALL_START || status == PLIVO_CALL_STATUS.CALLING) {
|
|
122
|
+
plivoBrowserSdk?.client?.hangup?.();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const handleCallFailed = (data, callInfo) => {
|
|
126
|
+
if (custom_reject)
|
|
127
|
+
custom_reject?.(data);
|
|
128
|
+
callback(PLIVO_CALL_STATUS.CALL_END, { message: data });
|
|
129
|
+
};
|
|
130
|
+
return {
|
|
131
|
+
plivoLogin,
|
|
132
|
+
plivoCallAnswer,
|
|
133
|
+
plivoCallReject,
|
|
134
|
+
plivoCall,
|
|
135
|
+
plivoEndCall,
|
|
136
|
+
plivoCallSwishMute
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -10,7 +10,6 @@ export const connectMqtt = () => {
|
|
|
10
10
|
return new Promise((resolve, reject) => {
|
|
11
11
|
reconnectCount = 0;
|
|
12
12
|
if (mqttClient && mqttClient?.connected) {
|
|
13
|
-
console.log('MQTT already connected');
|
|
14
13
|
return resolve();
|
|
15
14
|
}
|
|
16
15
|
const userInfo = JSON.parse(localStorage.getItem('user') || '{}');
|
|
@@ -30,7 +29,6 @@ export const connectMqtt = () => {
|
|
|
30
29
|
const connectUrl = `wss://${host}:${port}${path}`;
|
|
31
30
|
mqttClient = mqtt.connect(connectUrl, options);
|
|
32
31
|
mqttClient?.on('connect', () => {
|
|
33
|
-
console.log('MQTT Connected Successfully');
|
|
34
32
|
subscribedTopics.forEach((topic) => mqttClient?.subscribe(topic));
|
|
35
33
|
mqttClient?.on('message', (topic, message) => {
|
|
36
34
|
try {
|
|
@@ -75,7 +73,6 @@ export const disconnectMqtt = () => {
|
|
|
75
73
|
};
|
|
76
74
|
export const subscribeToTopic = (topic) => {
|
|
77
75
|
if (subscribedTopics.has(topic)) {
|
|
78
|
-
console.log(`Already subscribed to ${topic}`);
|
|
79
76
|
return;
|
|
80
77
|
}
|
|
81
78
|
if (mqttClient?.connected || true) {
|