@phonghq/go-chat 1.0.23 → 1.0.25

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/README.md +1 -1
  2. package/dist/assets/icons/IconCloseCircle.vue.d.ts +2 -0
  3. package/dist/assets/icons/IconSetting.vue.d.ts +2 -0
  4. package/dist/chat/App.vue.d.ts +2 -0
  5. package/dist/chat/page/home/ChatList.vue.d.ts +6 -3
  6. package/dist/chat/page/home/ChatMessage.vue.d.ts +2 -0
  7. package/dist/chat/page/home/ChatMessageItem.vue.d.ts +18 -0
  8. package/dist/chat/page/home/Home.vue.d.ts +4 -0
  9. package/dist/chat/page/setting/Setting.vue.d.ts +2 -0
  10. package/dist/components/chat/call/Calling.vue.d.ts +2 -0
  11. package/dist/components/chat/common/switch/SwitchBase.vue.d.ts +14 -0
  12. package/dist/components/chat/common/tab/TabBase.vue.d.ts +30 -0
  13. package/dist/components/chat/select/SelectBase.vue.d.ts +2 -0
  14. package/dist/components/common/drawer/DrawerBase.vue.d.ts +1 -1
  15. package/dist/components/common/drawer/DrawerBaseCustom.vue.d.ts +1 -0
  16. package/dist/composable/useCallHelper.d.ts +2 -0
  17. package/dist/composable/useListConversations.d.ts +48 -0
  18. package/dist/constant/color.d.ts +2 -2
  19. package/dist/go-chat.es.js +28838 -28734
  20. package/dist/go-chat.umd.js +14 -14
  21. package/dist/style.css +1 -1
  22. package/dist/test/assets/icons/IconCloseCircle.vue.js +36 -0
  23. package/dist/test/assets/icons/IconSetting.vue.js +33 -0
  24. package/dist/test/chat/App.vue.js +191 -90
  25. package/dist/test/chat/page/customer-detail/CustomerDetail.vue.js +0 -3
  26. package/dist/test/chat/page/home/ChatList.vue.js +225 -137
  27. package/dist/test/chat/page/home/ChatMessage.vue.js +45 -181
  28. package/dist/test/chat/page/home/ChatMessageItem.vue.js +335 -0
  29. package/dist/test/chat/page/home/Home.vue.js +38 -65
  30. package/dist/test/chat/page/home/HomeHeader.vue.js +18 -18
  31. package/dist/test/chat/page/home/InputChat.vue.js +62 -34
  32. package/dist/test/chat/page/setting/Setting.vue.js +125 -0
  33. package/dist/test/components/chat/call/Calling.vue.js +36 -24
  34. package/dist/test/components/chat/common/switch/SwitchBase.vue.js +70 -0
  35. package/dist/test/components/chat/common/tab/TabBase.vue.js +85 -0
  36. package/dist/test/components/chat/select/SelectBase.vue.js +26 -18
  37. package/dist/test/components/common/drawer/DrawerBaseCustom.vue.js +9 -4
  38. package/dist/test/composable/useDigibot.js +2 -1
  39. package/dist/test/composable/useInitData.js +4 -7
  40. package/dist/test/composable/useListConversations.js +124 -0
  41. package/dist/test/composable/usePlivo.js +18 -6
  42. package/dist/test/constant/color.js +4 -2
  43. package/dist/test/types/chat/call.js +4 -1
  44. package/dist/test/utils/chat/auth.js +15 -0
  45. package/dist/test/utils/chat/conversation.js +57 -0
  46. package/dist/test/utils/chat/phone-string.js +1 -1
  47. package/dist/types/chat/auth.d.ts +2 -0
  48. package/dist/types/chat/call.d.ts +3 -0
  49. package/dist/types/chat/global.d.ts +1 -0
  50. package/dist/types/conversation.d.ts +3 -1
  51. package/dist/types/message.d.ts +6 -0
  52. package/dist/utils/chat/auth.d.ts +5 -0
  53. package/dist/utils/chat/conversation.d.ts +7 -0
  54. package/dist/utils/chat/phone-string.d.ts +1 -1
  55. package/dist/utils/chat/user.d.ts +2 -0
  56. package/package.json +1 -1
@@ -1,9 +1,7 @@
1
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
- import { useCallHelper } from '../../../composable/useCallHelper';
5
4
  import IconPhoneCancel from '../../../assets/icons/call/IconPhoneCancel.vue';
6
- import { removeHandleWebSK } from '../../../plugins/websocket';
7
5
  import { downloadRecord } from '../../../utils/chat/call';
8
6
  import DrawerBaseCustom from '../../../components/common/drawer/DrawerBaseCustom.vue';
