@webinex/chatify 1.0.0-build2 → 1.0.0-rc2
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/package.json +90 -90
- package/src/ChatifyContext.tsx +41 -41
- package/src/core/action.tsx +319 -319
- package/src/core/client.ts +137 -137
- package/src/core/index.ts +14 -14
- package/src/core/models.tsx +75 -75
- package/src/core/reducer.tsx +86 -86
- package/src/core/state.ts +38 -38
- package/src/core/useAccounts.tsx +11 -11
- package/src/core/useAddChat.tsx +12 -12
- package/src/core/useAddMember.tsx +12 -12
- package/src/core/useAddMessage.tsx +40 -40
- package/src/core/useChat.tsx +12 -12
- package/src/core/useChatList.tsx +10 -10
- package/src/core/useLoadMore.tsx +42 -42
- package/src/core/useMessages.tsx +23 -23
- package/src/core/useMutation.tsx +48 -48
- package/src/core/useQuery.tsx +45 -45
- package/src/core/useReadMonitor.tsx +31 -31
- package/src/core/useRemoveMember.tsx +12 -12
- package/src/core/useSignalRMonitor.tsx +52 -52
- package/src/index.ts +3 -3
- package/src/ui/AddChat.tsx +55 -55
- package/src/ui/AddChatButton.tsx +19 -19
- package/src/ui/Aside.tsx +41 -41
- package/src/ui/Avatar.tsx +18 -18
- package/src/ui/Chat.tsx +26 -26
- package/src/ui/ChatBody.tsx +43 -43
- package/src/ui/ChatHeader.tsx +33 -33
- package/src/ui/ChatHeaderMembers.tsx +30 -30
- package/src/ui/ChatHeaderSettingsButton.tsx +26 -26
- package/src/ui/ChatListItem.tsx +101 -101
- package/src/ui/ChatName.tsx +15 -15
- package/src/ui/ChatSettings.tsx +59 -59
- package/src/ui/Chatify.tsx +106 -106
- package/src/ui/Footer.tsx +7 -7
- package/src/ui/Header.tsx +14 -14
- package/src/ui/Icon.tsx +21 -21
- package/src/ui/InputForm.tsx +51 -51
- package/src/ui/LoadMore.tsx +40 -40
- package/src/ui/Main.tsx +16 -16
- package/src/ui/Message.tsx +118 -118
- package/src/ui/MessageSkeleton.tsx +19 -19
- package/src/ui/SendingMessage.tsx +50 -50
- package/src/ui/SystemMessage.tsx +32 -32
- package/src/ui/index.ts +11 -11
- package/src/ui/localizer.tsx +68 -68
- package/src/ui/styles/aside.scss +94 -94
- package/src/ui/styles/index.scss +248 -248
- package/src/ui/styles/keyframes.scss +14 -14
- package/src/ui/styles/mixins.scss +20 -20
- package/src/ui/styles/variables.scss +10 -10
- package/src/util/customize.tsx +45 -45
- package/src/util/index.ts +3 -3
- package/src/util/uniqBy.tsx +17 -17
- package/src/util/uniqId.tsx +3 -3
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
2
|
-
import { useChat } from '../core';
|
|
3
|
-
import { Avatar, Tooltip } from 'antd';
|
|
4
|
-
import { customize } from '../util';
|
|
5
|
-
|
|
6
|
-
export interface ChatHeaderMembersProps {
|
|
7
|
-
id: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const _ChatHeaderMembers: FC<ChatHeaderMembersProps> = (props) => {
|
|
11
|
-
const { id } = props;
|
|
12
|
-
const { data: chat } = useChat({ chatId: id });
|
|
13
|
-
|
|
14
|
-
if (!chat?.members) {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<Avatar.Group maxCount={5}>
|
|
20
|
-
{chat.members.map((x) => (
|
|
21
|
-
<Tooltip key={x.id} title={x.name}>
|
|
22
|
-
<Avatar src={x.avatar}>{x.name}</Avatar>
|
|
23
|
-
</Tooltip>
|
|
24
|
-
))}
|
|
25
|
-
</Avatar.Group>
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
_ChatHeaderMembers.displayName = 'ChatHeaderMembers';
|
|
30
|
-
export const ChatHeaderMembers = customize('ChatHeaderMembers', _ChatHeaderMembers);
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { useChat } from '../core';
|
|
3
|
+
import { Avatar, Tooltip } from 'antd';
|
|
4
|
+
import { customize } from '../util';
|
|
5
|
+
|
|
6
|
+
export interface ChatHeaderMembersProps {
|
|
7
|
+
id: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const _ChatHeaderMembers: FC<ChatHeaderMembersProps> = (props) => {
|
|
11
|
+
const { id } = props;
|
|
12
|
+
const { data: chat } = useChat({ chatId: id });
|
|
13
|
+
|
|
14
|
+
if (!chat?.members) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Avatar.Group maxCount={5}>
|
|
20
|
+
{chat.members.map((x) => (
|
|
21
|
+
<Tooltip key={x.id} title={x.name}>
|
|
22
|
+
<Avatar src={x.avatar}>{x.name}</Avatar>
|
|
23
|
+
</Tooltip>
|
|
24
|
+
))}
|
|
25
|
+
</Avatar.Group>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
_ChatHeaderMembers.displayName = 'ChatHeaderMembers';
|
|
30
|
+
export const ChatHeaderMembers = customize('ChatHeaderMembers', _ChatHeaderMembers);
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { useDispatch } from '../core';
|
|
2
|
-
import { Button } from 'antd';
|
|
3
|
-
import { SettingOutlined } from '@ant-design/icons';
|
|
4
|
-
import { FC, useCallback } from 'react';
|
|
5
|
-
import { customize } from '../util';
|
|
6
|
-
|
|
7
|
-
export interface ChatSettingsButtonProps {
|
|
8
|
-
id: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const _ChatSettingsButton: FC<ChatSettingsButtonProps> = (props) => {
|
|
12
|
-
const { id } = props;
|
|
13
|
-
const dispatch = useDispatch();
|
|
14
|
-
const onSettingsClick = useCallback(
|
|
15
|
-
() => dispatch({ type: 'chat_settings_open', data: { chatId: id } }),
|
|
16
|
-
|
|
17
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18
|
-
[dispatch],
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
return <Button onClick={onSettingsClick} type="link" icon={<SettingOutlined />} />;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
_ChatSettingsButton.displayName = 'ChatSettingsButton';
|
|
25
|
-
|
|
26
|
-
export const ChatSettingsButton = customize('ChatSettingsButton', _ChatSettingsButton);
|
|
1
|
+
import { useDispatch } from '../core';
|
|
2
|
+
import { Button } from 'antd';
|
|
3
|
+
import { SettingOutlined } from '@ant-design/icons';
|
|
4
|
+
import { FC, useCallback } from 'react';
|
|
5
|
+
import { customize } from '../util';
|
|
6
|
+
|
|
7
|
+
export interface ChatSettingsButtonProps {
|
|
8
|
+
id: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const _ChatSettingsButton: FC<ChatSettingsButtonProps> = (props) => {
|
|
12
|
+
const { id } = props;
|
|
13
|
+
const dispatch = useDispatch();
|
|
14
|
+
const onSettingsClick = useCallback(
|
|
15
|
+
() => dispatch({ type: 'chat_settings_open', data: { chatId: id } }),
|
|
16
|
+
|
|
17
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18
|
+
[dispatch],
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return <Button onClick={onSettingsClick} type="link" icon={<SettingOutlined />} />;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
_ChatSettingsButton.displayName = 'ChatSettingsButton';
|
|
25
|
+
|
|
26
|
+
export const ChatSettingsButton = customize('ChatSettingsButton', _ChatSettingsButton);
|
package/src/ui/ChatListItem.tsx
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
import { useLocalizer } from './localizer';
|
|
2
|
-
import { formatSystemMessage } from './SystemMessage';
|
|
3
|
-
import { Avatar } from './Avatar';
|
|
4
|
-
import { ChatName } from './ChatName';
|
|
5
|
-
import { ChatListItem as ChatListItemModel } from '../core';
|
|
6
|
-
import { FC } from 'react';
|
|
7
|
-
import { customize } from '../util';
|
|
8
|
-
|
|
9
|
-
export interface ChatListItemBoxProps {
|
|
10
|
-
chat: ChatListItemModel;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const _ChatListItemName: FC<ChatListItemBoxProps> = (props) => {
|
|
14
|
-
const { name } = props.chat;
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<div className="wxchtf-chat-name">
|
|
18
|
-
<ChatName name={name} />
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
_ChatListItemName.displayName = 'ChatListItemName';
|
|
24
|
-
|
|
25
|
-
export const ChatListItemName = customize('ChatListItemName', _ChatListItemName);
|
|
26
|
-
|
|
27
|
-
const _ChatListItemUnreadCount: FC<ChatListItemBoxProps> = (props) => {
|
|
28
|
-
const { unreadCount } = props.chat;
|
|
29
|
-
|
|
30
|
-
if (unreadCount <= 0) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return <div className="wxchtf-unread-count">{unreadCount}</div>;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
_ChatListItemUnreadCount.displayName = 'ChatListItemUnreadCount';
|
|
38
|
-
|
|
39
|
-
export const ChatListItemUnreadCount = customize('ChatListItemUnreadCount', _ChatListItemUnreadCount);
|
|
40
|
-
|
|
41
|
-
const _ChatListItemLastMessage: FC<ChatListItemBoxProps> = (props) => {
|
|
42
|
-
return (
|
|
43
|
-
<div className="wxchtf-chat-last">
|
|
44
|
-
<ChatListItemLastMessageAuthor {...props} />
|
|
45
|
-
<ChatListItemLastMessageContent {...props} />
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
_ChatListItemLastMessage.displayName = 'ChatListItemLastMessage';
|
|
51
|
-
|
|
52
|
-
export const ChatListItemLastMessage = customize('ChatListItemLastMessage', _ChatListItemLastMessage);
|
|
53
|
-
|
|
54
|
-
export const ChatListItemLastMessageAuthor = customize<FC<ChatListItemBoxProps>, string>(
|
|
55
|
-
'ChatListItemLastMessageAuthor',
|
|
56
|
-
(props) => {
|
|
57
|
-
const { message } = props.chat;
|
|
58
|
-
|
|
59
|
-
if (message.sentBy.id === 'chatify::system') {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<div className="wxchtf-chat-last-author">
|
|
65
|
-
<Avatar account={message.sentBy} /> {message.sentBy.name}
|
|
66
|
-
</div>
|
|
67
|
-
);
|
|
68
|
-
},
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
export const ChatListItemLastMessageContent = customize<FC<ChatListItemBoxProps>, string>(
|
|
72
|
-
'ChatListItemLastMessageContent',
|
|
73
|
-
(props) => {
|
|
74
|
-
const { message } = props.chat;
|
|
75
|
-
const localizer = useLocalizer();
|
|
76
|
-
|
|
77
|
-
return (
|
|
78
|
-
<div className="wxchtf-chat-last-message">
|
|
79
|
-
{message.sentBy.id === 'chatify::system'
|
|
80
|
-
? formatSystemMessage(localizer, message.text)
|
|
81
|
-
: message.text}
|
|
82
|
-
</div>
|
|
83
|
-
);
|
|
84
|
-
},
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
const _ChatListItemBox: FC<ChatListItemBoxProps> = (props) => {
|
|
88
|
-
const { message } = props.chat;
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<div className={'wxchtf-chat' + (!message.read ? ' --unread' : '')}>
|
|
92
|
-
<ChatListItemName {...props} />
|
|
93
|
-
<ChatListItemUnreadCount {...props} />
|
|
94
|
-
<ChatListItemLastMessage {...props} />
|
|
95
|
-
</div>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
_ChatListItemBox.displayName = 'ChatListItemBox';
|
|
100
|
-
|
|
101
|
-
export const ChatListItemBox = customize('ChatListItemBox', _ChatListItemBox);
|
|
1
|
+
import { useLocalizer } from './localizer';
|
|
2
|
+
import { formatSystemMessage } from './SystemMessage';
|
|
3
|
+
import { Avatar } from './Avatar';
|
|
4
|
+
import { ChatName } from './ChatName';
|
|
5
|
+
import { ChatListItem as ChatListItemModel } from '../core';
|
|
6
|
+
import { FC } from 'react';
|
|
7
|
+
import { customize } from '../util';
|
|
8
|
+
|
|
9
|
+
export interface ChatListItemBoxProps {
|
|
10
|
+
chat: ChatListItemModel;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const _ChatListItemName: FC<ChatListItemBoxProps> = (props) => {
|
|
14
|
+
const { name } = props.chat;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="wxchtf-chat-name">
|
|
18
|
+
<ChatName name={name} />
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
_ChatListItemName.displayName = 'ChatListItemName';
|
|
24
|
+
|
|
25
|
+
export const ChatListItemName = customize('ChatListItemName', _ChatListItemName);
|
|
26
|
+
|
|
27
|
+
const _ChatListItemUnreadCount: FC<ChatListItemBoxProps> = (props) => {
|
|
28
|
+
const { unreadCount } = props.chat;
|
|
29
|
+
|
|
30
|
+
if (unreadCount <= 0) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return <div className="wxchtf-unread-count">{unreadCount}</div>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
_ChatListItemUnreadCount.displayName = 'ChatListItemUnreadCount';
|
|
38
|
+
|
|
39
|
+
export const ChatListItemUnreadCount = customize('ChatListItemUnreadCount', _ChatListItemUnreadCount);
|
|
40
|
+
|
|
41
|
+
const _ChatListItemLastMessage: FC<ChatListItemBoxProps> = (props) => {
|
|
42
|
+
return (
|
|
43
|
+
<div className="wxchtf-chat-last">
|
|
44
|
+
<ChatListItemLastMessageAuthor {...props} />
|
|
45
|
+
<ChatListItemLastMessageContent {...props} />
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
_ChatListItemLastMessage.displayName = 'ChatListItemLastMessage';
|
|
51
|
+
|
|
52
|
+
export const ChatListItemLastMessage = customize('ChatListItemLastMessage', _ChatListItemLastMessage);
|
|
53
|
+
|
|
54
|
+
export const ChatListItemLastMessageAuthor = customize<FC<ChatListItemBoxProps>, string>(
|
|
55
|
+
'ChatListItemLastMessageAuthor',
|
|
56
|
+
(props) => {
|
|
57
|
+
const { message } = props.chat;
|
|
58
|
+
|
|
59
|
+
if (message.sentBy.id === 'chatify::system') {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div className="wxchtf-chat-last-author">
|
|
65
|
+
<Avatar account={message.sentBy} /> {message.sentBy.name}
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
export const ChatListItemLastMessageContent = customize<FC<ChatListItemBoxProps>, string>(
|
|
72
|
+
'ChatListItemLastMessageContent',
|
|
73
|
+
(props) => {
|
|
74
|
+
const { message } = props.chat;
|
|
75
|
+
const localizer = useLocalizer();
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className="wxchtf-chat-last-message">
|
|
79
|
+
{message.sentBy.id === 'chatify::system'
|
|
80
|
+
? formatSystemMessage(localizer, message.text)
|
|
81
|
+
: message.text}
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const _ChatListItemBox: FC<ChatListItemBoxProps> = (props) => {
|
|
88
|
+
const { message } = props.chat;
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<div className={'wxchtf-chat' + (!message.read ? ' --unread' : '')}>
|
|
92
|
+
<ChatListItemName {...props} />
|
|
93
|
+
<ChatListItemUnreadCount {...props} />
|
|
94
|
+
<ChatListItemLastMessage {...props} />
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
_ChatListItemBox.displayName = 'ChatListItemBox';
|
|
100
|
+
|
|
101
|
+
export const ChatListItemBox = customize('ChatListItemBox', _ChatListItemBox);
|
package/src/ui/ChatName.tsx
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
2
|
-
import { customize } from '../util';
|
|
3
|
-
|
|
4
|
-
export interface ChatNameProps {
|
|
5
|
-
name: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const _ChatName: FC<ChatNameProps> = (props) => {
|
|
9
|
-
const { name } = props;
|
|
10
|
-
return <>{name}</>;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
_ChatName.displayName = 'ChatName';
|
|
14
|
-
|
|
15
|
-
export const ChatName = customize('ChatName', _ChatName);
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { customize } from '../util';
|
|
3
|
+
|
|
4
|
+
export interface ChatNameProps {
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const _ChatName: FC<ChatNameProps> = (props) => {
|
|
9
|
+
const { name } = props;
|
|
10
|
+
return <>{name}</>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
_ChatName.displayName = 'ChatName';
|
|
14
|
+
|
|
15
|
+
export const ChatName = customize('ChatName', _ChatName);
|
package/src/ui/ChatSettings.tsx
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { Button, Col, List, Row, Select } from 'antd';
|
|
2
|
-
import { Account, useAccounts, useAddMember, useChat, useSelect } from '../core';
|
|
3
|
-
import { CloseOutlined } from '@ant-design/icons';
|
|
4
|
-
import { useRemoveMember } from '../core';
|
|
5
|
-
import { useCallback, useMemo } from 'react';
|
|
6
|
-
|
|
7
|
-
function Member(props: { account: Account; chatId: string }) {
|
|
8
|
-
const { account, chatId } = props;
|
|
9
|
-
const [remove] = useRemoveMember();
|
|
10
|
-
|
|
11
|
-
const onRemoveClick = useCallback(
|
|
12
|
-
() => remove({ chatId, accountId: account.id, deleteHistory: false }),
|
|
13
|
-
[remove, chatId, account.id],
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<List.Item>
|
|
18
|
-
{account.name} <Button onClick={onRemoveClick} type="link" icon={<CloseOutlined />} />
|
|
19
|
-
</List.Item>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function ChatSettings() {
|
|
24
|
-
const [chatId] = useSelect((x) => [x.ui.chatId], []);
|
|
25
|
-
const { data: chat } = useChat({ chatId: chatId! });
|
|
26
|
-
const [add] = useAddMember();
|
|
27
|
-
const { data: accounts } = useAccounts();
|
|
28
|
-
const accountOptions = useMemo(() => accounts?.map((x) => ({ value: x.id, label: x.name })), [accounts]);
|
|
29
|
-
|
|
30
|
-
const onAdd = useCallback(
|
|
31
|
-
(id: string) => add({ chatId: chatId!, accountId: id, withHistory: true }),
|
|
32
|
-
[add, chatId],
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
if (!chat) {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<div className="wxchtf-chat-settings">
|
|
41
|
-
<Row justify="space-between">
|
|
42
|
-
<Col>
|
|
43
|
-
<h3 className="wxchtf-title">{chat.name}</h3>
|
|
44
|
-
</Col>
|
|
45
|
-
<Col>
|
|
46
|
-
<Button type="link" icon={<CloseOutlined />} />
|
|
47
|
-
</Col>
|
|
48
|
-
</Row>
|
|
49
|
-
<h4>Members</h4>
|
|
50
|
-
<List
|
|
51
|
-
dataSource={chat.members}
|
|
52
|
-
rowKey="id"
|
|
53
|
-
renderItem={(account) => <Member account={account} chatId={chatId!} />}
|
|
54
|
-
/>
|
|
55
|
-
|
|
56
|
-
<Select<string> style={{ width: '350px' }} options={accountOptions} value={null} onSelect={onAdd} />
|
|
57
|
-
</div>
|
|
58
|
-
);
|
|
59
|
-
}
|
|
1
|
+
import { Button, Col, List, Row, Select } from 'antd';
|
|
2
|
+
import { Account, useAccounts, useAddMember, useChat, useSelect } from '../core';
|
|
3
|
+
import { CloseOutlined } from '@ant-design/icons';
|
|
4
|
+
import { useRemoveMember } from '../core';
|
|
5
|
+
import { useCallback, useMemo } from 'react';
|
|
6
|
+
|
|
7
|
+
function Member(props: { account: Account; chatId: string }) {
|
|
8
|
+
const { account, chatId } = props;
|
|
9
|
+
const [remove] = useRemoveMember();
|
|
10
|
+
|
|
11
|
+
const onRemoveClick = useCallback(
|
|
12
|
+
() => remove({ chatId, accountId: account.id, deleteHistory: false }),
|
|
13
|
+
[remove, chatId, account.id],
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<List.Item>
|
|
18
|
+
{account.name} <Button onClick={onRemoveClick} type="link" icon={<CloseOutlined />} />
|
|
19
|
+
</List.Item>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function ChatSettings() {
|
|
24
|
+
const [chatId] = useSelect((x) => [x.ui.chatId], []);
|
|
25
|
+
const { data: chat } = useChat({ chatId: chatId! });
|
|
26
|
+
const [add] = useAddMember();
|
|
27
|
+
const { data: accounts } = useAccounts();
|
|
28
|
+
const accountOptions = useMemo(() => accounts?.map((x) => ({ value: x.id, label: x.name })), [accounts]);
|
|
29
|
+
|
|
30
|
+
const onAdd = useCallback(
|
|
31
|
+
(id: string) => add({ chatId: chatId!, accountId: id, withHistory: true }),
|
|
32
|
+
[add, chatId],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (!chat) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div className="wxchtf-chat-settings">
|
|
41
|
+
<Row justify="space-between">
|
|
42
|
+
<Col>
|
|
43
|
+
<h3 className="wxchtf-title">{chat.name}</h3>
|
|
44
|
+
</Col>
|
|
45
|
+
<Col>
|
|
46
|
+
<Button type="link" icon={<CloseOutlined />} />
|
|
47
|
+
</Col>
|
|
48
|
+
</Row>
|
|
49
|
+
<h4>Members</h4>
|
|
50
|
+
<List
|
|
51
|
+
dataSource={chat.members}
|
|
52
|
+
rowKey="id"
|
|
53
|
+
renderItem={(account) => <Member account={account} chatId={chatId!} />}
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<Select<string> style={{ width: '350px' }} options={accountOptions} value={null} onSelect={onAdd} />
|
|
57
|
+
</div>
|
|
58
|
+
);
|
|
59
|
+
}
|