stream-chat-react 13.12.0 → 13.13.0
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/components/Chat/hooks/useChat.js +1 -1
- package/dist/components/MessageList/MessageList.js +8 -5
- package/dist/components/MessageList/renderMessages.js +6 -6
- package/dist/context/ComponentContext.d.ts +4 -0
- package/dist/context/MessageListContext.d.ts +3 -0
- package/dist/experimental/index.browser.cjs.map +2 -2
- package/dist/experimental/index.node.cjs.map +2 -2
- package/dist/index.browser.cjs +62 -48
- package/dist/index.browser.cjs.map +2 -2
- package/dist/index.node.cjs +62 -48
- package/dist/index.node.cjs.map +2 -2
- package/package.json +1 -1
|
@@ -24,7 +24,7 @@ export const useChat = ({ client, defaultLanguage = 'en', i18nInstance, initialN
|
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
if (!client)
|
|
26
26
|
return;
|
|
27
|
-
const version = "13.
|
|
27
|
+
const version = "13.13.0";
|
|
28
28
|
const userAgent = client.getUserAgent();
|
|
29
29
|
if (!userAgent.includes('stream-chat-react')) {
|
|
30
30
|
// result looks like: 'stream-chat-react-2.3.2-stream-chat-javascript-client-browser-2.2.2'
|
|
@@ -25,9 +25,8 @@ const MessageListWithContext = (props) => {
|
|
|
25
25
|
const { channel, channelUnreadUiState, disableDateSeparator = false, groupStyles, hasMoreNewer = false, headerPosition, hideDeletedMessages = false, hideNewMessageSeparator = false, highlightedMessageId, internalInfiniteScrollProps: { threshold: loadMoreScrollThreshold = DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD, ...restInternalInfiniteScrollProps } = {}, jumpToLatestMessage = () => Promise.resolve(), loadMore: loadMoreCallback, loadMoreNewer: loadMoreNewerCallback, // @deprecated in favor of `channelCapabilities` - TODO: remove in next major release
|
|
26
26
|
maxTimeBetweenGroupedMessages, messageActions = Object.keys(MESSAGE_ACTIONS), messageLimit = DEFAULT_NEXT_CHANNEL_PAGE_SIZE, messages = [], noGroupByUser = false, notifications, pinPermissions = defaultPinPermissions, reactionDetailsSort, renderMessages = defaultRenderMessages, returnAllReadData = false, reviewProcessedMessage, showUnreadNotificationAlways, sortReactionDetails, sortReactions, suppressAutoscroll, threadList = false, unsafeHTML = false, } = props;
|
|
27
27
|
const [listElement, setListElement] = React.useState(null);
|
|
28
|
-
const [ulElement, setUlElement] = React.useState(null);
|
|
29
28
|
const { customClasses } = useChatContext('MessageList');
|
|
30
|
-
const { EmptyStateIndicator = DefaultEmptyStateIndicator, LoadingIndicator = DefaultLoadingIndicator, MessageListMainPanel = DefaultMessageListMainPanel, MessageListNotifications = DefaultMessageListNotifications, MessageNotification = DefaultMessageNotification, TypingIndicator = DefaultTypingIndicator, UnreadMessagesNotification = DefaultUnreadMessagesNotification, } = useComponentContext('MessageList');
|
|
29
|
+
const { EmptyStateIndicator = DefaultEmptyStateIndicator, LoadingIndicator = DefaultLoadingIndicator, MessageListMainPanel = DefaultMessageListMainPanel, MessageListNotifications = DefaultMessageListNotifications, MessageListWrapper = 'ul', MessageNotification = DefaultMessageNotification, TypingIndicator = DefaultTypingIndicator, UnreadMessagesNotification = DefaultUnreadMessagesNotification, } = useComponentContext('MessageList');
|
|
31
30
|
const { hasNewMessages, isMessageListScrolledToBottom, onScroll, scrollToBottom, wrapperRect, } = useScrollLocationLogic({
|
|
32
31
|
hasMoreNewer,
|
|
33
32
|
listElement,
|
|
@@ -125,7 +124,7 @@ const MessageListWithContext = (props) => {
|
|
|
125
124
|
}, [scrollToBottom, hasMoreNewer]);
|
|
126
125
|
React.useLayoutEffect(() => {
|
|
127
126
|
if (highlightedMessageId) {
|
|
128
|
-
const element =
|
|
127
|
+
const element = listElement?.querySelector(`[data-message-id='${highlightedMessageId}']`);
|
|
129
128
|
element?.scrollIntoView({ block: 'center' });
|
|
130
129
|
}
|
|
131
130
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -135,12 +134,16 @@ const MessageListWithContext = (props) => {
|
|
|
135
134
|
const dialogManagerId = threadList
|
|
136
135
|
? `message-list-dialog-manager-thread-${id}`
|
|
137
136
|
: `message-list-dialog-manager-${id}`;
|
|
138
|
-
return (React.createElement(MessageListContextProvider, { value: {
|
|
137
|
+
return (React.createElement(MessageListContextProvider, { value: {
|
|
138
|
+
listElement,
|
|
139
|
+
processedMessages: enrichedMessages,
|
|
140
|
+
scrollToBottom,
|
|
141
|
+
} },
|
|
139
142
|
React.createElement(MessageListMainPanel, null,
|
|
140
143
|
React.createElement(DialogManagerProvider, { id: dialogManagerId },
|
|
141
144
|
!threadList && showUnreadMessagesNotification && (React.createElement(UnreadMessagesNotification, { unreadCount: channelUnreadUiState?.unread_messages })),
|
|
142
145
|
React.createElement("div", { className: clsx(messageListClass, customClasses?.threadList), onScroll: onScroll, ref: setListElement, tabIndex: 0 }, showEmptyStateIndicator ? (React.createElement(EmptyStateIndicator, { listType: threadList ? 'thread' : 'message' })) : (React.createElement(InfiniteScroll, { className: 'str-chat__message-list-scroll', "data-testid": 'reverse-infinite-scroll', hasNextPage: props.hasMoreNewer, hasPreviousPage: props.hasMore, head: props.head, isLoading: props.loadingMore, loader: React.createElement("div", { className: 'str-chat__list__loading', key: 'loading-indicator' }, props.loadingMore && React.createElement(LoadingIndicator, { size: 20 })), loadNextPage: loadMoreNewer, loadPreviousPage: loadMore, threshold: loadMoreScrollThreshold, ...restInternalInfiniteScrollProps },
|
|
143
|
-
React.createElement(
|
|
146
|
+
React.createElement(MessageListWrapper, { className: 'str-chat__ul' }, elements),
|
|
144
147
|
React.createElement(TypingIndicator, { threadList: threadList }),
|
|
145
148
|
React.createElement("div", { key: 'bottom' })))))),
|
|
146
149
|
React.createElement(MessageListNotifications, { hasNewMessages: hasNewMessages, isMessageListScrolledToBottom: isMessageListScrolledToBottom, isNotAtLatestMessageSet: hasMoreNewer, MessageNotification: MessageNotification, notifications: notifications, scrollToBottom: scrollToBottomFromNotification, threadList: threadList, unreadCount: threadList ? undefined : channelUnreadUiState?.unread_messages })));
|
|
@@ -5,24 +5,24 @@ import { DateSeparator as DefaultDateSeparator } from '../DateSeparator';
|
|
|
5
5
|
import { EventComponent as DefaultMessageSystem } from '../EventComponent';
|
|
6
6
|
import { UnreadMessagesSeparator as DefaultUnreadMessagesSeparator } from './UnreadMessagesSeparator';
|
|
7
7
|
export function defaultRenderMessages({ channelUnreadUiState, components, customClasses, lastOwnMessage, lastReceivedMessageId: lastReceivedId, messageGroupStyles, messages, ownMessagesDeliveredToOthers, readData, sharedMessageProps: messageProps, }) {
|
|
8
|
-
const { DateSeparator = DefaultDateSeparator, HeaderComponent, MessageSystem = DefaultMessageSystem, UnreadMessagesSeparator = DefaultUnreadMessagesSeparator, } = components;
|
|
8
|
+
const { DateSeparator = DefaultDateSeparator, HeaderComponent, MessageListItem = 'li', MessageSystem = DefaultMessageSystem, UnreadMessagesSeparator = DefaultUnreadMessagesSeparator, } = components;
|
|
9
9
|
const renderedMessages = [];
|
|
10
10
|
let firstMessage;
|
|
11
11
|
let previousMessage = undefined;
|
|
12
12
|
for (let index = 0; index < messages.length; index++) {
|
|
13
13
|
const message = messages[index];
|
|
14
14
|
if (isDateSeparatorMessage(message)) {
|
|
15
|
-
renderedMessages.push(React.createElement("
|
|
15
|
+
renderedMessages.push(React.createElement(MessageListItem, { "data-index": index, key: `${message.date.toISOString()}-i` },
|
|
16
16
|
React.createElement(DateSeparator, { date: message.date, formatDate: messageProps.formatDate, unread: message.unread })));
|
|
17
17
|
}
|
|
18
18
|
else if (isIntroMessage(message)) {
|
|
19
19
|
if (HeaderComponent) {
|
|
20
|
-
renderedMessages.push(React.createElement("
|
|
20
|
+
renderedMessages.push(React.createElement(MessageListItem, { "data-index": index, key: 'intro' },
|
|
21
21
|
React.createElement(HeaderComponent, null)));
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
else if (message.type === 'system') {
|
|
25
|
-
renderedMessages.push(React.createElement(
|
|
25
|
+
renderedMessages.push(React.createElement(MessageListItem, { "data-index": index, "data-message-id": message.id, key: message.id || message.created_at.toISOString() },
|
|
26
26
|
React.createElement(MessageSystem, { message: message })));
|
|
27
27
|
}
|
|
28
28
|
else {
|
|
@@ -41,9 +41,9 @@ export function defaultRenderMessages({ channelUnreadUiState, components, custom
|
|
|
41
41
|
unreadMessageCount: channelUnreadUiState?.unread_messages,
|
|
42
42
|
});
|
|
43
43
|
renderedMessages.push(React.createElement(Fragment, { key: message.id || message.created_at.toISOString() },
|
|
44
|
-
isFirstUnreadMessage && UnreadMessagesSeparator && (React.createElement(
|
|
44
|
+
isFirstUnreadMessage && UnreadMessagesSeparator && (React.createElement(MessageListItem, { className: 'str-chat__li str-chat__unread-messages-separator-wrapper' },
|
|
45
45
|
React.createElement(UnreadMessagesSeparator, { unreadCount: channelUnreadUiState?.unread_messages }))),
|
|
46
|
-
React.createElement(
|
|
46
|
+
React.createElement(MessageListItem, { className: messageClass, "data-index": index, "data-message-id": message.id, "data-testid": messageClass },
|
|
47
47
|
React.createElement(Message, { deliveredTo: ownMessagesDeliveredToOthers[message.id] || [], groupStyles: [groupStyles], lastOwnMessage: lastOwnMessage, lastReceivedId: lastReceivedId, message: message, readBy: readData[message.id] || [], ...messageProps }))));
|
|
48
48
|
previousMessage = message;
|
|
49
49
|
}
|
|
@@ -178,6 +178,10 @@ export type ComponentContextValue = {
|
|
|
178
178
|
UnreadMessagesSeparator?: React.ComponentType<UnreadMessagesSeparatorProps>;
|
|
179
179
|
/** Custom UI component to display a message in the `VirtualizedMessageList`, does not have a default implementation */
|
|
180
180
|
VirtualMessage?: React.ComponentType<FixedHeightMessageProps>;
|
|
181
|
+
/** Custom UI component to wrap MessageList children. Default is the `ul` tag */
|
|
182
|
+
MessageListWrapper?: React.ComponentType<PropsWithChildren>;
|
|
183
|
+
/** Custom UI component to wrap each element of MessageList. Default is the `li` tag */
|
|
184
|
+
MessageListItem?: React.ComponentType<PropsWithChildren>;
|
|
181
185
|
};
|
|
182
186
|
export declare const ComponentContext: React.Context<ComponentContextValue>;
|
|
183
187
|
export declare const ComponentProvider: ({ children, value, }: PropsWithChildren<{
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { PropsWithChildren } from 'react';
|
|
3
|
+
import type { RenderedMessage } from '../components';
|
|
3
4
|
export type MessageListContextValue = {
|
|
5
|
+
/** Enriched message list, including date separators and intro message (if enabled) */
|
|
6
|
+
processedMessages: RenderedMessage[];
|
|
4
7
|
/** The scroll container within which the messages and typing indicator are rendered */
|
|
5
8
|
listElement: HTMLDivElement | null;
|
|
6
9
|
/** Function that scrolls the `listElement` to the bottom. */
|