@uzum-tech/ui 1.10.0 → 1.11.0
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/index.js +1269 -207
- package/dist/index.prod.js +3 -3
- package/es/_internal/index.d.ts +2 -0
- package/es/_internal/index.js +1 -0
- package/es/_internal/safe-top-scrollbar/index.d.ts +2 -0
- package/es/_internal/safe-top-scrollbar/index.js +1 -0
- package/es/_internal/safe-top-scrollbar/src/SafeTopScrollbar.d.ts +356 -0
- package/es/_internal/safe-top-scrollbar/src/SafeTopScrollbar.js +708 -0
- package/es/_internal/safe-top-scrollbar/src/styles/index.cssr.d.ts +2 -0
- package/es/_internal/safe-top-scrollbar/src/styles/index.cssr.js +80 -0
- package/es/_internal/safe-top-scrollbar/src/styles/rtl.cssr.d.ts +2 -0
- package/es/_internal/safe-top-scrollbar/src/styles/rtl.cssr.js +10 -0
- package/es/_internal/safe-top-scrollbar/styles/common.d.ts +7 -0
- package/es/_internal/safe-top-scrollbar/styles/common.js +7 -0
- package/es/_internal/safe-top-scrollbar/styles/dark.d.ts +3 -0
- package/es/_internal/safe-top-scrollbar/styles/dark.js +8 -0
- package/es/_internal/safe-top-scrollbar/styles/index.d.ts +4 -0
- package/es/_internal/safe-top-scrollbar/styles/index.js +3 -0
- package/es/_internal/safe-top-scrollbar/styles/light.d.ts +18 -0
- package/es/_internal/safe-top-scrollbar/styles/light.js +12 -0
- package/es/_internal/safe-top-scrollbar/styles/rtl.d.ts +3 -0
- package/es/_internal/safe-top-scrollbar/styles/rtl.js +6 -0
- package/es/chat/src/Chat.d.ts +14 -1
- package/es/chat/src/Chat.js +5 -0
- package/es/chat/src/ChatListItems.js +16 -1
- package/es/chat/src/ChatParts/ChatAttachment.js +31 -3
- package/es/chat/src/ChatParts/MainArea.js +68 -62
- package/es/chat/src/interface.d.ts +6 -2
- package/es/components.d.ts +1 -0
- package/es/components.js +1 -0
- package/es/config-provider/src/internal-interface.d.ts +2 -0
- package/es/drawer/src/Drawer.d.ts +18 -0
- package/es/drawer/src/Drawer.js +28 -26
- package/es/drawer/src/DrawerBodyWrapper.d.ts +8 -0
- package/es/drawer/src/DrawerBodyWrapper.js +36 -8
- package/es/infinite-scroll/src/InfiniteScroll.d.ts +16 -0
- package/es/infinite-scroll/src/InfiniteScroll.js +48 -12
- package/es/safe-top-scrollbar/index.d.ts +2 -0
- package/es/safe-top-scrollbar/index.js +1 -0
- package/es/safe-top-scrollbar/src/SafeTopScrollbar.d.ts +177 -0
- package/es/safe-top-scrollbar/src/SafeTopScrollbar.js +38 -0
- package/es/themes/dark.js +2 -0
- package/es/themes/light.js +2 -0
- package/es/version.d.ts +1 -1
- package/es/version.js +1 -1
- package/lib/_internal/index.d.ts +2 -0
- package/lib/_internal/index.js +4 -1
- package/lib/_internal/safe-top-scrollbar/index.d.ts +2 -0
- package/lib/_internal/safe-top-scrollbar/index.js +9 -0
- package/lib/_internal/safe-top-scrollbar/src/SafeTopScrollbar.d.ts +356 -0
- package/lib/_internal/safe-top-scrollbar/src/SafeTopScrollbar.js +714 -0
- package/lib/_internal/safe-top-scrollbar/src/styles/index.cssr.d.ts +2 -0
- package/lib/_internal/safe-top-scrollbar/src/styles/index.cssr.js +85 -0
- package/lib/_internal/safe-top-scrollbar/src/styles/rtl.cssr.d.ts +2 -0
- package/lib/_internal/safe-top-scrollbar/src/styles/rtl.cssr.js +15 -0
- package/lib/_internal/safe-top-scrollbar/styles/common.d.ts +7 -0
- package/lib/_internal/safe-top-scrollbar/styles/common.js +10 -0
- package/lib/_internal/safe-top-scrollbar/styles/dark.d.ts +3 -0
- package/lib/_internal/safe-top-scrollbar/styles/dark.js +10 -0
- package/lib/_internal/safe-top-scrollbar/styles/index.d.ts +4 -0
- package/lib/_internal/safe-top-scrollbar/styles/index.js +12 -0
- package/lib/_internal/safe-top-scrollbar/styles/light.d.ts +18 -0
- package/lib/_internal/safe-top-scrollbar/styles/light.js +16 -0
- package/lib/_internal/safe-top-scrollbar/styles/rtl.d.ts +3 -0
- package/lib/_internal/safe-top-scrollbar/styles/rtl.js +12 -0
- package/lib/chat/src/Chat.d.ts +14 -1
- package/lib/chat/src/Chat.js +5 -0
- package/lib/chat/src/ChatListItems.js +16 -1
- package/lib/chat/src/ChatParts/ChatAttachment.js +30 -2
- package/lib/chat/src/ChatParts/MainArea.js +68 -62
- package/lib/chat/src/interface.d.ts +6 -2
- package/lib/components.d.ts +1 -0
- package/lib/components.js +1 -0
- package/lib/config-provider/src/internal-interface.d.ts +2 -0
- package/lib/drawer/src/Drawer.d.ts +18 -0
- package/lib/drawer/src/Drawer.js +28 -26
- package/lib/drawer/src/DrawerBodyWrapper.d.ts +8 -0
- package/lib/drawer/src/DrawerBodyWrapper.js +36 -8
- package/lib/infinite-scroll/src/InfiniteScroll.d.ts +16 -0
- package/lib/infinite-scroll/src/InfiniteScroll.js +47 -11
- package/lib/safe-top-scrollbar/index.d.ts +2 -0
- package/lib/safe-top-scrollbar/index.js +9 -0
- package/lib/safe-top-scrollbar/src/SafeTopScrollbar.d.ts +177 -0
- package/lib/safe-top-scrollbar/src/SafeTopScrollbar.js +41 -0
- package/lib/themes/dark.js +5 -0
- package/lib/themes/light.js +5 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +6 -6
- package/volar.d.ts +1 -0
- package/web-types.json +67 -2
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { fadeInTransition } from '../../../../_styles/transitions/fade-in.cssr';
|
|
2
|
+
import { c, cB, cE, cM } from '../../../../_utils/cssr';
|
|
3
|
+
// vars:
|
|
4
|
+
// --u-scrollbar-bezier
|
|
5
|
+
// --u-scrollbar-color
|
|
6
|
+
// --u-scrollbar-color-hover
|
|
7
|
+
// --u-scrollbar-width
|
|
8
|
+
// --u-scrollbar-height
|
|
9
|
+
// --u-scrollbar-border-radius
|
|
10
|
+
// --u-scrollbar-rail-inset-horizontal
|
|
11
|
+
// --u-scrollbar-rail-inset-vertical
|
|
12
|
+
// --u-scrollbar-rail-color
|
|
13
|
+
export default cB('safe-top-scrollbar', `
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
position: relative;
|
|
16
|
+
z-index: auto;
|
|
17
|
+
height: 100%;
|
|
18
|
+
width: 100%;
|
|
19
|
+
`, [c('>', [cB('scrollbar-container', `
|
|
20
|
+
width: 100%;
|
|
21
|
+
overflow: scroll;
|
|
22
|
+
height: 100%;
|
|
23
|
+
min-height: inherit;
|
|
24
|
+
max-height: inherit;
|
|
25
|
+
scrollbar-width: none;
|
|
26
|
+
`, [c('&::-webkit-scrollbar, &::-webkit-scrollbar-track-piece, &::-webkit-scrollbar-thumb', `
|
|
27
|
+
width: 0;
|
|
28
|
+
height: 0;
|
|
29
|
+
display: none;
|
|
30
|
+
`), c('>', [
|
|
31
|
+
// We can't set overflow hidden since it affects positioning.
|
|
32
|
+
cB('scrollbar-content', `
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
min-width: 100%;
|
|
35
|
+
`)])])]), c('>, +', [cB('scrollbar-rail', `
|
|
36
|
+
position: absolute;
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
user-select: none;
|
|
39
|
+
background: var(--u-scrollbar-rail-color);
|
|
40
|
+
-webkit-user-select: none;
|
|
41
|
+
`, [cM('horizontal', `
|
|
42
|
+
height: var(--u-scrollbar-height);
|
|
43
|
+
`, [c('>', [cE('scrollbar', `
|
|
44
|
+
height: var(--u-scrollbar-height);
|
|
45
|
+
border-radius: var(--u-scrollbar-border-radius);
|
|
46
|
+
right: 0;
|
|
47
|
+
`)])]), cM('horizontal--top', `
|
|
48
|
+
top: var(--u-scrollbar-rail-top-horizontal-top);
|
|
49
|
+
right: var(--u-scrollbar-rail-right-horizontal-top);
|
|
50
|
+
bottom: var(--u-scrollbar-rail-bottom-horizontal-top);
|
|
51
|
+
left: var(--u-scrollbar-rail-left-horizontal-top);
|
|
52
|
+
`), cM('horizontal--bottom', `
|
|
53
|
+
top: var(--u-scrollbar-rail-top-horizontal-bottom);
|
|
54
|
+
right: var(--u-scrollbar-rail-right-horizontal-bottom);
|
|
55
|
+
bottom: var(--u-scrollbar-rail-bottom-horizontal-bottom);
|
|
56
|
+
left: var(--u-scrollbar-rail-left-horizontal-bottom);
|
|
57
|
+
`), cM('vertical', `
|
|
58
|
+
width: var(--u-scrollbar-width);
|
|
59
|
+
`, [c('>', [cE('scrollbar', `
|
|
60
|
+
width: var(--u-scrollbar-width);
|
|
61
|
+
border-radius: var(--u-scrollbar-border-radius);
|
|
62
|
+
bottom: 0;
|
|
63
|
+
`)])]), cM('vertical--left', `
|
|
64
|
+
top: var(--u-scrollbar-rail-top-vertical-left);
|
|
65
|
+
right: var(--u-scrollbar-rail-right-vertical-left);
|
|
66
|
+
bottom: var(--u-scrollbar-rail-bottom-vertical-left);
|
|
67
|
+
left: var(--u-scrollbar-rail-left-vertical-left);
|
|
68
|
+
`), cM('vertical--right', `
|
|
69
|
+
top: var(--u-scrollbar-rail-top-vertical-right);
|
|
70
|
+
right: var(--u-scrollbar-rail-right-vertical-right);
|
|
71
|
+
bottom: var(--u-scrollbar-rail-bottom-vertical-right);
|
|
72
|
+
left: var(--u-scrollbar-rail-left-vertical-right);
|
|
73
|
+
`), cM('disabled', [c('>', [cE('scrollbar', 'pointer-events: none;')])]), c('>', [cE('scrollbar', `
|
|
74
|
+
z-index: 1;
|
|
75
|
+
position: absolute;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
pointer-events: all;
|
|
78
|
+
background-color: var(--u-scrollbar-color);
|
|
79
|
+
transition: background-color .2s var(--u-scrollbar-bezier);
|
|
80
|
+
`, [fadeInTransition(), c('&:hover', 'background-color: var(--u-scrollbar-color-hover);')])])])])]);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { cB, c, cM, cE } from '../../../../_utils/cssr';
|
|
2
|
+
export default cB('scrollbar', [cM('rtl', `
|
|
3
|
+
direction: rtl;
|
|
4
|
+
`, [c('>', [cB('scrollbar-rail', [cM('horizontal', [c('>', [cE('scrollbar', `
|
|
5
|
+
left: 0;
|
|
6
|
+
right: unset;
|
|
7
|
+
`)])]), cM('vertical', `
|
|
8
|
+
left: 4px;
|
|
9
|
+
right: unset;
|
|
10
|
+
`)])])])]);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ThemeCommonVars } from '../../../_styles/common';
|
|
2
|
+
import type { Theme } from '../../../_mixins';
|
|
3
|
+
export declare const self: (vars: ThemeCommonVars) => {
|
|
4
|
+
height: string;
|
|
5
|
+
width: string;
|
|
6
|
+
borderRadius: string;
|
|
7
|
+
color: string;
|
|
8
|
+
colorHover: string;
|
|
9
|
+
railInsetHorizontalBottom: string;
|
|
10
|
+
railInsetHorizontalTop: string;
|
|
11
|
+
railInsetVerticalRight: string;
|
|
12
|
+
railInsetVerticalLeft: string;
|
|
13
|
+
railColor: string;
|
|
14
|
+
};
|
|
15
|
+
export type SafeTopScrollbarThemeVars = ReturnType<typeof self>;
|
|
16
|
+
declare const safeTopScrollbarLight: Theme<'SafeTopScrollbar', SafeTopScrollbarThemeVars>;
|
|
17
|
+
export default safeTopScrollbarLight;
|
|
18
|
+
export type SafeTopScrollbarTheme = typeof safeTopScrollbarLight;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { commonLight } from '../../../_styles/common';
|
|
2
|
+
import { commonVars } from './common';
|
|
3
|
+
export const self = (vars) => {
|
|
4
|
+
const { scrollbarColor, scrollbarColorHover, scrollbarHeight, scrollbarWidth, scrollbarBorderRadius } = vars;
|
|
5
|
+
return Object.assign(Object.assign({}, commonVars), { height: scrollbarHeight, width: scrollbarWidth, borderRadius: scrollbarBorderRadius, color: scrollbarColor, colorHover: scrollbarColorHover });
|
|
6
|
+
};
|
|
7
|
+
const safeTopScrollbarLight = {
|
|
8
|
+
name: 'SafeTopScrollbar',
|
|
9
|
+
common: commonLight,
|
|
10
|
+
self
|
|
11
|
+
};
|
|
12
|
+
export default safeTopScrollbarLight;
|
package/es/chat/src/Chat.d.ts
CHANGED
|
@@ -191,6 +191,10 @@ export declare const chatProps: {
|
|
|
191
191
|
type: PropType<ChatPropsType["onAttachmentUpload"]>;
|
|
192
192
|
default: undefined;
|
|
193
193
|
};
|
|
194
|
+
onAttachmentDownload: {
|
|
195
|
+
type: PropType<ChatPropsType["onAttachmentDownload"]>;
|
|
196
|
+
default: undefined;
|
|
197
|
+
};
|
|
194
198
|
onFilterChange: {
|
|
195
199
|
type: PropType<ChatPropsType["onFilterChange"]>;
|
|
196
200
|
default: undefined;
|
|
@@ -2413,6 +2417,10 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
2413
2417
|
type: PropType<ChatPropsType["onAttachmentUpload"]>;
|
|
2414
2418
|
default: undefined;
|
|
2415
2419
|
};
|
|
2420
|
+
onAttachmentDownload: {
|
|
2421
|
+
type: PropType<ChatPropsType["onAttachmentDownload"]>;
|
|
2422
|
+
default: undefined;
|
|
2423
|
+
};
|
|
2416
2424
|
onFilterChange: {
|
|
2417
2425
|
type: PropType<ChatPropsType["onFilterChange"]>;
|
|
2418
2426
|
default: undefined;
|
|
@@ -5652,6 +5660,10 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
5652
5660
|
type: PropType<ChatPropsType["onAttachmentUpload"]>;
|
|
5653
5661
|
default: undefined;
|
|
5654
5662
|
};
|
|
5663
|
+
onAttachmentDownload: {
|
|
5664
|
+
type: PropType<ChatPropsType["onAttachmentDownload"]>;
|
|
5665
|
+
default: undefined;
|
|
5666
|
+
};
|
|
5655
5667
|
onFilterChange: {
|
|
5656
5668
|
type: PropType<ChatPropsType["onFilterChange"]>;
|
|
5657
5669
|
default: undefined;
|
|
@@ -7716,6 +7728,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
7716
7728
|
onChatItemsScrollToBottom: () => void;
|
|
7717
7729
|
messages: ChatMessageData[] | undefined;
|
|
7718
7730
|
onMessageRetry: ((message: ChatMessageData) => void) | undefined;
|
|
7731
|
+
onAttachmentUpload: import("./interface").OnAttachmentUpload | undefined;
|
|
7719
7732
|
onChatClose: () => void;
|
|
7720
7733
|
onChatShare: () => void;
|
|
7721
7734
|
onUserProfile: () => void;
|
|
@@ -7749,7 +7762,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
7749
7762
|
chatItemsLoadingCount: number | undefined;
|
|
7750
7763
|
messagesLoading: boolean | undefined;
|
|
7751
7764
|
messagesLoadingCount: number | undefined;
|
|
7752
|
-
|
|
7765
|
+
onAttachmentDownload: import("./interface").OnAttachmentDownload | undefined;
|
|
7753
7766
|
onFilterChange: import("./interface").OnFilterChange | undefined;
|
|
7754
7767
|
onNetworkError: import("./interface").OnNetworkError | undefined;
|
|
7755
7768
|
onUploadError: import("./interface").OnUploadError | undefined;
|
package/es/chat/src/Chat.js
CHANGED
|
@@ -148,6 +148,9 @@ export const chatProps = Object.assign(Object.assign({}, useTheme.props), { chat
|
|
|
148
148
|
}, onAttachmentUpload: {
|
|
149
149
|
type: Function,
|
|
150
150
|
default: undefined
|
|
151
|
+
}, onAttachmentDownload: {
|
|
152
|
+
type: Function,
|
|
153
|
+
default: undefined
|
|
151
154
|
}, onFilterChange: {
|
|
152
155
|
type: Function,
|
|
153
156
|
default: undefined
|
|
@@ -394,6 +397,8 @@ export default defineComponent({
|
|
|
394
397
|
handleNetworkError,
|
|
395
398
|
handleUploadError,
|
|
396
399
|
handleSendError,
|
|
400
|
+
onAttachmentUpload: toRef(props, 'onAttachmentUpload'),
|
|
401
|
+
onAttachmentDownload: toRef(props, 'onAttachmentDownload'),
|
|
397
402
|
onChatClose: toRef(props, 'onChatClose'),
|
|
398
403
|
onChatShare: toRef(props, 'onChatShare'),
|
|
399
404
|
onUserProfile: toRef(props, 'onUserProfile'),
|
|
@@ -90,11 +90,26 @@ export default defineComponent({
|
|
|
90
90
|
var _a;
|
|
91
91
|
(_a = props.onChatSelect) === null || _a === void 0 ? void 0 : _a.call(props, chatId);
|
|
92
92
|
};
|
|
93
|
+
const toKeyString = (value) => {
|
|
94
|
+
if (typeof value === 'symbol')
|
|
95
|
+
return value.toString();
|
|
96
|
+
if (typeof value === 'function') {
|
|
97
|
+
const result = value();
|
|
98
|
+
return typeof result === 'string' || typeof result === 'number'
|
|
99
|
+
? String(result)
|
|
100
|
+
: '';
|
|
101
|
+
}
|
|
102
|
+
return value != null ? String(value) : '';
|
|
103
|
+
};
|
|
93
104
|
const renderChatItem = (item) => {
|
|
94
105
|
var _a, _b;
|
|
95
106
|
const isSelected = props.selectedChatId === item.id;
|
|
96
107
|
const isTyping = (_b = (_a = props.typingChatIds) === null || _a === void 0 ? void 0 : _a.includes(item.id)) !== null && _b !== void 0 ? _b : false;
|
|
97
|
-
|
|
108
|
+
const { id, title, subtitle } = item;
|
|
109
|
+
const keyId = toKeyString(id);
|
|
110
|
+
const keyTitle = toKeyString(title);
|
|
111
|
+
const keySubtitle = toKeyString(subtitle);
|
|
112
|
+
return (h(UListItem, { key: `${keyId}-${keyTitle}-${keySubtitle}`, showIcon: false, onClick: () => {
|
|
98
113
|
handleChatSelect(item.id);
|
|
99
114
|
}, class: [
|
|
100
115
|
`${mergedClsPrefixRef.value}-chat-sidebar__item`,
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { h, defineComponent, inject } from 'vue';
|
|
2
11
|
import { UUpload, UUploadFileList } from '../../../upload';
|
|
12
|
+
import { chatInjectionKey } from '../interface';
|
|
3
13
|
export default defineComponent({
|
|
4
14
|
name: 'ChatAttachment',
|
|
5
15
|
props: {
|
|
@@ -21,10 +31,28 @@ export default defineComponent({
|
|
|
21
31
|
}
|
|
22
32
|
},
|
|
23
33
|
setup(props, { slots }) {
|
|
34
|
+
const UChat = inject(chatInjectionKey, null);
|
|
35
|
+
const onAttachmentDownload = UChat === null || UChat === void 0 ? void 0 : UChat.onAttachmentDownload;
|
|
24
36
|
const getThumbnailUrl = (attachment) => {
|
|
25
37
|
const url = [attachment.preview, attachment.thumbnail].find((value) => typeof value === 'string');
|
|
26
38
|
return url !== null && url !== void 0 ? url : null;
|
|
27
39
|
};
|
|
40
|
+
const handleDownload = (file) => __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
if (onAttachmentDownload === null || onAttachmentDownload === void 0 ? void 0 : onAttachmentDownload.value) {
|
|
42
|
+
const attachment = props.attachments.find((att) => att.name === file.name);
|
|
43
|
+
if (attachment) {
|
|
44
|
+
try {
|
|
45
|
+
yield onAttachmentDownload.value(attachment);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('Download failed:', error);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
});
|
|
28
56
|
const renderAttachment = () => {
|
|
29
57
|
const fileList = props.attachments.map((attachment, index) => {
|
|
30
58
|
var _a, _b, _c;
|
|
@@ -40,7 +68,7 @@ export default defineComponent({
|
|
|
40
68
|
batchId: null
|
|
41
69
|
});
|
|
42
70
|
});
|
|
43
|
-
const uploadComponent = (h(UUpload, Object.assign({ abstract: true, fileList: fileList, fileListStyle: props.withPadding
|
|
71
|
+
const uploadComponent = (h(UUpload, Object.assign({ abstract: true }, props.uploadProps, { fileList: fileList, fileListStyle: props.withPadding
|
|
44
72
|
? {
|
|
45
73
|
display: 'flex',
|
|
46
74
|
flexDirection: 'column',
|
|
@@ -49,7 +77,7 @@ export default defineComponent({
|
|
|
49
77
|
}
|
|
50
78
|
: undefined, showRemoveButton: false, showDownloadButton: props.attachments.some((attachment) => attachment.status === 'finished' &&
|
|
51
79
|
attachment.url &&
|
|
52
|
-
attachment.url !== '#'), showRetryButton: props.attachments.some((attachment) => attachment.status === 'error') }
|
|
80
|
+
attachment.url !== '#'), showRetryButton: props.attachments.some((attachment) => attachment.status === 'error'), onDownload: handleDownload }), {
|
|
53
81
|
default: () => (h(UUploadFileList, null, {
|
|
54
82
|
'upload-file-title': slots['upload-file-title']
|
|
55
83
|
? ({ file }) => { var _a; return (_a = slots['upload-file-title']) === null || _a === void 0 ? void 0 : _a.call(slots, file); }
|
|
@@ -12,7 +12,7 @@ import { MessageStatus, ChatMessageType, chatInjectionKey } from '../interface';
|
|
|
12
12
|
import { UInput } from '../../../input';
|
|
13
13
|
import { UButton } from '../../../button';
|
|
14
14
|
import { UIcon } from '../../../icon';
|
|
15
|
-
import {
|
|
15
|
+
import { USafeTopScrollbar } from '../../../safe-top-scrollbar';
|
|
16
16
|
import { UTooltip } from '../../../tooltip';
|
|
17
17
|
import { UUpload, UUploadTrigger } from '../../../upload';
|
|
18
18
|
import { UFlex } from '../../../flex';
|
|
@@ -24,13 +24,14 @@ const SENDING_DELAY = 100;
|
|
|
24
24
|
export default defineComponent({
|
|
25
25
|
name: 'ChatMainArea',
|
|
26
26
|
setup(_, { slots }) {
|
|
27
|
-
const { mergedClsPrefixRef, mergedThemeRef, selectedChatRef, messagesRef, typingChatIdsRef, messagesLoadingRef, messagesLoadingCountRef, headerButtonPropsRef, headerIconPropsRef, headerShareButtonPropsRef, headerProfileButtonPropsRef, headerCloseButtonPropsRef, headerShareIconPropsRef, headerProfileIconPropsRef, messageUploadPropsRef, footerInputPropsRef, footerButtonPropsRef, footerUploadPropsRef, footerIconPropsRef, inputPlaceholderRef, retryTextRef, typingTextRef, closeButtonTextRef, shareButtonTooltipRef, profileButtonTooltipRef, unreadNotificationTextRef, notificationsShownSetRef, unreadCountsBeforeReadRef, markNotificationShown, handleMessageSend, handleMessageRetry, handleFooterInputChange, onChatClose, onChatShare, onUserProfile, onMessagesScrollToTop, onMessagesScrollToBottom
|
|
27
|
+
const { mergedClsPrefixRef, mergedThemeRef, selectedChatRef, messagesRef, typingChatIdsRef, messagesLoadingRef, messagesLoadingCountRef, headerButtonPropsRef, headerIconPropsRef, headerShareButtonPropsRef, headerProfileButtonPropsRef, headerCloseButtonPropsRef, headerShareIconPropsRef, headerProfileIconPropsRef, messageUploadPropsRef, footerInputPropsRef, footerButtonPropsRef, footerUploadPropsRef, footerIconPropsRef, inputPlaceholderRef, retryTextRef, typingTextRef, closeButtonTextRef, shareButtonTooltipRef, profileButtonTooltipRef, unreadNotificationTextRef, notificationsShownSetRef, unreadCountsBeforeReadRef, markNotificationShown, handleMessageSend, handleMessageRetry, handleFooterInputChange, onAttachmentUpload, onChatClose, onChatShare, onUserProfile, onMessagesScrollToTop, onMessagesScrollToBottom
|
|
28
28
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
29
29
|
} = inject(chatInjectionKey);
|
|
30
30
|
const messagesBodyRef = ref();
|
|
31
31
|
const inputRef = ref();
|
|
32
32
|
const inputValue = ref('');
|
|
33
33
|
const attachmentFileList = ref([]);
|
|
34
|
+
const uploadedAttachmentsMap = ref(new Map());
|
|
34
35
|
const lastScrollTop = ref(0);
|
|
35
36
|
const scrollTopFired = ref(false);
|
|
36
37
|
const scrollBottomFired = ref(false);
|
|
@@ -55,6 +56,8 @@ export default defineComponent({
|
|
|
55
56
|
scrollTopFired.value = false;
|
|
56
57
|
scrollBottomFired.value = false;
|
|
57
58
|
shouldScrollOnLoad.value = true;
|
|
59
|
+
attachmentFileList.value = [];
|
|
60
|
+
uploadedAttachmentsMap.value.clear();
|
|
58
61
|
if (unreadBeforeRead > 0 &&
|
|
59
62
|
!notificationsShownSetRef.value.has(newChat.id)) {
|
|
60
63
|
hasUnreadMessages.value = true;
|
|
@@ -153,22 +156,36 @@ export default defineComponent({
|
|
|
153
156
|
el.scrollTop = el.scrollHeight;
|
|
154
157
|
}
|
|
155
158
|
};
|
|
159
|
+
const toKeyString = (value) => {
|
|
160
|
+
if (typeof value === 'symbol')
|
|
161
|
+
return value.toString();
|
|
162
|
+
if (typeof value === 'function') {
|
|
163
|
+
const result = value();
|
|
164
|
+
return typeof result === 'string' || typeof result === 'number'
|
|
165
|
+
? String(result)
|
|
166
|
+
: '';
|
|
167
|
+
}
|
|
168
|
+
return value != null ? String(value) : '';
|
|
169
|
+
};
|
|
156
170
|
const renderHeader = () => {
|
|
157
171
|
return (h("div", { class: `${mergedClsPrefixRef.value}-chat-main__header` },
|
|
158
172
|
h(UFlex, { justify: "space-between", align: "flex-start", wrap: false }, {
|
|
159
|
-
default: () =>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
h(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
default: () => {
|
|
174
|
+
const chat = selectedChatRef.value;
|
|
175
|
+
const keyId = toKeyString(chat === null || chat === void 0 ? void 0 : chat.id);
|
|
176
|
+
const keyTitle = toKeyString(chat === null || chat === void 0 ? void 0 : chat.title);
|
|
177
|
+
return (h(Fragment, null,
|
|
178
|
+
h(UText, { key: `${keyId}-${keyTitle}`, variant: "heading-s-bold", class: `${mergedClsPrefixRef.value}-chat-main__header-title`, theme: mergedThemeRef.value.peers.Typography, themeOverrides: mergedThemeRef.value.peerOverrides.Typography }, {
|
|
179
|
+
default: () => { var _a, _b; return (_b = (_a = selectedChatRef.value) === null || _a === void 0 ? void 0 : _a.title) !== null && _b !== void 0 ? _b : ''; }
|
|
180
|
+
}),
|
|
181
|
+
h(UFlex, { align: "center", size: "small", class: `${mergedClsPrefixRef.value}-chat-main__header-actions` }, {
|
|
182
|
+
default: () => resolveSlot(slots.headerActions, () => {
|
|
183
|
+
const shareButtonProps = Object.assign(Object.assign({}, headerButtonPropsRef.value), headerShareButtonPropsRef.value);
|
|
184
|
+
const profileButtonProps = Object.assign(Object.assign({}, headerButtonPropsRef.value), headerProfileButtonPropsRef.value);
|
|
185
|
+
const closeButtonProps = Object.assign(Object.assign({}, headerButtonPropsRef.value), headerCloseButtonPropsRef.value);
|
|
186
|
+
const shareIconProps = Object.assign(Object.assign({}, headerIconPropsRef.value), headerShareIconPropsRef.value);
|
|
187
|
+
const profileIconProps = Object.assign(Object.assign({}, headerIconPropsRef.value), headerProfileIconPropsRef.value);
|
|
188
|
+
const buttons = [];
|
|
172
189
|
buttons.push(h(UTooltip, null, {
|
|
173
190
|
trigger: () => (h(UButton, Object.assign({ secondary: true, circle: true, size: "large" }, shareButtonProps, { theme: mergedThemeRef.value.peers.Button, themeOverrides: mergedThemeRef.value.peerOverrides
|
|
174
191
|
.Button, onClick: () => { var _a; return (_a = onChatShare === null || onChatShare === void 0 ? void 0 : onChatShare.value) === null || _a === void 0 ? void 0 : _a.call(onChatShare); } }), {
|
|
@@ -179,8 +196,6 @@ export default defineComponent({
|
|
|
179
196
|
})),
|
|
180
197
|
default: () => shareButtonTooltipRef.value
|
|
181
198
|
}));
|
|
182
|
-
}
|
|
183
|
-
if (profileButtonProps.disabled !== true) {
|
|
184
199
|
buttons.push(h(UTooltip, null, {
|
|
185
200
|
trigger: () => (h(UButton, Object.assign({ secondary: true, circle: true, size: "large" }, profileButtonProps, { theme: mergedThemeRef.value.peers.Button, themeOverrides: mergedThemeRef.value.peerOverrides
|
|
186
201
|
.Button, onClick: () => { var _a; return (_a = onUserProfile === null || onUserProfile === void 0 ? void 0 : onUserProfile.value) === null || _a === void 0 ? void 0 : _a.call(onUserProfile); } }), {
|
|
@@ -191,15 +206,13 @@ export default defineComponent({
|
|
|
191
206
|
})),
|
|
192
207
|
default: () => profileButtonTooltipRef.value
|
|
193
208
|
}));
|
|
194
|
-
}
|
|
195
|
-
if (closeButtonProps.disabled !== true) {
|
|
196
209
|
buttons.push(h(UButton, Object.assign({ type: "primary", size: "large", round: true }, closeButtonProps, { theme: mergedThemeRef.value.peers.Button, themeOverrides: mergedThemeRef.value.peerOverrides.Button, onClick: () => { var _a; return (_a = onChatClose === null || onChatClose === void 0 ? void 0 : onChatClose.value) === null || _a === void 0 ? void 0 : _a.call(onChatClose); } }), {
|
|
197
210
|
default: () => closeButtonTextRef.value
|
|
198
211
|
}));
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
})
|
|
202
|
-
|
|
212
|
+
return buttons;
|
|
213
|
+
})
|
|
214
|
+
})));
|
|
215
|
+
}
|
|
203
216
|
})));
|
|
204
217
|
};
|
|
205
218
|
const renderMessages = () => {
|
|
@@ -226,7 +239,11 @@ export default defineComponent({
|
|
|
226
239
|
const attachments = attachmentFileList.value.length > 0
|
|
227
240
|
? attachmentFileList.value.map((file) => {
|
|
228
241
|
var _a, _b, _c;
|
|
229
|
-
|
|
242
|
+
const uploadedAttachment = uploadedAttachmentsMap.value.get(file.id);
|
|
243
|
+
if (uploadedAttachment) {
|
|
244
|
+
return uploadedAttachment;
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
230
247
|
id: file.id,
|
|
231
248
|
type: ChatMessageType.FILE,
|
|
232
249
|
name: file.name,
|
|
@@ -236,13 +253,14 @@ export default defineComponent({
|
|
|
236
253
|
thumbnail: (_b = file.thumbnailUrl) !== null && _b !== void 0 ? _b : undefined,
|
|
237
254
|
status: file.status,
|
|
238
255
|
percentage: (_c = file.percentage) !== null && _c !== void 0 ? _c : undefined
|
|
239
|
-
}
|
|
256
|
+
};
|
|
240
257
|
})
|
|
241
258
|
: undefined;
|
|
242
259
|
handleMessageSend(inputValue.value.trim(), attachments);
|
|
243
260
|
inputValue.value = '';
|
|
244
261
|
attachmentFileList.value = [];
|
|
245
262
|
chatInputs.value[selectedChatRef.value.id] = '';
|
|
263
|
+
uploadedAttachmentsMap.value.clear();
|
|
246
264
|
hasUnreadMessages.value = false;
|
|
247
265
|
showNotificationManually.value = false;
|
|
248
266
|
}
|
|
@@ -253,39 +271,24 @@ export default defineComponent({
|
|
|
253
271
|
}
|
|
254
272
|
}
|
|
255
273
|
});
|
|
256
|
-
let fileUploadTimer = null;
|
|
257
|
-
const pendingFiles = ref([]);
|
|
258
274
|
const handleFileListUpdate = (fileList) => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
type: ChatMessageType.FILE,
|
|
275
|
-
name: file.name,
|
|
276
|
-
url: file.url ||
|
|
277
|
-
(file.file ? URL.createObjectURL(file.file) : '#'),
|
|
278
|
-
size: (_a = file.file) === null || _a === void 0 ? void 0 : _a.size,
|
|
279
|
-
thumbnail: (_b = file.thumbnailUrl) !== null && _b !== void 0 ? _b : undefined,
|
|
280
|
-
status: batchStatus,
|
|
281
|
-
percentage: (_c = file.percentage) !== null && _c !== void 0 ? _c : undefined
|
|
282
|
-
});
|
|
283
|
-
});
|
|
284
|
-
handleMessageSend('', attachments);
|
|
285
|
-
pendingFiles.value = [];
|
|
286
|
-
attachmentFileList.value = [];
|
|
275
|
+
attachmentFileList.value = fileList;
|
|
276
|
+
const uploadCallback = onAttachmentUpload === null || onAttachmentUpload === void 0 ? void 0 : onAttachmentUpload.value;
|
|
277
|
+
if (uploadCallback) {
|
|
278
|
+
const newFiles = fileList.filter((file) => file.file && !uploadedAttachmentsMap.value.has(file.id));
|
|
279
|
+
void (() => __awaiter(this, void 0, void 0, function* () {
|
|
280
|
+
for (const uploadFile of newFiles) {
|
|
281
|
+
if (uploadFile.file) {
|
|
282
|
+
try {
|
|
283
|
+
const attachment = yield uploadCallback(uploadFile.file);
|
|
284
|
+
uploadedAttachmentsMap.value.set(uploadFile.id, attachment);
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
console.error('File upload failed:', error);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
287
290
|
}
|
|
288
|
-
}
|
|
291
|
+
}))();
|
|
289
292
|
}
|
|
290
293
|
};
|
|
291
294
|
const renderFooter = () => {
|
|
@@ -294,11 +297,14 @@ export default defineComponent({
|
|
|
294
297
|
default: () => (h(UFlex, { align: "center", size: "small", class: `${mergedClsPrefixRef.value}-chat-main__input-container` }, {
|
|
295
298
|
default: () => (h(Fragment, null,
|
|
296
299
|
h(UUploadTrigger, { abstract: true }, {
|
|
297
|
-
default: ({ handleClick }) =>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
default: ({ handleClick }) => {
|
|
301
|
+
var _a;
|
|
302
|
+
return (h(UButton, Object.assign({ secondary: true, size: "large", class: `${mergedClsPrefixRef.value}-chat-main__attach-btn` }, footerButtonPropsRef.value, { disabled: (_a = footerInputPropsRef.value) === null || _a === void 0 ? void 0 : _a.disabled, theme: mergedThemeRef.value.peers.Button, themeOverrides: mergedThemeRef.value.peerOverrides.Button, onClick: handleClick }), {
|
|
303
|
+
default: () => (h(UIcon, Object.assign({ size: 24 }, footerIconPropsRef.value, { theme: mergedThemeRef.value.peers.Icon, themeOverrides: mergedThemeRef.value.peerOverrides.Icon }), {
|
|
304
|
+
default: () => h(AttachIcon, null)
|
|
305
|
+
}))
|
|
306
|
+
}));
|
|
307
|
+
}
|
|
302
308
|
}),
|
|
303
309
|
h(UInput, Object.assign({ ref: "inputRef", value: inputValue.value, placeholder: inputPlaceholderRef.value, class: `${mergedClsPrefixRef.value}-chat-main__input` }, footerInputPropsRef.value, { theme: mergedThemeRef.value.peers.Input, themeOverrides: mergedThemeRef.value.peerOverrides.Input, onUpdateValue: (value) => {
|
|
304
310
|
inputValue.value = value;
|
|
@@ -332,7 +338,7 @@ export default defineComponent({
|
|
|
332
338
|
const { mergedClsPrefixRef } = inject(chatInjectionKey);
|
|
333
339
|
return (h("div", { class: `${mergedClsPrefixRef.value}-chat-main` },
|
|
334
340
|
this.renderHeader(),
|
|
335
|
-
h(
|
|
341
|
+
h(USafeTopScrollbar, { ref: "messagesBodyRef", class: `${mergedClsPrefixRef.value}-chat-main__body`, onScroll: this.handleMessagesScroll }, {
|
|
336
342
|
default: () => this.renderMessages()
|
|
337
343
|
}),
|
|
338
344
|
this.renderFooter()));
|
|
@@ -67,7 +67,7 @@ export interface ChatMessageData {
|
|
|
67
67
|
timestamp?: string | number | Date | (() => VNodeChild);
|
|
68
68
|
status?: MessageStatus;
|
|
69
69
|
date?: string;
|
|
70
|
-
attachment?: ChatAttachment
|
|
70
|
+
attachment?: ChatAttachment[];
|
|
71
71
|
uploadProps?: Partial<UploadProps>;
|
|
72
72
|
senderAvatar?: string | (() => VNodeChild);
|
|
73
73
|
senderName?: string | (() => VNodeChild);
|
|
@@ -80,7 +80,7 @@ export interface ChatMessageProps {
|
|
|
80
80
|
content?: string;
|
|
81
81
|
timestamp?: string | number | Date | (() => VNodeChild);
|
|
82
82
|
status?: MessageStatus;
|
|
83
|
-
attachment?: ChatAttachment
|
|
83
|
+
attachment?: ChatAttachment[];
|
|
84
84
|
uploadProps?: Partial<UploadProps>;
|
|
85
85
|
senderAvatar?: string | (() => VNodeChild);
|
|
86
86
|
senderName?: string | (() => VNodeChild);
|
|
@@ -165,6 +165,7 @@ export interface ChatProps {
|
|
|
165
165
|
onMessageSend?: OnMessageSend;
|
|
166
166
|
onMessageRetry?: (message: ChatMessageData) => void;
|
|
167
167
|
onAttachmentUpload?: OnAttachmentUpload;
|
|
168
|
+
onAttachmentDownload?: OnAttachmentDownload;
|
|
168
169
|
onFilterChange?: OnFilterChange;
|
|
169
170
|
onFooterInputChange?: (value: string, chatId: ChatId) => void;
|
|
170
171
|
onNetworkError?: OnNetworkError;
|
|
@@ -225,6 +226,7 @@ export interface ChatFooterProps {
|
|
|
225
226
|
export type OnChatSelect = (key: ChatId, item: ChatListItemData) => void;
|
|
226
227
|
export type OnMessageSend = (content: string, attachments?: ChatAttachment[]) => void;
|
|
227
228
|
export type OnAttachmentUpload = (file: File) => Promise<ChatAttachment>;
|
|
229
|
+
export type OnAttachmentDownload = (attachment: ChatAttachment) => Promise<void>;
|
|
228
230
|
export type OnFilterChange = (filter: {
|
|
229
231
|
type: string;
|
|
230
232
|
value: any;
|
|
@@ -311,6 +313,8 @@ export declare const chatInjectionKey: InjectionKey<{
|
|
|
311
313
|
message: string;
|
|
312
314
|
content: string;
|
|
313
315
|
}) => void;
|
|
316
|
+
onAttachmentUpload?: Ref<OnAttachmentUpload | undefined>;
|
|
317
|
+
onAttachmentDownload?: Ref<OnAttachmentDownload | undefined>;
|
|
314
318
|
onChatClose?: Ref<(() => void) | undefined>;
|
|
315
319
|
onChatShare?: Ref<(() => void) | undefined>;
|
|
316
320
|
onUserProfile?: Ref<(() => void) | undefined>;
|
package/es/components.d.ts
CHANGED