@webinex/chatify 2.0.0-alpha13 → 2.0.0-alpha14

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.
Files changed (143) hide show
  1. package/dist/{Chatify-CwAfN1wu.js → Chatify-CP2jgo8d.js} +191 -118
  2. package/dist/Chatify-CP2jgo8d.js.map +1 -0
  3. package/dist/Chatify.css +28 -0
  4. package/dist/audit.js +3 -2
  5. package/dist/audit.js.map +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/types/audit/index.d.ts +17 -15
  8. package/dist/types/ui/Chat/ChatContext.d.ts +2 -0
  9. package/dist/types/ui/Chat/ChatPanel.d.ts +7 -0
  10. package/dist/types/ui/Chat/ChatView.d.ts +4 -2
  11. package/dist/types/ui/ChatGroup/ChatGroupContext.d.ts +4 -1
  12. package/dist/types/ui/ChatGroup/ChatGroupPanel.d.ts +21 -2
  13. package/dist/types/ui/Conversation/Conversation.d.ts +1 -0
  14. package/dist/types/ui/Conversation/ConversationContext.d.ts +1 -0
  15. package/dist/types/ui/Conversation/ConversationHeader.d.ts +4 -1
  16. package/dist/types/ui/localizer.d.ts +4 -1
  17. package/dist/types/ui/useCompact.d.ts +4 -0
  18. package/package.json +81 -81
  19. package/src/audit/AuditChatList.tsx +25 -25
  20. package/src/audit/AuditConversationPanel.tsx +49 -48
  21. package/src/audit/AuditPanel.tsx +76 -76
  22. package/src/audit/AuditPanelCustomizeValue.ts +11 -11
  23. package/src/audit/AuditSearch.tsx +89 -89
  24. package/src/audit/AuditSearchValue.tsx +42 -42
  25. package/src/audit/auditApi.tsx +113 -113
  26. package/src/audit/index.d.ts +18 -18
  27. package/src/audit/index.tsx +28 -28
  28. package/src/audit/styles.scss +72 -72
  29. package/src/core/api/api.ts +675 -675
  30. package/src/core/api/baseApi.ts +38 -38
  31. package/src/core/api/index.ts +1 -1
  32. package/src/core/client.ts +298 -298
  33. package/src/core/constants.ts +1 -1
  34. package/src/core/debounce.ts +90 -90
  35. package/src/core/index.ts +4 -4
  36. package/src/core/types.tsx +182 -182
  37. package/src/index.ts +2 -2
  38. package/src/styles/aside.scss +34 -26
  39. package/src/styles/chat-list.scss +138 -138
  40. package/src/styles/chat.scss +11 -11
  41. package/src/styles/conversation.scss +199 -200
  42. package/src/styles/index.scss +227 -220
  43. package/src/styles/input.scss +148 -148
  44. package/src/styles/keyframes.scss +14 -14
  45. package/src/styles/members.scss +30 -13
  46. package/src/styles/mixins.scss +38 -25
  47. package/src/styles/variables.scss +13 -13
  48. package/src/ui/Chat/ChatContext.tsx +32 -30
  49. package/src/ui/Chat/ChatEditableHeaderName.tsx +63 -63
  50. package/src/ui/Chat/ChatHeaderActions.tsx +19 -19
  51. package/src/ui/Chat/ChatPanel.tsx +46 -30
  52. package/src/ui/Chat/ChatView.tsx +122 -115
  53. package/src/ui/Chat/Members/ChatMembersButton.tsx +9 -9
  54. package/src/ui/Chat/Members/ChatMembersPanel.tsx +128 -112
  55. package/src/ui/Chat/Members/ChatMembersPreview.tsx +25 -25
  56. package/src/ui/Chat/Members/index.ts +13 -13
  57. package/src/ui/Chat/index.ts +6 -6
  58. package/src/ui/ChatGroup/AutoReply/AutoReplyButton.tsx +21 -21
  59. package/src/ui/ChatGroup/AutoReply/AutoReplyForm.tsx +50 -50
  60. package/src/ui/ChatGroup/AutoReply/AutoReplyPanel.tsx +94 -94
  61. package/src/ui/ChatGroup/AutoReply/AutoReplyPeriodInput.tsx +22 -22
  62. package/src/ui/ChatGroup/AutoReply/AutoReplyTextInput.tsx +22 -22
  63. package/src/ui/ChatGroup/AutoReply/index.ts +19 -19
  64. package/src/ui/ChatGroup/ChatGroupContext.tsx +63 -61
  65. package/src/ui/ChatGroup/ChatGroupPanel.tsx +110 -75
  66. package/src/ui/ChatGroup/Create/CreateChatButton.tsx +15 -15
  67. package/src/ui/ChatGroup/Create/CreateChatForm.tsx +36 -36
  68. package/src/ui/ChatGroup/Create/CreateChatMemberInput.tsx +65 -65
  69. package/src/ui/ChatGroup/Create/CreateChatNameInput.tsx +25 -25
  70. package/src/ui/ChatGroup/Create/CreateChatPanel.tsx +45 -45
  71. package/src/ui/ChatGroup/Create/index.ts +19 -19
  72. package/src/ui/ChatGroup/Layout/ChatGroupActions.tsx +15 -15
  73. package/src/ui/ChatGroup/Layout/ChatGroupAside.tsx +12 -12
  74. package/src/ui/ChatGroup/Layout/ChatGroupBody.tsx +17 -10
  75. package/src/ui/ChatGroup/Layout/ChatGroupFooter.tsx +3 -3
  76. package/src/ui/ChatGroup/Layout/ChatGroupHeader.tsx +5 -5
  77. package/src/ui/ChatGroup/Layout/ChatGroupMain.tsx +21 -19
  78. package/src/ui/ChatGroup/Layout/index.ts +22 -22
  79. package/src/ui/ChatGroup/List/ChatListPanel.tsx +28 -28
  80. package/src/ui/ChatGroup/List/index.ts +8 -8
  81. package/src/ui/ChatGroup/index.ts +6 -6
  82. package/src/ui/Chatify.tsx +15 -15
  83. package/src/ui/Conversation/Conversation.tsx +96 -92
  84. package/src/ui/Conversation/ConversationActions.tsx +12 -12
  85. package/src/ui/Conversation/ConversationBody.tsx +28 -28
  86. package/src/ui/Conversation/ConversationContext.ts +31 -30
  87. package/src/ui/Conversation/ConversationHeader.tsx +35 -19
  88. package/src/ui/Conversation/ConversationName.tsx +7 -7
  89. package/src/ui/Conversation/InputBox/InputBox.tsx +126 -126
  90. package/src/ui/Conversation/InputBox/InputBoxFile.tsx +38 -38
  91. package/src/ui/Conversation/InputBox/InputBoxFileList.tsx +21 -21
  92. package/src/ui/Conversation/InputBox/InputFilesBox.tsx +78 -78
  93. package/src/ui/Conversation/InputBox/InputSubmitButtonBox.tsx +26 -26
  94. package/src/ui/Conversation/InputBox/InputTextBox.tsx +63 -61
  95. package/src/ui/Conversation/InputBox/index.ts +23 -23
  96. package/src/ui/Conversation/Message/MessageAuthor.tsx +13 -13
  97. package/src/ui/Conversation/Message/MessageBox.tsx +20 -20
  98. package/src/ui/Conversation/Message/MessageContent.tsx +15 -15
  99. package/src/ui/Conversation/Message/MessageFile.tsx +54 -54
  100. package/src/ui/Conversation/Message/MessageFileList.tsx +14 -14
  101. package/src/ui/Conversation/Message/MessageInfoBox.tsx +28 -28
  102. package/src/ui/Conversation/Message/MessageRow.tsx +28 -28
  103. package/src/ui/Conversation/Message/MessageText.tsx +7 -7
  104. package/src/ui/Conversation/Message/index.ts +28 -28
  105. package/src/ui/Conversation/NextObserver/NextMessagesObserver.tsx +47 -47
  106. package/src/ui/Conversation/NextObserver/index.ts +1 -1
  107. package/src/ui/Conversation/ReadObserver/MessageReadObserver.tsx +49 -49
  108. package/src/ui/Conversation/ReadObserver/index.ts +1 -1
  109. package/src/ui/Conversation/SendingMessage/SendingMessageBox.tsx +16 -16
  110. package/src/ui/Conversation/SendingMessage/SendingMessageContent.tsx +13 -13
  111. package/src/ui/Conversation/SendingMessage/SendingMessageInfoBox.tsx +13 -13
  112. package/src/ui/Conversation/SendingMessage/SendingMessageText.tsx +7 -7
  113. package/src/ui/Conversation/SendingMessage/index.ts +16 -16
  114. package/src/ui/Conversation/SystemMessage/SystemMessageBox.tsx +20 -20
  115. package/src/ui/Conversation/SystemMessage/SystemMessageRow.tsx +28 -28
  116. package/src/ui/Conversation/SystemMessage/index.ts +10 -10
  117. package/src/ui/Conversation/index.ts +13 -13
  118. package/src/ui/Thread/ThreadActions.tsx +22 -22
  119. package/src/ui/Thread/ThreadContext.ts +13 -13
  120. package/src/ui/Thread/ThreadPanel.tsx +128 -127
  121. package/src/ui/Thread/index.tsx +3 -3
  122. package/src/ui/color.ts +20 -20
  123. package/src/ui/common/Avatar.tsx +20 -20
  124. package/src/ui/common/ChatList/ChatList.tsx +83 -84
  125. package/src/ui/common/ChatList/ChatListItemAvatar.tsx +22 -22
  126. package/src/ui/common/ChatList/ChatListItemBox.tsx +32 -32
  127. package/src/ui/common/ChatList/ChatListItemLastMessage.tsx +15 -15
  128. package/src/ui/common/ChatList/ChatListItemLastMessageAuthor.tsx +15 -15
  129. package/src/ui/common/ChatList/ChatListItemLastMessageContent.tsx +21 -21
  130. package/src/ui/common/ChatList/ChatListItemLastMessageSentAt.tsx +22 -22
  131. package/src/ui/common/ChatList/ChatListItemName.tsx +8 -8
  132. package/src/ui/common/ChatList/ChatListItemUnreadCount.tsx +12 -12
  133. package/src/ui/common/ChatList/ChatListValue.ts +9 -9
  134. package/src/ui/common/ChatList/index.ts +32 -32
  135. package/src/ui/common/Icon.tsx +48 -48
  136. package/src/ui/common/MessageSkeleton.tsx +20 -20
  137. package/src/ui/common/index.ts +14 -14
  138. package/src/ui/customize.tsx +51 -51
  139. package/src/ui/index.ts +11 -11
  140. package/src/ui/localizer.tsx +148 -137
  141. package/src/ui/useCompact.tsx +32 -0
  142. package/src/ui/useFormatter.tsx +17 -17
  143. package/dist/Chatify-CwAfN1wu.js.map +0 -1
