@phonghq/go-chat 1.0.11 → 1.0.13

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 (56) hide show
  1. package/dist/assets/icons/IconAiCheck.vue.d.ts +2 -0
  2. package/dist/assets/icons/call/IconClose.vue.d.ts +2 -0
  3. package/dist/assets/icons/call/IconSoundDownload.vue.d.ts +2 -0
  4. package/dist/chat/App.vue.d.ts +7 -2
  5. package/dist/chat/page/customer-detail/CustomerDetail.vue.d.ts +1 -1
  6. package/dist/chat/page/home/ChatList.vue.d.ts +29 -1
  7. package/dist/chat/page/home/ChatMessage.vue.d.ts +1 -1
  8. package/dist/chat/page/home/Home.vue.d.ts +1 -1
  9. package/dist/components/chat/ScrollEvent/ScrollEvent.vue.d.ts +1 -0
  10. package/dist/components/chat/call/Calling.vue.d.ts +8 -2
  11. package/dist/components/chat/common/input/InputSearch.vue.d.ts +1 -1
  12. package/dist/components/chat/select/SelectBase.vue.d.ts +22 -0
  13. package/dist/composable/useCallHelper.d.ts +6 -2
  14. package/dist/composable/useInitData.d.ts +2 -4
  15. package/dist/go-chat.es.js +22339 -20111
  16. package/dist/go-chat.umd.js +44 -14
  17. package/dist/plugins/websocket.d.ts +12 -2
  18. package/dist/router/index.d.ts +2 -0
  19. package/dist/style.css +1 -1
  20. package/dist/test/assets/icons/IconAiCheck.vue.js +28 -0
  21. package/dist/test/assets/icons/call/IconClose.vue.js +26 -0
  22. package/dist/test/assets/icons/call/IconSoundDownload.vue.js +50 -0
  23. package/dist/test/chat/App.vue.js +145 -90
  24. package/dist/test/chat/page/customer-detail/CustomerDetail.vue.js +6 -5
  25. package/dist/test/chat/page/home/ChatList.vue.js +30 -9
  26. package/dist/test/chat/page/home/ChatMessage.vue.js +17 -9
  27. package/dist/test/chat/page/home/Home.vue.js +3 -3
  28. package/dist/test/chat/page/home/NewCustomer.vue.js +0 -12
  29. package/dist/test/components/chat/ScrollEvent/ScrollEvent.vue.js +7 -1
  30. package/dist/test/components/chat/call/Calling.vue.js +198 -76
  31. package/dist/test/components/chat/common/input/InputSearch.vue.js +2 -2
  32. package/dist/test/components/chat/select/SelectBase.vue.js +98 -0
  33. package/dist/test/components/common/drawer/DrawerBaseCustom.vue.js +0 -1
  34. package/dist/test/composable/data.json +32 -0
  35. package/dist/test/composable/useCallHelper.js +143 -33
  36. package/dist/test/composable/useDigibot.js +1 -1
  37. package/dist/test/composable/useInitData.js +17 -12
  38. package/dist/test/constant/color.js +1 -1
  39. package/dist/test/plugins/axios.js +2 -1
  40. package/dist/test/plugins/mqtt.js +11 -5
  41. package/dist/test/plugins/websocket.js +84 -4
  42. package/dist/test/router/index.js +39 -0
  43. package/dist/test/utils/chat/auth.js +10 -2
  44. package/dist/test/utils/chat/call.js +32 -5
  45. package/dist/test/utils/chat/phone-string.js +4 -0
  46. package/dist/test/utils/chat/user.js +7 -2
  47. package/dist/test/views/NotFound.vue.js +47 -0
  48. package/dist/test/views/TenantPhone.vue.js +270 -0
  49. package/dist/types/chat/global.d.ts +4 -0
  50. package/dist/utils/chat/auth.d.ts +5 -1
  51. package/dist/utils/chat/call.d.ts +5 -2
  52. package/dist/utils/chat/phone-string.d.ts +1 -0
  53. package/dist/utils/chat/user.d.ts +4 -0
  54. package/dist/views/NotFound.vue.d.ts +2 -0
  55. package/dist/views/TenantPhone.vue.d.ts +2 -0
  56. package/package.json +1 -1
