@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
package/src/ui/Icon.tsx
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
2
|
-
import { customize } from './customize';
|
|
3
|
-
import SendOutlined from '@ant-design/icons/SendOutlined';
|
|
4
|
-
import PaperClipOutlined from '@ant-design/icons/PaperClipOutlined';
|
|
5
|
-
import UserAddOutlined from '@ant-design/icons/UserAddOutlined';
|
|
6
|
-
import UsergroupAddOutlined from '@ant-design/icons/UsergroupAddOutlined';
|
|
7
|
-
import UserDeleteOutlined from '@ant-design/icons/UserDeleteOutlined';
|
|
8
|
-
import UsergroupDeleteOutlined from '@ant-design/icons/UsergroupDeleteOutlined';
|
|
9
|
-
import TeamOutlined from '@ant-design/icons/TeamOutlined';
|
|
10
|
-
import EditOutlined from '@ant-design/icons/EditOutlined';
|
|
11
|
-
|
|
12
|
-
export type IconType = keyof typeof ICONS;
|
|
13
|
-
|
|
14
|
-
export interface IconProps {
|
|
15
|
-
type: IconType;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const ICONS = {
|
|
19
|
-
attach: PaperClipOutlined,
|
|
20
|
-
send: SendOutlined,
|
|
21
|
-
remove: UserDeleteOutlined,
|
|
22
|
-
remove_delete_history: UsergroupDeleteOutlined,
|
|
23
|
-
add: UserAddOutlined,
|
|
24
|
-
add_with_history: UsergroupAddOutlined,
|
|
25
|
-
team: TeamOutlined,
|
|
26
|
-
edit: EditOutlined,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const Icon = customize<FC<IconProps>>('Icon', (props) => {
|
|
30
|
-
const { type } = props;
|
|
31
|
-
const IconComponent = ICONS[type];
|
|
32
|
-
return IconComponent ? <IconComponent /> : null;
|
|
33
|
-
});
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { customize } from './customize';
|
|
3
|
+
import SendOutlined from '@ant-design/icons/SendOutlined';
|
|
4
|
+
import PaperClipOutlined from '@ant-design/icons/PaperClipOutlined';
|
|
5
|
+
import UserAddOutlined from '@ant-design/icons/UserAddOutlined';
|
|
6
|
+
import UsergroupAddOutlined from '@ant-design/icons/UsergroupAddOutlined';
|
|
7
|
+
import UserDeleteOutlined from '@ant-design/icons/UserDeleteOutlined';
|
|
8
|
+
import UsergroupDeleteOutlined from '@ant-design/icons/UsergroupDeleteOutlined';
|
|
9
|
+
import TeamOutlined from '@ant-design/icons/TeamOutlined';
|
|
10
|
+
import EditOutlined from '@ant-design/icons/EditOutlined';
|
|
11
|
+
|
|
12
|
+
export type IconType = keyof typeof ICONS;
|
|
13
|
+
|
|
14
|
+
export interface IconProps {
|
|
15
|
+
type: IconType;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const ICONS = {
|
|
19
|
+
attach: PaperClipOutlined,
|
|
20
|
+
send: SendOutlined,
|
|
21
|
+
remove: UserDeleteOutlined,
|
|
22
|
+
remove_delete_history: UsergroupDeleteOutlined,
|
|
23
|
+
add: UserAddOutlined,
|
|
24
|
+
add_with_history: UsergroupAddOutlined,
|
|
25
|
+
team: TeamOutlined,
|
|
26
|
+
edit: EditOutlined,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Icon = customize<FC<IconProps>>('Icon', (props) => {
|
|
30
|
+
const { type } = props;
|
|
31
|
+
const IconComponent = ICONS[type];
|
|
32
|
+
return IconComponent ? <IconComponent /> : null;
|
|
33
|
+
});
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { useCallback, useState } from 'react';
|
|
2
|
-
import { useSelect, useSendMutation } from '../../core';
|
|
3
|
-
import { uniqId } from '../../util';
|
|
4
|
-
import { InputFilesBox } from './InputFilesBox';
|
|
5
|
-
import { InputTextBox } from './InputTextBox';
|
|
6
|
-
import { customize } from '../customize';
|
|
7
|
-
import { InputSubmitButtonBox } from './InputSubmitButtonBox';
|
|
8
|
-
|
|
9
|
-
function useSend(text: string, setText: (value: string) => void) {
|
|
10
|
-
const chatId = useSelect((x) => x.ui.chatId!, []);
|
|
11
|
-
const [add] = useSendMutation();
|
|
12
|
-
|
|
13
|
-
return useCallback(() => {
|
|
14
|
-
if (text.length === 0) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
setText('');
|
|
19
|
-
add({ chatId, text: text, files: [], requestId: uniqId() });
|
|
20
|
-
|
|
21
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
22
|
-
}, [chatId, text]);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const InputBox = customize('InputBox', () => {
|
|
26
|
-
const [text, setText] = useState('');
|
|
27
|
-
const onSend = useSend(text, setText);
|
|
28
|
-
|
|
29
|
-
return (
|
|
30
|
-
<div className="wxchtf-input-form">
|
|
31
|
-
<div className="wxchtf-input-box">
|
|
32
|
-
<InputFilesBox />
|
|
33
|
-
<InputTextBox value={text} onSend={onSend} onChange={setText} />
|
|
34
|
-
<InputSubmitButtonBox onSubmit={onSend} />
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
);
|
|
38
|
-
});
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
import { useSelect, useSendMutation } from '../../core';
|
|
3
|
+
import { uniqId } from '../../util';
|
|
4
|
+
import { InputFilesBox } from './InputFilesBox';
|
|
5
|
+
import { InputTextBox } from './InputTextBox';
|
|
6
|
+
import { customize } from '../customize';
|
|
7
|
+
import { InputSubmitButtonBox } from './InputSubmitButtonBox';
|
|
8
|
+
|
|
9
|
+
function useSend(text: string, setText: (value: string) => void) {
|
|
10
|
+
const chatId = useSelect((x) => x.ui.chatId!, []);
|
|
11
|
+
const [add] = useSendMutation();
|
|
12
|
+
|
|
13
|
+
return useCallback(() => {
|
|
14
|
+
if (text.length === 0) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setText('');
|
|
19
|
+
add({ chatId, text: text, files: [], requestId: uniqId() });
|
|
20
|
+
|
|
21
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
22
|
+
}, [chatId, text]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const InputBox = customize('InputBox', () => {
|
|
26
|
+
const [text, setText] = useState('');
|
|
27
|
+
const onSend = useSend(text, setText);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div className="wxchtf-input-form">
|
|
31
|
+
<div className="wxchtf-input-box">
|
|
32
|
+
<InputFilesBox />
|
|
33
|
+
<InputTextBox value={text} onSend={onSend} onChange={setText} />
|
|
34
|
+
<InputSubmitButtonBox onSubmit={onSend} />
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Button } from 'antd';
|
|
2
|
-
import { customize } from '../customize';
|
|
3
|
-
import { Icon } from '../Icon';
|
|
4
|
-
|
|
5
|
-
export const InputFilesBox = customize('InputFilesBox', () => (
|
|
6
|
-
<div className="wxchtf-add-files-box">
|
|
7
|
-
<Button type="link" icon={<Icon type="attach" />} className="wxchtf-add-files-btn" />
|
|
8
|
-
</div>
|
|
9
|
-
));
|
|
1
|
+
import { Button } from 'antd';
|
|
2
|
+
import { customize } from '../customize';
|
|
3
|
+
import { Icon } from '../Icon';
|
|
4
|
+
|
|
5
|
+
export const InputFilesBox = customize('InputFilesBox', () => (
|
|
6
|
+
<div className="wxchtf-add-files-box">
|
|
7
|
+
<Button type="link" icon={<Icon type="attach" />} className="wxchtf-add-files-btn" />
|
|
8
|
+
</div>
|
|
9
|
+
));
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Button } from 'antd';
|
|
2
|
-
import { customize } from '../customize';
|
|
3
|
-
import { Icon } from '../Icon';
|
|
4
|
-
|
|
5
|
-
export interface InputSubmitButtonBoxProps {
|
|
6
|
-
onSubmit: () => void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const InputSubmitButtonBox = customize('InputSubmitButtonBox', (props: InputSubmitButtonBoxProps) => {
|
|
10
|
-
const { onSubmit } = props;
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div className="wxchtf-submit-btn-box">
|
|
14
|
-
<Button onClick={onSubmit} type="link" icon={<Icon type="send" />} className="wxchtf-submit-btn" />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
});
|
|
1
|
+
import { Button } from 'antd';
|
|
2
|
+
import { customize } from '../customize';
|
|
3
|
+
import { Icon } from '../Icon';
|
|
4
|
+
|
|
5
|
+
export interface InputSubmitButtonBoxProps {
|
|
6
|
+
onSubmit: () => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const InputSubmitButtonBox = customize('InputSubmitButtonBox', (props: InputSubmitButtonBoxProps) => {
|
|
10
|
+
const { onSubmit } = props;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="wxchtf-submit-btn-box">
|
|
14
|
+
<Button onClick={onSubmit} type="link" icon={<Icon type="send" />} className="wxchtf-submit-btn" />
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
});
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { Input } from 'antd';
|
|
2
|
-
import { customize } from '../customize';
|
|
3
|
-
import isHotkey from 'is-hotkey';
|
|
4
|
-
import { memo, useCallback } from 'react';
|
|
5
|
-
import { useLocalizer } from '../localizer';
|
|
6
|
-
|
|
7
|
-
export interface TextInputBoxProps {
|
|
8
|
-
value: string;
|
|
9
|
-
onChange: (value: string) => void;
|
|
10
|
-
onSend: (value: string) => void;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const isSend = isHotkey('ctrl+enter');
|
|
14
|
-
|
|
15
|
-
const AUTO_SIZE = { maxRows: 5 };
|
|
16
|
-
|
|
17
|
-
export const InputTextBox = customize(
|
|
18
|
-
'InputTextBox',
|
|
19
|
-
memo((props: TextInputBoxProps) => {
|
|
20
|
-
const { value, onChange, onSend } = props;
|
|
21
|
-
const localizer = useLocalizer();
|
|
22
|
-
|
|
23
|
-
const onInputChange = useCallback(
|
|
24
|
-
(e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value),
|
|
25
|
-
[onChange],
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
const onKeyDown = useCallback(
|
|
29
|
-
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
30
|
-
if (isSend(e)) {
|
|
31
|
-
onSend(value);
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
[onSend, value],
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<div className="wxchtf-text-input-box">
|
|
39
|
-
<Input.TextArea
|
|
40
|
-
value={value}
|
|
41
|
-
onChange={onInputChange}
|
|
42
|
-
autoSize={AUTO_SIZE}
|
|
43
|
-
className="wxchtf-text-input-textarea"
|
|
44
|
-
placeholder={localizer.input.placeholder()}
|
|
45
|
-
onKeyDown={onKeyDown}
|
|
46
|
-
/>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
}),
|
|
50
|
-
);
|
|
1
|
+
import { Input } from 'antd';
|
|
2
|
+
import { customize } from '../customize';
|
|
3
|
+
import isHotkey from 'is-hotkey';
|
|
4
|
+
import { memo, useCallback } from 'react';
|
|
5
|
+
import { useLocalizer } from '../localizer';
|
|
6
|
+
|
|
7
|
+
export interface TextInputBoxProps {
|
|
8
|
+
value: string;
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
onSend: (value: string) => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const isSend = isHotkey('ctrl+enter');
|
|
14
|
+
|
|
15
|
+
const AUTO_SIZE = { maxRows: 5 };
|
|
16
|
+
|
|
17
|
+
export const InputTextBox = customize(
|
|
18
|
+
'InputTextBox',
|
|
19
|
+
memo((props: TextInputBoxProps) => {
|
|
20
|
+
const { value, onChange, onSend } = props;
|
|
21
|
+
const localizer = useLocalizer();
|
|
22
|
+
|
|
23
|
+
const onInputChange = useCallback(
|
|
24
|
+
(e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value),
|
|
25
|
+
[onChange],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const onKeyDown = useCallback(
|
|
29
|
+
(e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
|
30
|
+
if (isSend(e)) {
|
|
31
|
+
onSend(value);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
[onSend, value],
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className="wxchtf-text-input-box">
|
|
39
|
+
<Input.TextArea
|
|
40
|
+
value={value}
|
|
41
|
+
onChange={onInputChange}
|
|
42
|
+
autoSize={AUTO_SIZE}
|
|
43
|
+
className="wxchtf-text-input-textarea"
|
|
44
|
+
placeholder={localizer.input.placeholder()}
|
|
45
|
+
onKeyDown={onKeyDown}
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}),
|
|
50
|
+
);
|
package/src/ui/InputBox/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './InputBox';
|
|
2
|
-
export * from './InputFilesBox';
|
|
3
|
-
export * from './InputSubmitButtonBox';
|
|
4
|
-
export * from './InputTextBox';
|
|
1
|
+
export * from './InputBox';
|
|
2
|
+
export * from './InputFilesBox';
|
|
3
|
+
export * from './InputSubmitButtonBox';
|
|
4
|
+
export * from './InputTextBox';
|
package/src/ui/Layout/Aside.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { customize } from '../customize';
|
|
2
|
-
import { ChatList } from '../ChatList';
|
|
3
|
-
|
|
4
|
-
export const Aside = customize('Aside', () => {
|
|
5
|
-
return (
|
|
6
|
-
<div className="wxchtf-aside">
|
|
7
|
-
<ChatList />
|
|
8
|
-
</div>
|
|
9
|
-
);
|
|
10
|
-
});
|
|
1
|
+
import { customize } from '../customize';
|
|
2
|
+
import { ChatList } from '../ChatList';
|
|
3
|
+
|
|
4
|
+
export const Aside = customize('Aside', () => {
|
|
5
|
+
return (
|
|
6
|
+
<div className="wxchtf-aside">
|
|
7
|
+
<ChatList />
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
package/src/ui/Layout/Body.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { customize } from '../customize';
|
|
2
|
-
import { Aside } from './Aside';
|
|
3
|
-
import { Main } from './Main';
|
|
4
|
-
|
|
5
|
-
export const Body = customize('Body', () => (
|
|
6
|
-
<div className="wxchtf-body">
|
|
7
|
-
<Aside />
|
|
8
|
-
<Main />
|
|
9
|
-
</div>
|
|
10
|
-
));
|
|
1
|
+
import { customize } from '../customize';
|
|
2
|
+
import { Aside } from './Aside';
|
|
3
|
+
import { Main } from './Main';
|
|
4
|
+
|
|
5
|
+
export const Body = customize('Body', () => (
|
|
6
|
+
<div className="wxchtf-body">
|
|
7
|
+
<Aside />
|
|
8
|
+
<Main />
|
|
9
|
+
</div>
|
|
10
|
+
));
|
package/src/ui/Layout/Footer.tsx
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { customize } from '../customize';
|
|
2
|
-
|
|
3
|
-
export const Footer = customize('Footer', () => <div className="wxchtf-footer"></div>);
|
|
1
|
+
import { customize } from '../customize';
|
|
2
|
+
|
|
3
|
+
export const Footer = customize('Footer', () => <div className="wxchtf-footer"></div>);
|
package/src/ui/Layout/Header.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { AddChatButton } from '../AddChatButton';
|
|
2
|
-
import { customize } from '../customize';
|
|
3
|
-
|
|
4
|
-
export const Header = customize('Header', () => {
|
|
5
|
-
return (
|
|
6
|
-
<div className="wxchtf-header">
|
|
7
|
-
<AddChatButton />
|
|
8
|
-
</div>
|
|
9
|
-
);
|
|
10
|
-
});
|
|
1
|
+
import { AddChatButton } from '../AddChatButton';
|
|
2
|
+
import { customize } from '../customize';
|
|
3
|
+
|
|
4
|
+
export const Header = customize('Header', () => {
|
|
5
|
+
return (
|
|
6
|
+
<div className="wxchtf-header">
|
|
7
|
+
<AddChatButton />
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
});
|
package/src/ui/Layout/Main.tsx
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { useSelect } from '../../core';
|
|
2
|
-
import { customize } from '../customize';
|
|
3
|
-
import { CreateChatPanel } from '../CreateChatPanel';
|
|
4
|
-
import { ChatPanel } from '../ChatPanel';
|
|
5
|
-
|
|
6
|
-
export const Main = customize('Main', () => {
|
|
7
|
-
const { view, chatId } = useSelect((x) => ({ view: x.ui.view, chatId: x.ui.chatId }), []);
|
|
8
|
-
|
|
9
|
-
return (
|
|
10
|
-
<div className="wxchtf-main">
|
|
11
|
-
{view === 'chat' && chatId && <ChatPanel id={chatId} key={chatId} />}
|
|
12
|
-
{view === 'new-chat' && <CreateChatPanel />}
|
|
13
|
-
</div>
|
|
14
|
-
);
|
|
15
|
-
});
|
|
1
|
+
import { useSelect } from '../../core';
|
|
2
|
+
import { customize } from '../customize';
|
|
3
|
+
import { CreateChatPanel } from '../CreateChatPanel';
|
|
4
|
+
import { ChatPanel } from '../ChatPanel';
|
|
5
|
+
|
|
6
|
+
export const Main = customize('Main', () => {
|
|
7
|
+
const { view, chatId } = useSelect((x) => ({ view: x.ui.view, chatId: x.ui.chatId }), []);
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<div className="wxchtf-main">
|
|
11
|
+
{view === 'chat' && chatId && <ChatPanel id={chatId} key={chatId} />}
|
|
12
|
+
{view === 'new-chat' && <CreateChatPanel />}
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
});
|
package/src/ui/Layout/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './Aside';
|
|
2
|
-
export * from './Header';
|
|
3
|
-
export * from './Footer';
|
|
4
|
-
export * from './Main';
|
|
5
|
-
export * from './Body';
|
|
1
|
+
export * from './Aside';
|
|
2
|
+
export * from './Header';
|
|
3
|
+
export * from './Footer';
|
|
4
|
+
export * from './Main';
|
|
5
|
+
export * from './Body';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { customize } from '../customize';
|
|
2
|
-
import { Avatar } from '../Avatar';
|
|
3
|
-
import type { MessageBoxProps } from './MessageBox';
|
|
4
|
-
|
|
5
|
-
export const MessageAuthor = customize('MessageAuthor', (props: MessageBoxProps) => {
|
|
6
|
-
const { sentBy } = props.message;
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<div className="wxchtf-message-author">
|
|
10
|
-
<Avatar account={sentBy} />
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
});
|
|
1
|
+
import { customize } from '../customize';
|
|
2
|
+
import { Avatar } from '../Avatar';
|
|
3
|
+
import type { MessageBoxProps } from './MessageBox';
|
|
4
|
+
|
|
5
|
+
export const MessageAuthor = customize('MessageAuthor', (props: MessageBoxProps) => {
|
|
6
|
+
const { sentBy } = props.message;
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div className="wxchtf-message-author">
|
|
10
|
+
<Avatar account={sentBy} />
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
import { Message } from '../../core';
|
|
3
|
-
import { customize } from '../customize';
|
|
4
|
-
import { MessageReadObserver } from '../MessageReadObserver';
|
|
5
|
-
import { MessageRow } from './MessageRow';
|
|
6
|
-
|
|
7
|
-
export interface MessageBoxProps {
|
|
8
|
-
message: Message;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const MessageBox = customize('MessageBox', (props: MessageBoxProps) => {
|
|
12
|
-
const ref = useRef<HTMLDivElement | null>(null);
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<>
|
|
16
|
-
<MessageReadObserver messageRef={ref} {...props} />
|
|
17
|
-
<MessageRow containerRef={ref} {...props} />
|
|
18
|
-
</>
|
|
19
|
-
);
|
|
20
|
-
});
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { Message } from '../../core';
|
|
3
|
+
import { customize } from '../customize';
|
|
4
|
+
import { MessageReadObserver } from '../MessageReadObserver';
|
|
5
|
+
import { MessageRow } from './MessageRow';
|
|
6
|
+
|
|
7
|
+
export interface MessageBoxProps {
|
|
8
|
+
message: Message;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const MessageBox = customize('MessageBox', (props: MessageBoxProps) => {
|
|
12
|
+
const ref = useRef<HTMLDivElement | null>(null);
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<MessageReadObserver messageRef={ref} {...props} />
|
|
17
|
+
<MessageRow containerRef={ref} {...props} />
|
|
18
|
+
</>
|
|
19
|
+
);
|
|
20
|
+
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { customize } from '../customize';
|
|
2
|
-
import { MessageText } from './MessageText';
|
|
3
|
-
import { MessageInfoBox } from './MessageInfoBox';
|
|
4
|
-
import type { MessageBoxProps } from './MessageBox';
|
|
5
|
-
|
|
6
|
-
export const MessageContent = customize('MessageContent', (props: MessageBoxProps) => {
|
|
7
|
-
return (
|
|
8
|
-
<div className="wxchtf-message-content">
|
|
9
|
-
<MessageText {...props} />
|
|
10
|
-
<MessageInfoBox {...props} />
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
});
|
|
1
|
+
import { customize } from '../customize';
|
|
2
|
+
import { MessageText } from './MessageText';
|
|
3
|
+
import { MessageInfoBox } from './MessageInfoBox';
|
|
4
|
+
import type { MessageBoxProps } from './MessageBox';
|
|
5
|
+
|
|
6
|
+
export const MessageContent = customize('MessageContent', (props: MessageBoxProps) => {
|
|
7
|
+
return (
|
|
8
|
+
<div className="wxchtf-message-content">
|
|
9
|
+
<MessageText {...props} />
|
|
10
|
+
<MessageInfoBox {...props} />
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
});
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { useMe } from '../../ChatifyContext';
|
|
2
|
-
import { useSelect } from '../../core';
|
|
3
|
-
import { customize } from '../customize';
|
|
4
|
-
import { useLocalizer } from '../localizer';
|
|
5
|
-
import type { MessageBoxProps } from './MessageBox';
|
|
6
|
-
|
|
7
|
-
export const MessageInfoBox = customize('MessageInfoBox', (props: MessageBoxProps) => {
|
|
8
|
-
const { message } = props;
|
|
9
|
-
const { id, sentBy, sentAt } = message;
|
|
10
|
-
const me = useMe();
|
|
11
|
-
const my = sentBy.id === me;
|
|
12
|
-
const localizer = useLocalizer();
|
|
13
|
-
const reading = useSelect((x) => x.queue.read.queued.includes(id), []);
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<div className="wxchtf-message-info-box">
|
|
17
|
-
<div className="wxchtf-message-sent-at">{localizer.timestamp(sentAt)}</div>
|
|
18
|
-
{!my && (
|
|
19
|
-
<div className="wxchtf-message-read-box">
|
|
20
|
-
{reading ? localizer.message.reading() : localizer.message.read()}
|
|
21
|
-
</div>
|
|
22
|
-
)}
|
|
23
|
-
</div>
|
|
24
|
-
);
|
|
25
|
-
});
|
|
1
|
+
import { useMe } from '../../ChatifyContext';
|
|
2
|
+
import { useSelect } from '../../core';
|
|
3
|
+
import { customize } from '../customize';
|
|
4
|
+
import { useLocalizer } from '../localizer';
|
|
5
|
+
import type { MessageBoxProps } from './MessageBox';
|
|
6
|
+
|
|
7
|
+
export const MessageInfoBox = customize('MessageInfoBox', (props: MessageBoxProps) => {
|
|
8
|
+
const { message } = props;
|
|
9
|
+
const { id, sentBy, sentAt } = message;
|
|
10
|
+
const me = useMe();
|
|
11
|
+
const my = sentBy.id === me;
|
|
12
|
+
const localizer = useLocalizer();
|
|
13
|
+
const reading = useSelect((x) => x.queue.read.queued.includes(id), []);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="wxchtf-message-info-box">
|
|
17
|
+
<div className="wxchtf-message-sent-at">{localizer.timestamp(sentAt)}</div>
|
|
18
|
+
{!my && (
|
|
19
|
+
<div className="wxchtf-message-read-box">
|
|
20
|
+
{reading ? localizer.message.reading() : localizer.message.read()}
|
|
21
|
+
</div>
|
|
22
|
+
)}
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { useMe } from '../../ChatifyContext';
|
|
2
|
-
import { Ref } from 'react';
|
|
3
|
-
import { customize } from '../customize';
|
|
4
|
-
import { MessageAuthor } from './MessageAuthor';
|
|
5
|
-
import { MessageContent } from './MessageContent';
|
|
6
|
-
import { MessageBoxProps } from './MessageBox';
|
|
7
|
-
|
|
8
|
-
export interface MessageRowProps extends MessageBoxProps {
|
|
9
|
-
containerRef?: Ref<HTMLDivElement>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const MessageRow = customize('MessageRow', (props: MessageRowProps) => {
|
|
13
|
-
const { message, containerRef } = props;
|
|
14
|
-
const { sentBy } = message;
|
|
15
|
-
const me = useMe();
|
|
16
|
-
const my = sentBy.id === me;
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<div ref={containerRef} className={'wxchtf-message' + (my ? ' --my' : '')}>
|
|
20
|
-
<MessageAuthor {...props} />
|
|
21
|
-
<MessageContent {...props} />
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
});
|
|
1
|
+
import { useMe } from '../../ChatifyContext';
|
|
2
|
+
import { Ref } from 'react';
|
|
3
|
+
import { customize } from '../customize';
|
|
4
|
+
import { MessageAuthor } from './MessageAuthor';
|
|
5
|
+
import { MessageContent } from './MessageContent';
|
|
6
|
+
import { MessageBoxProps } from './MessageBox';
|
|
7
|
+
|
|
8
|
+
export interface MessageRowProps extends MessageBoxProps {
|
|
9
|
+
containerRef?: Ref<HTMLDivElement>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const MessageRow = customize('MessageRow', (props: MessageRowProps) => {
|
|
13
|
+
const { message, containerRef } = props;
|
|
14
|
+
const { sentBy } = message;
|
|
15
|
+
const me = useMe();
|
|
16
|
+
const my = sentBy.id === me;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div ref={containerRef} className={'wxchtf-message' + (my ? ' --my' : '')}>
|
|
20
|
+
<MessageAuthor {...props} />
|
|
21
|
+
<MessageContent {...props} />
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { customize } from '../customize';
|
|
2
|
-
import { MessageBoxProps } from './MessageBox';
|
|
3
|
-
|
|
4
|
-
export const MessageText = customize('MessageText', (props: MessageBoxProps) => {
|
|
5
|
-
const { text } = props.message;
|
|
6
|
-
return <div className="wxchtf-message-text">{text}</div>;
|
|
7
|
-
});
|
|
1
|
+
import { customize } from '../customize';
|
|
2
|
+
import { MessageBoxProps } from './MessageBox';
|
|
3
|
+
|
|
4
|
+
export const MessageText = customize('MessageText', (props: MessageBoxProps) => {
|
|
5
|
+
const { text } = props.message;
|
|
6
|
+
return <div className="wxchtf-message-text">{text}</div>;
|
|
7
|
+
});
|