@tencentcloud/chat-uikit-react 3.0.2 → 3.4.2
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/.eslintrc.cjs +5 -4
- package/CHANGELOG.md +9 -0
- package/debug/GenerateTestUserSig-es.js +26 -0
- package/debug/lib-generate-test-usersig-es.min.js +2 -0
- package/dist/components/Chat/Chat.d.ts +1 -1
- package/dist/components/Chat/Chat.js +18 -23
- package/dist/components/ChatHeader/AudioCallPicker/AudioCallPicker.d.ts +30 -0
- package/dist/components/ChatHeader/AudioCallPicker/AudioCallPicker.js +135 -0
- package/dist/components/ChatHeader/AudioCallPicker/index.d.ts +1 -0
- package/dist/components/ChatHeader/AudioCallPicker/index.js +4 -0
- package/dist/components/ChatHeader/ChatHeader.d.ts +6 -0
- package/dist/components/ChatHeader/ChatHeader.js +43 -41
- package/dist/components/ChatHeader/ChatHeaderUI/ChatHeaderUI.d.ts +14 -9
- package/dist/components/ChatHeader/ChatHeaderUI/ChatHeaderUI.js +47 -65
- package/dist/components/ChatHeader/VideoCallPicker/VideoCallPicker.d.ts +30 -0
- package/dist/components/ChatHeader/VideoCallPicker/VideoCallPicker.js +135 -0
- package/dist/components/ChatHeader/VideoCallPicker/index.d.ts +1 -0
- package/dist/components/ChatHeader/VideoCallPicker/index.js +4 -0
- package/dist/components/ChatHeader/index.d.ts +2 -1
- package/dist/components/ChatHeader/index.js +4 -2
- package/dist/components/Checkbox/index.js +1 -1
- package/dist/components/Modal/Modal.js +1 -1
- package/dist/components/Model/index.js +1 -1
- package/dist/components/Plugins/index.js +1 -1
- package/dist/components/Popup/index.js +1 -1
- package/dist/components/PopupNew/Popup.js +1 -1
- package/dist/components/Profile/Profile.js +20 -22
- package/dist/components/Profile/ProfileDefault.d.ts +3 -2
- package/dist/components/Profile/ProfileDefault.js +55 -56
- package/dist/components/Profile/hooks/useMyProfile.d.ts +2 -3
- package/dist/components/Profile/hooks/useMyProfile.js +1 -1
- package/dist/components/Profile/myProfile/MyProfile.d.ts +1 -1
- package/dist/components/Profile/myProfile/MyProfile.js +12 -16
- package/dist/components/index.js +27 -25
- package/dist/context/ChatContext.d.ts +1 -1
- package/dist/context/ChatContext.js +11 -16
- package/dist/context/ContactContext.d.ts +1 -1
- package/dist/external_modules/mui-BhvHeL5-.js +2253 -0
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.js +2 -2
- package/dist/{states/ChatHeaderState.d.ts → hooks/useChatHeader.d.ts} +6 -6
- package/dist/hooks/useChatHeader.js +41 -0
- package/dist/index-UBuvRM8r-DTXQB6zV.js +34000 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +93 -4129
- package/dist/server/mainServer.js +2 -2
- package/dist/states/UIManagerState.d.ts +5 -5
- package/dist/states/UIManagerState.js +2 -2
- package/dist/states/index.d.ts +0 -1
- package/dist/states/index.js +2 -4
- package/dist/styles/AudioCallPicker.css +1 -0
- package/dist/styles/ChatHeaderUI.css +1 -1
- package/dist/styles/VideoCallPicker.css +1 -0
- package/dist/styles/index-UBuvRM8r.css +1 -0
- package/dist/styles/index.css +1 -1
- package/dist/styles/index2.css +1 -1
- package/dist/styles/index3.css +1 -1
- package/dist/styles/index4.css +1 -1
- package/dist/styles/index5.css +1 -1
- package/dist/types/message.d.ts +1 -1
- package/dist/types/user.d.ts +4 -4
- package/package.json +12 -20
- package/src/components/ChatHeader/AudioCallPicker/AudioCallPicker.module.scss +57 -0
- package/src/components/ChatHeader/AudioCallPicker/AudioCallPicker.tsx +234 -0
- package/src/components/ChatHeader/AudioCallPicker/index.ts +1 -0
- package/src/components/ChatHeader/ChatHeader.tsx +15 -3
- package/src/components/ChatHeader/ChatHeaderUI/ChatHeaderUI.tsx +33 -40
- package/src/components/ChatHeader/VideoCallPicker/VideoCallPicker.module.scss +57 -0
- package/src/components/ChatHeader/VideoCallPicker/VideoCallPicker.tsx +233 -0
- package/src/components/ChatHeader/VideoCallPicker/index.ts +1 -0
- package/src/components/ChatHeader/index.ts +2 -1
- package/src/components/Profile/Profile.tsx +7 -6
- package/src/components/Profile/ProfileDefault.tsx +8 -8
- package/src/components/Profile/hooks/useMyProfile.tsx +2 -3
- package/src/components/Profile/myProfile/MyProfile.tsx +1 -1
- package/src/context/ChatContext.tsx +1 -1
- package/src/context/ContactContext.tsx +1 -1
- package/src/hooks/index.ts +2 -2
- package/src/{states/ChatHeaderState.ts → hooks/useChatHeader.ts} +19 -22
- package/src/index.ts +3 -5
- package/src/server/mainServer.ts +2 -2
- package/src/states/UIManagerState.ts +9 -9
- package/src/states/index.ts +0 -2
- package/src/styles/index.scss +0 -1
- package/src/types/message.ts +1 -1
- package/src/types/user.ts +4 -4
- package/vite.config.ts +4 -25
- package/dist/ChatSetting-BtQwjHr0.js +0 -28525
- package/dist/assets/fonts/iconfont.ttf +0 -0
- package/dist/assets/fonts/iconfont.woff +0 -0
- package/dist/assets/fonts/iconfont.woff2 +0 -0
- package/dist/components/ChatHeader/ChatHeaderActions/ChatHeaderActions.d.ts +0 -11
- package/dist/components/ChatHeader/ChatHeaderActions/ChatHeaderActions.js +0 -79
- package/dist/components/ChatHeader/ChatHeaderActions/index.d.ts +0 -1
- package/dist/components/ChatHeader/ChatHeaderActions/index.js +0 -4
- package/dist/components/IconFont/Icon.d.ts +0 -21
- package/dist/components/IconFont/Icon.js +0 -47
- package/dist/components/IconFont/index.d.ts +0 -2
- package/dist/components/IconFont/index.js +0 -4
- package/dist/external_modules/lodash-vwDjcXxQ.js +0 -0
- package/dist/external_modules/mui-BcA3SBHM.js +0 -2473
- package/dist/states/ChatHeaderState.js +0 -48
- package/dist/styles/ChatHeaderActions.css +0 -1
- package/dist/styles/ChatSetting.css +0 -1
- package/dist/styles/Icon2.css +0 -1
- package/src/assets/fonts/iconfont.ttf +0 -0
- package/src/assets/fonts/iconfont.woff +0 -0
- package/src/assets/fonts/iconfont.woff2 +0 -0
- package/src/components/ChatHeader/ChatHeaderActions/ChatHeaderActions.module.scss +0 -44
- package/src/components/ChatHeader/ChatHeaderActions/ChatHeaderActions.tsx +0 -105
- package/src/components/ChatHeader/ChatHeaderActions/index.ts +0 -1
- package/src/components/IconFont/Icon.module.scss +0 -42
- package/src/components/IconFont/Icon.tsx +0 -68
- package/src/components/IconFont/index.ts +0 -3
- package/src/styles/fonts/icon-font.scss +0 -18
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
-
import { useUIKit
|
|
3
|
-
import { useConversationListState, View, Avatar as DefaultAvatar, useUIOpenControlState } from 'tuikit-atomicx-react';
|
|
2
|
+
import { useUIKit } from '@tencentcloud/uikit-base-component-react';
|
|
4
3
|
import cs from 'classnames';
|
|
5
|
-
import {
|
|
4
|
+
import { View, Avatar as DefaultAvatar } from 'tuikit-atomicx-react';
|
|
5
|
+
import { AudioCallPicker } from '../AudioCallPicker';
|
|
6
|
+
import { VideoCallPicker } from '../VideoCallPicker';
|
|
6
7
|
import classes from './ChatHeaderUI.module.scss';
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import type { AvatarProps } from 'tuikit-atomicx-react';
|
|
8
|
+
import type { UserStatus } from '../../../types/user';
|
|
9
|
+
import type { ConversationModel } from 'tuikit-atomicx-react';
|
|
10
10
|
|
|
11
|
-
interface
|
|
11
|
+
interface ChatHeaderUIProps {
|
|
12
12
|
/** Custom title, if not provided, will use conversation info */
|
|
13
13
|
title: string;
|
|
14
14
|
/** Whether it's a group conversation */
|
|
@@ -18,17 +18,23 @@ interface IChatHeaderUIProps {
|
|
|
18
18
|
/** Whether the peer is typing */
|
|
19
19
|
isPeerTyping?: boolean;
|
|
20
20
|
/** user status */
|
|
21
|
-
userStatus?:
|
|
21
|
+
userStatus?: UserStatus | undefined;
|
|
22
22
|
/** Whether to show user status */
|
|
23
|
-
enableUserStatus?: boolean;
|
|
23
|
+
enableUserStatus?: boolean | undefined;
|
|
24
|
+
/** Whether to show call features */
|
|
25
|
+
enableCall?: boolean | undefined;
|
|
24
26
|
/** Whether it's a system conversation */
|
|
25
27
|
system?: boolean | undefined;
|
|
26
28
|
/** IM conversation model */
|
|
27
|
-
conversation?:
|
|
29
|
+
conversation?: ConversationModel | undefined;
|
|
28
30
|
/** Whether to show call features */
|
|
29
31
|
chatHeaderActions?: Array<'videoCall' | 'audioCall' | 'chatSetting' | 'search'> | undefined;
|
|
30
32
|
/** Custom avatar component */
|
|
31
|
-
Avatar?: React.ComponentType<
|
|
33
|
+
Avatar?: React.ComponentType<any> | undefined;
|
|
34
|
+
/** Custom left slot */
|
|
35
|
+
ChatHeaderLeft?: React.ReactNode | undefined;
|
|
36
|
+
/** Custom right slot */
|
|
37
|
+
ChatHeaderRight?: React.ReactNode | undefined;
|
|
32
38
|
/** Additional class names */
|
|
33
39
|
className?: string | undefined;
|
|
34
40
|
/** Additional style */
|
|
@@ -37,12 +43,7 @@ interface IChatHeaderUIProps {
|
|
|
37
43
|
onSearchClick?: (() => void) | undefined;
|
|
38
44
|
}
|
|
39
45
|
|
|
40
|
-
const
|
|
41
|
-
Online: 'Online',
|
|
42
|
-
Offline: 'Offline',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const ChatHeaderUI = (props: IChatHeaderUIProps) => {
|
|
46
|
+
const ChatHeaderUI = (props: ChatHeaderUIProps) => {
|
|
46
47
|
const {
|
|
47
48
|
title,
|
|
48
49
|
avatar,
|
|
@@ -50,18 +51,17 @@ const ChatHeaderUI = (props: IChatHeaderUIProps) => {
|
|
|
50
51
|
system = false,
|
|
51
52
|
userStatus,
|
|
52
53
|
enableUserStatus = true,
|
|
53
|
-
|
|
54
|
+
enableCall = false,
|
|
54
55
|
Avatar,
|
|
55
56
|
isGroup,
|
|
56
57
|
className,
|
|
57
58
|
style,
|
|
59
|
+
ChatHeaderLeft = null,
|
|
60
|
+
ChatHeaderRight = null,
|
|
58
61
|
} = props;
|
|
59
62
|
|
|
60
63
|
const { t } = useUIKit();
|
|
61
64
|
|
|
62
|
-
const { setChatSettingOpen, setChatSearchOpen } = useUIOpenControlState();
|
|
63
|
-
const { setActiveConversation } = useConversationListState();
|
|
64
|
-
|
|
65
65
|
if (system) {
|
|
66
66
|
return (
|
|
67
67
|
<View
|
|
@@ -73,12 +73,6 @@ const ChatHeaderUI = (props: IChatHeaderUIProps) => {
|
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function clearCurrentConversation() {
|
|
77
|
-
setActiveConversation('');
|
|
78
|
-
setChatSettingOpen(false);
|
|
79
|
-
setChatSearchOpen(false);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
76
|
return (
|
|
83
77
|
<View
|
|
84
78
|
className={cs(classes['chat-header'], className)}
|
|
@@ -86,19 +80,14 @@ const ChatHeaderUI = (props: IChatHeaderUIProps) => {
|
|
|
86
80
|
>
|
|
87
81
|
<View className={classes['chat-header__container']}>
|
|
88
82
|
<View className={classes['chat-header__left']}>
|
|
89
|
-
|
|
90
|
-
<IconChevronLeft
|
|
91
|
-
onClick={clearCurrentConversation}
|
|
92
|
-
size="28px"
|
|
93
|
-
/>
|
|
94
|
-
</button>
|
|
83
|
+
{ChatHeaderLeft}
|
|
95
84
|
{
|
|
96
85
|
Avatar
|
|
97
86
|
? (
|
|
98
|
-
<Avatar src={avatar || ''} />
|
|
87
|
+
<Avatar src={avatar || ''} alt={title} />
|
|
99
88
|
)
|
|
100
89
|
: (
|
|
101
|
-
<DefaultAvatar src={avatar || ''} />
|
|
90
|
+
<DefaultAvatar src={avatar || ''} alt={title} isShowOnlineStatus={!isGroup && enableUserStatus} isOnline={userStatus?.statusType === 1} />
|
|
102
91
|
)
|
|
103
92
|
}
|
|
104
93
|
<View className={classes['chat-header__info']}>
|
|
@@ -112,13 +101,17 @@ const ChatHeaderUI = (props: IChatHeaderUIProps) => {
|
|
|
112
101
|
)}
|
|
113
102
|
</View>
|
|
114
103
|
{!isGroup && enableUserStatus && (userStatus?.statusType === 1
|
|
115
|
-
? <View className={classes['chat-header__live']}>{t(
|
|
116
|
-
: <View className={classes['chat-header__live']}>{t(
|
|
104
|
+
? <View className={classes['chat-header__live']}>{t('TUIChat.Online')}</View>
|
|
105
|
+
: <View className={classes['chat-header__live']}>{t('TUIChat.Offline')}</View>)}
|
|
117
106
|
</View>
|
|
118
107
|
</View>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
108
|
+
{enableCall && (
|
|
109
|
+
<View className={classes['chat-header__call']} flexDir="row" gap={8}>
|
|
110
|
+
<AudioCallPicker />
|
|
111
|
+
<VideoCallPicker />
|
|
112
|
+
</View>
|
|
113
|
+
)}
|
|
114
|
+
{ChatHeaderRight}
|
|
122
115
|
</View>
|
|
123
116
|
</View>
|
|
124
117
|
);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@use "@tencentcloud/uikit-base-component-react/dist/styles/theme/util" as *;
|
|
2
|
+
|
|
3
|
+
.video-call-picker {
|
|
4
|
+
&__button {
|
|
5
|
+
display: flex;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
padding: 4px 6px;
|
|
10
|
+
border: none;
|
|
11
|
+
background: transparent;
|
|
12
|
+
transition: background-color 0.5s ease;
|
|
13
|
+
border-radius: 4px;
|
|
14
|
+
outline: none;
|
|
15
|
+
|
|
16
|
+
@include theme() {
|
|
17
|
+
&:hover {
|
|
18
|
+
background-color: get(button-color-secondary-hover);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&:active {
|
|
22
|
+
background-color: get(button-color-secondary-active);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:focus {
|
|
27
|
+
outline: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&--disabled {
|
|
31
|
+
opacity: 0.5;
|
|
32
|
+
cursor: not-allowed;
|
|
33
|
+
user-select: none;
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&__icon {
|
|
39
|
+
transition: color 0.2s ease;
|
|
40
|
+
|
|
41
|
+
@include theme() {
|
|
42
|
+
color: get(text-color-link);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Global styles for dialog (non-module)
|
|
48
|
+
|
|
49
|
+
.group-call-dialog {
|
|
50
|
+
background: white;
|
|
51
|
+
border-radius: 8px;
|
|
52
|
+
max-width: 500px;
|
|
53
|
+
max-height: 70vh;
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 15%);
|
|
57
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { useState, useRef, useMemo, useCallback } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
IconVideoFilled,
|
|
5
|
+
Dialog,
|
|
6
|
+
useUIKit,
|
|
7
|
+
} from '@tencentcloud/uikit-base-component-react';
|
|
8
|
+
import cs from 'classnames';
|
|
9
|
+
import {
|
|
10
|
+
View,
|
|
11
|
+
useConversationListState,
|
|
12
|
+
useGroupSettingState,
|
|
13
|
+
ConversationType,
|
|
14
|
+
startCall,
|
|
15
|
+
UserPicker,
|
|
16
|
+
useLoginState,
|
|
17
|
+
} from 'tuikit-atomicx-react';
|
|
18
|
+
import classes from './VideoCallPicker.module.scss';
|
|
19
|
+
import type { IUserPickerRef } from 'tuikit-atomicx-react';
|
|
20
|
+
|
|
21
|
+
interface VideoCallPickerProps {
|
|
22
|
+
/**
|
|
23
|
+
* Label text for the button
|
|
24
|
+
*/
|
|
25
|
+
label?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Icon size in pixels
|
|
28
|
+
*/
|
|
29
|
+
iconSize?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the button is disabled
|
|
32
|
+
*/
|
|
33
|
+
disabled?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Custom className for the button
|
|
36
|
+
*/
|
|
37
|
+
className?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Custom style for the button
|
|
40
|
+
*/
|
|
41
|
+
style?: React.CSSProperties;
|
|
42
|
+
/**
|
|
43
|
+
* Custom icon slot
|
|
44
|
+
*/
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface GroupMemberOption {
|
|
49
|
+
key: string;
|
|
50
|
+
label: string;
|
|
51
|
+
avatarUrl?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const VIDEO_CALL_TYPE = 2;
|
|
55
|
+
const MEMBER_PAGE_SIZE = 80;
|
|
56
|
+
const MAX_GROUP_CALL_MEMBERS = 8;
|
|
57
|
+
const MIN_GROUP_CALL_MEMBERS = 1;
|
|
58
|
+
|
|
59
|
+
const VideoCallPicker = (props: VideoCallPickerProps) => {
|
|
60
|
+
const {
|
|
61
|
+
label = '',
|
|
62
|
+
iconSize = 20,
|
|
63
|
+
disabled = false,
|
|
64
|
+
className,
|
|
65
|
+
style,
|
|
66
|
+
children,
|
|
67
|
+
} = props;
|
|
68
|
+
|
|
69
|
+
const { t } = useUIKit();
|
|
70
|
+
const { loginUserInfo } = useLoginState();
|
|
71
|
+
const { activeConversation } = useConversationListState();
|
|
72
|
+
const { allMembers, getGroupMemberList, memberCount } = useGroupSettingState();
|
|
73
|
+
|
|
74
|
+
const [isGroupCallDialogVisible, setIsGroupCallDialogVisible] = useState(false);
|
|
75
|
+
const groupMemberPickerRef = useRef<IUserPickerRef>(null);
|
|
76
|
+
|
|
77
|
+
const selfUserId = useMemo(() => loginUserInfo?.userId, [loginUserInfo]);
|
|
78
|
+
|
|
79
|
+
const isPrivateConversation = useMemo(() => activeConversation?.type === ConversationType.C2C, [activeConversation]);
|
|
80
|
+
|
|
81
|
+
const groupMemberOptions = useMemo<GroupMemberOption[]>(() => allMembers?.map((member: any) => ({
|
|
82
|
+
key: member.userID,
|
|
83
|
+
label: member.nick || member.userID,
|
|
84
|
+
avatarUrl: member.avatar,
|
|
85
|
+
})) ?? [], [allMembers]);
|
|
86
|
+
|
|
87
|
+
const canStartCall = useMemo(() => {
|
|
88
|
+
if (!activeConversation || disabled) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
// TODO: add more call permission check logic
|
|
92
|
+
return true;
|
|
93
|
+
}, [activeConversation, disabled]);
|
|
94
|
+
|
|
95
|
+
const initiatePrivateCall = useCallback((): void => {
|
|
96
|
+
const peerUserId = activeConversation?.userProfile?.userID;
|
|
97
|
+
if (!peerUserId) {
|
|
98
|
+
console.warn('No peer user ID found for C2C call');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
startCall({
|
|
104
|
+
userIDList: [peerUserId],
|
|
105
|
+
type: VIDEO_CALL_TYPE,
|
|
106
|
+
});
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error('Failed to start private video call:', error);
|
|
109
|
+
}
|
|
110
|
+
}, [activeConversation]);
|
|
111
|
+
|
|
112
|
+
const loadMoreGroupMembers = useCallback((): void => {
|
|
113
|
+
if (activeConversation?.type !== ConversationType.GROUP) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const currentMemberCount = allMembers?.length || 0;
|
|
118
|
+
const totalMemberCount = memberCount || 0;
|
|
119
|
+
|
|
120
|
+
if (currentMemberCount < totalMemberCount) {
|
|
121
|
+
getGroupMemberList({
|
|
122
|
+
count: MEMBER_PAGE_SIZE,
|
|
123
|
+
offset: currentMemberCount,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}, [activeConversation, allMembers, memberCount, getGroupMemberList]);
|
|
127
|
+
|
|
128
|
+
const showGroupCallDialog = useCallback((): void => {
|
|
129
|
+
loadMoreGroupMembers();
|
|
130
|
+
setIsGroupCallDialogVisible(true);
|
|
131
|
+
}, [loadMoreGroupMembers]);
|
|
132
|
+
|
|
133
|
+
const handleCloseGroupCallDialog = useCallback(() => {
|
|
134
|
+
setIsGroupCallDialogVisible(false);
|
|
135
|
+
}, []);
|
|
136
|
+
|
|
137
|
+
const initiateGroupCall = useCallback((): void => {
|
|
138
|
+
const currentGroupId = activeConversation?.groupProfile?.groupID;
|
|
139
|
+
if (!groupMemberPickerRef.current || !currentGroupId) {
|
|
140
|
+
console.warn('Missing group information for group call');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const selectedMembers = groupMemberPickerRef.current.getSelectedItems();
|
|
145
|
+
if (!Array.isArray(selectedMembers) || selectedMembers.length === 0) {
|
|
146
|
+
console.warn('No members selected for group call');
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const selectedUserIds = selectedMembers.map(member => member.key);
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
startCall({
|
|
154
|
+
userIDList: selectedUserIds,
|
|
155
|
+
chatGroupID: currentGroupId,
|
|
156
|
+
type: VIDEO_CALL_TYPE,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
handleCloseGroupCallDialog();
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.error('Failed to start group video call:', error);
|
|
162
|
+
}
|
|
163
|
+
}, [activeConversation, handleCloseGroupCallDialog]);
|
|
164
|
+
|
|
165
|
+
const handleVideoCallClick = useCallback(() => {
|
|
166
|
+
if (!canStartCall) {
|
|
167
|
+
console.warn('Cannot start video call');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (isPrivateConversation) {
|
|
172
|
+
initiatePrivateCall();
|
|
173
|
+
} else {
|
|
174
|
+
showGroupCallDialog();
|
|
175
|
+
}
|
|
176
|
+
}, [canStartCall, isPrivateConversation, initiatePrivateCall, showGroupCallDialog]);
|
|
177
|
+
|
|
178
|
+
const handleConfirmGroupCall = useCallback(() => {
|
|
179
|
+
initiateGroupCall();
|
|
180
|
+
}, [initiateGroupCall]);
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<>
|
|
184
|
+
<View>
|
|
185
|
+
<button
|
|
186
|
+
type="button"
|
|
187
|
+
className={cs(
|
|
188
|
+
classes['video-call-picker__button'],
|
|
189
|
+
{
|
|
190
|
+
[classes['video-call-picker__button--disabled']]: disabled,
|
|
191
|
+
},
|
|
192
|
+
className,
|
|
193
|
+
)}
|
|
194
|
+
style={style}
|
|
195
|
+
onClick={handleVideoCallClick}
|
|
196
|
+
disabled={disabled}
|
|
197
|
+
aria-label={label || 'Video Call'}
|
|
198
|
+
>
|
|
199
|
+
{children || (
|
|
200
|
+
<IconVideoFilled
|
|
201
|
+
className={classes['video-call-picker__icon']}
|
|
202
|
+
size={`${iconSize}px`}
|
|
203
|
+
/>
|
|
204
|
+
)}
|
|
205
|
+
</button>
|
|
206
|
+
|
|
207
|
+
<Dialog
|
|
208
|
+
visible={isGroupCallDialogVisible}
|
|
209
|
+
title={t('MessageInput.select_call_members')}
|
|
210
|
+
cancelText={t('MessageInput.cancel')}
|
|
211
|
+
onCancel={handleCloseGroupCallDialog}
|
|
212
|
+
onClose={handleCloseGroupCallDialog}
|
|
213
|
+
confirmText={t('MessageInput.initiate_call')}
|
|
214
|
+
onConfirm={handleConfirmGroupCall}
|
|
215
|
+
className={classes['group-call-dialog']}
|
|
216
|
+
>
|
|
217
|
+
<UserPicker
|
|
218
|
+
ref={groupMemberPickerRef}
|
|
219
|
+
displayMode="list"
|
|
220
|
+
dataSource={groupMemberOptions}
|
|
221
|
+
lockedItems={selfUserId ? [{ key: selfUserId }] : []}
|
|
222
|
+
maxCount={MAX_GROUP_CALL_MEMBERS}
|
|
223
|
+
minCount={MIN_GROUP_CALL_MEMBERS}
|
|
224
|
+
onReachEnd={loadMoreGroupMembers}
|
|
225
|
+
/>
|
|
226
|
+
</Dialog>
|
|
227
|
+
</View>
|
|
228
|
+
</>
|
|
229
|
+
);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
export { VideoCallPicker };
|
|
233
|
+
export type { VideoCallPickerProps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { VideoCallPicker } from './VideoCallPicker';
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import { MyProfile } from './myProfile/index';
|
|
4
|
-
|
|
5
|
-
import './styles/index.scss';
|
|
2
|
+
import React, { useState } from 'react';
|
|
6
3
|
import { useMyProfile } from './hooks';
|
|
4
|
+
import { MyProfile } from './myProfile/index';
|
|
7
5
|
import { TUIProfileDefault } from './ProfileDefault';
|
|
8
|
-
import
|
|
6
|
+
import './styles/index.scss';
|
|
9
7
|
|
|
10
8
|
interface TUIProfileProps {
|
|
11
9
|
className?: string | undefined;
|
|
@@ -22,7 +20,7 @@ function UnMemoizedProfile<T extends TUIProfileProps>(
|
|
|
22
20
|
|
|
23
21
|
const { myProfile, updateMyProfile } = useMyProfile();
|
|
24
22
|
|
|
25
|
-
const
|
|
23
|
+
const [isProfileOpen, setProfileOpen] = useState(false);
|
|
26
24
|
|
|
27
25
|
const TUIProfileUIComponent = PropTUIProfile || TUIProfileDefault;
|
|
28
26
|
|
|
@@ -42,6 +40,9 @@ function UnMemoizedProfile<T extends TUIProfileProps>(
|
|
|
42
40
|
className={className}
|
|
43
41
|
userInfo={myProfile}
|
|
44
42
|
update={updateMyProfile}
|
|
43
|
+
onClose={() => {
|
|
44
|
+
setProfileOpen(false);
|
|
45
|
+
}}
|
|
45
46
|
/>
|
|
46
47
|
)}
|
|
47
48
|
</>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { PropsWithChildren } from 'react';
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
|
-
import TUIChatEngine from '@tencentcloud/chat-uikit-engine';
|
|
3
|
+
import TUIChatEngine from '@tencentcloud/chat-uikit-engine-lite';
|
|
4
4
|
import { IconChevronLeft, useUIKit } from '@tencentcloud/uikit-base-component-react';
|
|
5
|
-
import { Avatar
|
|
6
|
-
import { useUIManagerState } from '../../states';
|
|
5
|
+
import { Avatar } from 'tuikit-atomicx-react';
|
|
7
6
|
import { DivWithEdit } from '../DivWithEdit';
|
|
8
7
|
import { DatePicker } from './DatePicker';
|
|
9
|
-
import type { Profile } from '@tencentcloud/chat';
|
|
10
|
-
import type { UpdateMyProfileParams } from '@tencentcloud/chat-uikit-engine';
|
|
8
|
+
import type { Profile } from '@tencentcloud/lite-chat';
|
|
9
|
+
import type { UpdateMyProfileParams } from '@tencentcloud/chat-uikit-engine-lite';
|
|
11
10
|
|
|
12
11
|
const gender: any = {
|
|
13
12
|
[TUIChatEngine.TYPES.GENDER_UNKNOWN]: 'Unknown',
|
|
@@ -53,6 +52,7 @@ const allowTypeList = [
|
|
|
53
52
|
export interface TUIProfileDefaultProps {
|
|
54
53
|
userInfo?: Profile | undefined;
|
|
55
54
|
update?: ((option: UpdateMyProfileParams) => void) | undefined;
|
|
55
|
+
onClose?: () => void;
|
|
56
56
|
className?: string | undefined;
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -61,12 +61,12 @@ function TUIProfileDefaultWithContext<T extends TUIProfileDefaultProps>(
|
|
|
61
61
|
): React.ReactElement {
|
|
62
62
|
const {
|
|
63
63
|
userInfo,
|
|
64
|
-
className,
|
|
65
64
|
update,
|
|
65
|
+
onClose,
|
|
66
|
+
className,
|
|
66
67
|
} = props;
|
|
67
68
|
|
|
68
69
|
const { t } = useUIKit();
|
|
69
|
-
const { setProfileOpen } = useUIOpenControlState();
|
|
70
70
|
|
|
71
71
|
const [isEditName, setIsEditName] = useState('');
|
|
72
72
|
|
|
@@ -242,7 +242,7 @@ function TUIProfileDefaultWithContext<T extends TUIProfileDefaultProps>(
|
|
|
242
242
|
<header
|
|
243
243
|
className="tui-profile-header"
|
|
244
244
|
onClick={() => {
|
|
245
|
-
|
|
245
|
+
onClose?.();
|
|
246
246
|
}}
|
|
247
247
|
>
|
|
248
248
|
<IconChevronLeft size="24px" />
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import { Profile } from '@tencentcloud/chat';
|
|
3
2
|
import {
|
|
4
3
|
TUIUserService,
|
|
5
4
|
TUIStore,
|
|
6
5
|
StoreName,
|
|
7
6
|
UpdateMyProfileParams,
|
|
8
|
-
} from "@tencentcloud/chat-uikit-engine";
|
|
7
|
+
} from "@tencentcloud/chat-uikit-engine-lite";
|
|
9
8
|
export interface ProfileParams {
|
|
10
9
|
nick?: string,
|
|
11
10
|
avatar?: string,
|
|
@@ -23,7 +22,7 @@ export interface ProfileParams {
|
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
export function useMyProfile() {
|
|
26
|
-
const [myProfile, setMyProfile] = useState<
|
|
25
|
+
const [myProfile, setMyProfile] = useState<any>();
|
|
27
26
|
|
|
28
27
|
const updateMyProfile = (options: UpdateMyProfileParams) => {
|
|
29
28
|
TUIUserService.updateMyProfile(options);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import './styles/index.scss';
|
|
3
3
|
import { defaultUserAvatar } from '../../../constant/avatar';
|
|
4
|
-
import type { Profile as TProfile } from '@tencentcloud/chat';
|
|
4
|
+
import type { Profile as TProfile } from '@tencentcloud/lite-chat';
|
|
5
5
|
import { Avatar } from 'tuikit-atomicx-react';
|
|
6
6
|
import { IconHorizontalMoreTwo } from '@tencentcloud/uikit-base-component-react';
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useContext, createContext, useMemo } from 'react';
|
|
2
2
|
import { useUIManagerState } from '../states';
|
|
3
|
-
import type { IConversationModel } from '@tencentcloud/chat-uikit-engine';
|
|
3
|
+
import type { IConversationModel } from '@tencentcloud/chat-uikit-engine-lite';
|
|
4
4
|
|
|
5
5
|
interface IChatProps {
|
|
6
6
|
children?: React.ReactNode;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, {
|
|
2
2
|
PropsWithChildren, useContext,
|
|
3
3
|
} from 'react';
|
|
4
|
-
import { Friend, Profile, FriendApplication } from '@tencentcloud/chat';
|
|
4
|
+
import type { Friend, Profile, FriendApplication } from '@tencentcloud/lite-chat';
|
|
5
5
|
|
|
6
6
|
export interface TUIContactContextValue {
|
|
7
7
|
friendList?: Friend[];
|
package/src/hooks/index.ts
CHANGED