9
7
  import Avatar from '../../../components/chat/customer/Avatar.vue';
@@ -14,7 +12,18 @@ import IconClose from '../../../assets/icons/call/IconClose.vue';
14
12
  import { usePlivo } from '../../../composable/usePlivo';
15
13
  import { PLIVO_CALL_STATUS } from '../../../types/chat/call';
16
14
  import IconMic from '../../../assets/icons/call/IconMic.vue';
17
- const { call, end, handleMedia, startIncomingCall, handleCallAnswer, callAnswer, uuid, startPeerConnection } = useCallHelper();
15
+ const props = withDefaults(defineProps(), {});
16
+ const emit = defineEmits();
17
+ // const {
18
+ // // call,
19
+ // // end,
20
+ // // handleMedia,
21
+ // // startIncomingCall,
22
+ // // handleCallAnswer,
23
+ // // callAnswer,
24
+ // // uuid,
25
+ // // startPeerConnection
26
+ // } = useCallHelper()
18
27
  const handlePlivoCallBack = (status, data) => {
19
28
  if (status == PLIVO_CALL_STATUS.RINGING) {
20
29
  getUserOffer(data?.phone ?? '');
@@ -27,7 +36,8 @@ const handlePlivoCallBack = (status, data) => {
27
36
  }
28
37
  else if (status == PLIVO_CALL_STATUS.CALL_END) {
29
38
  errorMessage.value = data?.message ?? '';
30
- endCall();
39
+ const closeModal = data?.reason == 'ORIGINATOR_CANCEL';
40
+ endCall({ closeModal });
31
41
  callStatus.value = status;
32
42
  }
33
43
  else if (status == PLIVO_CALL_STATUS.CALL_START) {
@@ -36,8 +46,6 @@ const handlePlivoCallBack = (status, data) => {
36
46
  }
37
47
  };
38
48
  const { plivoLogin, plivoCallAnswer, plivoCall, plivoEndCall, plivoCallSwishMute } = usePlivo(handlePlivoCallBack);
39
- const props = withDefaults(defineProps(), {});
40
- const emit = defineEmits();
41
49
  const STATUS_LABEL = computed(() => {
42
50
  return {
43
51
  [PLIVO_CALL_STATUS.CONNECTING]: 'Connecting...',
@@ -46,7 +54,10 @@ const STATUS_LABEL = computed(() => {
46
54
  [PLIVO_CALL_STATUS.CONNECT_FAILED]: errorMessage.value || 'Connect Error',
47
55
  [PLIVO_CALL_STATUS.CALL_START]: '',
48
56
  [PLIVO_CALL_STATUS.CALL_END]: errorMessage.value || 'Call Ended',
49
- [PLIVO_CALL_STATUS.NO_ANSWER]: 'No Answer'
57
+ [PLIVO_CALL_STATUS.NO_ANSWER]: 'No Answer',
58
+ [PLIVO_CALL_STATUS.CANCEL]: '',
59
+ [PLIVO_CALL_STATUS.TIME_OUT]: '',
60
+ [PLIVO_CALL_STATUS.BUSY]: ''
50
61
  };
51
62
  });
52
63
  const label = computed(() => STATUS_LABEL.value[callStatus.value] ?? '');
@@ -64,10 +75,12 @@ let timeOut = null;
64
75
  let callType = 'call';
65
76
  let uuidEnd = '';
66
77
  onMounted(async () => {
67
- await plivoLogin('');
78
+ if (dataProfile.value?.tenant_phone) {
79
+ await plivoLogin('');
80
+ }
68
81
  });
69
82
  onUnmounted(() => {
70
- removeHandleWebSK('call-message');
83
+ // removeHandleWebSK('call-message')
71
84
  if (timer)
72
85
  clearInterval(timer);
73
86
  if (timeOut)
@@ -85,21 +98,22 @@ function startTimer() {
85
98
  }, 1000);
86
99
  }
87
100
  function endCall(option) {
88
- plivoEndCall(callStatus.value);
89
- callStatus.value = PLIVO_CALL_STATUS.CALL_END;
90
- uuidEnd = uuid.value;
91
- clearInterval(timer);
92
- disable.value = false;
93
101
  if (option?.closeModal) {
94
102
  drawerVisible.value = false;
95
103
  drawerVisibleRef.value?.close();
96
104
  }
105
+ plivoEndCall(callStatus.value);
106
+ callStatus.value = PLIVO_CALL_STATUS.CALL_END;
107
+ clearInterval(timer);
108
+ disable.value = false;
97
109
  isMute.value = false;
98
110
  duration.value = '00:00';
99
111
  if (timer)
100
112
  clearInterval(timer);
101
113
  if (timeOut)
102
114
  clearTimeout(timeOut);
115
+ emit('endCall', userRemoter.value, callType);
116
+ callType = '';
103
117
  }
104
118
  const open = () => {
105
119
  drawerVisible.value = true;
@@ -231,6 +245,7 @@ const __VLS_0 = __VLS_asFunctionalComponent(DrawerBaseCustom, new DrawerBaseCust
231
245
  width: (500),
232
246
  disabledClose: (__VLS_ctx.disable),
233
247
  responsive: (__VLS_ctx.responsive),
248
+ absolute: true,
234
249
  }));
235
250
  const __VLS_1 = __VLS_0({
236
251
  ...{ 'onAfterClose': {} },
@@ -238,6 +253,7 @@ const __VLS_1 = __VLS_0({
238
253
  width: (500),
239
254
  disabledClose: (__VLS_ctx.disable),
240
255
  responsive: (__VLS_ctx.responsive),
256
+ absolute: true,
241
257
  }, ...__VLS_functionalComponentArgsRest(__VLS_0));
242
258
  let __VLS_3;
243
259
  let __VLS_4;
@@ -282,9 +298,9 @@ const { default: __VLS_8 } = __VLS_2.slots;
282
298
  __VLS_asFunctionalElement(__VLS_elements.h2, __VLS_elements.h2)({
283
299
  ...{ class: "text-2xl font-semibold" },
284
300
  });
285
- (__VLS_ctx.userRemoter?.username);
301
+ (__VLS_ctx.userRemoter?.username || __VLS_ctx.formatPhone10number(__VLS_ctx.userRemoter?.phone ?? ''));
286
302
  // @ts-ignore
287
- [userRemoter,];
303
+ [userRemoter, userRemoter, formatPhone10number,];
288
304
  __VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
289
305
  ...{ class: "text-gray-400 mt-1" },
290
306
  });
@@ -299,7 +315,7 @@ const { default: __VLS_8 } = __VLS_2.slots;
299
315
  [callStatus, PLIVO_CALL_STATUS,];
300
316
  __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
301
317
  ...{ onClick: (__VLS_ctx.answer) },
302
- ...{ class: "w-16 h-16 bg-[#22C55E] hover:bg-green-600 text-white rounded-full flex items-center justify-center shadow-lg transition" },
318
+ ...{ class: "w-16 h-16 bg-chat-success hover:bg-green-600 text-white rounded-full flex items-center justify-center shadow-lg transition" },
303
319
  });
304
320
  // @ts-ignore
305
321
  [answer,];
@@ -377,7 +393,7 @@ const { default: __VLS_8 } = __VLS_2.slots;
377
393
  // @ts-ignore
378
394
  [endCall,];
379
395
  } },
