@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.
- package/dist/{Chatify-CwAfN1wu.js → Chatify-CP2jgo8d.js} +191 -118
- package/dist/Chatify-CP2jgo8d.js.map +1 -0
- package/dist/Chatify.css +28 -0
- package/dist/audit.js +3 -2
- package/dist/audit.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/types/audit/index.d.ts +17 -15
- package/dist/types/ui/Chat/ChatContext.d.ts +2 -0
- package/dist/types/ui/Chat/ChatPanel.d.ts +7 -0
- package/dist/types/ui/Chat/ChatView.d.ts +4 -2
- package/dist/types/ui/ChatGroup/ChatGroupContext.d.ts +4 -1
- package/dist/types/ui/ChatGroup/ChatGroupPanel.d.ts +21 -2
- package/dist/types/ui/Conversation/Conversation.d.ts +1 -0
- package/dist/types/ui/Conversation/ConversationContext.d.ts +1 -0
- package/dist/types/ui/Conversation/ConversationHeader.d.ts +4 -1
- package/dist/types/ui/localizer.d.ts +4 -1
- package/dist/types/ui/useCompact.d.ts +4 -0
- package/package.json +81 -81
- package/src/audit/AuditChatList.tsx +25 -25
- package/src/audit/AuditConversationPanel.tsx +49 -48
- package/src/audit/AuditPanel.tsx +76 -76
- package/src/audit/AuditPanelCustomizeValue.ts +11 -11
- package/src/audit/AuditSearch.tsx +89 -89
- package/src/audit/AuditSearchValue.tsx +42 -42
- package/src/audit/auditApi.tsx +113 -113
- package/src/audit/index.d.ts +18 -18
- package/src/audit/index.tsx +28 -28
- package/src/audit/styles.scss +72 -72
- package/src/core/api/api.ts +675 -675
- package/src/core/api/baseApi.ts +38 -38
- package/src/core/api/index.ts +1 -1
- package/src/core/client.ts +298 -298
- package/src/core/constants.ts +1 -1
- package/src/core/debounce.ts +90 -90
- package/src/core/index.ts +4 -4
- package/src/core/types.tsx +182 -182
- package/src/index.ts +2 -2
- package/src/styles/aside.scss +34 -26
- package/src/styles/chat-list.scss +138 -138
- package/src/styles/chat.scss +11 -11
- package/src/styles/conversation.scss +199 -200
- package/src/styles/index.scss +227 -220
- package/src/styles/input.scss +148 -148
- package/src/styles/keyframes.scss +14 -14
- package/src/styles/members.scss +30 -13
- package/src/styles/mixins.scss +38 -25
- package/src/styles/variables.scss +13 -13
- package/src/ui/Chat/ChatContext.tsx +32 -30
- package/src/ui/Chat/ChatEditableHeaderName.tsx +63 -63
- package/src/ui/Chat/ChatHeaderActions.tsx +19 -19
- package/src/ui/Chat/ChatPanel.tsx +46 -30
- package/src/ui/Chat/ChatView.tsx +122 -115
- package/src/ui/Chat/Members/ChatMembersButton.tsx +9 -9
- package/src/ui/Chat/Members/ChatMembersPanel.tsx +128 -112
- package/src/ui/Chat/Members/ChatMembersPreview.tsx +25 -25
- package/src/ui/Chat/Members/index.ts +13 -13
- package/src/ui/Chat/index.ts +6 -6
- package/src/ui/ChatGroup/AutoReply/AutoReplyButton.tsx +21 -21
- package/src/ui/ChatGroup/AutoReply/AutoReplyForm.tsx +50 -50
- package/src/ui/ChatGroup/AutoReply/AutoReplyPanel.tsx +94 -94
- package/src/ui/ChatGroup/AutoReply/AutoReplyPeriodInput.tsx +22 -22
- package/src/ui/ChatGroup/AutoReply/AutoReplyTextInput.tsx +22 -22
- package/src/ui/ChatGroup/AutoReply/index.ts +19 -19
- package/src/ui/ChatGroup/ChatGroupContext.tsx +63 -61
- package/src/ui/ChatGroup/ChatGroupPanel.tsx +110 -75
- package/src/ui/ChatGroup/Create/CreateChatButton.tsx +15 -15
- package/src/ui/ChatGroup/Create/CreateChatForm.tsx +36 -36
- package/src/ui/ChatGroup/Create/CreateChatMemberInput.tsx +65 -65
- package/src/ui/ChatGroup/Create/CreateChatNameInput.tsx +25 -25
- package/src/ui/ChatGroup/Create/CreateChatPanel.tsx +45 -45
- package/src/ui/ChatGroup/Create/index.ts +19 -19
- package/src/ui/ChatGroup/Layout/ChatGroupActions.tsx +15 -15
- package/src/ui/ChatGroup/Layout/ChatGroupAside.tsx +12 -12
- package/src/ui/ChatGroup/Layout/ChatGroupBody.tsx +17 -10
- package/src/ui/ChatGroup/Layout/ChatGroupFooter.tsx +3 -3
- package/src/ui/ChatGroup/Layout/ChatGroupHeader.tsx +5 -5
- package/src/ui/ChatGroup/Layout/ChatGroupMain.tsx +21 -19
- package/src/ui/ChatGroup/Layout/index.ts +22 -22
- package/src/ui/ChatGroup/List/ChatListPanel.tsx +28 -28
- package/src/ui/ChatGroup/List/index.ts +8 -8
- package/src/ui/ChatGroup/index.ts +6 -6
- package/src/ui/Chatify.tsx +15 -15
- package/src/ui/Conversation/Conversation.tsx +96 -92
- package/src/ui/Conversation/ConversationActions.tsx +12 -12
- package/src/ui/Conversation/ConversationBody.tsx +28 -28
- package/src/ui/Conversation/ConversationContext.ts +31 -30
- package/src/ui/Conversation/ConversationHeader.tsx +35 -19
- package/src/ui/Conversation/ConversationName.tsx +7 -7
- package/src/ui/Conversation/InputBox/InputBox.tsx +126 -126
- package/src/ui/Conversation/InputBox/InputBoxFile.tsx +38 -38
- package/src/ui/Conversation/InputBox/InputBoxFileList.tsx +21 -21
- package/src/ui/Conversation/InputBox/InputFilesBox.tsx +78 -78
- package/src/ui/Conversation/InputBox/InputSubmitButtonBox.tsx +26 -26
- package/src/ui/Conversation/InputBox/InputTextBox.tsx +63 -61
- package/src/ui/Conversation/InputBox/index.ts +23 -23
- package/src/ui/Conversation/Message/MessageAuthor.tsx +13 -13
- package/src/ui/Conversation/Message/MessageBox.tsx +20 -20
- package/src/ui/Conversation/Message/MessageContent.tsx +15 -15
- package/src/ui/Conversation/Message/MessageFile.tsx +54 -54
- package/src/ui/Conversation/Message/MessageFileList.tsx +14 -14
- package/src/ui/Conversation/Message/MessageInfoBox.tsx +28 -28
- package/src/ui/Conversation/Message/MessageRow.tsx +28 -28
- package/src/ui/Conversation/Message/MessageText.tsx +7 -7
- package/src/ui/Conversation/Message/index.ts +28 -28
- package/src/ui/Conversation/NextObserver/NextMessagesObserver.tsx +47 -47
- package/src/ui/Conversation/NextObserver/index.ts +1 -1
- package/src/ui/Conversation/ReadObserver/MessageReadObserver.tsx +49 -49
- package/src/ui/Conversation/ReadObserver/index.ts +1 -1
- package/src/ui/Conversation/SendingMessage/SendingMessageBox.tsx +16 -16
- package/src/ui/Conversation/SendingMessage/SendingMessageContent.tsx +13 -13
- package/src/ui/Conversation/SendingMessage/SendingMessageInfoBox.tsx +13 -13
- package/src/ui/Conversation/SendingMessage/SendingMessageText.tsx +7 -7
- package/src/ui/Conversation/SendingMessage/index.ts +16 -16
- package/src/ui/Conversation/SystemMessage/SystemMessageBox.tsx +20 -20
- package/src/ui/Conversation/SystemMessage/SystemMessageRow.tsx +28 -28
- package/src/ui/Conversation/SystemMessage/index.ts +10 -10
- package/src/ui/Conversation/index.ts +13 -13
- package/src/ui/Thread/ThreadActions.tsx +22 -22
- package/src/ui/Thread/ThreadContext.ts +13 -13
- package/src/ui/Thread/ThreadPanel.tsx +128 -127
- package/src/ui/Thread/index.tsx +3 -3
- package/src/ui/color.ts +20 -20
- package/src/ui/common/Avatar.tsx +20 -20
- package/src/ui/common/ChatList/ChatList.tsx +83 -84
- package/src/ui/common/ChatList/ChatListItemAvatar.tsx +22 -22
- package/src/ui/common/ChatList/ChatListItemBox.tsx +32 -32
- package/src/ui/common/ChatList/ChatListItemLastMessage.tsx +15 -15
- package/src/ui/common/ChatList/ChatListItemLastMessageAuthor.tsx +15 -15
- package/src/ui/common/ChatList/ChatListItemLastMessageContent.tsx +21 -21
- package/src/ui/common/ChatList/ChatListItemLastMessageSentAt.tsx +22 -22
- package/src/ui/common/ChatList/ChatListItemName.tsx +8 -8
- package/src/ui/common/ChatList/ChatListItemUnreadCount.tsx +12 -12
- package/src/ui/common/ChatList/ChatListValue.ts +9 -9
- package/src/ui/common/ChatList/index.ts +32 -32
- package/src/ui/common/Icon.tsx +48 -48
- package/src/ui/common/MessageSkeleton.tsx +20 -20
- package/src/ui/common/index.ts +14 -14
- package/src/ui/customize.tsx +51 -51
- package/src/ui/index.ts +11 -11
- package/src/ui/localizer.tsx +148 -137
- package/src/ui/useCompact.tsx +32 -0
- package/src/ui/useFormatter.tsx +17 -17
- package/dist/Chatify-CwAfN1wu.js.map +0 -1
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { chatifyApi } from '../../../core';
|
|
2
|
-
import { customize } from '../../customize';
|
|
3
|
-
import { useLocalizer } from '../../localizer';
|
|
4
|
-
import { useConversation } from '../ConversationContext';
|
|
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 { lastReadMessageId, isReading, noReadTracking } = useConversation();
|
|
11
|
-
const me = chatifyApi.settings.me();
|
|
12
|
-
const my = sentBy.id === me;
|
|
13
|
-
const localizer = useLocalizer();
|
|
14
|
-
const isRead = lastReadMessageId != null && id.localeCompare(lastReadMessageId) <= 0;
|
|
15
|
-
const reading = !isRead && isReading?.(id);
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div className="wxchtf-message-info-box">
|
|
19
|
-
{!my && <div className="wxchtf-message-author-name">{sentBy.name},</div>}
|
|
20
|
-
<div className="wxchtf-message-sent-at">{localizer.timestamp(sentAt)}</div>
|
|
21
|
-
{!my && !noReadTracking && (
|
|
22
|
-
<div className="wxchtf-message-read-box">
|
|
23
|
-
{reading ? localizer.message.reading() : localizer.message.read()}
|
|
24
|
-
</div>
|
|
25
|
-
)}
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
});
|
|
1
|
+
import { chatifyApi } from '../../../core';
|
|
2
|
+
import { customize } from '../../customize';
|
|
3
|
+
import { useLocalizer } from '../../localizer';
|
|
4
|
+
import { useConversation } from '../ConversationContext';
|
|
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 { lastReadMessageId, isReading, noReadTracking } = useConversation();
|
|
11
|
+
const me = chatifyApi.settings.me();
|
|
12
|
+
const my = sentBy.id === me;
|
|
13
|
+
const localizer = useLocalizer();
|
|
14
|
+
const isRead = lastReadMessageId != null && id.localeCompare(lastReadMessageId) <= 0;
|
|
15
|
+
const reading = !isRead && isReading?.(id);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="wxchtf-message-info-box">
|
|
19
|
+
{!my && <div className="wxchtf-message-author-name">{sentBy.name},</div>}
|
|
20
|
+
<div className="wxchtf-message-sent-at">{localizer.timestamp(sentAt)}</div>
|
|
21
|
+
{!my && !noReadTracking && (
|
|
22
|
+
<div className="wxchtf-message-read-box">
|
|
23
|
+
{reading ? localizer.message.reading() : localizer.message.read()}
|
|
24
|
+
</div>
|
|
25
|
+
)}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { Ref } from 'react';
|
|
2
|
-
import { customize } from '../../customize';
|
|
3
|
-
import { MessageAuthor } from './MessageAuthor';
|
|
4
|
-
import { MessageContent } from './MessageContent';
|
|
5
|
-
import { MessageBoxProps } from './MessageBox';
|
|
6
|
-
import { MessageInfoBox } from './MessageInfoBox';
|
|
7
|
-
import { chatifyApi } from '../../../core';
|
|
8
|
-
|
|
9
|
-
export interface MessageRowProps extends MessageBoxProps {
|
|
10
|
-
containerRef?: Ref<HTMLDivElement>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const MessageRow = customize('MessageRow', (props: MessageRowProps) => {
|
|
14
|
-
const { message, containerRef } = props;
|
|
15
|
-
const { sentBy } = message;
|
|
16
|
-
const me = chatifyApi.settings.me();
|
|
17
|
-
const my = sentBy.id === me;
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<div ref={containerRef} className={'wxchtf-message' + (my ? ' --my' : '')}>
|
|
21
|
-
<MessageAuthor {...props} />
|
|
22
|
-
<div>
|
|
23
|
-
<MessageInfoBox {...props} />
|
|
24
|
-
<MessageContent {...props} />
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
});
|
|
1
|
+
import { Ref } from 'react';
|
|
2
|
+
import { customize } from '../../customize';
|
|
3
|
+
import { MessageAuthor } from './MessageAuthor';
|
|
4
|
+
import { MessageContent } from './MessageContent';
|
|
5
|
+
import { MessageBoxProps } from './MessageBox';
|
|
6
|
+
import { MessageInfoBox } from './MessageInfoBox';
|
|
7
|
+
import { chatifyApi } from '../../../core';
|
|
8
|
+
|
|
9
|
+
export interface MessageRowProps extends MessageBoxProps {
|
|
10
|
+
containerRef?: Ref<HTMLDivElement>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const MessageRow = customize('MessageRow', (props: MessageRowProps) => {
|
|
14
|
+
const { message, containerRef } = props;
|
|
15
|
+
const { sentBy } = message;
|
|
16
|
+
const me = chatifyApi.settings.me();
|
|
17
|
+
const my = sentBy.id === me;
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div ref={containerRef} className={'wxchtf-message' + (my ? ' --my' : '')}>
|
|
21
|
+
<MessageAuthor {...props} />
|
|
22
|
+
<div>
|
|
23
|
+
<MessageInfoBox {...props} />
|
|
24
|
+
<MessageContent {...props} />
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -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
|
+
});
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { MessageAuthor } from './MessageAuthor';
|
|
2
|
-
import { MessageBox } from './MessageBox';
|
|
3
|
-
import { MessageContent } from './MessageContent';
|
|
4
|
-
import { MessageFile } from './MessageFile';
|
|
5
|
-
import { MessageFileList } from './MessageFileList';
|
|
6
|
-
import { MessageInfoBox } from './MessageInfoBox';
|
|
7
|
-
import { MessageRow } from './MessageRow';
|
|
8
|
-
import { MessageText } from './MessageText';
|
|
9
|
-
|
|
10
|
-
export * from './MessageAuthor';
|
|
11
|
-
export * from './MessageBox';
|
|
12
|
-
export * from './MessageContent';
|
|
13
|
-
export * from './MessageInfoBox';
|
|
14
|
-
export * from './MessageRow';
|
|
15
|
-
export * from './MessageText';
|
|
16
|
-
export * from './MessageFileList';
|
|
17
|
-
export * from './MessageFile';
|
|
18
|
-
|
|
19
|
-
export interface MessageCustomizeValue {
|
|
20
|
-
MessageAuthor?: typeof MessageAuthor.Component | null;
|
|
21
|
-
MessageBox?: typeof MessageBox.Component | null;
|
|
22
|
-
MessageContent?: typeof MessageContent.Component | null;
|
|
23
|
-
MessageInfoBox?: typeof MessageInfoBox.Component | null;
|
|
24
|
-
MessageRow?: typeof MessageRow.Component | null;
|
|
25
|
-
MessageText?: typeof MessageText.Component | null;
|
|
26
|
-
MessageFileList?: typeof MessageFileList.Component | null;
|
|
27
|
-
MessageFile?: typeof MessageFile.Component | null;
|
|
28
|
-
}
|
|
1
|
+
import { MessageAuthor } from './MessageAuthor';
|
|
2
|
+
import { MessageBox } from './MessageBox';
|
|
3
|
+
import { MessageContent } from './MessageContent';
|
|
4
|
+
import { MessageFile } from './MessageFile';
|
|
5
|
+
import { MessageFileList } from './MessageFileList';
|
|
6
|
+
import { MessageInfoBox } from './MessageInfoBox';
|
|
7
|
+
import { MessageRow } from './MessageRow';
|
|
8
|
+
import { MessageText } from './MessageText';
|
|
9
|
+
|
|
10
|
+
export * from './MessageAuthor';
|
|
11
|
+
export * from './MessageBox';
|
|
12
|
+
export * from './MessageContent';
|
|
13
|
+
export * from './MessageInfoBox';
|
|
14
|
+
export * from './MessageRow';
|
|
15
|
+
export * from './MessageText';
|
|
16
|
+
export * from './MessageFileList';
|
|
17
|
+
export * from './MessageFile';
|
|
18
|
+
|
|
19
|
+
export interface MessageCustomizeValue {
|
|
20
|
+
MessageAuthor?: typeof MessageAuthor.Component | null;
|
|
21
|
+
MessageBox?: typeof MessageBox.Component | null;
|
|
22
|
+
MessageContent?: typeof MessageContent.Component | null;
|
|
23
|
+
MessageInfoBox?: typeof MessageInfoBox.Component | null;
|
|
24
|
+
MessageRow?: typeof MessageRow.Component | null;
|
|
25
|
+
MessageText?: typeof MessageText.Component | null;
|
|
26
|
+
MessageFileList?: typeof MessageFileList.Component | null;
|
|
27
|
+
MessageFile?: typeof MessageFile.Component | null;
|
|
28
|
+
}
|
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import { MessageSkeleton } from '../../common/MessageSkeleton';
|
|
3
|
-
|
|
4
|
-
export interface NextMessagesObserverProps {
|
|
5
|
-
onLoad: () => void;
|
|
6
|
-
loading: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function NextMessagesObserver(props: NextMessagesObserverProps) {
|
|
10
|
-
const { onLoad, loading } = props;
|
|
11
|
-
const [intersecting, setIntersecting] = useState(false);
|
|
12
|
-
const ref = useRef<HTMLDivElement | null>(null);
|
|
13
|
-
const timerRef = useRef<number>();
|
|
14
|
-
|
|
15
|
-
const observer = useMemo(
|
|
16
|
-
() =>
|
|
17
|
-
new IntersectionObserver(([entry]) => {
|
|
18
|
-
if (entry.isIntersecting) {
|
|
19
|
-
timerRef.current = window.setTimeout(() => setIntersecting(true), 200);
|
|
20
|
-
} else {
|
|
21
|
-
clearTimeout(timerRef.current!);
|
|
22
|
-
}
|
|
23
|
-
}),
|
|
24
|
-
[],
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
observer.observe(ref.current!);
|
|
29
|
-
return () => observer.disconnect();
|
|
30
|
-
}, [observer]);
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
if (!intersecting) {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
onLoad();
|
|
38
|
-
|
|
39
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
-
}, [intersecting]);
|
|
41
|
-
|
|
42
|
-
if (loading || intersecting) {
|
|
43
|
-
return <MessageSkeleton count={4} />;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return <div className="wxchtf-next" ref={ref} />;
|
|
47
|
-
}
|
|
1
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { MessageSkeleton } from '../../common/MessageSkeleton';
|
|
3
|
+
|
|
4
|
+
export interface NextMessagesObserverProps {
|
|
5
|
+
onLoad: () => void;
|
|
6
|
+
loading: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function NextMessagesObserver(props: NextMessagesObserverProps) {
|
|
10
|
+
const { onLoad, loading } = props;
|
|
11
|
+
const [intersecting, setIntersecting] = useState(false);
|
|
12
|
+
const ref = useRef<HTMLDivElement | null>(null);
|
|
13
|
+
const timerRef = useRef<number>();
|
|
14
|
+
|
|
15
|
+
const observer = useMemo(
|
|
16
|
+
() =>
|
|
17
|
+
new IntersectionObserver(([entry]) => {
|
|
18
|
+
if (entry.isIntersecting) {
|
|
19
|
+
timerRef.current = window.setTimeout(() => setIntersecting(true), 200);
|
|
20
|
+
} else {
|
|
21
|
+
clearTimeout(timerRef.current!);
|
|
22
|
+
}
|
|
23
|
+
}),
|
|
24
|
+
[],
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
observer.observe(ref.current!);
|
|
29
|
+
return () => observer.disconnect();
|
|
30
|
+
}, [observer]);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (!intersecting) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
onLoad();
|
|
38
|
+
|
|
39
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
|
+
}, [intersecting]);
|
|
41
|
+
|
|
42
|
+
if (loading || intersecting) {
|
|
43
|
+
return <MessageSkeleton count={4} />;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return <div className="wxchtf-next" ref={ref} />;
|
|
47
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './NextMessagesObserver';
|
|
1
|
+
export * from './NextMessagesObserver';
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { FC, RefObject, useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
import { MessageBoxProps } from '../Message';
|
|
3
|
-
import { useConversation } from '../ConversationContext';
|
|
4
|
-
|
|
5
|
-
export interface MessageReadObserverProps extends MessageBoxProps {
|
|
6
|
-
messageRef: RefObject<HTMLDivElement | null>;
|
|
7
|
-
}
|
|
8
|
-
const Observer: FC<MessageReadObserverProps> = (props) => {
|
|
9
|
-
const { message, messageRef } = props;
|
|
10
|
-
const { onRead, lastReadMessageId } = useConversation();
|
|
11
|
-
const isRead = lastReadMessageId != null && message.id.localeCompare(lastReadMessageId) <= 0;
|
|
12
|
-
const readRef = useRef(isRead);
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
readRef.current = readRef.current || isRead;
|
|
16
|
-
}, [isRead]);
|
|
17
|
-
|
|
18
|
-
const observer = useMemo(
|
|
19
|
-
() =>
|
|
20
|
-
new IntersectionObserver(([entry]) => {
|
|
21
|
-
if (entry.isIntersecting && !readRef.current) {
|
|
22
|
-
readRef.current = true;
|
|
23
|
-
onRead?.(message.id);
|
|
24
|
-
}
|
|
25
|
-
}),
|
|
26
|
-
|
|
27
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
-
[],
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
observer.observe(messageRef.current!);
|
|
33
|
-
return () => observer.disconnect();
|
|
34
|
-
|
|
35
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
-
}, [observer]);
|
|
37
|
-
|
|
38
|
-
return <></>;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export function MessageReadObserver(props: MessageReadObserverProps) {
|
|
42
|
-
const { noReadTracking } = useConversation();
|
|
43
|
-
|
|
44
|
-
if (noReadTracking === true) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return <Observer {...props} />;
|
|
49
|
-
}
|
|
1
|
+
import { FC, RefObject, useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { MessageBoxProps } from '../Message';
|
|
3
|
+
import { useConversation } from '../ConversationContext';
|
|
4
|
+
|
|
5
|
+
export interface MessageReadObserverProps extends MessageBoxProps {
|
|
6
|
+
messageRef: RefObject<HTMLDivElement | null>;
|
|
7
|
+
}
|
|
8
|
+
const Observer: FC<MessageReadObserverProps> = (props) => {
|
|
9
|
+
const { message, messageRef } = props;
|
|
10
|
+
const { onRead, lastReadMessageId } = useConversation();
|
|
11
|
+
const isRead = lastReadMessageId != null && message.id.localeCompare(lastReadMessageId) <= 0;
|
|
12
|
+
const readRef = useRef(isRead);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
readRef.current = readRef.current || isRead;
|
|
16
|
+
}, [isRead]);
|
|
17
|
+
|
|
18
|
+
const observer = useMemo(
|
|
19
|
+
() =>
|
|
20
|
+
new IntersectionObserver(([entry]) => {
|
|
21
|
+
if (entry.isIntersecting && !readRef.current) {
|
|
22
|
+
readRef.current = true;
|
|
23
|
+
onRead?.(message.id);
|
|
24
|
+
}
|
|
25
|
+
}),
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
+
[],
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
observer.observe(messageRef.current!);
|
|
33
|
+
return () => observer.disconnect();
|
|
34
|
+
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
}, [observer]);
|
|
37
|
+
|
|
38
|
+
return <></>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function MessageReadObserver(props: MessageReadObserverProps) {
|
|
42
|
+
const { noReadTracking } = useConversation();
|
|
43
|
+
|
|
44
|
+
if (noReadTracking === true) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return <Observer {...props} />;
|
|
49
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './MessageReadObserver';
|
|
1
|
+
export * from './MessageReadObserver';
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { File } from '../../../core';
|
|
2
|
-
import { customize } from '../../customize';
|
|
3
|
-
import { SendingMessageContent } from './SendingMessageContent';
|
|
4
|
-
|
|
5
|
-
export interface SendingMessageBoxProps {
|
|
6
|
-
text: string;
|
|
7
|
-
files: File[];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const SendingMessageBox = customize('SendingMessageBox', (props: SendingMessageBoxProps) => {
|
|
11
|
-
return (
|
|
12
|
-
<div className="wxchtf-sending-message">
|
|
13
|
-
<SendingMessageContent {...props} />
|
|
14
|
-
</div>
|
|
15
|
-
);
|
|
16
|
-
});
|
|
1
|
+
import { File } from '../../../core';
|
|
2
|
+
import { customize } from '../../customize';
|
|
3
|
+
import { SendingMessageContent } from './SendingMessageContent';
|
|
4
|
+
|
|
5
|
+
export interface SendingMessageBoxProps {
|
|
6
|
+
text: string;
|
|
7
|
+
files: File[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const SendingMessageBox = customize('SendingMessageBox', (props: SendingMessageBoxProps) => {
|
|
11
|
+
return (
|
|
12
|
+
<div className="wxchtf-sending-message">
|
|
13
|
+
<SendingMessageContent {...props} />
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { customize } from '../../customize';
|
|
2
|
-
import { SendingMessageText } from './SendingMessageText';
|
|
3
|
-
import { SendingMessageInfoBox } from './SendingMessageInfoBox';
|
|
4
|
-
import type { SendingMessageBoxProps } from './SendingMessageBox';
|
|
5
|
-
|
|
6
|
-
export const SendingMessageContent = customize('SendingMessageContent', (props: SendingMessageBoxProps) => {
|
|
7
|
-
return (
|
|
8
|
-
<div className="wxchtf-sending-message-content">
|
|
9
|
-
<SendingMessageText {...props} />
|
|
10
|
-
<SendingMessageInfoBox {...props} />
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
});
|
|
1
|
+
import { customize } from '../../customize';
|
|
2
|
+
import { SendingMessageText } from './SendingMessageText';
|
|
3
|
+
import { SendingMessageInfoBox } from './SendingMessageInfoBox';
|
|
4
|
+
import type { SendingMessageBoxProps } from './SendingMessageBox';
|
|
5
|
+
|
|
6
|
+
export const SendingMessageContent = customize('SendingMessageContent', (props: SendingMessageBoxProps) => {
|
|
7
|
+
return (
|
|
8
|
+
<div className="wxchtf-sending-message-content">
|
|
9
|
+
<SendingMessageText {...props} />
|
|
10
|
+
<SendingMessageInfoBox {...props} />
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { customize } from '../../customize';
|
|
2
|
-
import { useLocalizer } from '../../localizer';
|
|
3
|
-
import type { SendingMessageBoxProps } from './SendingMessageBox';
|
|
4
|
-
|
|
5
|
-
export const SendingMessageInfoBox = customize('SendingMessageInfoBox', (_: SendingMessageBoxProps) => {
|
|
6
|
-
const localizer = useLocalizer();
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<div className="wxchtf-sending-message-info-box">
|
|
10
|
-
<div className="wxchtf-sending-message-sending-box">{localizer.message.sending()}</div>
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
});
|
|
1
|
+
import { customize } from '../../customize';
|
|
2
|
+
import { useLocalizer } from '../../localizer';
|
|
3
|
+
import type { SendingMessageBoxProps } from './SendingMessageBox';
|
|
4
|
+
|
|
5
|
+
export const SendingMessageInfoBox = customize('SendingMessageInfoBox', (_: SendingMessageBoxProps) => {
|
|
6
|
+
const localizer = useLocalizer();
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div className="wxchtf-sending-message-info-box">
|
|
10
|
+
<div className="wxchtf-sending-message-sending-box">{localizer.message.sending()}</div>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { customize } from '../../customize';
|
|
2
|
-
import type { SendingMessageBoxProps } from './SendingMessageBox';
|
|
3
|
-
|
|
4
|
-
export const SendingMessageText = customize('SendingMessageText', (props: SendingMessageBoxProps) => {
|
|
5
|
-
const { text } = props;
|
|
6
|
-
return <div className="wxchtf-sending-message-text">{text}</div>;
|
|
7
|
-
});
|
|
1
|
+
import { customize } from '../../customize';
|
|
2
|
+
import type { SendingMessageBoxProps } from './SendingMessageBox';
|
|
3
|
+
|
|
4
|
+
export const SendingMessageText = customize('SendingMessageText', (props: SendingMessageBoxProps) => {
|
|
5
|
+
const { text } = props;
|
|
6
|
+
return <div className="wxchtf-sending-message-text">{text}</div>;
|
|
7
|
+
});
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { SendingMessageBox } from './SendingMessageBox';
|
|
2
|
-
import { SendingMessageContent } from './SendingMessageContent';
|
|
3
|
-
import { SendingMessageInfoBox } from './SendingMessageInfoBox';
|
|
4
|
-
import { SendingMessageText } from './SendingMessageText';
|
|
5
|
-
|
|
6
|
-
export * from './SendingMessageBox';
|
|
7
|
-
export * from './SendingMessageContent';
|
|
8
|
-
export * from './SendingMessageInfoBox';
|
|
9
|
-
export * from './SendingMessageText';
|
|
10
|
-
|
|
11
|
-
export interface SendingMessageCustomizeValue {
|
|
12
|
-
SendingMessageBox?: typeof SendingMessageBox.Component | null;
|
|
13
|
-
SendingMessageContent?: typeof SendingMessageContent.Component | null;
|
|
14
|
-
SendingMessageInfoBox?: typeof SendingMessageInfoBox.Component | null;
|
|
15
|
-
SendingMessageText?: typeof SendingMessageText.Component | null;
|
|
16
|
-
}
|
|
1
|
+
import { SendingMessageBox } from './SendingMessageBox';
|
|
2
|
+
import { SendingMessageContent } from './SendingMessageContent';
|
|
3
|
+
import { SendingMessageInfoBox } from './SendingMessageInfoBox';
|
|
4
|
+
import { SendingMessageText } from './SendingMessageText';
|
|
5
|
+
|
|
6
|
+
export * from './SendingMessageBox';
|
|
7
|
+
export * from './SendingMessageContent';
|
|
8
|
+
export * from './SendingMessageInfoBox';
|
|
9
|
+
export * from './SendingMessageText';
|
|
10
|
+
|
|
11
|
+
export interface SendingMessageCustomizeValue {
|
|
12
|
+
SendingMessageBox?: typeof SendingMessageBox.Component | null;
|
|
13
|
+
SendingMessageContent?: typeof SendingMessageContent.Component | null;
|
|
14
|
+
SendingMessageInfoBox?: typeof SendingMessageInfoBox.Component | null;
|
|
15
|
+
SendingMessageText?: typeof SendingMessageText.Component | null;
|
|
16
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
import { customize } from '../../customize';
|
|
3
|
-
import { MessageBase } from '../../../core';
|
|
4
|
-
import { SystemMessageRow } from './SystemMessageRow';
|
|
5
|
-
import { MessageReadObserver } from '../ReadObserver';
|
|
6
|
-
|
|
7
|
-
export interface SystemMessageBoxProps {
|
|
8
|
-
message: MessageBase;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const SystemMessageBox = customize('SystemMessageBox', (props: SystemMessageBoxProps) => {
|
|
12
|
-
const ref = useRef<HTMLDivElement | null>(null);
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<>
|
|
16
|
-
<MessageReadObserver messageRef={ref} {...props} />
|
|
17
|
-
<SystemMessageRow containerRef={ref} {...props} />
|
|
18
|
-
</>
|
|
19
|
-
);
|
|
20
|
-
});
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { customize } from '../../customize';
|
|
3
|
+
import { MessageBase } from '../../../core';
|
|
4
|
+
import { SystemMessageRow } from './SystemMessageRow';
|
|
5
|
+
import { MessageReadObserver } from '../ReadObserver';
|
|
6
|
+
|
|
7
|
+
export interface SystemMessageBoxProps {
|
|
8
|
+
message: MessageBase;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const SystemMessageBox = customize('SystemMessageBox', (props: SystemMessageBoxProps) => {
|
|
12
|
+
const ref = useRef<HTMLDivElement | null>(null);
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<MessageReadObserver messageRef={ref} {...props} />
|
|
17
|
+
<SystemMessageRow containerRef={ref} {...props} />
|
|
18
|
+
</>
|
|
19
|
+
);
|
|
20
|
+
});
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { Ref } from 'react';
|
|
2
|
-
import { customize } from '../../customize';
|
|
3
|
-
import { Localizer, useLocalizer } from '../../localizer';
|
|
4
|
-
import { MessageBase } from '../../../core';
|
|
5
|
-
|
|
6
|
-
export interface SystemMessageRowProps {
|
|
7
|
-
message: MessageBase;
|
|
8
|
-
containerRef?: Ref<HTMLDivElement>;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function formatSystemMessage(localizer: Localizer, text: string): React.ReactNode {
|
|
12
|
-
const [key, payload] = text.split('::', 2);
|
|
13
|
-
const data = payload ? JSON.parse(payload) : null;
|
|
14
|
-
return localizer.system[key as keyof Localizer['system']](key as any, data);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const SystemMessageRow = customize('SystemMessageRow', (props: SystemMessageRowProps) => {
|
|
18
|
-
const { message, containerRef } = props;
|
|
19
|
-
const { text, sentAt } = message;
|
|
20
|
-
const localizer = useLocalizer();
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<div ref={containerRef} className="wxchtf-system-message">
|
|
24
|
-
<div className="wxchtf-text">{text && formatSystemMessage(localizer, text)}</div>
|
|
25
|
-
<div className="wxchtf-timestamp">{localizer.timestamp(sentAt)}</div>
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
});
|
|
1
|
+
import { Ref } from 'react';
|
|
2
|
+
import { customize } from '../../customize';
|
|
3
|
+
import { Localizer, useLocalizer } from '../../localizer';
|
|
4
|
+
import { MessageBase } from '../../../core';
|
|
5
|
+
|
|
6
|
+
export interface SystemMessageRowProps {
|
|
7
|
+
message: MessageBase;
|
|
8
|
+
containerRef?: Ref<HTMLDivElement>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function formatSystemMessage(localizer: Localizer, text: string): React.ReactNode {
|
|
12
|
+
const [key, payload] = text.split('::', 2);
|
|
13
|
+
const data = payload ? JSON.parse(payload) : null;
|
|
14
|
+
return localizer.system[key as keyof Localizer['system']](key as any, data);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const SystemMessageRow = customize('SystemMessageRow', (props: SystemMessageRowProps) => {
|
|
18
|
+
const { message, containerRef } = props;
|
|
19
|
+
const { text, sentAt } = message;
|
|
20
|
+
const localizer = useLocalizer();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div ref={containerRef} className="wxchtf-system-message">
|
|
24
|
+
<div className="wxchtf-text">{text && formatSystemMessage(localizer, text)}</div>
|
|
25
|
+
<div className="wxchtf-timestamp">{localizer.timestamp(sentAt)}</div>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { SystemMessageBox } from './SystemMessageBox';
|
|
2
|
-
import { SystemMessageRow } from './SystemMessageRow';
|
|
3
|
-
|
|
4
|
-
export * from './SystemMessageBox';
|
|
5
|
-
export * from './SystemMessageRow';
|
|
6
|
-
|
|
7
|
-
export interface SystemMessageCustomizeValue {
|
|
8
|
-
SystemMessageBox?: typeof SystemMessageBox.Component | null;
|
|
9
|
-
SystemMessageRow?: typeof SystemMessageRow.Component | null;
|
|
10
|
-
}
|
|
1
|
+
import { SystemMessageBox } from './SystemMessageBox';
|
|
2
|
+
import { SystemMessageRow } from './SystemMessageRow';
|
|
3
|
+
|
|
4
|
+
export * from './SystemMessageBox';
|
|
5
|
+
export * from './SystemMessageRow';
|
|
6
|
+
|
|
7
|
+
export interface SystemMessageCustomizeValue {
|
|
8
|
+
SystemMessageBox?: typeof SystemMessageBox.Component | null;
|
|
9
|
+
SystemMessageRow?: typeof SystemMessageRow.Component | null;
|
|
10
|
+
}
|