@@ -1,24 +1,27 @@
1
- /// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
2
- import { ref, onMounted, onUnmounted, watch, computed } from 'vue';
1
+ import { ref, onMounted, onUnmounted, computed } from 'vue';
3
2
  import IconPhone from '../../../assets/icons/call/IconPhone.vue';
4
3
  import { dataProfile } from '../../../utils/chat/auth.js';
5
4
  import { useCallHelper } from '../../../composable/useCallHelper';
6
5
  import IconPhoneCancel from '../../../assets/icons/call/IconPhoneCancel.vue';
7
- import { addHandleWebSK, removeHandleWebSK } from '../../../plugins/websocket';
8
- import { callClient } from '../../../utils/chat/call';
9
- import { useAudioStream } from '../../../composable/TestSound';
6
+ import { addHandleWebSK, initWebSocket, removeHandleWebSK } from '../../../plugins/websocket';
7
+ import { downloadRecord } from '../../../utils/chat/call';
10
8
  import DrawerBaseCustom from '../../../components/common/drawer/DrawerBaseCustom.vue';
11
9
  import Avatar from '../../../components/chat/customer/Avatar.vue';
12
- const { handleOffer, handleOfferResponse, call, end, userRemoter, handleMedia, startIncomingCall } = useCallHelper();
13
- const { enqueueSpeakerChunk, processSpeakerQueue } = useAudioStream('');
10
+ import { getUserDetailChat } from '../../../utils/chat/user';
11
+ import { formatPhone10number } from '../../../utils/chat/phone-string';
12
+ import IconSoundDownload from '../../../assets/icons/call/IconSoundDownload.vue';
13
+ import IconClose from '../../../assets/icons/call/IconClose.vue';
14
+ const { call, end, userRemoter, handleMedia, startIncomingCall, handleCallAnswer, callAnswer, uuid } = useCallHelper();
14
15
  const props = withDefaults(defineProps(), {});
16
+ const emit = defineEmits();
15
17
  const STATUS = {
16
18
  CONNECTING: 'Connecting...',
17
19
  CALLING: 'calling',
18
20
  RINGING: 'ringing',
19
- CONNECT_FAILED: 'Connect Error',
21
+ CONNECT_FAILED: 'failed',
20
22
  CALL_START: 'in-progress',
21
- CALL_END: 'completed'
23
+ CALL_END: 'completed',
24
+ NO_ANSWER: 'no-answer'
22
25
  };