380
- ...{ class: "w-16 h-16 rounded-full bg-[#EF4444] hover:bg-red-700 flex items-center justify-center" },
396
+ ...{ class: "w-16 h-16 rounded-full bg-chat-error hover:bg-red-700 flex items-center justify-center" },
381
397
  });
382
398
  /** @type {[typeof IconPhoneCancel, ]} */ ;
383
399
  // @ts-ignore
@@ -392,10 +408,6 @@ const { default: __VLS_8 } = __VLS_2.slots;
392
408
  [duration,];
393
409
  }
394
410
  var __VLS_2;
395
- __VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
396
- id: "go-chat-remote-audio",
397
- autoplay: true,
398
- });
399
411
  /** @type {__VLS_StyleScopedClasses['']} */ ;
400
412
  /** @type {__VLS_StyleScopedClasses['flex']} */ ;
401
413
  /** @type {__VLS_StyleScopedClasses['flex-col']} */ ;
@@ -425,7 +437,7 @@ __VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
425
437
  /** @type {__VLS_StyleScopedClasses['mt-10']} */ ;
426
438
  /** @type {__VLS_StyleScopedClasses['w-16']} */ ;
427
439
  /** @type {__VLS_StyleScopedClasses['h-16']} */ ;
428
- /** @type {__VLS_StyleScopedClasses['bg-[#22C55E]']} */ ;
440
+ /** @type {__VLS_StyleScopedClasses['bg-chat-success']} */ ;
429
441
  /** @type {__VLS_StyleScopedClasses['hover:bg-green-600']} */ ;
430
442
  /** @type {__VLS_StyleScopedClasses['text-white']} */ ;
431
443
  /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