@@ -1,78 +1,78 @@
1
- import { Button } from 'antd';
2
- import { customize } from '../../customize';
3
- import { Icon } from '../../common/Icon';
4
- import { File } from '../../../core';
5
- import { useCallback, useEffect, useRef } from 'react';
6
-
7
- export interface InputFilesBoxProps {
8
- value: File[];
9
- accept?: string;
10
- loading?: boolean;
11
- disabled?: boolean;
12
- onAddedClick?: () => void;
13
- onUpload: (value: globalThis.File[]) => void;
14
- }
15
-
16
- export const InputFileButton = customize('InputFileButton', (props: InputFilesBoxProps) => {
17
- const { onUpload, onAddedClick, accept, loading, value, disabled } = props;
18
- const inputRef = useRef<HTMLInputElement | null>(null);
19
- const onClick = useCallback(() => inputRef.current?.click(), []);
20
- const countButtonRef = useRef<HTMLButtonElement | null>(null);
21
-
22
- useEffect(() => {
23
- countButtonRef.current?.classList.add('active');
24
- }, [value]);
25
-
26
- const onCountButtonAnimationEnd = useCallback(() => {
27
- countButtonRef.current?.classList.remove('active');
28
- }, []);
29
-
30
- const onInputChange = useCallback(
31
- (e: React.ChangeEvent<HTMLInputElement>) => {
32
- const files = e.target.files;
33
- files && files.length > 0 && onUpload(Array.from(files));
34
- },
35
- [onUpload],
36
- );
37
-
38
- return (
39
- <>
40
- <Button
41
- loading={loading}
42
- onClick={onClick}
43
- type="link"
44
- disabled={disabled}
45
- icon={<Icon type="attach" />}
46
- className="wxchtf-add-files-btn"
47
- />
48
- {value.length > 0 && (
49
- <Button
50
- ref={countButtonRef}
51
- className="wxchtf-add-files-added-btn"
52
- onAnimationIteration={onCountButtonAnimationEnd}
53
- onClick={onAddedClick}
54
- type="link"
55
- disabled={disabled}
56
- icon={<>+{value.length}</>}
57
- />
58
- )}
59
- <input
60
- value=""
61
- accept={accept}
62
- onChange={onInputChange}
63
- ref={inputRef}
64
- type="file"
65
- multiple
66
- style={{ display: 'none' }}
67
- />
68
- </>
69
- );
70
- });
71
-
72
- export const InputFilesBox = customize('InputFilesBox', (props: InputFilesBoxProps) => {
73
- return (
74
- <div className="wxchtf-add-files-box">
75
- <InputFileButton {...props} />
76
- </div>
77
- );
78
- });
1
+ import { Button } from 'antd';
2
+ import { customize } from '../../customize';
3
+ import { Icon } from '../../common/Icon';
4
+ import { File } from '../../../core';
5
+ import { useCallback, useEffect, useRef } from 'react';
6
+
7
+ export interface InputFilesBoxProps {
8
+ value: File[];
9
+ accept?: string;
10
+ loading?: boolean;
11
+ disabled?: boolean;
12
+ onAddedClick?: () => void;
13
+ onUpload: (value: globalThis.File[]) => void;
14
+ }
15
+
16
+ export const InputFileButton = customize('InputFileButton', (props: InputFilesBoxProps) => {
17
+ const { onUpload, onAddedClick, accept, loading, value, disabled } = props;
18
+ const inputRef = useRef<HTMLInputElement | null>(null);
19
+ const onClick = useCallback(() => inputRef.current?.click(), []);
20
+ const countButtonRef = useRef<HTMLButtonElement | null>(null);
21
+
22
+ useEffect(() => {
23
+ countButtonRef.current?.classList.add('active');
24
+ }, [value]);
25
+
26
+ const onCountButtonAnimationEnd = useCallback(() => {
27
+ countButtonRef.current?.classList.remove('active');
28
+ }, []);
29
+
30
+ const onInputChange = useCallback(
31
+ (e: React.ChangeEvent<HTMLInputElement>) => {
32
+ const files = e.target.files;
33
+ files && files.length > 0 && onUpload(Array.from(files));
34
+ },
35
+ [onUpload],
36
+ );
37
+
38
+ return (
39
+ <>
40
+ <Button
41
+ loading={loading}
42
+ onClick={onClick}
43
+ type="link"
44
+ disabled={disabled}
45
+ icon={<Icon type="attach" />}
46
+ className="wxchtf-add-files-btn"
47
+ />
48
+ {value.length > 0 && (
49
+ <Button
50
+ ref={countButtonRef}
51
+ className="wxchtf-add-files-added-btn"
52
+ onAnimationIteration={onCountButtonAnimationEnd}
53
+ onClick={onAddedClick}
54
+ type="link"
55
+ disabled={disabled}
56
+ icon={<>+{value.length}</>}
57
+ />
58
+ )}
59
+ <input
60
+ value=""
61
+ accept={accept}
62
+ onChange={onInputChange}
63
+ ref={inputRef}
64
+ type="file"
65
+ multiple
66
+ style={{ display: 'none' }}
67
+ />
68
+ </>
69
+ );
70
+ });
71
+
72
+ export const InputFilesBox = customize('InputFilesBox', (props: InputFilesBoxProps) => {
73
+ return (
74
+ <div className="wxchtf-add-files-box">
75
+ <InputFileButton {...props} />
76
+ </div>
77
+ );
78
+ });
@@ -1,26 +1,26 @@
1
- import { Button } from 'antd';
2
- import { customize } from '../../customize';
3
- import { Icon } from '../../common/Icon';
4
-
5
- export interface InputSubmitButtonBoxProps {
6
- onSubmit: () => void;
7
- disabled?: boolean;
8
- loading?: boolean;
9
- }
10
-
11
- export const InputSubmitButtonBox = customize('InputSubmitButtonBox', (props: InputSubmitButtonBoxProps) => {
12
- const { onSubmit, disabled, loading } = props;
13
-
14
- return (
15
- <div className="wxchtf-submit-btn-box">
16
- <Button
17
- onClick={onSubmit}
18
- type="link"
19
- icon={<Icon type="send" />}
20
- className="wxchtf-submit-btn"
21
- disabled={disabled}
22
- loading={loading}
23
- />
24
- </div>
25
- );
26
- });
1
+ import { Button } from 'antd';
2
+ import { customize } from '../../customize';
3
+ import { Icon } from '../../common/Icon';
4
+
5
+ export interface InputSubmitButtonBoxProps {
6
+ onSubmit: () => void;
7
+ disabled?: boolean;
8
+ loading?: boolean;
9
+ }
10
+
11
+ export const InputSubmitButtonBox = customize('InputSubmitButtonBox', (props: InputSubmitButtonBoxProps) => {
12
+ const { onSubmit, disabled, loading } = props;
13
+
14
+ return (
15
+ <div className="wxchtf-submit-btn-box">
16
+ <Button
17
+ onClick={onSubmit}
18
+ type="link"
19
+ icon={<Icon type="send" />}
20
+ className="wxchtf-submit-btn"
21
+ disabled={disabled}
22
+ loading={loading}
23
+ />
24
+ </div>
25
+ );
26
+ });
@@ -1,61 +1,63 @@
1
- import { Input } from 'antd';
2
- import { customize } from '../../customize';
3
- import { isHotkey } from 'is-hotkey';
4
- import { RefObject, memo, useCallback } from 'react';
5
- import { useLocalizer } from '../../localizer';
6
- import { TextAreaProps } from 'antd/es/input';
7
-
8
- export interface TextInputBoxProps {
9
- value: string;
10
- onChange: (value: string) => void;
11
- onSend: (value: string) => void;
12
- disabled?: boolean;
13
- inputRef?: RefObject<HTMLTextAreaElement>;
14
- }
15
-
16
- const isEnter = isHotkey('enter');
17
- const isCtrlEnter = isHotkey('ctrl+enter');
18
-
19
- const AUTO_SIZE: TextAreaProps['autoSize'] = { maxRows: 5, minRows: 1 };
20
-
21
- export const InputTextBox = customize(
22
- 'InputTextBox',
23
- memo((props: TextInputBoxProps) => {
24
- const { value, onChange, onSend, disabled, inputRef } = props;
25
- const localizer = useLocalizer();
26
-
27
- const onInputChange = useCallback(
28
- (e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value),
29
- [onChange],
30
- );
31
-
32
- const onKeyDown = useCallback(
33
- (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
34
- if (disabled) {
35
- e.preventDefault();
36
- return;
37
- }
38
-
39
- if (isEnter(e) || isCtrlEnter(e)) {
40
- e.preventDefault();
41
- onSend(value);
42
- }
43
- },
44
- [onSend, value, disabled],
45
- );
46
-
47
- return (
48
- <div className="wxchtf-text-input-box">
49
- <Input.TextArea
50
- ref={inputRef}
51
- value={value}
52
- onChange={onInputChange}
53
- autoSize={AUTO_SIZE}
54
- className="wxchtf-text-input-textarea"
55
- placeholder={localizer.input.placeholder()}
56
- onKeyDown={onKeyDown}
57
- />
58
- </div>
59
- );
60
- }),
61
- );
1
+ import { Input } from 'antd';
2
+ import { customize } from '../../customize';
3
+ import { isHotkey } from 'is-hotkey';
4
+ import { RefObject, memo, useCallback } from 'react';
5
+ import { useLocalizer } from '../../localizer';
6
+ import { TextAreaProps } from 'antd/es/input';
7
+ import { useConversation } from '../ConversationContext';
8
+
9
+ export interface TextInputBoxProps {
10
+ value: string;
11
+ onChange: (value: string) => void;
12
+ onSend: (value: string) => void;
13
+ disabled?: boolean;
14
+ inputRef?: RefObject<HTMLTextAreaElement>;
15
+ }
16
+
17
+ const isEnter = isHotkey('enter');
18
+ const isCtrlEnter = isHotkey('ctrl+enter');
19
+
20
+ const AUTO_SIZE: TextAreaProps['autoSize'] = { maxRows: 5, minRows: 1 };
21
+
22
+ export const InputTextBox = customize(
23
+ 'InputTextBox',
24
+ memo((props: TextInputBoxProps) => {
25
+ const { value, onChange, onSend, disabled, inputRef } = props;
26
+ const localizer = useLocalizer();
27
+ const { compact } = useConversation();
28
+
29
+ const onInputChange = useCallback(
30
+ (e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value),
31
+ [onChange],
32
+ );
33
+
34
+ const onKeyDown = useCallback(
35
+ (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
36
+ if (disabled) {
37
+ e.preventDefault();
38
+ return;
39
+ }
40
+
41
+ if (isEnter(e) || isCtrlEnter(e)) {
42
+ e.preventDefault();
43
+ onSend(value);
44
+ }
45
+ },
46
+ [onSend, value, disabled],
47
+ );
48
+
49
+ return (
50
+ <div className="wxchtf-text-input-box">
51
+ <Input.TextArea
52
+ ref={inputRef}
53
+ value={value}
54
+ onChange={onInputChange}
55
+ autoSize={AUTO_SIZE}
56
+ className="wxchtf-text-input-textarea"
57
+ placeholder={localizer.input.placeholder(compact ? 'compact' : 'default')}
58
+ onKeyDown={onKeyDown}
59
+ />
60
+ </div>
61
+ );
62
+ }),
63
+ );
@@ -1,23 +1,23 @@
1
- import { InputBox } from './InputBox';
2
- import { InputBoxFile } from './InputBoxFile';
3
- import { InputBoxFileList } from './InputBoxFileList';
4
- import { InputFileButton, InputFilesBox } from './InputFilesBox';
5
- import { InputSubmitButtonBox } from './InputSubmitButtonBox';
6
- import { InputTextBox } from './InputTextBox';
7
-
8
- export * from './InputBox';
9
- export * from './InputFilesBox';
10
- export * from './InputSubmitButtonBox';
11
- export * from './InputTextBox';
12
- export * from './InputBoxFileList';
13
- export * from './InputBoxFile';
14
-
15
- export interface InputBoxCustomizeValue {
16
- InputBox?: typeof InputBox.Component | null;
17
- InputTextBox?: typeof InputTextBox.Component | null;
18
- InputFilesBox?: typeof InputFilesBox.Component | null;
19
- InputSubmitButtonBox?: typeof InputSubmitButtonBox.Component | null;
20
- InputBoxFileList?: typeof InputBoxFileList.Component | null;
21
- InputBoxFile?: typeof InputBoxFile.Component | null;
22
- InputFileButton?: typeof InputFileButton.Component | null;
23
- }
1
+ import { InputBox } from './InputBox';
2
+ import { InputBoxFile } from './InputBoxFile';
3
+ import { InputBoxFileList } from './InputBoxFileList';
4
+ import { InputFileButton, InputFilesBox } from './InputFilesBox';
5
+ import { InputSubmitButtonBox } from './InputSubmitButtonBox';
6
+ import { InputTextBox } from './InputTextBox';
7
+
8
+ export * from './InputBox';
9
+ export * from './InputFilesBox';
10
+ export * from './InputSubmitButtonBox';
11
+ export * from './InputTextBox';
12
+ export * from './InputBoxFileList';
13
+ export * from './InputBoxFile';
14
+
15
+ export interface InputBoxCustomizeValue {
16
+ InputBox?: typeof InputBox.Component | null;
17
+ InputTextBox?: typeof InputTextBox.Component | null;
18
+ InputFilesBox?: typeof InputFilesBox.Component | null;
19
+ InputSubmitButtonBox?: typeof InputSubmitButtonBox.Component | null;
20
+ InputBoxFileList?: typeof InputBoxFileList.Component | null;
21
+ InputBoxFile?: typeof InputBoxFile.Component | null;
22
+ InputFileButton?: typeof InputFileButton.Component | null;
23
+ }
@@ -1,13 +1,13 @@
1
- import { customize } from '../../customize';
2
- import { Avatar } from '../../common/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 '../../common/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 { customize } from '../../customize';
3
- import { MessageReadObserver } from '../ReadObserver';
4
- import { MessageRow } from './MessageRow';
5
- import { MessageBase } from '../../../core';
6
-
7
- export interface MessageBoxProps {
8
- message: MessageBase;
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 { customize } from '../../customize';
3
+ import { MessageReadObserver } from '../ReadObserver';
4
+ import { MessageRow } from './MessageRow';
5
+ import { MessageBase } from '../../../core';
6
+
7
+ export interface MessageBoxProps {
8
+ message: MessageBase;
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,15 +1,15 @@
1
- import { customize } from '../../customize';
2
- import { MessageText } from './MessageText';
3
- import type { MessageBoxProps } from './MessageBox';
4
- import { MessageFileList } from './MessageFileList';
5
-
6
- export const MessageContent = customize('MessageContent', (props: MessageBoxProps) => {
7
- const { files, text } = props.message;
8
-
9
- return (
10
- <div className="wxchtf-message-content">
11
- {text && <MessageText {...props} />}
12
- {files.length > 0 && <MessageFileList {...props} />}
13
- </div>
14
- );
15
- });
1
+ import { customize } from '../../customize';
2
+ import { MessageText } from './MessageText';
3
+ import type { MessageBoxProps } from './MessageBox';
4
+ import { MessageFileList } from './MessageFileList';
5
+
6
+ export const MessageContent = customize('MessageContent', (props: MessageBoxProps) => {
7
+ const { files, text } = props.message;
8
+
9
+ return (
10
+ <div className="wxchtf-message-content">
11
+ {text && <MessageText {...props} />}
12
+ {files.length > 0 && <MessageFileList {...props} />}
13
+ </div>
14
+ );
15
+ });
@@ -1,54 +1,54 @@
1
- import { Button } from 'antd';
2
- import { File } from '../../../core';
3
- import { customize, useCustomizeContext } from '../../customize';
4
- import { useFormatter } from '../../useFormatter';
5
- import { Icon } from '../../common';
6
- import { ConversationCustomizeValue } from '../Conversation';
7
- import { useCallback, useState } from 'react';
8
-
9
- function open(url: string) {
10
- const w = window.open(url, '_blank');
11
- w?.focus();
12
- }
13
-
14
- export interface MessageFileProps {
15
- file: File;
16
- }
17
-
18
- function useOpen(props: MessageFileProps) {
19
- const { file } = props;
20
- const { flippo } = useCustomizeContext<ConversationCustomizeValue>();
21
- const [isOpenFetching, setIsOpenFetching] = useState(false);
22
-
23
- const onOpen = useCallback(
24
- () =>
25
- flippo &&
26
- Promise.resolve(setIsOpenFetching(true))
27
- .then(() => flippo!.getSasUrl(file.ref))
28
- .then(open)
29
- .finally(() => setIsOpenFetching(false)),
30
- [flippo, file.ref],
31
- );
32
-
33
- return [onOpen, { isOpenFetching }] as const;
34
- }
35
-
36
- export const MessageFile = customize('MessageFile', (props: MessageFileProps) => {
37
- const { file } = props;
38
- const formatter = useFormatter();
39
- const [onOpen, { isOpenFetching }] = useOpen(props);
40
-
41
- return (
42
- <div className="wxchtf-file">
43
- <div className="wxchtf-icon">
44
- <Button loading={isOpenFetching} onClick={onOpen} type="link" icon={<Icon type="open-file" />} />
45
- </div>
46
- <div className="wxchtf-file-info">
47
- <div className="wxchtf-name" title={file.name}>
48
- {file.name}
49
- </div>
50
- <div className="wxchtf-size">{formatter.size(file.bytes)}</div>
51
- </div>
52
- </div>
53
- );
54
- });
1
+ import { Button } from 'antd';
2
+ import { File } from '../../../core';
3
+ import { customize, useCustomizeContext } from '../../customize';
4
+ import { useFormatter } from '../../useFormatter';
5
+ import { Icon } from '../../common';
6
+ import { ConversationCustomizeValue } from '../Conversation';
7
+ import { useCallback, useState } from 'react';
8
+
9
+ function open(url: string) {
10
+ const w = window.open(url, '_blank');
11
+ w?.focus();
12
+ }
13
+
14
+ export interface MessageFileProps {
15
+ file: File;
16
+ }
17
+
18
+ function useOpen(props: MessageFileProps) {
19
+ const { file } = props;
20
+ const { flippo } = useCustomizeContext<ConversationCustomizeValue>();
21
+ const [isOpenFetching, setIsOpenFetching] = useState(false);
22
+
23
+ const onOpen = useCallback(
24
+ () =>
25
+ flippo &&
26
+ Promise.resolve(setIsOpenFetching(true))
27
+ .then(() => flippo!.getSasUrl(file.ref))
28
+ .then(open)
29
+ .finally(() => setIsOpenFetching(false)),
30
+ [flippo, file.ref],
31
+ );
32
+
33
+ return [onOpen, { isOpenFetching }] as const;
34
+ }
35
+
36
+ export const MessageFile = customize('MessageFile', (props: MessageFileProps) => {
37
+ const { file } = props;
38
+ const formatter = useFormatter();
39
+ const [onOpen, { isOpenFetching }] = useOpen(props);
40
+
41
+ return (
42
+ <div className="wxchtf-file">
43
+ <div className="wxchtf-icon">
44
+ <Button loading={isOpenFetching} onClick={onOpen} type="link" icon={<Icon type="open-file" />} />
45
+ </div>
46
+ <div className="wxchtf-file-info">
47
+ <div className="wxchtf-name" title={file.name}>
48
+ {file.name}
49
+ </div>
50
+ <div className="wxchtf-size">{formatter.size(file.bytes)}</div>
51
+ </div>
52
+ </div>
53
+ );
54
+ });
@@ -1,14 +1,14 @@
1
- import { customize } from '../../customize';
2
- import { MessageBoxProps } from './MessageBox';
3
- import { MessageFile } from './MessageFile';
4
-
5
- export const MessageFileList = customize('MessageFileList', (props: MessageBoxProps) => {
6
- const { files } = props.message;
7
- return (
8
- <div className="wxchtf-file-list">
9
- {files.map((file) => (
10
- <MessageFile key={file.ref} file={file} />
11
- ))}
12
- </div>
13
- );
14
- });
1
+ import { customize } from '../../customize';
2
+ import { MessageBoxProps } from './MessageBox';
3
+ import { MessageFile } from './MessageFile';
4
+
5
+ export const MessageFileList = customize('MessageFileList', (props: MessageBoxProps) => {
6
+ const { files } = props.message;
7
+ return (
8
+ <div className="wxchtf-file-list">
9
+ {files.map((file) => (
10
+ <MessageFile key={file.ref} file={file} />
11
+ ))}
12
+ </div>
13
+ );
14
+ });