23
26
  const STATUS_LABEL = computed(() => {
24
27
  return {
@@ -27,7 +30,8 @@ const STATUS_LABEL = computed(() => {
27
30
  [STATUS.RINGING]: 'Ringing...',
28
31
  [STATUS.CONNECT_FAILED]: errorMessage.value || 'Connect Error',
29
32
  [STATUS.CALL_START]: '',
30
- [STATUS.CALL_END]: 'Call Ended'
33
+ [STATUS.CALL_END]: 'Call Ended',
34
+ [STATUS.NO_ANSWER]: 'No Answer'
31
35
  };
32
36
  });
33
37
  const callStatus = ref(STATUS.CONNECTING);
@@ -35,16 +39,17 @@ const duration = ref('00:00');
35
39
  const drawerVisible = ref(false);
36
40
  const disable = ref(false);
37
41
  const errorMessage = ref('');
42
+ const record_link = ref('');
38
43
  const drawerVisibleRef = ref(null);
39
44
  let timer = null;
40
45
  let timeOut = null;
46
+ let callType = 'call';
47
+ let uuidEnd = '';
41
48
  onMounted(() => {
42
- // timeOut = setTimeout(() => {
43
- // callStatus.value = 'Connected'
44
- // startTimer()
45
- // }, 2000)
49
+ addHandleWebSK('call-message', handleMqttMessage);
46
50
  });
47
51
  onUnmounted(() => {
52
+ removeHandleWebSK('call-message');
48
53
  if (timer)
49
54
  clearInterval(timer);
50
55
  if (timeOut)
@@ -67,18 +72,21 @@ function toggleMute() {
67
72
  function toggleSpeaker() {
68
73
  alert('Speaker toggled');
69
74
  }
70
- function endCall() {
75
+ function endCall(option) {
71
76
  callStatus.value = STATUS.CALL_END;
72
- end('');
77
+ uuidEnd = uuid.value;
78
+ end();
73
79
  clearInterval(timer);
74
80
  disable.value = false;
75
- drawerVisible.value = false;
76
- drawerVisibleRef.value?.close();
81
+ if (option?.closeModal) {
82
+ drawerVisible.value = false;
83
+ drawerVisibleRef.value?.close();
84
+ }
85
+ duration.value = '00:00';
77
86
  if (timer)
78
87
  clearInterval(timer);
79
88
  if (timeOut)
80
89
  clearTimeout(timeOut);
81
- errorMessage.value = '';
82
90
  }
83
91
  const open = () => {
84
92
  drawerVisible.value = true;
@@ -88,7 +96,9 @@ const open = () => {
88
96
  const startCall = async (data) => {
89
97
  try {
90
98
  callStatus.value = STATUS.CONNECTING;
99
+ initWebSocket();
91
100
  open();
101
+ callType = 'call';
92
102
  await call(data);
93
103
  callStatus.value = STATUS.CALLING;
94
104
  }
@@ -98,55 +108,95 @@ const startCall = async (data) => {
98
108
  callStatus.value = STATUS.CONNECT_FAILED;
99
109
  }
100
110
  };
101
- const answer = async () => {
102
- await callClient(dataWebSK);
103
- callStatus.value = STATUS.CALL_START;
104
- // sendOfferOk()
111
+ const answer = async (message) => {
112
+ try {
113
+ await callAnswer(message?.data?.call_uuid);
114
+ await startIncomingCall(message?.data?.call_uuid);
115
+ callStatus.value = STATUS.CALL_START;
116
+ }
117
+ catch (e) {
118
+ endCall();
119
+ callStatus.value = STATUS.CONNECT_FAILED;
120
+ errorMessage.value = e?.message || JSON.stringify(e);
121
+ }
122
+ };
123
+ const getUserOffer = async (phone) => {
124
+ let res = null;
125
+ try {
126
+ let data = {
127
+ phone: formatPhone10number(phone, '1'),
128
+ client_id: dataProfile.value?.tenant_id ?? ''
129
+ };
130
+ res = await getUserDetailChat(data);
131
+ }
132
+ catch (e) {
133
+ console.log(e);
134
+ }
135
+ const user = {
136
+ username: res?.full_name || 'Unknown Name',
137
+ phone: '1' + res?.phone
138
+ };
139
+ userRemoter.value = user;
140
+ emit('userCalling', userRemoter.value);
105
141
  };
106
142
  const handleMqttMessage = async (message) => {
143
+ console.log(message);
107
144
  let da = true;
108
- if (message?.data?.status == STATUS.RINGING) {
109
- if (message?.data?.to_number == dataProfile.value?.phone) {
110
- callStatus.value = STATUS.RINGING;
111
- dataWebSK = {
112
- from: message.data.from_number,
113
- to: message.data.to_number
114
- };
115
- open();
145
+ if (message.event == 'call_update') {
146
+ if (message?.data?.status == STATUS.RINGING) {
147
+ if (message?.data?.to_number == dataProfile.value?.phone) {
148
+ callStatus.value = STATUS.RINGING;
149
+ dataWebSK = {
150
+ from: message.data.from_number,
151
+ to: message.data.to_number
152
+ };
153
+ getUserOffer(message.data.from_number);
154
+ handleCallAnswer(message);
155
+ open();
156
+ }
116
157
  }
117
- }
118
- else if (message?.data?.status == STATUS.CALL_START) {
119
- try {
120
- await startIncomingCall();
121
- startTimer();
122
- callStatus.value = STATUS.CALL_START;
158
+ else if (message?.data?.status == STATUS.CALL_START) {
159
+ try {
160
+ await startIncomingCall(message?.data?.call_uuid);
161
+ startTimer();
162
+ callStatus.value = STATUS.CALL_START;
163
+ }
164
+ catch (e) {
165
+ console.log(e);
166
+ endCall();
167
+ }
123
168
  }
124
- catch (e) {
125
- console.log(e);
169
+ else if (message?.data?.status == STATUS.CALL_END) {
126
170
  endCall();
127
171
  }
172
+ else if (message?.data?.status == STATUS.CONNECT_FAILED ||
173
+ message?.data?.status == STATUS.NO_ANSWER) {
174
+ endCall();
175
+ callStatus.value = message?.data?.status;
176
+ }
177
+ else {
178
+ // console.log(message)
179
+ da = false;
180
+ // handleMedia(message)
181
+ }
128
182
  }
129
- else if (message?.data?.status == STATUS.CALL_END) {
130
- endCall();
131
- }
132
- else {
133
- da = false;
134
- handleMedia(message);
183
+ else if (message?.event == 'record_uploaded') {
184
+ if (uuidEnd == message?.data?.call_uuid) {
185
+ record_link.value = message?.data?.recording_url;
186
+ }
135
187
  }
136
- if (da)
137
- console.log(message);
188
+ // if (da){
189
+ // } else console.log('-----------------', message)
190
+ };
191
+ const exportRecordFile = async () => {
192
+ downloadRecord(record_link.value);
193
+ };
194
+ const handleAfterClose = () => {
195
+ record_link.value = '';
196
+ uuidEnd = '';
138
197
  };
139
198
  const __VLS_exposed = { startCall, endCall };
140
199
  defineExpose(__VLS_exposed);
141
- watch(dataProfile, async (newValue, oldValue) => {
142
- if (oldValue?.id && oldValue?.id != newValue?.id) {
143
- removeHandleWebSK('call-message');
144
- }
145
- if (newValue?.id && oldValue?.id != newValue?.id) {
146
- addHandleWebSK('call-message', handleMqttMessage);
147
- addHandleWebSK('call-message', handleMqttMessage);
148
- }
149
- }, { immediate: true });
150
200
  debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
151
201
  const __VLS_defaults = {};
152
202
  const __VLS_ctx = {
@@ -154,6 +204,7 @@ const __VLS_ctx = {
154
204
  ...{},
155
205
  ...{},
156
206
  ...{},
207
+ ...{},
157
208
  };
158
209
  let __VLS_elements;
159
210
  let __VLS_components;
@@ -161,24 +212,30 @@ let __VLS_directives;
161
212
  /** @type {[typeof DrawerBaseCustom, typeof DrawerBaseCustom, ]} */ ;
162
213
  // @ts-ignore
163
214
  const __VLS_0 = __VLS_asFunctionalComponent(DrawerBaseCustom, new DrawerBaseCustom({
215
+ ...{ 'onAfterClose': {} },
164
216
  ref: "drawerVisibleRef",
165
217
  width: (500),
166
218
  disabledClose: (__VLS_ctx.disable),
167
219
  responsive: (__VLS_ctx.responsive),
168
220
  }));
169
221
  const __VLS_1 = __VLS_0({
222
+ ...{ 'onAfterClose': {} },
170
223
  ref: "drawerVisibleRef",
171
224
  width: (500),
172
225
  disabledClose: (__VLS_ctx.disable),
173
226
  responsive: (__VLS_ctx.responsive),
174
227
  }, ...__VLS_functionalComponentArgsRest(__VLS_0));
228
+ let __VLS_3;
229
+ let __VLS_4;
230
+ const __VLS_5 = ({ afterClose: {} },
231
+ { onAfterClose: (__VLS_ctx.handleAfterClose) });
175
232
  /** @type {typeof __VLS_ctx.drawerVisibleRef} */ ;
176
- var __VLS_3 = {};
177
- const { default: __VLS_5 } = __VLS_2.slots;
233
+ var __VLS_6 = {};
234
+ const { default: __VLS_8 } = __VLS_2.slots;
178
235
  // @ts-ignore
179
- [disable, responsive, drawerVisibleRef,];
236
+ [disable, responsive, handleAfterClose, drawerVisibleRef,];
180
237
  {
181
- const { content: __VLS_6 } = __VLS_2.slots;
238
+ const { content: __VLS_9 } = __VLS_2.slots;
182
239
  __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
183
240
  ...{ class: "flex flex-col items-center justify-center h-full bg-chat-haze-300 text-white relative" },
184
241
  });
@@ -187,7 +244,7 @@ const { default: __VLS_5 } = __VLS_2.slots;
187
244
  });
188
245
  /** @type {[typeof Avatar, ]} */ ;
189
246
  // @ts-ignore
190
- const __VLS_7 = __VLS_asFunctionalComponent(Avatar, new Avatar({
247
+ const __VLS_10 = __VLS_asFunctionalComponent(Avatar, new Avatar({
191
248
  ...{ class: "" },
192
249
  src: (__VLS_ctx.userRemoter?.avatar ?? ''),
193
250
  id: (__VLS_ctx.userRemoter?.id ?? ''),
@@ -195,14 +252,14 @@ const { default: __VLS_5 } = __VLS_2.slots;
195
252
  name: (__VLS_ctx.userRemoter?.username),
196
253
  size: "xxl",
197
254
  }));
198
- const __VLS_8 = __VLS_7({
255
+ const __VLS_11 = __VLS_10({
199
256
  ...{ class: "" },
200
257
  src: (__VLS_ctx.userRemoter?.avatar ?? ''),
201
258
  id: (__VLS_ctx.userRemoter?.id ?? ''),
202
259
  color: (__VLS_ctx.userRemoter?.color),
203
260
  name: (__VLS_ctx.userRemoter?.username),
204
261
  size: "xxl",
205
- }, ...__VLS_functionalComponentArgsRest(__VLS_7));
262
+ }, ...__VLS_functionalComponentArgsRest(__VLS_10));
206
263
  // @ts-ignore
207
264
  [userRemoter, userRemoter, userRemoter, userRemoter,];
208
265
  __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
@@ -234,19 +291,61 @@ const { default: __VLS_5 } = __VLS_2.slots;
234
291
  [answer,];
235
292
  /** @type {[typeof IconPhone, ]} */ ;
236
293
  // @ts-ignore
237
- const __VLS_11 = __VLS_asFunctionalComponent(IconPhone, new IconPhone({}));
238
- const __VLS_12 = __VLS_11({}, ...__VLS_functionalComponentArgsRest(__VLS_11));
294
+ const __VLS_14 = __VLS_asFunctionalComponent(IconPhone, new IconPhone({}));
295
+ const __VLS_15 = __VLS_14({}, ...__VLS_functionalComponentArgsRest(__VLS_14));
296
+ }
297
+ if (__VLS_ctx.record_link && __VLS_ctx.callStatus == __VLS_ctx.STATUS.CALL_END) {
298
+ // @ts-ignore
299
+ [callStatus, STATUS, record_link,];
300
+ __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
301
+ ...{ onClick: (__VLS_ctx.exportRecordFile) },
302
+ href: (__VLS_ctx.record_link),
303
+ download: "recording.mp3",
304
+ ...{ class: "w-16 h-16 bg-white hover:bg-green-600 text-white rounded-full flex items-center justify-center shadow-lg transition" },
305
+ });
306
+ // @ts-ignore
307
+ [record_link, exportRecordFile,];
308
+ /** @type {[typeof IconSoundDownload, ]} */ ;
309
+ // @ts-ignore
310
+ const __VLS_18 = __VLS_asFunctionalComponent(IconSoundDownload, new IconSoundDownload({}));
311
+ const __VLS_19 = __VLS_18({}, ...__VLS_functionalComponentArgsRest(__VLS_18));
312
+ }
313
+ if (__VLS_ctx.callStatus == __VLS_ctx.STATUS.CALL_END) {
314
+ // @ts-ignore
315
+ [callStatus, STATUS,];
316
+ __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
317
+ ...{ onClick: (...[$event]) => {
318
+ if (!(__VLS_ctx.callStatus == __VLS_ctx.STATUS.CALL_END))
319
+ return;
320
+ __VLS_ctx.endCall({ closeModal: true });
321
+ // @ts-ignore
322
+ [endCall,];
323
+ } },
324
+ ...{ class: "w-16 h-16 bg-white hover:bg-green-600 text-white rounded-full flex items-center justify-center shadow-lg transition" },
325
+ });
326
+ /** @type {[typeof IconClose, ]} */ ;
327
+ // @ts-ignore
328
+ const __VLS_22 = __VLS_asFunctionalComponent(IconClose, new IconClose({}));
329
+ const __VLS_23 = __VLS_22({}, ...__VLS_functionalComponentArgsRest(__VLS_22));
330
+ }
331
+ if (__VLS_ctx.callStatus != __VLS_ctx.STATUS.CALL_END) {
332
+ // @ts-ignore
333
+ [callStatus, STATUS,];
334
+ __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
335
+ ...{ onClick: (...[$event]) => {
336
+ if (!(__VLS_ctx.callStatus != __VLS_ctx.STATUS.CALL_END))
337
+ return;
338
+ __VLS_ctx.endCall();
339
+ // @ts-ignore
340
+ [endCall,];
341
+ } },
342
+ ...{ class: "w-16 h-16 rounded-full bg-[#EF4444] hover:bg-red-700 flex items-center justify-center" },
343
+ });
344
+ /** @type {[typeof IconPhoneCancel, ]} */ ;
345
+ // @ts-ignore
346
+ const __VLS_26 = __VLS_asFunctionalComponent(IconPhoneCancel, new IconPhoneCancel({}));
347
+ const __VLS_27 = __VLS_26({}, ...__VLS_functionalComponentArgsRest(__VLS_26));
239
348
  }
240
- __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
241
- ...{ onClick: (__VLS_ctx.endCall) },
242
- ...{ class: "w-16 h-16 rounded-full bg-[#EF4444] hover:bg-red-700 flex items-center justify-center" },
243
- });
244
- // @ts-ignore
245
- [endCall,];
246
- /** @type {[typeof IconPhoneCancel, ]} */ ;
247
- // @ts-ignore
248
- const __VLS_15 = __VLS_asFunctionalComponent(IconPhoneCancel, new IconPhoneCancel({}));
249
- const __VLS_16 = __VLS_15({}, ...__VLS_functionalComponentArgsRest(__VLS_15));
250
349
  __VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
251
350
  ...{ class: "absolute bottom-6 text-gray-500 text-sm" },
252
351
  });
@@ -303,6 +402,28 @@ __VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
303
402
  /** @type {__VLS_StyleScopedClasses['transition']} */ ;
304
403
  /** @type {__VLS_StyleScopedClasses['w-16']} */ ;
305
404
  /** @type {__VLS_StyleScopedClasses['h-16']} */ ;
405
+ /** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
406
+ /** @type {__VLS_StyleScopedClasses['hover:bg-green-600']} */ ;
407
+ /** @type {__VLS_StyleScopedClasses['text-white']} */ ;
408
+ /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
409
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
410
+ /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
411
+ /** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
412
+ /** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
413
+ /** @type {__VLS_StyleScopedClasses['transition']} */ ;
414
+ /** @type {__VLS_StyleScopedClasses['w-16']} */ ;
415
+ /** @type {__VLS_StyleScopedClasses['h-16']} */ ;
416
+ /** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
417
+ /** @type {__VLS_StyleScopedClasses['hover:bg-green-600']} */ ;
418
+ /** @type {__VLS_StyleScopedClasses['text-white']} */ ;
419
+ /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
420
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
421
+ /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
422
+ /** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
423
+ /** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
424
+ /** @type {__VLS_StyleScopedClasses['transition']} */ ;
425
+ /** @type {__VLS_StyleScopedClasses['w-16']} */ ;
426
+ /** @type {__VLS_StyleScopedClasses['h-16']} */ ;
306
427
  /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
307
428
  /** @type {__VLS_StyleScopedClasses['bg-[#EF4444]']} */ ;
308
429
  /** @type {__VLS_StyleScopedClasses['hover:bg-red-700']} */ ;
@@ -314,9 +435,10 @@ __VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
314
435
  /** @type {__VLS_StyleScopedClasses['text-gray-500']} */ ;
315
436
  /** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
316
437
  // @ts-ignore
317
- var __VLS_4 = __VLS_3;
438
+ var __VLS_7 = __VLS_6;
318
439
  const __VLS_export = (await import('vue')).defineComponent({
319
440
  setup: () => (__VLS_exposed),
441
+ __typeEmits: {},
320
442
  __typeProps: {},
321
443
  props: {},
322
444
  });
@@ -40,12 +40,12 @@ const __VLS_1 = __VLS_0({}, ...__VLS_functionalComponentArgsRest(__VLS_0));
40
40
  __VLS_asFunctionalElement(__VLS_elements.input)({
41
41
  ...{ onInput: (__VLS_ctx.search) },
42
42
  ...{ class: "sc-full chat-input bg-[#F7F8F9] pr-4 py-3 pl-10" },
43
- ...{ class: ({ '!bg-white': __VLS_ctx.response == 'mobile' }) },
43
+ ...{ class: ({ '!bg-white': __VLS_ctx.responsive == 'mobile' }) },
44
44
  placeholder: (props.placeholder),
45
45
  });
46
46
  (__VLS_ctx.keyword);
47
47
  // @ts-ignore
48
- [search, response, keyword,];
48
+ [search, responsive, keyword,];
49
49
  /** @type {__VLS_StyleScopedClasses['relative']} */ ;
50
50
  /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
51
51
  /** @type {__VLS_StyleScopedClasses['inset-y-0']} */ ;
@@ -0,0 +1,98 @@
1
+ /// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
2
+ import { ref, computed } from 'vue';
3
+ const props = defineProps();
4
+ const emit = defineEmits();
5
+ const open = ref(false);
6
+ const selectedLabel = computed(() => {
7
+ return props.options.find(o => o.value === props.modelValue)?.label ?? '';
8
+ });
9
+ function toggle() {
10
+ open.value = !open.value;
11
+ }
12
+ function select(option) {
13
+ emit('update:modelValue', option.value);
14
+ emit('select', option.value);
15
+ open.value = false;
16
+ }
17
+ debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
18
+ const __VLS_ctx = {
19
+ ...{},
20
+ ...{},
21
+ ...{},
22
+ ...{},
23
+ ...{},
24
+ };
25
+ let __VLS_elements;
26
+ let __VLS_components;
27
+ let __VLS_directives;
28
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
29
+ ...{ onBlur: (...[$event]) => {
30
+ __VLS_ctx.open = false;
31
+ // @ts-ignore
32
+ [open,];
33
+ } },
34
+ ...{ onClick: (__VLS_ctx.toggle) },
35
+ ...{ class: "relative inline-block w-full" },
36
+ tabindex: "0",
37
+ });
38
+ // @ts-ignore
39
+ [toggle,];
40
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
41
+ ...{ class: "cursor-pointer pointer-events-none" },
42
+ });
43
+ var __VLS_0 = {};
44
+ __VLS_asFunctionalElement(__VLS_elements.ul, __VLS_elements.ul)({
45
+ ...{ class: "w-max absolute right-0 z-10 mt-1 max-h-48 overflow-auto rounded-md border border-gray-200 bg-white shadow-lg" },
46
+ });
47
+ __VLS_asFunctionalDirective(__VLS_directives.vShow)(null, { ...__VLS_directiveBindingRestFields, value: (__VLS_ctx.open) }, null, null);
48
+ // @ts-ignore
49
+ [open,];
50
+ for (const [option, idx] of __VLS_getVForSourceType((__VLS_ctx.options))) {
51
+ // @ts-ignore
52
+ [options,];
53
+ __VLS_asFunctionalElement(__VLS_elements.li, __VLS_elements.li)({
54
+ ...{ onClick: (...[$event]) => {
55
+ __VLS_ctx.select(option);
56
+ // @ts-ignore
57
+ [select,];
58
+ } },
59
+ key: (idx),
60
+ ...{ class: "cursor-pointer text-black px-3 py-2 hover:bg-chat-haze-200" },
61
+ ...{ class: ({ 'bg-primary !text-white': option.value === __VLS_ctx.modelValue }) },
62
+ });
63
+ // @ts-ignore
64
+ [modelValue,];
65
+ (option.label);
66
+ }
67
+ /** @type {__VLS_StyleScopedClasses['relative']} */ ;
68
+ /** @type {__VLS_StyleScopedClasses['inline-block']} */ ;
69
+ /** @type {__VLS_StyleScopedClasses['w-full']} */ ;
70
+ /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
71
+ /** @type {__VLS_StyleScopedClasses['pointer-events-none']} */ ;
72
+ /** @type {__VLS_StyleScopedClasses['w-max']} */ ;
73
+ /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
74
+ /** @type {__VLS_StyleScopedClasses['right-0']} */ ;
75
+ /** @type {__VLS_StyleScopedClasses['z-10']} */ ;
76
+ /** @type {__VLS_StyleScopedClasses['mt-1']} */ ;
77
+ /** @type {__VLS_StyleScopedClasses['max-h-48']} */ ;
78
+ /** @type {__VLS_StyleScopedClasses['overflow-auto']} */ ;
79
+ /** @type {__VLS_StyleScopedClasses['rounded-md']} */ ;
80
+ /** @type {__VLS_StyleScopedClasses['border']} */ ;
81
+ /** @type {__VLS_StyleScopedClasses['border-gray-200']} */ ;
82
+ /** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
83
+ /** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
84
+ /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
85
+ /** @type {__VLS_StyleScopedClasses['text-black']} */ ;
86
+ /** @type {__VLS_StyleScopedClasses['px-3']} */ ;
87
+ /** @type {__VLS_StyleScopedClasses['py-2']} */ ;
88
+ /** @type {__VLS_StyleScopedClasses['hover:bg-chat-haze-200']} */ ;
89
+ /** @type {__VLS_StyleScopedClasses['bg-primary']} */ ;
90
+ /** @type {__VLS_StyleScopedClasses['!text-white']} */ ;
91
+ // @ts-ignore
92
+ var __VLS_1 = __VLS_0;
93
+ const __VLS_base = (await import('vue')).defineComponent({
94
+ __typeEmits: {},
95
+ __typeProps: {},
96
+ });
97
+ const __VLS_export = {};
98
+ export default {};
@@ -1,4 +1,3 @@
1
- /// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
2
1
  import { computed, ref } from 'vue';