@@ -470,7 +482,7 @@ __VLS_asFunctionalElement(__VLS_elements.audio, __VLS_elements.audio)({
470
482
  /** @type {__VLS_StyleScopedClasses['w-16']} */ ;
471
483
  /** @type {__VLS_StyleScopedClasses['h-16']} */ ;
472
484
  /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
473
- /** @type {__VLS_StyleScopedClasses['bg-[#EF4444]']} */ ;
485
+ /** @type {__VLS_StyleScopedClasses['bg-chat-error']} */ ;
474
486
  /** @type {__VLS_StyleScopedClasses['hover:bg-red-700']} */ ;
475
487
  /** @type {__VLS_StyleScopedClasses['flex']} */ ;
476
488
  /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
@@ -0,0 +1,70 @@
1
+ /// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
2
+ const props = withDefaults(defineProps(), {});
3
+ const result = defineModel();
4
+ debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
5
+ const __VLS_modelEmit = defineEmits();
6
+ const __VLS_defaults = {};
7
+ const __VLS_ctx = {
8
+ ...{},
9
+ ...{},
10
+ ...{},
11
+ ...{},
12
+ ...{},
13
+ };
14
+ let __VLS_elements;
15
+ let __VLS_components;
16
+ let __VLS_directives;
17
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
18
+ ...{ onClick: (...[$event]) => {
19
+ __VLS_ctx.result = !__VLS_ctx.result;
20
+ // @ts-ignore
21
+ [result, result,];
22
+ } },
23
+ ...{ class: "flex items-center gap-2 cursor-pointer w-max" },
24
+ });
25
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
26
+ ...{ class: "w-10 h-5 flex items-center bg-chat-haze-300 rounded-full p-1 cursor-pointer transition" },
27
+ ...{ class: (__VLS_ctx.result ? 'bg-chat-primary' : 'bg-chat-haze-300') },
28
+ });
29
+ // @ts-ignore
30
+ [result,];
31
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
32
+ ...{ class: "bg-white w-4 h-4 rounded-full shadow transform transition" },
33
+ ...{ class: (__VLS_ctx.result ? 'translate-x-4' : '') },
34
+ });
35
+ // @ts-ignore
36
+ [result,];
37
+ __VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({
38
+ ...{ class: "font-semibold" },
39
+ });
40
+ (__VLS_ctx.label ?? '');
41
+ // @ts-ignore
42
+ [label,];
43
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
44
+ /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
45
+ /** @type {__VLS_StyleScopedClasses['gap-2']} */ ;
46
+ /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
47
+ /** @type {__VLS_StyleScopedClasses['w-max']} */ ;
48
+ /** @type {__VLS_StyleScopedClasses['w-10']} */ ;
49
+ /** @type {__VLS_StyleScopedClasses['h-5']} */ ;
50
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
51
+ /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
52
+ /** @type {__VLS_StyleScopedClasses['bg-chat-haze-300']} */ ;
53
+ /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
54
+ /** @type {__VLS_StyleScopedClasses['p-1']} */ ;
55
+ /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
56
+ /** @type {__VLS_StyleScopedClasses['transition']} */ ;
57
+ /** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
58
+ /** @type {__VLS_StyleScopedClasses['w-4']} */ ;
59
+ /** @type {__VLS_StyleScopedClasses['h-4']} */ ;
60
+ /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
61
+ /** @type {__VLS_StyleScopedClasses['shadow']} */ ;
62
+ /** @type {__VLS_StyleScopedClasses['transform']} */ ;
63
+ /** @type {__VLS_StyleScopedClasses['transition']} */ ;
64
+ /** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
65
+ const __VLS_export = (await import('vue')).defineComponent({
66
+ __typeEmits: {},
67
+ __typeProps: {},
68
+ props: {},
69
+ });
70
+ export default {};
@@ -0,0 +1,85 @@
1
+ const props = withDefaults(defineProps(), {});
2
+ const emit = defineEmits();
3
+ const active = defineModel('active');
4
+ const handleTabClick = (tab) => {
5
+ active.value = tab.value;
6
+ emit('change', tab.value);
7
+ };
8
+ debugger; /* PartiallyEnd: #3632/scriptSetup.vue */
9
+ const __VLS_modelEmit = defineEmits();
10
+ const __VLS_defaults = {};
11
+ const __VLS_ctx = {
12
+ ...{},
13
+ ...{},
14
+ ...{},
15
+ ...{},
16
+ ...{},
17
+ };
18
+ let __VLS_elements;
19
+ let __VLS_components;
20
+ let __VLS_directives;
21
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
22
+ ...{ class: "w-full" },
23
+ });
24
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
25
+ ...{ class: "flex p-1 bg-chat-haze-200 w-max rounded-xl" },
26
+ });
27
+ for (const [tab] of __VLS_getVForSourceType((__VLS_ctx.tabs))) {
28
+ // @ts-ignore
29
+ [tabs,];
30
+ __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
31
+ ...{ onClick: (...[$event]) => {
32
+ __VLS_ctx.handleTabClick(tab);
33
+ // @ts-ignore
34
+ [handleTabClick,];
35
+ } },
36
+ key: (tab.value),
37
+ ...{ class: "px-4 py-2 rounded-xl text-sm font-medium relative" },
38
+ ...{ class: (__VLS_ctx.active === tab.value ? 'bg-white' : '') },
39
+ });
40
+ // @ts-ignore
41
+ [active,];
42
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
43
+ ...{ class: "w-5 h-5 bg-chat-error rounded-full absolute -top-[8px] -right-2 text-white" },
44
+ });
45
+ __VLS_asFunctionalDirective(__VLS_directives.vShow)(null, { ...__VLS_directiveBindingRestFields, value: (tab.badge) }, null, null);
46
+ (tab.badge);
47
+ (tab.label);
48
+ }
49
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
50
+ ...{ class: "mt-4" },
51
+ });
52
+ var __VLS_0 = {};
53
+ var __VLS_1 = __VLS_tryAsConstant(__VLS_ctx.active);
54
+ // @ts-ignore
55
+ [active,];
56
+ /** @type {__VLS_StyleScopedClasses['w-full']} */ ;
57
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
58
+ /** @type {__VLS_StyleScopedClasses['p-1']} */ ;
59
+ /** @type {__VLS_StyleScopedClasses['bg-chat-haze-200']} */ ;
60
+ /** @type {__VLS_StyleScopedClasses['w-max']} */ ;
61
+ /** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
62
+ /** @type {__VLS_StyleScopedClasses['px-4']} */ ;
63
+ /** @type {__VLS_StyleScopedClasses['py-2']} */ ;
64
+ /** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
65
+ /** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
66
+ /** @type {__VLS_StyleScopedClasses['font-medium']} */ ;
67
+ /** @type {__VLS_StyleScopedClasses['relative']} */ ;
68
+ /** @type {__VLS_StyleScopedClasses['w-5']} */ ;
69
+ /** @type {__VLS_StyleScopedClasses['h-5']} */ ;
70
+ /** @type {__VLS_StyleScopedClasses['bg-chat-error']} */ ;
71
+ /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
72
+ /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
73
+ /** @type {__VLS_StyleScopedClasses['-top-[8px]']} */ ;
74
+ /** @type {__VLS_StyleScopedClasses['-right-2']} */ ;
75
+ /** @type {__VLS_StyleScopedClasses['text-white']} */ ;
76
+ /** @type {__VLS_StyleScopedClasses['mt-4']} */ ;
77
+ // @ts-ignore
78
+ var __VLS_2 = __VLS_1, __VLS_3 = __VLS_0;
79
+ const __VLS_base = (await import('vue')).defineComponent({
80
+ __typeEmits: {},
81
+ __typeProps: {},
82
+ props: {},
83
+ });
84
+ const __VLS_export = {};
85
+ export default {};
@@ -6,7 +6,17 @@ const open = ref(false);
6
6
  const selectedLabel = computed(() => {
7
7
  return props.options.find(o => o.value === props.modelValue)?.label ?? '';
8
8
  });
