@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.
- package/dist/assets/icons/IconUser.vue.d.ts +2 -0
- package/dist/chat/page/home/ChatList.vue.d.ts +8 -0
- package/dist/composable/useDigibot.d.ts +1 -1
- package/dist/composable/useInitData.d.ts +4 -1
- package/dist/composable/useListConversations.d.ts +3 -0
- package/dist/go-chat.es.js +8765 -8647
- package/dist/go-chat.umd.js +15 -15
- package/dist/style.css +1 -1
- package/dist/test/assets/icons/IconUser.vue.js +25 -0
- package/dist/test/chat/App.vue.js +108 -10
- package/dist/test/chat/page/customer-detail/CustomerDetail.vue.js +2 -2
- package/dist/test/chat/page/home/ChatList.vue.js +52 -12
- package/dist/test/chat/page/home/ChatMessageItem.vue.js +12 -3
- package/dist/test/chat/page/home/Home.vue.js +14 -2
- package/dist/test/components/chat/call/Calling.vue.js +6 -4
- package/dist/test/components/chat/customer/Avatar.vue.js +23 -4
- package/dist/test/composable/useDigibot.js +3 -3
- package/dist/test/composable/useInitData.js +18 -9
- package/dist/test/composable/useListConversations.js +21 -6
- package/dist/test/utils/chat/cache.js +63 -0
- package/dist/test/utils/chat/conversation.js +7 -0
- package/dist/test/views/NotTenantPhone.vue.js +99 -0
- package/dist/types/conversation.d.ts +1 -0
- package/dist/utils/chat/cache.d.ts +7 -0
- package/dist/utils/chat/conversation.d.ts +1 -0
- package/dist/views/NotTenantPhone.vue.d.ts +9 -0
- package/package.json +1 -1
|
@@ -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 (
|
|
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?.
|
|
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 || '
|
|
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.
|
|
349
|
+
(__VLS_ctx.userRemoter?.username || __VLS_ctx.phoneNumberFormat(__VLS_ctx.userRemoter?.phone ?? ''));
|
|
348
350
|
// @ts-ignore
|
|
349
|
-
[userRemoter, userRemoter,
|
|
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() ?? '
|
|
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' :
|
|
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:
|
|
4
|
-
receiver_id:
|
|
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
|
-
|
|
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 (
|
|
56
|
-
|
|
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 {};
|
|
@@ -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;
|