@phonghq/go-chat 1.0.42 → 1.0.43

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.
@@ -9,8 +9,10 @@ import { addHandleMqttMessage, connectMqtt, publishMessage, removeHandleMqttMess
9
9
  import { TOPIC_DETAIL_CHAT, TOPIC_PLIVO_SMS } from '../../../constant/mqtt';
10
10
  import { MessageState } from '../../../constant/message';
11
11
  import { publicTopicConversationUpdate } from '../../../utils/chat/conversation';
12
+ import { getCache, removeOldestCache, setCache } from '../../../utils/chat/cache';
12
13
  const props = withDefaults(defineProps(), {});
13
14
  const emit = defineEmits();
15
+ const MESSAGE_STORAGE_KEY = 'chat-message-';
14
16
  const reversedList = computed(() => listMessage.value.slice().reverse());
15
17
  let page = 1;
16
18
  let pageCount = 1;
@@ -46,6 +48,7 @@ const handleDisconnectMqtt = async () => {
46
48
  removeHandleMqttMessage('chat-home-1');
47
49
  };
48
50
  const mqttMessageHandler = (topic, message) => {
51
+ // console.log(topic, message)
49
52
  if ((infoUser.value?.id && message?.sender_id?.toString() == infoUser.value?.id?.toString())
50
53
  || (infoUser.value?.id && message?.receiver_id?.toString() == infoUser.value?.id?.toString())) {
51
54
  const index = listMessage.value.findIndex((item) => item.id === message?.id);
@@ -63,14 +66,23 @@ const handleGetMessage = async (option) => {
63
66
  try {
64
67
  const id = props.receiverId;
65
68
  const params = { page: option?.resetList ? 1 : page, receiver_id: props.receiverId };
69
+ if (params.page <= 1) {
70
+ const cache = getCache(MESSAGE_STORAGE_KEY + id);
71
+ if (cache.data) {
72
+ listMessage.value = cache.data ?? [];
73
+ chatMessageRef.value?.scrollBottom();
74
+ }
75
+ }
66
76
  let res = await getMessage(params);
67
77
  // res.items = res.items.reverse()
68
78
  page = res._meta?.currentPage || 1;
69
79
  pageCount = res._meta?.pageCount || 1;
70
80
  if (id == props.receiverId) {
71
- if (option?.resetList) {
81
+ if (page <= 1) {
72
82
  listMessage.value = res.items;
73
83
  chatMessageRef.value?.scrollBottom();
84
+ setCache(MESSAGE_STORAGE_KEY + id, res.items);
85
+ removeOldestCache(8, MESSAGE_STORAGE_KEY);
74
86
  }
75
87
  else {
76
88
  listMessage.value.push(...res.items);
@@ -171,7 +183,7 @@ const handleSendMessage = async (data) => {
171
183
  console.log(error);
172
184
  updateMessageItem(data.id, {
173
185
  state: MessageState.Failed,
174
- error: typeof error?.message == 'string' ? error.message : ''
186
+ error: typeof error?.messages == 'string' ? error.messages : ''
175
187
  });
176
188
  }
177
189
  };
@@ -14,6 +14,7 @@ import { PLIVO_CALL_STATUS } from '../../../types/chat/call';
14
14
  import IconMic from '../../../assets/icons/call/IconMic.vue';
15
15
  import { useError } from '../../../composable/useError';
16
16
  import { useDebounce } from '../../../utils/debounce';
17
+ import { phoneNumberFormat } from '../../../utils/string-helper';
17
18
  const props = withDefaults(defineProps(), {});
18
19
  const emit = defineEmits();
19
20
  // const {
@@ -204,14 +205,15 @@ const getUserOffer = async (phone) => {
204
205
  phone: formatPhone10number(phone, '1'),
205
206
  client_id: dataProfile.value?.tenant_id ?? ''
206
207
  };
208
+ console.log(data);
207
209
  res = await getUserDetailChat(data);
208
210
  }
209
211
  catch (e) {
210
212
  console.log(e);
211
213
  }
212
214
  const user = {
213
- username: res?.full_name || 'Unknown Name',
214
- phone: '1' + res?.phone
215
+ username: res?.full_name || '',
216
+ phone: res?.phone ? '1' + res?.phone : phone
215
217
  };
216
218
  userRemoter.value = user;
217
219
  emit('userCalling', userRemoter.value);
@@ -344,9 +346,9 @@ const { default: __VLS_8 } = __VLS_2.slots;
344
346
  __VLS_asFunctionalElement(__VLS_elements.h2, __VLS_elements.h2)({
345
347
  ...{ class: "text-2xl font-semibold" },
346
348
  });
347
- (__VLS_ctx.userRemoter?.username || __VLS_ctx.formatPhone10number(__VLS_ctx.userRemoter?.phone ?? ''));
349
+ (__VLS_ctx.userRemoter?.username || __VLS_ctx.phoneNumberFormat(__VLS_ctx.userRemoter?.phone ?? ''));
348
350
  // @ts-ignore
349
- [userRemoter, userRemoter, formatPhone10number,];
351
+ [userRemoter, userRemoter, phoneNumberFormat,];
350
352
  __VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
351
353
  ...{ class: "text-gray-400 mt-1" },
352
354
  });
@@ -1,11 +1,12 @@
1
1
  /// <reference types="C:/phonghq/go-chat-v2/node_modules/.vue-global-types/vue_3.5_0.d.ts" />
2
2
  import { computed } from 'vue';
3
3
  import { digibotId } from '../../../composable/useDigibot';
4
+ import IconUser from '../../../assets/icons/IconUser.vue';
4
5
  const props = withDefaults(defineProps(), {
5
6
  size: 'md',
6
7
  src: ''
7
8
  });
8
- const initials = computed(() => props.name?.[0]?.toUpperCase() ?? 'n/a');
9
+ const initials = computed(() => props.name?.[0]?.toUpperCase() ?? '');
9
10
  const sizeClass = computed(() => {
10
11
  const s = props.size;
11
12
  if (typeof s === 'number')
@@ -50,10 +51,10 @@ let __VLS_directives;
50
51
  /** @type {__VLS_StyleScopedClasses['bot-wrap']} */ ;
51
52
  __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
52
53
  ...{ class: ([
53
- 'flex items-center justify-center rounded-full font-medium overflow-hidden select-none',
54
+ 'flex items-center justify-center rounded-full font-medium overflow-hidden select-none text-white',
54
55
  __VLS_ctx.sizeClass
55
56
  ]) },
56
- ...{ style: ({ backgroundColor: __VLS_ctx.id == __VLS_ctx.digibotId ? 'transparent' : (__VLS_ctx.color || '#266699') }) },
57
+ ...{ style: ({ backgroundColor: __VLS_ctx.id == __VLS_ctx.digibotId ? 'transparent' : __VLS_ctx.color || '#4a7c9e' }) },
57
58
  });
58
59
  // @ts-ignore
59
60
  [sizeClass, id, digibotId, color,];
@@ -76,12 +77,28 @@ else if (__VLS_ctx.src) {
76
77
  // @ts-ignore
77
78
  [src,];
78
79
  }
79
- else {
80
+ else if (__VLS_ctx.initials) {
81
+ // @ts-ignore
82
+ [initials,];
80
83
  __VLS_asFunctionalElement(__VLS_elements.span, __VLS_elements.span)({});
81
84
  (__VLS_ctx.initials);
82
85
  // @ts-ignore
83
86
  [initials,];
84
87
  }
88
+ else {
89
+ /** @type {[typeof IconUser, ]} */ ;
90
+ // @ts-ignore
91
+ const __VLS_0 = __VLS_asFunctionalComponent(IconUser, new IconUser({
92
+ ...{ class: (__VLS_ctx.sizeClass) },
93
+ ...{ class: "scale-50" },
94
+ }));
95
+ const __VLS_1 = __VLS_0({
96
+ ...{ class: (__VLS_ctx.sizeClass) },
97
+ ...{ class: "scale-50" },
98
+ }, ...__VLS_functionalComponentArgsRest(__VLS_0));
99
+ // @ts-ignore
100
+ [sizeClass,];
101
+ }
85
102
  /** @type {__VLS_StyleScopedClasses['flex']} */ ;
86
103
  /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
87
104
  /** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
@@ -89,11 +106,13 @@ else {
89
106
  /** @type {__VLS_StyleScopedClasses['font-medium']} */ ;
90
107
  /** @type {__VLS_StyleScopedClasses['overflow-hidden']} */ ;
91
108
  /** @type {__VLS_StyleScopedClasses['select-none']} */ ;
109
+ /** @type {__VLS_StyleScopedClasses['text-white']} */ ;
92
110
  /** @type {__VLS_StyleScopedClasses['w-4/5']} */ ;
93
111
  /** @type {__VLS_StyleScopedClasses['h-4/5']} */ ;
94
112
  /** @type {__VLS_StyleScopedClasses['w-full']} */ ;
95
113
  /** @type {__VLS_StyleScopedClasses['h-full']} */ ;
96
114
  /** @type {__VLS_StyleScopedClasses['object-cover']} */ ;
115
+ /** @type {__VLS_StyleScopedClasses['scale-50']} */ ;
97
116
  const __VLS_export = (await import('vue')).defineComponent({
98
117
  __typeProps: {},
99
118
  props: {},
@@ -1,7 +1,8 @@
1
1
  //PINIA
2
+ export const digibotId = -98;
2
3
  export const digibotData = {
3
- id: -98,
4
- receiver_id: 101,
4
+ id: digibotId,
5
+ receiver_id: digibotId,
5
6
  username: 'Gocheckin AI',
6
7
  phone: '',
7
8
  avatar: '',
@@ -14,7 +15,6 @@ export const digibotData = {
14
15
  color: '#4F46E5',
15
16
  is_unknown: 0
16
17
  };
17
- export const digibotId = -98;
18
18
  export function useDigibot() {
19
19
  return {
20
20
  digibotData,
@@ -5,7 +5,6 @@ import { routerPush } from '../utils/chat/chat-router';
5
5
  import { PAGE } from '../constant/general';
6
6
  import { connectMqtt, subscribeToTopic, unsubscribeFromTopic } from '../plugins/mqtt';
7
7
  import { TOPIC_DETAIL_CALL } from '../constant/mqtt';
8
- import { checkHasBusinessTenantPhone } from '../plugins/pocketbase';
9
8
  // import router from '../router'
10
9
  //PINIA
11
10
  export const isRouterReady = ref(false);
@@ -22,23 +21,22 @@ export function useInitData() {
22
21
  // return
23
22
  // }
24
23
  }
25
- // connectMqtt()
26
24
  await initData(data.props, data.response);
27
25
  await connectMqtt();
26
+ const res = checkNotificationParams();
27
+ isRouterReady.value = true;
28
+ return res;
28
29
  }
29
30
  catch (error) {
30
- console.log(error);
31
- }
32
- finally {
33
31
  isRouterReady.value = true;
32
+ console.log(error);
33
+ return {};
34
34
  }
35
35
  };
36
36
  const initData = async (props, response) => {
37
- const res = await getProfile();
37
+ await getProfile();
38
38
  if (dataProfile.value?.user_type == 'tenant') {
39
39
  await checkTenantPhone();
40
- if (dataProfile.value)
41
- dataProfile.value.has_business_tenant_phone = await checkHasBusinessTenantPhone(dataProfile.value?.tenant_id);
42
40
  }
43
41
  unsubscribeFromTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
44
42
  subscribeToTopic(TOPIC_DETAIL_CALL + dataProfile.value?.id);
@@ -49,6 +47,17 @@ export function useInitData() {
49
47
  routerPush(PAGE.HOME);
50
48
  }
51
49
  };
50
+ const checkNotificationParams = () => {
51
+ // return {conversation_id: '316', is_unknown: '0'}
52
+ const queryString = window.location.search;
53
+ const urlParams = new URLSearchParams(queryString);
54
+ const conversation_id = urlParams.get('conversation_id') || '';
55
+ const is_unknown = urlParams.get('is_unknown') || '';
56
+ if (!conversation_id || !is_unknown)
57
+ return {};
58
+ clearApiParams();
59
+ return { conversation_id, is_unknown };
60
+ };
52
61
  const loginApiLink = async () => {
53
62
  try {
54
63
  const queryString = window.location.search;
@@ -80,7 +89,7 @@ export function useInitData() {
80
89
  };
81
90
  const clearApiParams = () => {
82
91
  const url = new URL(window.location.href);
83
- url.search = "";
92
+ url.search = '';
84
93
  window.history.replaceState({}, document.title, url);
85
94
  };
86
95
  return {
@@ -6,8 +6,10 @@ import { useDebounce } from '../utils/debounce';
6
6
  import { getConversation } from '../utils/chat/conversation';
7
7
  import { readMessages } from '../utils/chat/message';
8
8
  import { useDigibot } from '../composable/useDigibot';
9
+ import { getCache, setCache } from '../utils/chat/cache';
9
10
  const { digibotData, digibotId } = useDigibot();
10
11
  export const useListConversations = (is_unknown) => {
12
+ const STORAGE_KEY = 'chat-conversation-';
11
13
  let pageCount = 0;
12
14
  const listConversations = ref([]);
13
15
  const params = ref({
@@ -52,8 +54,8 @@ export const useListConversations = (is_unknown) => {
52
54
  if ((data.is_unknown ?? 0) != is_unknown)
53
55
  return;
54
56
  getDataMqtt();
55
- if ((topic === TOPIC_HOME[0] + dataProfile.value?.id) || topic === (TOPIC_HOME[3] + dataProfile.value?.id)) {
56
- console.log(data);
57
+ if (topic === TOPIC_HOME[0] + dataProfile.value?.id ||
58
+ topic === TOPIC_HOME[3] + dataProfile.value?.id) {
57
59
  const index = listConversations.value.findIndex((item) => item.id === data.id);
58
60
  const hasChatBox = listConversations.value.findIndex((item) => item.id === digibotId);
59
61
  if (index != -1) {
@@ -81,15 +83,16 @@ export const useListConversations = (is_unknown) => {
81
83
  listConversations.value[index].status = data.is_online ? 1 : 0;
82
84
  }
83
85
  }
84
- console.log(listConversations.value, is_unknown);
85
86
  };
86
87
  const getDataMqtt = useDebounce(() => {
87
88
  getData(undefined, { hideLoading: true, reset: true });
88
89
  }, 5000);
89
90
  const getData = async (data, option) => {
90
91
  try {
91
- // if (!option?.hideLoading) isLoadingSearch.value = true
92
92
  params.value = { ...params.value, ...(data ?? {}) };
93
+ if (option?.reset) {
94
+ params.value.page = 1;
95
+ }
93
96
  const res = await getConversation({ ...params.value, is_unknown });
94
97
  if (option?.reset) {
95
98
  listConversations.value = [];
@@ -100,14 +103,25 @@ export const useListConversations = (is_unknown) => {
100
103
  listConversations.value.push(...(res?.items ?? []));
101
104
  params.value.page = res?._meta?.currentPage || 1;
102
105
  pageCount = res?._meta?.pageCount || 1;
106
+ if (params.value.page <= 1) {
107
+ setCache(STORAGE_KEY + is_unknown, listConversations.value);
108
+ }
103
109
  }
104
110
  catch (error) {
105
111
  console.error(error);
106
112
  }
107
113
  finally {
108
- // isLoadingSearch.value = false
109
114
  }
110
115
  };
116
+ const getDataCache = () => {
117
+ const cache_data = getCache(STORAGE_KEY + is_unknown);
118
+ if (cache_data.data) {
119
+ listConversations.value = [];
120
+ listConversations.value.push(...(cache_data.data ?? []));
121
+ return true;
122
+ }
123
+ return false;
124
+ };
111
125
  const handleReadMessage = (receiver_id) => {
112
126
  const index = listConversations.value.findIndex((e) => e.receiver_id == receiver_id);
113
127
  if (index > -1) {
@@ -122,6 +136,7 @@ export const useListConversations = (is_unknown) => {
122
136
  params,
123
137
  pageCount,
124
138
  getData,
125
- handleReadMessage
139
+ handleReadMessage,
140
+ getDataCache
126
141
  };
127
142
  };
@@ -0,0 +1,63 @@
1
+ import { dataProfile } from '../../utils/chat/auth';
2
+ export function setCache(key, data, ttlMs = 1000) {
3
+ if (!dataProfile.value?.id)
4
+ return;
5
+ const now = Date.now();
6
+ const id = dataProfile.value?.id;
7
+ const payload = {
8
+ timestamp: now,
9
+ ttl: ttlMs,
10
+ id: id,
11
+ data
12
+ };
13
+ localStorage.setItem(key, JSON.stringify(payload));
14
+ }
15
+ export function getCache(key) {
16
+ if (!dataProfile.value?.id)
17
+ return { data: null };
18
+ const raw = localStorage.getItem(key);
19
+ const id = dataProfile.value?.id;
20
+ if (!raw)
21
+ return { data: null };
22
+ try {
23
+ const payload = JSON.parse(raw);
24
+ if (!payload.timestamp || !payload.ttl)
25
+ return { data: null };
26
+ if (!payload?.id || payload?.id != id)
27
+ return { data: null };
28
+ const isExpired = Date.now() - payload.timestamp > payload.ttl;
29
+ return {
30
+ data: payload.data,
31
+ needReload: isExpired
32
+ };
33
+ }
34
+ catch (e) {
35
+ console.warn("Cache parse error:", e);
36
+ return { data: null };
37
+ }
38
+ }
39
+ export function clearCache(key) {
40
+ localStorage.removeItem(key);
41
+ }
42
+ export function removeOldestCache(limit, prefix) {
43
+ const allKeys = Object.keys(localStorage).filter(k => k.startsWith(prefix));
44
+ if (allKeys.length > limit) {
45
+ const entries = allKeys.map(k => {
46
+ const raw = localStorage.getItem(k);
47
+ try {
48
+ const parsed = JSON.parse(raw || "{}");
49
+ return { key: k, expire: parsed.timestamp || 0 };
50
+ }
51
+ catch {
52
+ return { key: k, expire: 0 };
53
+ }
54
+ });
55
+ entries.sort((a, b) => a.expire - b.expire);
56
+ while (entries.length > limit) {
57
+ const oldest = entries.shift();
58
+ if (oldest) {
59
+ localStorage.removeItem(oldest.key);
60
+ }
61
+ }
62
+ }
63
+ }
@@ -11,6 +11,13 @@ export const getConversation = async (param) => {
11
11
  });
12
12
  return res;
13
13
  };
14
+ export const getConversationView = async (id) => {
15
+ let res = await axios.get('/api/v1/message/conversation/view', {
16
+ params: { id }
17
+ });
18
+ res.receiver_id = res.customer_id ?? 0;
19
+ return res;
20
+ };
14
21
  export const publicTopicConversationUpdate = async (data) => {
15
22
  const res = await getCountUnread({
16
23
  conversation_id: data.infoUser?.conversation_id ?? 0,
@@ -0,0 +1,99 @@
1
+ const tryAgain = () => {
2
+ if (props.isLib) {
3
+ emit('tryAgain');
4
+ }
5
+ else {
6
+ window.location.href = '/';
7
+ }
8
+ };
9
+ const props = withDefaults(defineProps(), {});
10
+ const emit = defineEmits();
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: "flex flex-col items-center justify-center w-full h-full py-10 text-center" },
25
+ });
26
+ __VLS_asFunctionalElement(__VLS_elements.div, __VLS_elements.div)({
27
+ ...{ class: "w-24 h-24 flex items-center justify-center rounded-full bg-gray-100" },
28
+ });
29
+ __VLS_asFunctionalElement(__VLS_elements.svg, __VLS_elements.svg)({
30
+ xmlns: "http://www.w3.org/2000/svg",
31
+ ...{ class: "w-10 h-10 text-gray-400" },
32
+ fill: "none",
33
+ viewBox: "0 0 24 24",
34
+ 'stroke-width': "1.5",
35
+ stroke: "currentColor",
36
+ });
37
+ __VLS_asFunctionalElement(__VLS_elements.path)({
38
+ 'stroke-linecap': "round",
39
+ 'stroke-linejoin': "round",
40
+ d: "\u004d\u0032\u002e\u0032\u0035\u0020\u0036\u002e\u0037\u0035\u0063\u0030\u0020\u0038\u002e\u0032\u0038\u0034\u0020\u0036\u002e\u0037\u0031\u0036\u0020\u0031\u0035\u0020\u0031\u0035\u0020\u0031\u0035\u0068\u0031\u002e\u0035\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0061\u0032\u002e\u0032\u0035\u0020\u0032\u002e\u0032\u0035\u0020\u0030\u0020\u0030\u0020\u0030\u0020\u0032\u002e\u0032\u0035\u002d\u0032\u002e\u0032\u0035\u0076\u002d\u0032\u002e\u0030\u0037\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0063\u0030\u002d\u002e\u0035\u0031\u0036\u002d\u002e\u0033\u0035\u0031\u002d\u002e\u0039\u0036\u0036\u002d\u002e\u0038\u0035\u0032\u002d\u0031\u002e\u0030\u0039\u0031\u006c\u002d\u0034\u002e\u0034\u0032\u0033\u002d\u0031\u002e\u0031\u0030\u0036\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0061\u0031\u002e\u0031\u0032\u0035\u0020\u0031\u002e\u0031\u0032\u0035\u0020\u0030\u0020\u0030\u0020\u0030\u002d\u0031\u002e\u0031\u0037\u0033\u002e\u0034\u0031\u0037\u006c\u002d\u002e\u0039\u0037\u0020\u0031\u002e\u0032\u0039\u0033\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0063\u002d\u002e\u0032\u0036\u0035\u002e\u0033\u0035\u0033\u002d\u002e\u0037\u0033\u0039\u002e\u0035\u0030\u0032\u002d\u0031\u002e\u0031\u0035\u0033\u002e\u0033\u0032\u0036\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0061\u0031\u0032\u002e\u0030\u0033\u0035\u0020\u0031\u0032\u002e\u0030\u0033\u0035\u0020\u0030\u0020\u0030\u0020\u0031\u002d\u0035\u002e\u0033\u0034\u0038\u002d\u0035\u002e\u0033\u0034\u0038\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0063\u002d\u002e\u0031\u0037\u0036\u002d\u002e\u0034\u0031\u0034\u002d\u002e\u0030\u0032\u0037\u002d\u002e\u0038\u0038\u0038\u002e\u0033\u0032\u0036\u002d\u0031\u002e\u0031\u0035\u0033\u006c\u0031\u002e\u0032\u0039\u0033\u002d\u002e\u0039\u0037\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0063\u002e\u0033\u0039\u002d\u002e\u0032\u0039\u0033\u002e\u0035\u0036\u0033\u002d\u002e\u0037\u0039\u0035\u002e\u0034\u0031\u0037\u002d\u0031\u002e\u0031\u0037\u0033\u004c\u0036\u002e\u0036\u0036\u0020\u0033\u002e\u0031\u0030\u0032\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0041\u0031\u002e\u0031\u0032\u0035\u0020\u0031\u002e\u0031\u0032\u0035\u0020\u0030\u0020\u0030\u0020\u0030\u0020\u0035\u002e\u0035\u0036\u0039\u0020\u0032\u002e\u0032\u0035\u0048\u0033\u002e\u0035\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0041\u0031\u002e\u0032\u0035\u0020\u0031\u002e\u0032\u0035\u0020\u0030\u0020\u0030\u0020\u0030\u0020\u0032\u002e\u0032\u0035\u0020\u0033\u002e\u0035\u0076\u0033\u002e\u0032\u0035\u007a",
41
+ });
42
+ __VLS_asFunctionalElement(__VLS_elements.h2, __VLS_elements.h2)({
43
+ ...{ class: "mt-4 text-3xl font-semibold text-gray-700" },
44
+ });
45
+ __VLS_asFunctionalElement(__VLS_elements.p, __VLS_elements.p)({
46
+ ...{ class: "mt-1 text-xl text-chat-haze-500 max-w-[700px]" },
47
+ });
48
+ __VLS_asFunctionalElement(__VLS_elements.button, __VLS_elements.button)({
49
+ ...{ onClick: (...[$event]) => {
50
+ __VLS_ctx.tryAgain();
51
+ // @ts-ignore
52
+ [tryAgain,];
53
+ } },
54
+ ...{ class: "mt-6 px-4 py-2 rounded-xl h-14 w-[150px] bg-chat-primary text-white text-lg font-semibold hover:bg-blue-700 transition" },
55
+ });
56
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
57
+ /** @type {__VLS_StyleScopedClasses['flex-col']} */ ;
58
+ /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
59
+ /** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
60
+ /** @type {__VLS_StyleScopedClasses['w-full']} */ ;
61
+ /** @type {__VLS_StyleScopedClasses['h-full']} */ ;
62
+ /** @type {__VLS_StyleScopedClasses['py-10']} */ ;
63
+ /** @type {__VLS_StyleScopedClasses['text-center']} */ ;
64
+ /** @type {__VLS_StyleScopedClasses['w-24']} */ ;
65
+ /** @type {__VLS_StyleScopedClasses['h-24']} */ ;
66
+ /** @type {__VLS_StyleScopedClasses['flex']} */ ;
67
+ /** @type {__VLS_StyleScopedClasses['items-center']} */ ;
68
+ /** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
69
+ /** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
70
+ /** @type {__VLS_StyleScopedClasses['bg-gray-100']} */ ;
71
+ /** @type {__VLS_StyleScopedClasses['w-10']} */ ;
72
+ /** @type {__VLS_StyleScopedClasses['h-10']} */ ;
73
+ /** @type {__VLS_StyleScopedClasses['text-gray-400']} */ ;
74
+ /** @type {__VLS_StyleScopedClasses['mt-4']} */ ;
75
+ /** @type {__VLS_StyleScopedClasses['text-3xl']} */ ;
76
+ /** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
77
+ /** @type {__VLS_StyleScopedClasses['text-gray-700']} */ ;
78
+ /** @type {__VLS_StyleScopedClasses['mt-1']} */ ;
79
+ /** @type {__VLS_StyleScopedClasses['text-xl']} */ ;
80
+ /** @type {__VLS_StyleScopedClasses['text-chat-haze-500']} */ ;
81
+ /** @type {__VLS_StyleScopedClasses['max-w-[700px]']} */ ;
82
+ /** @type {__VLS_StyleScopedClasses['mt-6']} */ ;
83
+ /** @type {__VLS_StyleScopedClasses['px-4']} */ ;
84
+ /** @type {__VLS_StyleScopedClasses['py-2']} */ ;
85
+ /** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
86
+ /** @type {__VLS_StyleScopedClasses['h-14']} */ ;
87
+ /** @type {__VLS_StyleScopedClasses['w-[150px]']} */ ;
88
+ /** @type {__VLS_StyleScopedClasses['bg-chat-primary']} */ ;
89
+ /** @type {__VLS_StyleScopedClasses['text-white']} */ ;
90
+ /** @type {__VLS_StyleScopedClasses['text-lg']} */ ;
91
+ /** @type {__VLS_StyleScopedClasses['font-semibold']} */ ;
92
+ /** @type {__VLS_StyleScopedClasses['hover:bg-blue-700']} */ ;
93
+ /** @type {__VLS_StyleScopedClasses['transition']} */ ;
94
+ const __VLS_export = (await import('vue')).defineComponent({
95
+ __typeEmits: {},
96
+ __typeProps: {},
97
+ props: {},
98
+ });
99
+ export default {};
@@ -12,6 +12,7 @@ export type IConversation = {
12
12
  status: number;
13
13
  color: string;
14
14
  is_unknown: number;
15
+ customer_id?: number;
15
16
  };
16
17
  export type IParamGetConversation = {
17
18
  page?: number;
@@ -0,0 +1,7 @@
1
+ export declare function setCache(key: string, data: any, ttlMs?: number): void;
2
+ export declare function getCache<T = any>(key: string): {
3
+ data: T | null;
4
+ needReload?: boolean;
5
+ };
6
+ export declare function clearCache(key: string): void;
7
+ export declare function removeOldestCache(limit: number, prefix: string): void;
@@ -2,6 +2,7 @@ import type { IConversation, IParamGetConversation } from '../../types/conversat
2
2
  import type { DataWithMetaResponse } from '../../types/global';
3
3
  import type { IResUser } from '../../types/message';
4
4
  export declare const getConversation: (param: IParamGetConversation) => Promise<DataWithMetaResponse<IConversation[]>>;
5
+ export declare const getConversationView: (id: any) => Promise<IConversation>;
5
6
  export declare const publicTopicConversationUpdate: (data: {
6
7
  infoUser: IResUser | null;
7
8
  isSendImg?: boolean;
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ isLib: boolean;
3
+ };
4
+ declare const _default: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
5
+ tryAgain: () => any;
6
+ }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
7
+ onTryAgain?: (() => any) | undefined;
8
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phonghq/go-chat",
3
- "version": "1.0.42",
3
+ "version": "1.0.43",
4
4
  "private": false,
5
5
  "files": [
6
6
  "dist"