9
+ const positionClass = computed(() => {
10
+ let result = '';
11
+ if (props.placement === 'bottom')
12
+ return 'top-2 translate-y-full';
13
+ else
14
+ return '-top-4 -translate-y-full';
15
+ return '';
16
+ });
9
17
  function toggle() {
18
+ if (props.disabled)
19
+ return;
10
20
  open.value = !open.value;
11
21
  }
12
22
  function select(option) {
@@ -37,16 +47,13 @@ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
37
47
  });
38
48
  // @ts-ignore
39
49
  [toggle,];
40
- __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
41
- ...{ class: "cursor-pointer pointer-events-none" },
42
- });
43
- var __VLS_0 = {};
44
50
  __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" },
51
+ ...{ class: "w-max absolute -translate-y-full left-0 z-10 mt-1 max-h-48 overflow-auto rounded-md shadow-custom bg-white shadow-lg" },
52
+ ...{ class: (__VLS_ctx.positionClass) },
46
53
  });
47
54
  __VLS_asFunctionalDirective(__VLS_directives.vShow)(null, { ...__VLS_directiveBindingRestFields, value: (__VLS_ctx.open) }, null, null);
48
55
  // @ts-ignore
49
- [open,];
56
+ [open, positionClass,];
50
57
  for (const [option, idx] of __VLS_getVForSourceType((__VLS_ctx.options))) {
51
58
  // @ts-ignore
52
59
  [options,];
@@ -57,37 +64,38 @@ for (const [option, idx] of __VLS_getVForSourceType((__VLS_ctx.options))) {
57
64
  [select,];
58
65
  } },