3
2
  const props = withDefaults(defineProps(), {
4
3
  position: 'right',
@@ -0,0 +1,32 @@
1
+ [
2
+ {
3
+ "type": "audio_chunk",
4
+ "size_bytes": 160,
5
+ "hex_preview": "36 25 39 bb c0 41 48 bc c3 32 27 3f c7 f6 ee aa 9f ae b3 9e",
6
+ "samples_count": 160
7
+ },
8
+ {
9
+ "type": "audio_chunk",
10
+ "size_bytes": 160,
11
+ "hex_preview": "3f d9 ac b3 3d 3b b9 a8 ac b4 b3 ac af bc ae 9e 9b a5 ac a9",
12
+ "samples_count": 160
13
+ },
14
+ {
15
+ "type": "audio_chunk",
16
+ "size_bytes": 160,
17
+ "hex_preview": "b1 a3 b3 a9 a8 a8 ae a3 a7 a6 a6 a8 a7 ab a9 ad af ae aa a6 ab",
18
+ "samples_count": 160
19
+ },
20
+ {
21
+ "type": "audio_chunk",
22
+ "size_bytes": 160,
23
+ "hex_preview": "b3 b1 b2 b0 ae ae b0 b2 b3 b1 b1 b0 b0 af af ae ae ae ad ac ac",
24
+ "samples_count": 160
25
+ },
26
+ {
27
+ "type": "audio_chunk",
28
+ "size_bytes": 160,
29
+ "hex_preview": "ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad",
30
+ "samples_count": 160
31
+ }
32
+ ]