@webinex/chatify 1.0.0-rc3 → 1.0.2-rc3
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/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/core/action.d.ts +10 -4
- package/dist/esm/types/core/state.d.ts +2 -1
- package/dist/esm/types/core/useGetAccountsQuery.d.ts +3 -1
- package/dist/esm/types/core/useGetChatListQuery.d.ts +3 -1
- package/dist/esm/types/core/useGetChatQuery.d.ts +3 -1
- package/dist/esm/types/ui/Icon.d.ts +8 -8
- package/dist/index.d.ts +21 -14
- package/package.json +92 -92
- package/src/ChatifyContext.tsx +41 -41
- package/src/core/action.tsx +421 -405
- package/src/core/client.ts +143 -143
- package/src/core/index.ts +17 -17
- package/src/core/models.tsx +82 -82
- package/src/core/reducer.tsx +87 -87
- package/src/core/state.ts +93 -92
- package/src/core/useAddChatMutation.tsx +22 -22
- package/src/core/useAddMemberMutation.tsx +25 -25
- package/src/core/useFetchNextMutation.tsx +28 -28
- package/src/core/useGetAccountsQuery.tsx +30 -33
- package/src/core/useGetChatListQuery.tsx +30 -33
- package/src/core/useGetChatQuery.tsx +31 -34
- package/src/core/useGetMessagesQuery.tsx +35 -35
- package/src/core/useReadMonitor.tsx +32 -32
- package/src/core/useRemoveMemberMutation.tsx +23 -23
- package/src/core/useSendMutation.tsx +24 -24
- package/src/core/useSignalRMonitor.tsx +66 -66
- package/src/core/useUpdateChatNameMutation.tsx +23 -23
- package/src/index.ts +3 -3
- package/src/styles/aside.scss +94 -94
- package/src/styles/chat.scss +222 -222
- package/src/styles/index.scss +79 -79
- package/src/styles/keyframes.scss +14 -14
- package/src/styles/mixins.scss +20 -20
- package/src/styles/settings.scss +5 -5
- package/src/styles/variables.scss +10 -10
- package/src/ui/AddChatButton.tsx +15 -15
- package/src/ui/Avatar.tsx +18 -18
- package/src/ui/ChatList/ChatList.tsx +42 -42
- package/src/ui/ChatList/ChatListItemBox.tsx +22 -22
- package/src/ui/ChatList/ChatListItemLastMessage.tsx +13 -13
- package/src/ui/ChatList/ChatListItemLastMessageAuthor.tsx +20 -20
- package/src/ui/ChatList/ChatListItemLastMessageContent.tsx +21 -21
- package/src/ui/ChatList/ChatListItemName.tsx +13 -13
- package/src/ui/ChatList/ChatListItemUnreadCount.tsx +12 -12
- package/src/ui/ChatList/index.ts +7 -7
- package/src/ui/ChatName.tsx +10 -10
- package/src/ui/ChatPanel/ChatBody.tsx +44 -44
- package/src/ui/ChatPanel/ChatHeader.tsx +33 -33
- package/src/ui/ChatPanel/ChatHeaderMembers.tsx +26 -26
- package/src/ui/ChatPanel/ChatHeaderName.tsx +67 -67
- package/src/ui/ChatPanel/ChatMembersButton.tsx +21 -21
- package/src/ui/ChatPanel/ChatMembersPanel.tsx +117 -117
- package/src/ui/ChatPanel/ChatPanel.tsx +27 -27
- package/src/ui/ChatPanel/index.ts +6 -6
- package/src/ui/Chatify.tsx +148 -148
- package/src/ui/CreateChatPanel/CreateChatForm.tsx +36 -36
- package/src/ui/CreateChatPanel/CreateChatMemberInput.tsx +66 -66
- package/src/ui/CreateChatPanel/CreateChatNameInput.tsx +25 -25
- package/src/ui/CreateChatPanel/CreateChatPanel.tsx +33 -33
- package/src/ui/CreateChatPanel/index.ts +4 -4
- package/src/ui/Icon.tsx +33 -33
- package/src/ui/InputBox/InputBox.tsx +38 -38
- package/src/ui/InputBox/InputFilesBox.tsx +9 -9
- package/src/ui/InputBox/InputSubmitButtonBox.tsx +17 -17
- package/src/ui/InputBox/InputTextBox.tsx +50 -50
- package/src/ui/InputBox/index.ts +4 -4
- package/src/ui/Layout/Aside.tsx +10 -10
- package/src/ui/Layout/Body.tsx +10 -10
- package/src/ui/Layout/Footer.tsx +3 -3
- package/src/ui/Layout/Header.tsx +10 -10
- package/src/ui/Layout/Main.tsx +15 -15
- package/src/ui/Layout/index.ts +5 -5
- package/src/ui/Message/MessageAuthor.tsx +13 -13
- package/src/ui/Message/MessageBox.tsx +20 -20
- package/src/ui/Message/MessageContent.tsx +13 -13
- package/src/ui/Message/MessageInfoBox.tsx +25 -25
- package/src/ui/Message/MessageRow.tsx +24 -24
- package/src/ui/Message/MessageText.tsx +7 -7
- package/src/ui/Message/index.ts +6 -6
- package/src/ui/MessageReadObserver.tsx +45 -45
- package/src/ui/MessageSkeleton.tsx +19 -19
- package/src/ui/Next.tsx +48 -48
- package/src/ui/SendingMessage/SendingMessageBox.tsx +16 -16
- package/src/ui/SendingMessage/SendingMessageContent.tsx +13 -13
- package/src/ui/SendingMessage/SendingMessageInfoBox.tsx +13 -13
- package/src/ui/SendingMessage/SendingMessageText.tsx +7 -7
- package/src/ui/SendingMessage/index.ts +4 -4
- package/src/ui/SystemMessage/SystemMessageBox.tsx +20 -20
- package/src/ui/SystemMessage/SystemMessageRow.tsx +43 -43
- package/src/ui/SystemMessage/index.ts +2 -2
- package/src/ui/customize.tsx +45 -45
- package/src/ui/index.ts +11 -11
- package/src/ui/localizer.tsx +80 -80
- package/src/util/index.ts +2 -2
- package/src/util/uniqBy.tsx +17 -17
- package/src/util/uniqId.tsx +3 -3
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
import { Input, Tooltip } from 'antd';
|
|
2
|
-
import { useSelect, useUpdateChatNameMutation } from '../../core';
|
|
3
|
-
import { ChatName } from '../ChatName';
|
|
4
|
-
import { customize } from '../customize';
|
|
5
|
-
import { useEffect, useState } from 'react';
|
|
6
|
-
import isHotkey from 'is-hotkey';
|
|
7
|
-
|
|
8
|
-
export interface ChatHeaderNameProps {
|
|
9
|
-
id: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const isEscape = isHotkey('escape');
|
|
13
|
-
const isEnter = isHotkey('enter');
|
|
14
|
-
|
|
15
|
-
function useUpdateChatName(id: string, value: string) {
|
|
16
|
-
const [updateChatName] = useUpdateChatNameMutation();
|
|
17
|
-
return () => updateChatName({ id, name: value });
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const ChatHeaderName = customize('ChatHeaderName', (props: ChatHeaderNameProps) => {
|
|
21
|
-
const { id } = props;
|
|
22
|
-
const chat = useSelect((x) => x.query.chatList.data!.find((x) => x.id === id)!, [id]);
|
|
23
|
-
const name = chat.name;
|
|
24
|
-
const [editNameValue, setEditNameValue] = useState('');
|
|
25
|
-
const [edit, setEdit] = useState(false);
|
|
26
|
-
const updateChatName = useUpdateChatName(id, editNameValue);
|
|
27
|
-
|
|
28
|
-
useEffect(() => {
|
|
29
|
-
if (edit) {
|
|
30
|
-
setEditNameValue(name);
|
|
31
|
-
}
|
|
32
|
-
}, [edit, name]);
|
|
33
|
-
|
|
34
|
-
if (!chat.active) {
|
|
35
|
-
return <span className="wxchtf-chat-name">{name}</span>;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
if (edit) {
|
|
39
|
-
return (
|
|
40
|
-
<Input
|
|
41
|
-
value={editNameValue}
|
|
42
|
-
onChange={(e) => setEditNameValue(e.target.value)}
|
|
43
|
-
onBlur={() => setEdit(false)}
|
|
44
|
-
onKeyDown={(e) => {
|
|
45
|
-
if (isEscape(e)) {
|
|
46
|
-
setEdit(false);
|
|
47
|
-
} else if (isEnter(e)) {
|
|
48
|
-
setEdit(false);
|
|
49
|
-
|
|
50
|
-
if (editNameValue !== name) {
|
|
51
|
-
updateChatName();
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}}
|
|
55
|
-
autoFocus
|
|
56
|
-
/>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<Tooltip title="Click to edit name...">
|
|
62
|
-
<span className="wxchtf-chat-name --editable" onClick={() => setEdit(true)}>
|
|
63
|
-
<ChatName name={name} />
|
|
64
|
-
</span>
|
|
65
|
-
</Tooltip>
|
|
66
|
-
);
|
|
67
|
-
});
|
|
1
|
+
import { Input, Tooltip } from 'antd';
|
|
2
|
+
import { useSelect, useUpdateChatNameMutation } from '../../core';
|
|
3
|
+
import { ChatName } from '../ChatName';
|
|
4
|
+
import { customize } from '../customize';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import isHotkey from 'is-hotkey';
|
|
7
|
+
|
|
8
|
+
export interface ChatHeaderNameProps {
|
|
9
|
+
id: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const isEscape = isHotkey('escape');
|
|
13
|
+
const isEnter = isHotkey('enter');
|
|
14
|
+
|
|
15
|
+
function useUpdateChatName(id: string, value: string) {
|
|
16
|
+
const [updateChatName] = useUpdateChatNameMutation();
|
|
17
|
+
return () => updateChatName({ id, name: value });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const ChatHeaderName = customize('ChatHeaderName', (props: ChatHeaderNameProps) => {
|
|
21
|
+
const { id } = props;
|
|
22
|
+
const chat = useSelect((x) => x.query.chatList.data!.find((x) => x.id === id)!, [id]);
|
|
23
|
+
const name = chat.name;
|
|
24
|
+
const [editNameValue, setEditNameValue] = useState('');
|
|
25
|
+
const [edit, setEdit] = useState(false);
|
|
26
|
+
const updateChatName = useUpdateChatName(id, editNameValue);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (edit) {
|
|
30
|
+
setEditNameValue(name);
|
|
31
|
+
}
|
|
32
|
+
}, [edit, name]);
|
|
33
|
+
|
|
34
|
+
if (!chat.active) {
|
|
35
|
+
return <span className="wxchtf-chat-name">{name}</span>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (edit) {
|
|
39
|
+
return (
|
|
40
|
+
<Input
|
|
41
|
+
value={editNameValue}
|
|
42
|
+
onChange={(e) => setEditNameValue(e.target.value)}
|
|
43
|
+
onBlur={() => setEdit(false)}
|
|
44
|
+
onKeyDown={(e) => {
|
|
45
|
+
if (isEscape(e)) {
|
|
46
|
+
setEdit(false);
|
|
47
|
+
} else if (isEnter(e)) {
|
|
48
|
+
setEdit(false);
|
|
49
|
+
|
|
50
|
+
if (editNameValue !== name) {
|
|
51
|
+
updateChatName();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}}
|
|
55
|
+
autoFocus
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<Tooltip title="Click to edit name...">
|
|
62
|
+
<span className="wxchtf-chat-name --editable" onClick={() => setEdit(true)}>
|
|
63
|
+
<ChatName name={name} />
|
|
64
|
+
</span>
|
|
65
|
+
</Tooltip>
|
|
66
|
+
);
|
|
67
|
+
});
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { useDispatch } from '../../core';
|
|
2
|
-
import { Button } from 'antd';
|
|
3
|
-
import { useCallback } from 'react';
|
|
4
|
-
import { customize } from '../customize';
|
|
5
|
-
import { Icon } from '../Icon';
|
|
6
|
-
|
|
7
|
-
export interface ChatMembersButtonProps {
|
|
8
|
-
id: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const ChatMembersButton = customize('ChatMembersButton', (_: ChatMembersButtonProps) => {
|
|
12
|
-
const dispatch = useDispatch();
|
|
13
|
-
const onSettingsClick = useCallback(
|
|
14
|
-
() => dispatch({ type: 'toggle_members_view', data: void 0 }),
|
|
15
|
-
|
|
16
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
17
|
-
[dispatch],
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
return <Button onClick={onSettingsClick} type="link" icon={<Icon type="team" />} />;
|
|
21
|
-
});
|
|
1
|
+
import { useDispatch } from '../../core';
|
|
2
|
+
import { Button } from 'antd';
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
import { customize } from '../customize';
|
|
5
|
+
import { Icon } from '../Icon';
|
|
6
|
+
|
|
7
|
+
export interface ChatMembersButtonProps {
|
|
8
|
+
id: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ChatMembersButton = customize('ChatMembersButton', (_: ChatMembersButtonProps) => {
|
|
12
|
+
const dispatch = useDispatch();
|
|
13
|
+
const onSettingsClick = useCallback(
|
|
14
|
+
() => dispatch({ type: 'toggle_members_view', data: void 0 }),
|
|
15
|
+
|
|
16
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
17
|
+
[dispatch],
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
return <Button onClick={onSettingsClick} type="link" icon={<Icon type="team" />} />;
|
|
21
|
+
});
|
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
import { Button, List, Space, Tooltip } from 'antd';
|
|
2
|
-
import {
|
|
3
|
-
useAddMemberMutation,
|
|
4
|
-
useGetAccountsQuery,
|
|
5
|
-
useGetChatQuery,
|
|
6
|
-
useRemoveMemberMutation,
|
|
7
|
-
} from '../../core';
|
|
8
|
-
import { customize } from '../customize';
|
|
9
|
-
import { useCallback, useMemo } from 'react';
|
|
10
|
-
import { Icon } from '../Icon';
|
|
11
|
-
import { Avatar } from '../Avatar';
|
|
12
|
-
|
|
13
|
-
export interface ChatMembersPanelProps {
|
|
14
|
-
id: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ChatMemberListItemProps {
|
|
18
|
-
id: string;
|
|
19
|
-
chatId: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function useAdd(chatId: string, accountId: string, withHistory: boolean) {
|
|
23
|
-
const [add, state] = useAddMemberMutation();
|
|
24
|
-
const onAdd = useCallback(
|
|
25
|
-
() => add({ chatId, accountId, withHistory }),
|
|
26
|
-
[add, chatId, accountId, withHistory],
|
|
27
|
-
);
|
|
28
|
-
return [onAdd, state] as const;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function useRemove(chatId: string, accountId: string, deleteHistory: boolean) {
|
|
32
|
-
const [remove, state] = useRemoveMemberMutation();
|
|
33
|
-
const onRemove = useCallback(
|
|
34
|
-
() => remove({ chatId, accountId, deleteHistory }),
|
|
35
|
-
[remove, chatId, accountId, deleteHistory],
|
|
36
|
-
);
|
|
37
|
-
return [onRemove, state] as const;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const ChatMemberListItem = customize('ChatMemberListItem', (props: ChatMemberListItemProps) => {
|
|
41
|
-
const { chatId } = props;
|
|
42
|
-
const { data: chat } = useGetChatQuery({ chatId });
|
|
43
|
-
const { data: accounts } = useGetAccountsQuery();
|
|
44
|
-
const account = accounts!.find((x) => x.id === props.id)!;
|
|
45
|
-
const isMember = chat!.members.some((x) => x.id === account.id);
|
|
46
|
-
const [onAddWithoutHistory] = useAdd(chatId, account.id, false);
|
|
47
|
-
const [onAddWithHistory] = useAdd(chatId, account.id, true);
|
|
48
|
-
const [onRemoveKeepHistory] = useRemove(chatId, account.id, false);
|
|
49
|
-
const [onRemoveDeleteHistory] = useRemove(chatId, account.id, true);
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<List.Item
|
|
53
|
-
className="wxchtf-chat-members-list-item"
|
|
54
|
-
actions={
|
|
55
|
-
isMember
|
|
56
|
-
? [
|
|
57
|
-
<Tooltip key="remove" title="Remove (keep history)">
|
|
58
|
-
<Button onClick={onRemoveKeepHistory} type="link" icon={<Icon type="remove" />} />
|
|
59
|
-
</Tooltip>,
|
|
60
|
-
<Tooltip key="remove_delete_history" title="Remove (delete history)">
|
|
61
|
-
<Button
|
|
62
|
-
onClick={onRemoveDeleteHistory}
|
|
63
|
-
type="link"
|
|
64
|
-
icon={<Icon type="remove_delete_history" />}
|
|
65
|
-
/>
|
|
66
|
-
</Tooltip>,
|
|
67
|
-
]
|
|
68
|
-
: [
|
|
69
|
-
<Tooltip key="add_no_history" title="Add (no history)">
|
|
70
|
-
<Button onClick={onAddWithoutHistory} type="link" icon={<Icon type="add" />} />
|
|
71
|
-
</Tooltip>,
|
|
72
|
-
<Tooltip key="add" title="Add (share history)">
|
|
73
|
-
<Button onClick={onAddWithHistory} type="link" icon={<Icon type="add_with_history" />} />
|
|
74
|
-
</Tooltip>,
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
>
|
|
78
|
-
<Space>
|
|
79
|
-
<Avatar account={account} />
|
|
80
|
-
<span>{account.name}</span>
|
|
81
|
-
</Space>
|
|
82
|
-
</List.Item>
|
|
83
|
-
);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
export const ChatMembersPanel = customize('ChatMembersPanel', (props: ChatMembersPanelProps) => {
|
|
87
|
-
const { id } = props;
|
|
88
|
-
|
|
89
|
-
const { data: chat } = useGetChatQuery({ chatId: id });
|
|
90
|
-
const { data: accounts } = useGetAccountsQuery();
|
|
91
|
-
const ordered = useMemo(
|
|
92
|
-
() =>
|
|
93
|
-
accounts
|
|
94
|
-
?.slice()
|
|
95
|
-
.sort(
|
|
96
|
-
(a, b) =>
|
|
97
|
-
(chat?.members.some((m) => m.id === a.id) ? -100 : 0) -
|
|
98
|
-
(chat?.members.some((m) => m.id === b.id) ? -100 : 0) +
|
|
99
|
-
a.name.localeCompare(b.name),
|
|
100
|
-
),
|
|
101
|
-
[accounts, chat],
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
if (!chat?.members || !accounts) {
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return (
|
|
109
|
-
<div className="wxchtf-chat-members-panel">
|
|
110
|
-
<List
|
|
111
|
-
className="wxchtf-chat-members-list"
|
|
112
|
-
dataSource={ordered}
|
|
113
|
-
renderItem={(item) => <ChatMemberListItem id={item.id} chatId={id} />}
|
|
114
|
-
/>
|
|
115
|
-
</div>
|
|
116
|
-
);
|
|
117
|
-
});
|
|
1
|
+
import { Button, List, Space, Tooltip } from 'antd';
|
|
2
|
+
import {
|
|
3
|
+
useAddMemberMutation,
|
|
4
|
+
useGetAccountsQuery,
|
|
5
|
+
useGetChatQuery,
|
|
6
|
+
useRemoveMemberMutation,
|
|
7
|
+
} from '../../core';
|
|
8
|
+
import { customize } from '../customize';
|
|
9
|
+
import { useCallback, useMemo } from 'react';
|
|
10
|
+
import { Icon } from '../Icon';
|
|
11
|
+
import { Avatar } from '../Avatar';
|
|
12
|
+
|
|
13
|
+
export interface ChatMembersPanelProps {
|
|
14
|
+
id: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ChatMemberListItemProps {
|
|
18
|
+
id: string;
|
|
19
|
+
chatId: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function useAdd(chatId: string, accountId: string, withHistory: boolean) {
|
|
23
|
+
const [add, state] = useAddMemberMutation();
|
|
24
|
+
const onAdd = useCallback(
|
|
25
|
+
() => add({ chatId, accountId, withHistory }),
|
|
26
|
+
[add, chatId, accountId, withHistory],
|
|
27
|
+
);
|
|
28
|
+
return [onAdd, state] as const;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function useRemove(chatId: string, accountId: string, deleteHistory: boolean) {
|
|
32
|
+
const [remove, state] = useRemoveMemberMutation();
|
|
33
|
+
const onRemove = useCallback(
|
|
34
|
+
() => remove({ chatId, accountId, deleteHistory }),
|
|
35
|
+
[remove, chatId, accountId, deleteHistory],
|
|
36
|
+
);
|
|
37
|
+
return [onRemove, state] as const;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const ChatMemberListItem = customize('ChatMemberListItem', (props: ChatMemberListItemProps) => {
|
|
41
|
+
const { chatId } = props;
|
|
42
|
+
const { data: chat } = useGetChatQuery({ chatId });
|
|
43
|
+
const { data: accounts } = useGetAccountsQuery();
|
|
44
|
+
const account = accounts!.find((x) => x.id === props.id)!;
|
|
45
|
+
const isMember = chat!.members.some((x) => x.id === account.id);
|
|
46
|
+
const [onAddWithoutHistory] = useAdd(chatId, account.id, false);
|
|
47
|
+
const [onAddWithHistory] = useAdd(chatId, account.id, true);
|
|
48
|
+
const [onRemoveKeepHistory] = useRemove(chatId, account.id, false);
|
|
49
|
+
const [onRemoveDeleteHistory] = useRemove(chatId, account.id, true);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<List.Item
|
|
53
|
+
className="wxchtf-chat-members-list-item"
|
|
54
|
+
actions={
|
|
55
|
+
isMember
|
|
56
|
+
? [
|
|
57
|
+
<Tooltip key="remove" title="Remove (keep history)">
|
|
58
|
+
<Button onClick={onRemoveKeepHistory} type="link" icon={<Icon type="remove" />} />
|
|
59
|
+
</Tooltip>,
|
|
60
|
+
<Tooltip key="remove_delete_history" title="Remove (delete history)">
|
|
61
|
+
<Button
|
|
62
|
+
onClick={onRemoveDeleteHistory}
|
|
63
|
+
type="link"
|
|
64
|
+
icon={<Icon type="remove_delete_history" />}
|
|
65
|
+
/>
|
|
66
|
+
</Tooltip>,
|
|
67
|
+
]
|
|
68
|
+
: [
|
|
69
|
+
<Tooltip key="add_no_history" title="Add (no history)">
|
|
70
|
+
<Button onClick={onAddWithoutHistory} type="link" icon={<Icon type="add" />} />
|
|
71
|
+
</Tooltip>,
|
|
72
|
+
<Tooltip key="add" title="Add (share history)">
|
|
73
|
+
<Button onClick={onAddWithHistory} type="link" icon={<Icon type="add_with_history" />} />
|
|
74
|
+
</Tooltip>,
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
<Space>
|
|
79
|
+
<Avatar account={account} />
|
|
80
|
+
<span>{account.name}</span>
|
|
81
|
+
</Space>
|
|
82
|
+
</List.Item>
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
export const ChatMembersPanel = customize('ChatMembersPanel', (props: ChatMembersPanelProps) => {
|
|
87
|
+
const { id } = props;
|
|
88
|
+
|
|
89
|
+
const { data: chat } = useGetChatQuery({ chatId: id });
|
|
90
|
+
const { data: accounts } = useGetAccountsQuery();
|
|
91
|
+
const ordered = useMemo(
|
|
92
|
+
() =>
|
|
93
|
+
accounts
|
|
94
|
+
?.slice()
|
|
95
|
+
.sort(
|
|
96
|
+
(a, b) =>
|
|
97
|
+
(chat?.members.some((m) => m.id === a.id) ? -100 : 0) -
|
|
98
|
+
(chat?.members.some((m) => m.id === b.id) ? -100 : 0) +
|
|
99
|
+
a.name.localeCompare(b.name),
|
|
100
|
+
),
|
|
101
|
+
[accounts, chat],
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
if (!chat?.members || !accounts) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div className="wxchtf-chat-members-panel">
|
|
110
|
+
<List
|
|
111
|
+
className="wxchtf-chat-members-list"
|
|
112
|
+
dataSource={ordered}
|
|
113
|
+
renderItem={(item) => <ChatMemberListItem id={item.id} chatId={id} />}
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
);
|
|
117
|
+
});
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { ChatHeader } from './ChatHeader';
|
|
2
|
-
import { ChatBody } from './ChatBody';
|
|
3
|
-
import { InputBox } from '../InputBox/InputBox';
|
|
4
|
-
import { useSelect } from '../../core';
|
|
5
|
-
import { customize } from '../customize';
|
|
6
|
-
import { ChatMembersPanel } from './ChatMembersPanel';
|
|
7
|
-
|
|
8
|
-
export interface ChatPanelProps {
|
|
9
|
-
id: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const ChatPanel = customize('ChatPanel', (props: ChatPanelProps) => {
|
|
13
|
-
const { id } = props;
|
|
14
|
-
const chat = useSelect((x) => x.query.chatList.data!.find((x) => x.id === id)!, [id]);
|
|
15
|
-
const chatMembersOpen = useSelect((x) => x.ui.showMembers, []);
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div className="wxchtf-chat-panel">
|
|
19
|
-
<div className="wxchtf-chat-main">
|
|
20
|
-
<ChatHeader id={id} />
|
|
21
|
-
<ChatBody id={id} />
|
|
22
|
-
{chat.active && <InputBox />}
|
|
23
|
-
</div>
|
|
24
|
-
{chatMembersOpen && <ChatMembersPanel id={id} />}
|
|
25
|
-
</div>
|
|
26
|
-
);
|
|
27
|
-
});
|
|
1
|
+
import { ChatHeader } from './ChatHeader';
|
|
2
|
+
import { ChatBody } from './ChatBody';
|
|
3
|
+
import { InputBox } from '../InputBox/InputBox';
|
|
4
|
+
import { useSelect } from '../../core';
|
|
5
|
+
import { customize } from '../customize';
|
|
6
|
+
import { ChatMembersPanel } from './ChatMembersPanel';
|
|
7
|
+
|
|
8
|
+
export interface ChatPanelProps {
|
|
9
|
+
id: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const ChatPanel = customize('ChatPanel', (props: ChatPanelProps) => {
|
|
13
|
+
const { id } = props;
|
|
14
|
+
const chat = useSelect((x) => x.query.chatList.data!.find((x) => x.id === id)!, [id]);
|
|
15
|
+
const chatMembersOpen = useSelect((x) => x.ui.showMembers, []);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="wxchtf-chat-panel">
|
|
19
|
+
<div className="wxchtf-chat-main">
|
|
20
|
+
<ChatHeader id={id} />
|
|
21
|
+
<ChatBody id={id} />
|
|
22
|
+
{chat.active && <InputBox />}
|
|
23
|
+
</div>
|
|
24
|
+
{chatMembersOpen && <ChatMembersPanel id={id} />}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './ChatBody';
|
|
2
|
-
export * from './ChatHeader';
|
|
3
|
-
export * from './ChatHeaderMembers';
|
|
4
|
-
export * from './ChatHeaderName';
|
|
5
|
-
export * from './ChatPanel';
|
|
6
|
-
export * from './ChatMembersButton';
|
|
1
|
+
export * from './ChatBody';
|
|
2
|
+
export * from './ChatHeader';
|
|
3
|
+
export * from './ChatHeaderMembers';
|
|
4
|
+
export * from './ChatHeaderName';
|
|
5
|
+
export * from './ChatPanel';
|
|
6
|
+
export * from './ChatMembersButton';
|