59
66
  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 }) },
67
+ ...{ class: "cursor-pointer text-black px-6 py-2 hover:bg-chat-haze-200 border-b border-chat-haze-200" },
62
68
  });
63
- // @ts-ignore
64
- [modelValue,];
65
69
  (option.label);
66
70
  }
71
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
72
+ ...{ class: "cursor-pointer pointer-events-none" },
73
+ });
74
+ var __VLS_0 = {};
67
75
  /** @type {__VLS_StyleScopedClasses['relative']} */ ;
68
76
  /** @type {__VLS_StyleScopedClasses['inline-block']} */ ;
69
77
  /** @type {__VLS_StyleScopedClasses['w-full']} */ ;
70
- /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
71
- /** @type {__VLS_StyleScopedClasses['pointer-events-none']} */ ;
72
78
  /** @type {__VLS_StyleScopedClasses['w-max']} */ ;
73
79
  /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
74
- /** @type {__VLS_StyleScopedClasses['right-0']} */ ;
80
+ /** @type {__VLS_StyleScopedClasses['-translate-y-full']} */ ;
81
+ /** @type {__VLS_StyleScopedClasses['left-0']} */ ;
75
82
  /** @type {__VLS_StyleScopedClasses['z-10']} */ ;
76
83
  /** @type {__VLS_StyleScopedClasses['mt-1']} */ ;
77
84
  /** @type {__VLS_StyleScopedClasses['max-h-48']} */ ;
78
85
  /** @type {__VLS_StyleScopedClasses['overflow-auto']} */ ;
79
86
  /** @type {__VLS_StyleScopedClasses['rounded-md']} */ ;
80
- /** @type {__VLS_StyleScopedClasses['border']} */ ;
81
- /** @type {__VLS_StyleScopedClasses['border-gray-200']} */ ;
87
+ /** @type {__VLS_StyleScopedClasses['shadow-custom']} */ ;
82
88
  /** @type {__VLS_StyleScopedClasses['bg-white']} */ ;
83
89
  /** @type {__VLS_StyleScopedClasses['shadow-lg']} */ ;
84
90
  /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
85
91
  /** @type {__VLS_StyleScopedClasses['text-black']} */ ;
86
- /** @type {__VLS_StyleScopedClasses['px-3']} */ ;
92
+ /** @type {__VLS_StyleScopedClasses['px-6']} */ ;
87
93
  /** @type {__VLS_StyleScopedClasses['py-2']} */ ;
88
94
  /** @type {__VLS_StyleScopedClasses['hover:bg-chat-haze-200']} */ ;
89
- /** @type {__VLS_StyleScopedClasses['bg-primary']} */ ;
90
- /** @type {__VLS_StyleScopedClasses['!text-white']} */ ;
95
+ /** @type {__VLS_StyleScopedClasses['border-b']} */ ;
96
+ /** @type {__VLS_StyleScopedClasses['border-chat-haze-200']} */ ;
97
+ /** @type {__VLS_StyleScopedClasses['cursor-pointer']} */ ;
98
+ /** @type {__VLS_StyleScopedClasses['pointer-events-none']} */ ;
91
99
  // @ts-ignore
92
100
  var __VLS_1 = __VLS_0;
93
101
  const __VLS_base = (await import('vue')).defineComponent({
@@ -51,11 +51,11 @@ let __VLS_components;
51
51
  let __VLS_directives;
52
52
  /** @type {__VLS_StyleScopedClasses['drawer-box']} */ ;
53
53
  __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
54
- ...{ class: "absolute top-0 bottom-0 right-0 left-0 z-[1500] drawer" },
55
- ...{ class: (__VLS_ctx.show ? 'opacity-1' : 'pointer-events-none opacity-0 delay-300') },
54
+ ...{ class: "top-0 bottom-0 right-0 left-0 z-[1500] drawer" },
55
+ ...{ class: ({ 'opacity-1': __VLS_ctx.show, 'pointer-events-none opacity-0 delay-300': !__VLS_ctx.show, 'absolute': __VLS_ctx.absolute, 'fixed': !__VLS_ctx.absolute }) },
56
56
  });
57
57
  // @ts-ignore
58
- [show,];
58
+ [show, show, absolute, absolute,];
59
59
  if (!__VLS_ctx.disabledClose) {
60
60
  // @ts-ignore
61
61
  [disabledClose,];
@@ -84,13 +84,18 @@ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
84
84
  ...{ class: "flex p-4 content" },
85
85
  });
86
86
  __VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({});
87
- /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
88
87
  /** @type {__VLS_StyleScopedClasses['top-0']} */ ;
89
88
  /** @type {__VLS_StyleScopedClasses['bottom-0']} */ ;
90
89
  /** @type {__VLS_StyleScopedClasses['right-0']} */ ;
91
90
  /** @type {__VLS_StyleScopedClasses['left-0']} */ ;
92
91
  /** @type {__VLS_StyleScopedClasses['z-[1500]']} */ ;
93
92
  /** @type {__VLS_StyleScopedClasses['drawer']} */ ;
93
+ /** @type {__VLS_StyleScopedClasses['opacity-1']} */ ;
94
+ /** @type {__VLS_StyleScopedClasses['pointer-events-none']} */ ;
95
+ /** @type {__VLS_StyleScopedClasses['opacity-0']} */ ;
96
+ /** @type {__VLS_StyleScopedClasses['delay-300']} */ ;
97
+ /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
98
+ /** @type {__VLS_StyleScopedClasses['fixed']} */ ;
94
99
  /** @type {__VLS_StyleScopedClasses['absolute']} */ ;
95
100
  /** @type {__VLS_StyleScopedClasses['w-full']} */ ;
96
101
  /** @type {__VLS_StyleScopedClasses['h-full']} */ ;
@@ -3,7 +3,7 @@ export const digibotData = {
3
3
  id: -98,
4
4
  receiver_id: 101,
5
5
  username: 'Gocheckin AI',
6
- customer_phone: '',
6
+ phone: '',
7
7
  avatar: '',
8
8
  last_message: '',
9
9
  last_message_time: '',
@@ -12,6 +12,7 @@ export const digibotData = {
12
12
  unread_count: 0,
13
13
  status: 1,
14
14
  color: '#4F46E5',
15
+ is_unknown: 0
15
16
  };
16
17
  export const digibotId = -98;
17
18
  export function useDigibot() {
@@ -1,11 +1,10 @@
1
1
  import { ref } from 'vue';
2
2
  import { sdkInit } from '../plugins/sdk';
3
- import { dataProfile, getProfile, loginLink } from '../utils/chat/auth';
3
+ import { checkTenantPhone, dataProfile, getProfile, loginLink } from '../utils/chat/auth';
4
4
  import { routerPush } from '../utils/chat/chat-router';
5
5
  import { PAGE } from '../constant/general';
6
6
  import { subscribeToTopic, unsubscribeFromTopic } from '../plugins/mqtt';
7
7
  import { TOPIC_DETAIL_CALL } from '../constant/mqtt';
8
- import { getWebSocket, initWebSocket } from '../plugins/websocket';
9
8
  // import router from '../router'
10
9
  //PINIA
11
10
  export const isRouterReady = ref(false);
@@ -34,13 +33,11 @@ export function useInitData() {
34
33
  };
35
34
  const initData = async (props, response) => {
36
35
  const res = await getProfile();
37
- await getWebSocket();
38
- initWebSocket();
36
+ if (dataProfile.value?.user_type == 'tenant') {
37
+ await checkTenantPhone();
38
+ }
39
39
  unsubscribeFromTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
40
40
  subscribeToTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
41
- // if((!res?.phone && res.tenant_id && !props.isLib)) {
42
- // router.push({name: 'tenant-phone'})
43
- // }
44
41
  if (response == 'mobile') {
45
42
  routerPush(PAGE.CHAT_LIST);
46
43
  }
@@ -0,0 +1,124 @@
1
+ import { nextTick, onMounted, onUnmounted, ref } from 'vue';
2
+ import { TOPIC_HOME, TOPIC_STATUS_USER } from '../constant/mqtt';
3
+ import { addHandleMqttMessage, connectMqtt, removeHandleMqttMessage, subscribeToTopic, unsubscribeFromTopic } from '../plugins/mqtt';
4
+ import { dataProfile } from '../utils/chat/auth';
5
+ import { useDebounce } from '../utils/debounce';
6
+ import { getConversation } from '../utils/chat/conversation';
7
+ import { readMessages } from '../utils/chat/message';
8
+ import { useDigibot } from '../composable/useDigibot';
9
+ const { digibotData, digibotId } = useDigibot();
10
+ export const useListConversations = (is_unknown) => {
11
+ let pageCount = 0;
12
+ const listConversations = ref([]);
13
+ const params = ref({
14
+ page: 1,
15
+ search: ''
16
+ });
17
+ const isLoadingSearch = ref(false);
18
+ onMounted(() => {
19
+ handleConnectMqtt();
20
+ });
21
+ onUnmounted(() => {
22
+ handleDisconnectMqtt;
23
+ });
24
+ const handleDisconnectMqtt = () => {
25
+ TOPIC_HOME.forEach((item) => {
26
+ unsubscribeFromTopic(item + dataProfile.value?.id);
27
+ removeHandleMqttMessage('chat-list-' + item + '-' + is_unknown);
28
+ });
29
+ if (dataProfile.value?.user_type == 'tenant') {
30
+ subscribeToTopic(TOPIC_STATUS_USER + dataProfile.value?.id);
31
+ removeHandleMqttMessage('chat-list-' + TOPIC_STATUS_USER + '-' + is_unknown);
32
+ }
33
+ };
34
+ const handleConnectMqtt = async () => {
35
+ try {
36
+ if (dataProfile.value) {
37
+ await connectMqtt();
38
+ TOPIC_HOME.forEach((item) => {
39
+ subscribeToTopic(item + dataProfile.value?.id);
40
+ addHandleMqttMessage('chat-list-' + item + '-' + is_unknown, item + dataProfile.value?.id, mqttMessageHandler);
41
+ });
42
+ subscribeToTopic(TOPIC_STATUS_USER + dataProfile.value?.id);
43
+ addHandleMqttMessage('chat-list-' + TOPIC_STATUS_USER + '-' + is_unknown, TOPIC_STATUS_USER + dataProfile.value?.id, mqttMessageHandler);
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error(error);
48
+ }
49
+ };
50
+ const mqttMessageHandler = (topic, data) => {
51
+ if ((data.is_unknown ?? 0) != is_unknown)
52
+ return;
53
+ getDataMqtt();
54
+ if (topic === TOPIC_HOME[0] + dataProfile.value?.id) {
55
+ const index = listConversations.value.findIndex((item) => item.id === data.id);
56
+ const hasChatBox = listConversations.value.findIndex((item) => item.id === digibotId);
57
+ if (index != -1) {
58
+ listConversations.value.splice(index, 1);
59
+ }
60
+ if (hasChatBox > -1) {
61
+ listConversations.value.splice(1, 0, data);
62
+ }
63
+ else {
64
+ listConversations.value.unshift(data);
65
+ }
66
+ }
67
+ if (topic === TOPIC_HOME[1] + dataProfile.value?.id) {
68
+ const index = listConversations.value.findIndex((item) => item.id === data.id);
69
+ if (index != -1) {
70
+ listConversations.value[index].unread_count = 0;
71
+ }
72
+ }
73
+ if (topic === TOPIC_HOME[2] + dataProfile.value?.id) {
74
+ listConversations.value.unshift(data?.conversations);
75
+ }
76
+ if (topic === TOPIC_STATUS_USER + dataProfile.value?.id) {
77
+ const index = listConversations.value.findIndex((e) => e.receiver_id == Number(data?.customer_id));
78
+ if (index != -1) {
79
+ listConversations.value[index].status = data.is_online ? 1 : 0;
80
+ }
81
+ }
82
+ };
83
+ const getDataMqtt = useDebounce(() => {
84
+ getData(undefined, { hideLoading: true, reset: true });
85
+ }, 5000);
86
+ const getData = async (data, option) => {
87
+ try {
88
+ // if (!option?.hideLoading) isLoadingSearch.value = true
89
+ params.value = { ...params.value, ...(data ?? {}) };
90
+ const res = await getConversation({ ...params.value, is_unknown });
91
+ if (option?.reset) {
92
+ listConversations.value = [];
93
+ if (is_unknown == 0)
94
+ listConversations.value.push(digibotData);
95
+ await nextTick();
96
+ }
97
+ listConversations.value.push(...(res?.items ?? []));
98
+ params.value.page = res?._meta?.currentPage || 1;
99
+ pageCount = res?._meta?.pageCount || 1;
100
+ }
101
+ catch (error) {
102
+ console.error(error);
103
+ }
104
+ finally {
105
+ // isLoadingSearch.value = false
106
+ }
107
+ };
108
+ const handleReadMessage = (receiver_id) => {
109
+ const index = listConversations.value.findIndex((e) => e.receiver_id == receiver_id);
110
+ if (index > -1) {
111
+ if (listConversations.value[index].unread_count) {
112
+ readMessages(listConversations.value[index].id);
113
+ listConversations.value[index].unread_count = 0;
114
+ }
115
+ }
116
+ };
117
+ return {
118
+ listConversations,
119
+ params,
120
+ pageCount,
121
+ getData,
122
+ handleReadMessage
123
+ };
124
+ };