stream-chat-react 12.0.0-rc.9 → 12.1.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/Avatar/Avatar.js +5 -1
- package/dist/components/Channel/Channel.d.ts +5 -106
- package/dist/components/Channel/Channel.js +76 -24
- package/dist/components/Channel/hooks/useCreateChannelStateContext.js +2 -1
- package/dist/components/ChannelHeader/ChannelHeader.js +4 -5
- package/dist/components/ChannelPreview/hooks/useChannelPreviewInfo.js +14 -16
- package/dist/components/ChannelPreview/utils.js +9 -20
- package/dist/components/ChannelSearch/hooks/useChannelSearch.js +2 -3
- package/dist/components/Chat/Chat.d.ts +1 -1
- package/dist/components/Chat/hooks/useChat.d.ts +2 -2
- package/dist/components/Chat/hooks/useChat.js +11 -8
- package/dist/components/ChatView/ChatView.d.ts +18 -0
- package/dist/components/ChatView/ChatView.js +103 -0
- package/dist/components/ChatView/index.d.ts +1 -0
- package/dist/components/ChatView/index.js +1 -0
- package/dist/components/DateSeparator/DateSeparator.d.ts +1 -1
- package/dist/components/Dialog/DialogAnchor.d.ts +25 -0
- package/dist/components/Dialog/DialogAnchor.js +68 -0
- package/dist/components/Dialog/DialogManager.d.ts +43 -0
- package/dist/components/Dialog/DialogManager.js +98 -0
- package/dist/components/Dialog/DialogPortal.d.ts +7 -0
- package/dist/components/Dialog/DialogPortal.js +25 -0
- package/dist/components/Dialog/hooks/index.d.ts +1 -0
- package/dist/components/Dialog/hooks/index.js +1 -0
- package/dist/components/Dialog/hooks/useDialog.d.ts +4 -0
- package/dist/components/Dialog/hooks/useDialog.js +26 -0
- package/dist/components/Dialog/index.d.ts +4 -0
- package/dist/components/Dialog/index.js +4 -0
- package/dist/components/EventComponent/EventComponent.d.ts +1 -1
- package/dist/components/Message/Message.js +5 -6
- package/dist/components/Message/MessageOptions.d.ts +1 -2
- package/dist/components/Message/MessageOptions.js +14 -11
- package/dist/components/Message/MessageSimple.js +6 -14
- package/dist/components/Message/MessageTimestamp.d.ts +1 -1
- package/dist/components/Message/QuotedMessage.js +2 -1
- package/dist/components/Message/Timestamp.d.ts +1 -1
- package/dist/components/Message/Timestamp.js +2 -2
- package/dist/components/Message/hooks/useReactionHandler.d.ts +1 -7
- package/dist/components/Message/hooks/useReactionHandler.js +8 -63
- package/dist/components/Message/utils.d.ts +10 -1
- package/dist/components/Message/utils.js +19 -7
- package/dist/components/MessageActions/MessageActions.d.ts +1 -2
- package/dist/components/MessageActions/MessageActions.js +26 -55
- package/dist/components/MessageActions/MessageActionsBox.d.ts +1 -1
- package/dist/components/MessageActions/MessageActionsBox.js +6 -6
- package/dist/components/MessageInput/MessageInputFlat.js +2 -2
- package/dist/components/MessageInput/QuotedMessagePreview.js +2 -1
- package/dist/components/MessageInput/hooks/useUserTrigger.js +0 -1
- package/dist/components/MessageList/MessageList.js +9 -9
- package/dist/components/MessageList/MessageListMainPanel.d.ts +1 -1
- package/dist/components/MessageList/MessageListMainPanel.js +1 -1
- package/dist/components/MessageList/VirtualizedMessageList.d.ts +2 -1
- package/dist/components/MessageList/VirtualizedMessageList.js +45 -40
- package/dist/components/MessageList/VirtualizedMessageListComponents.d.ts +1 -1
- package/dist/components/MessageList/VirtualizedMessageListComponents.js +6 -6
- package/dist/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.js +2 -2
- package/dist/components/MessageList/renderMessages.d.ts +2 -2
- package/dist/components/MessageList/renderMessages.js +4 -1
- package/dist/components/MessageList/utils.js +1 -1
- package/dist/components/Reactions/ReactionSelector.d.ts +6 -3
- package/dist/components/Reactions/ReactionSelector.js +34 -24
- package/dist/components/Reactions/ReactionSelectorWithButton.d.ts +13 -0
- package/dist/components/Reactions/ReactionSelectorWithButton.js +22 -0
- package/dist/components/Reactions/ReactionsList.d.ts +4 -4
- package/dist/components/Reactions/hooks/useProcessReactions.js +2 -1
- package/dist/components/Thread/Thread.js +38 -10
- package/dist/components/Threads/ThreadContext.d.ts +9 -0
- package/dist/components/Threads/ThreadContext.js +9 -0
- package/dist/components/Threads/ThreadList/ThreadList.d.ts +9 -0
- package/dist/components/Threads/ThreadList/ThreadList.js +41 -0
- package/dist/components/Threads/ThreadList/ThreadListEmptyPlaceholder.d.ts +2 -0
- package/dist/components/Threads/ThreadList/ThreadListEmptyPlaceholder.js +5 -0
- package/dist/components/Threads/ThreadList/ThreadListItem.d.ts +9 -0
- package/dist/components/Threads/ThreadList/ThreadListItem.js +52 -0
- package/dist/components/Threads/ThreadList/ThreadListItemUI.d.ts +15 -0
- package/dist/components/Threads/ThreadList/ThreadListItemUI.js +75 -0
- package/dist/components/Threads/ThreadList/ThreadListLoadingIndicator.d.ts +2 -0
- package/dist/components/Threads/ThreadList/ThreadListLoadingIndicator.js +14 -0
- package/dist/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.d.ts +2 -0
- package/dist/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.js +16 -0
- package/dist/components/Threads/ThreadList/index.d.ts +3 -0
- package/dist/components/Threads/ThreadList/index.js +3 -0
- package/dist/components/Threads/UnreadCountBadge.d.ts +6 -0
- package/dist/components/Threads/UnreadCountBadge.js +5 -0
- package/dist/components/Threads/hooks/useThreadManagerState.d.ts +2 -0
- package/dist/components/Threads/hooks/useThreadManagerState.js +6 -0
- package/dist/components/Threads/hooks/useThreadState.d.ts +5 -0
- package/dist/components/Threads/hooks/useThreadState.js +11 -0
- package/dist/components/Threads/icons.d.ts +8 -0
- package/dist/components/Threads/icons.js +13 -0
- package/dist/components/Threads/index.d.ts +2 -0
- package/dist/components/Threads/index.js +2 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +3 -0
- package/dist/context/ComponentContext.d.ts +64 -40
- package/dist/context/ComponentContext.js +7 -9
- package/dist/context/DialogManagerContext.d.ts +10 -0
- package/dist/context/DialogManagerContext.js +14 -0
- package/dist/context/MessageContext.d.ts +3 -11
- package/dist/context/MessageContext.js +3 -2
- package/dist/context/TranslationContext.d.ts +1 -11
- package/dist/context/TranslationContext.js +1 -9
- package/dist/context/WithComponents.d.ts +5 -0
- package/dist/context/WithComponents.js +7 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +2 -0
- package/dist/css/v2/index.css +2 -2
- package/dist/css/v2/index.layout.css +2 -2
- package/dist/i18n/Streami18n.d.ts +1 -3
- package/dist/i18n/Streami18n.js +1 -2
- package/dist/i18n/index.d.ts +2 -1
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/types.d.ts +26 -0
- package/dist/i18n/types.js +1 -0
- package/dist/i18n/utils.d.ts +9 -20
- package/dist/i18n/utils.js +10 -1
- package/dist/index.browser.cjs +10823 -10583
- package/dist/index.browser.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.node.cjs +10765 -10541
- package/dist/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/index.browser.cjs +7 -169
- package/dist/plugins/Emojis/index.browser.cjs.map +4 -4
- package/dist/plugins/Emojis/index.node.cjs +7 -169
- package/dist/plugins/Emojis/index.node.cjs.map +4 -4
- package/dist/plugins/encoders/mp3.browser.cjs +2 -4
- package/dist/plugins/encoders/mp3.browser.cjs.map +1 -1
- package/dist/plugins/encoders/mp3.node.cjs +2 -4
- package/dist/plugins/encoders/mp3.node.cjs.map +1 -1
- package/dist/scss/v2/Avatar/Avatar-layout.scss +10 -2
- package/dist/scss/v2/Avatar/Avatar-theme.scss +5 -0
- package/dist/scss/v2/ChatView/ChatView-layout.scss +43 -0
- package/dist/scss/v2/ChatView/ChatView-theme.scss +32 -0
- package/dist/scss/v2/Dialog/Dialog-layout.scss +8 -0
- package/dist/scss/v2/LoadingIndicator/LoadingIndicator-layout.scss +16 -0
- package/dist/scss/v2/Message/Message-layout.scss +8 -0
- package/dist/scss/v2/MessageActionsBox/MessageActionsBox-theme.scss +8 -0
- package/dist/scss/v2/MessageList/MessageList-layout.scss +0 -6
- package/dist/scss/v2/MessageList/VirtualizedMessageList-layout.scss +0 -12
- package/dist/scss/v2/MessageReactions/MessageReactionsSelector-layout.scss +16 -0
- package/dist/scss/v2/MessageReactions/MessageReactionsSelector-theme.scss +6 -0
- package/dist/scss/v2/Thread/Thread-layout.scss +15 -1
- package/dist/scss/v2/ThreadList/ThreadList-layout.scss +152 -0
- package/dist/scss/v2/ThreadList/ThreadList-theme.scss +75 -0
- package/dist/scss/v2/UnreadCountBadge/UnreadCountBadge-layout.scss +49 -0
- package/dist/scss/v2/UnreadCountBadge/UnreadCountBadge-theme.scss +11 -0
- package/dist/scss/v2/_base.scss +31 -0
- package/dist/scss/v2/index.layout.scss +4 -0
- package/dist/scss/v2/index.scss +3 -0
- package/dist/store/hooks/index.d.ts +1 -0
- package/dist/store/hooks/index.js +1 -0
- package/dist/store/hooks/useStateStore.d.ts +3 -0
- package/dist/store/hooks/useStateStore.js +15 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.js +1 -0
- package/package.json +7 -6
- package/dist/assets/Poweredby_100px-White_VertText.png +0 -0
- package/dist/assets/str-chat__reaction-list-sprite@1x.png +0 -0
- package/dist/assets/str-chat__reaction-list-sprite@2x.png +0 -0
- package/dist/assets/str-chat__reaction-list-sprite@3x.png +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { TimestampFormatterOptions } from '../../i18n/
|
|
2
|
+
import type { TimestampFormatterOptions } from '../../i18n/types';
|
|
3
3
|
export interface TimestampProps extends TimestampFormatterOptions {
|
|
4
4
|
customClass?: string;
|
|
5
5
|
timestamp?: Date | string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { useMessageContext } from '../../context/MessageContext';
|
|
3
|
-
import {
|
|
4
|
-
import { getDateString } from '../../i18n/utils';
|
|
3
|
+
import { useTranslationContext } from '../../context/TranslationContext';
|
|
4
|
+
import { getDateString, isDate } from '../../i18n/utils';
|
|
5
5
|
export function Timestamp(props) {
|
|
6
6
|
const { calendar, calendarFormats, customClass, format, timestamp } = props;
|
|
7
7
|
const { formatDate } = useMessageContext('MessageTimestamp');
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { StreamMessage } from '../../../context/ChannelStateContext';
|
|
3
|
-
import type { ReactEventHandler } from '../types';
|
|
4
3
|
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
5
4
|
export declare const reactionHandlerWarning = "Reaction handler was called, but it is missing one of its required arguments.\nMake sure the ChannelAction and ChannelState contexts are properly set and the hook is initialized with a valid message.";
|
|
6
5
|
export declare const useReactionHandler: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(message?: StreamMessage<StreamChatGenerics>) => (reactionType: string, event?: React.BaseSyntheticEvent) => Promise<void>;
|
|
7
|
-
export declare const useReactionClick: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(message?: StreamMessage<StreamChatGenerics>, reactionSelectorRef?: RefObject<HTMLDivElement | null>, messageWrapperRef?: RefObject<HTMLDivElement | null>, closeReactionSelectorOnClick?: boolean) => {
|
|
8
|
-
isReactionEnabled: boolean;
|
|
9
|
-
onReactionListClick: ReactEventHandler;
|
|
10
|
-
showDetailedReactions: boolean;
|
|
11
|
-
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { useCallback
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
2
|
import throttle from 'lodash.throttle';
|
|
3
3
|
import { useChannelActionContext } from '../../../context/ChannelActionContext';
|
|
4
4
|
import { useChannelStateContext } from '../../../context/ChannelStateContext';
|
|
5
5
|
import { useChatContext } from '../../../context/ChatContext';
|
|
6
|
+
import { useThreadContext } from '../../Threads';
|
|
6
7
|
export const reactionHandlerWarning = `Reaction handler was called, but it is missing one of its required arguments.
|
|
7
8
|
Make sure the ChannelAction and ChannelState contexts are properly set and the hook is initialized with a valid message.`;
|
|
8
9
|
export const useReactionHandler = (message) => {
|
|
10
|
+
const thread = useThreadContext();
|
|
9
11
|
const { updateMessage } = useChannelActionContext('useReactionHandler');
|
|
10
12
|
const { channel, channelCapabilities } = useChannelStateContext('useReactionHandler');
|
|
11
13
|
const { client } = useChatContext('useReactionHandler');
|
|
@@ -64,14 +66,19 @@ export const useReactionHandler = (message) => {
|
|
|
64
66
|
const tempMessage = createMessagePreview(add, newReaction, message);
|
|
65
67
|
try {
|
|
66
68
|
updateMessage(tempMessage);
|
|
69
|
+
// @ts-expect-error
|
|
70
|
+
thread?.upsertReplyLocally({ message: tempMessage });
|
|
67
71
|
const messageResponse = add
|
|
68
72
|
? await channel.sendReaction(id, { type })
|
|
69
73
|
: await channel.deleteReaction(id, type);
|
|
74
|
+
// seems useless as we're expecting WS event to come in and replace this anyway
|
|
70
75
|
updateMessage(messageResponse.message);
|
|
71
76
|
}
|
|
72
77
|
catch (error) {
|
|
73
78
|
// revert to the original message if the API call fails
|
|
74
79
|
updateMessage(message);
|
|
80
|
+
// @ts-expect-error
|
|
81
|
+
thread?.upsertReplyLocally({ message });
|
|
75
82
|
}
|
|
76
83
|
}, 1000);
|
|
77
84
|
return async (reactionType, event) => {
|
|
@@ -107,65 +114,3 @@ export const useReactionHandler = (message) => {
|
|
|
107
114
|
}
|
|
108
115
|
};
|
|
109
116
|
};
|
|
110
|
-
export const useReactionClick = (message, reactionSelectorRef, messageWrapperRef, closeReactionSelectorOnClick) => {
|
|
111
|
-
const { channelCapabilities = {} } = useChannelStateContext('useReactionClick');
|
|
112
|
-
const [showDetailedReactions, setShowDetailedReactions] = useState(false);
|
|
113
|
-
const hasListener = useRef(false);
|
|
114
|
-
const isReactionEnabled = channelCapabilities['send-reaction'];
|
|
115
|
-
const messageDeleted = !!message?.deleted_at;
|
|
116
|
-
const closeDetailedReactions = useCallback((event) => {
|
|
117
|
-
if (event.target instanceof HTMLElement &&
|
|
118
|
-
reactionSelectorRef?.current?.contains(event.target) &&
|
|
119
|
-
!closeReactionSelectorOnClick) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
setShowDetailedReactions(false);
|
|
123
|
-
},
|
|
124
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
125
|
-
[setShowDetailedReactions, reactionSelectorRef]);
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
const messageWrapper = messageWrapperRef?.current;
|
|
128
|
-
if (showDetailedReactions && !hasListener.current) {
|
|
129
|
-
hasListener.current = true;
|
|
130
|
-
document.addEventListener('click', closeDetailedReactions);
|
|
131
|
-
if (messageWrapper) {
|
|
132
|
-
messageWrapper.addEventListener('mouseleave', closeDetailedReactions);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (!showDetailedReactions && hasListener.current) {
|
|
136
|
-
document.removeEventListener('click', closeDetailedReactions);
|
|
137
|
-
if (messageWrapper) {
|
|
138
|
-
messageWrapper.removeEventListener('mouseleave', closeDetailedReactions);
|
|
139
|
-
}
|
|
140
|
-
hasListener.current = false;
|
|
141
|
-
}
|
|
142
|
-
return () => {
|
|
143
|
-
if (hasListener.current) {
|
|
144
|
-
document.removeEventListener('click', closeDetailedReactions);
|
|
145
|
-
if (messageWrapper) {
|
|
146
|
-
messageWrapper.removeEventListener('mouseleave', closeDetailedReactions);
|
|
147
|
-
}
|
|
148
|
-
hasListener.current = false;
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
}, [showDetailedReactions, closeDetailedReactions, messageWrapperRef]);
|
|
152
|
-
useEffect(() => {
|
|
153
|
-
const messageWrapper = messageWrapperRef?.current;
|
|
154
|
-
if (messageDeleted && hasListener.current) {
|
|
155
|
-
document.removeEventListener('click', closeDetailedReactions);
|
|
156
|
-
if (messageWrapper) {
|
|
157
|
-
messageWrapper.removeEventListener('mouseleave', closeDetailedReactions);
|
|
158
|
-
}
|
|
159
|
-
hasListener.current = false;
|
|
160
|
-
}
|
|
161
|
-
}, [messageDeleted, closeDetailedReactions, messageWrapperRef]);
|
|
162
|
-
const onReactionListClick = (event) => {
|
|
163
|
-
event?.stopPropagation?.();
|
|
164
|
-
setShowDetailedReactions((prev) => !prev);
|
|
165
|
-
};
|
|
166
|
-
return {
|
|
167
|
-
isReactionEnabled,
|
|
168
|
-
onReactionListClick,
|
|
169
|
-
showDetailedReactions,
|
|
170
|
-
};
|
|
171
|
-
};
|
|
@@ -2,7 +2,7 @@ import type { TFunction } from 'i18next';
|
|
|
2
2
|
import type { MessageResponse, Mute, StreamChat, UserResponse } from 'stream-chat';
|
|
3
3
|
import type { PinPermissions } from './hooks';
|
|
4
4
|
import type { MessageProps } from './types';
|
|
5
|
-
import type { MessageContextValue, StreamMessage } from '../../context';
|
|
5
|
+
import type { ComponentContextValue, CustomMessageActions, MessageContextValue, StreamMessage } from '../../context';
|
|
6
6
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
7
7
|
/**
|
|
8
8
|
* Following function validates a function which returns notification message.
|
|
@@ -39,7 +39,16 @@ export type Capabilities = {
|
|
|
39
39
|
};
|
|
40
40
|
export declare const getMessageActions: (actions: MessageActionsArray | boolean, { canDelete, canEdit, canFlag, canMarkUnread, canMute, canPin, canQuote, canReact, canReply, }: Capabilities) => MessageActionsArray<string>;
|
|
41
41
|
export declare const ACTIONS_NOT_WORKING_IN_THREAD: string[];
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated use `shouldRenderMessageActions` instead
|
|
44
|
+
*/
|
|
42
45
|
export declare const showMessageActionsBox: (actions: MessageActionsArray<string>, inThread?: boolean | undefined) => boolean;
|
|
46
|
+
export declare const shouldRenderMessageActions: <SCG extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ customMessageActions, CustomMessageActionsList, inThread, messageActions, }: {
|
|
47
|
+
messageActions: MessageActionsArray;
|
|
48
|
+
customMessageActions?: CustomMessageActions<SCG>;
|
|
49
|
+
CustomMessageActionsList?: ComponentContextValue<SCG>['CustomMessageActionsList'];
|
|
50
|
+
inThread?: boolean;
|
|
51
|
+
}) => boolean;
|
|
43
52
|
export declare const areMessagePropsEqual: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(prevProps: MessageProps<StreamChatGenerics> & {
|
|
44
53
|
mutes?: Mute<StreamChatGenerics>[];
|
|
45
54
|
showDetailedReactions?: boolean;
|
|
@@ -140,22 +140,31 @@ export const getMessageActions = (actions, { canDelete, canEdit, canFlag, canMar
|
|
|
140
140
|
};
|
|
141
141
|
export const ACTIONS_NOT_WORKING_IN_THREAD = [
|
|
142
142
|
MESSAGE_ACTIONS.pin,
|
|
143
|
-
MESSAGE_ACTIONS.react,
|
|
144
143
|
MESSAGE_ACTIONS.reply,
|
|
145
144
|
MESSAGE_ACTIONS.markUnread,
|
|
146
145
|
];
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
/**
|
|
147
|
+
* @deprecated use `shouldRenderMessageActions` instead
|
|
148
|
+
*/
|
|
149
|
+
export const showMessageActionsBox = (actions, inThread) => shouldRenderMessageActions({ inThread, messageActions: actions });
|
|
150
|
+
export const shouldRenderMessageActions = ({ customMessageActions, CustomMessageActionsList, inThread, messageActions, }) => {
|
|
151
|
+
if (typeof CustomMessageActionsList !== 'undefined' ||
|
|
152
|
+
typeof customMessageActions !== 'undefined')
|
|
153
|
+
return true;
|
|
154
|
+
if (!messageActions.length)
|
|
149
155
|
return false;
|
|
150
|
-
}
|
|
151
156
|
if (inThread &&
|
|
152
|
-
|
|
157
|
+
messageActions.filter((action) => !ACTIONS_NOT_WORKING_IN_THREAD.includes(action)).length === 0) {
|
|
153
158
|
return false;
|
|
154
159
|
}
|
|
155
|
-
if (
|
|
160
|
+
if (messageActions.length === 1 &&
|
|
161
|
+
(messageActions.includes(MESSAGE_ACTIONS.react) ||
|
|
162
|
+
messageActions.includes(MESSAGE_ACTIONS.reply))) {
|
|
156
163
|
return false;
|
|
157
164
|
}
|
|
158
|
-
if (
|
|
165
|
+
if (messageActions.length === 2 &&
|
|
166
|
+
messageActions.includes(MESSAGE_ACTIONS.react) &&
|
|
167
|
+
messageActions.includes(MESSAGE_ACTIONS.reply)) {
|
|
159
168
|
return false;
|
|
160
169
|
}
|
|
161
170
|
return true;
|
|
@@ -185,6 +194,9 @@ export const areMessagePropsEqual = (prevProps, nextProps) => {
|
|
|
185
194
|
if (nextProps.showDetailedReactions !== prevProps.showDetailedReactions) {
|
|
186
195
|
return false;
|
|
187
196
|
}
|
|
197
|
+
if (nextProps.closeReactionSelectorOnClick !== prevProps.closeReactionSelectorOnClick) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
188
200
|
const messagesAreEqual = areMessagesEqual(prevMessage, nextMessage);
|
|
189
201
|
if (!messagesAreEqual)
|
|
190
202
|
return false;
|
|
@@ -6,13 +6,12 @@ export type MessageActionsProps<StreamChatGenerics extends DefaultStreamChatGene
|
|
|
6
6
|
ActionsIcon?: React.ComponentType<IconProps>;
|
|
7
7
|
customWrapperClass?: string;
|
|
8
8
|
inline?: boolean;
|
|
9
|
-
messageWrapperRef?: React.RefObject<HTMLDivElement>;
|
|
10
9
|
mine?: () => boolean;
|
|
11
10
|
};
|
|
12
11
|
export declare const MessageActions: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(props: MessageActionsProps<StreamChatGenerics>) => React.JSX.Element | null;
|
|
13
12
|
export type MessageActionsWrapperProps = {
|
|
14
|
-
setActionsBoxOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
15
13
|
customWrapperClass?: string;
|
|
16
14
|
inline?: boolean;
|
|
15
|
+
toggleOpen?: () => void;
|
|
17
16
|
};
|
|
18
17
|
export {};
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import React, { useCallback, useRef } from 'react';
|
|
2
3
|
import { MessageActionsBox } from './MessageActionsBox';
|
|
4
|
+
import { DialogAnchor, useDialog, useDialogIsOpen } from '../Dialog';
|
|
3
5
|
import { ActionsIcon as DefaultActionsIcon } from '../Message/icons';
|
|
4
|
-
import { isUserMuted } from '../Message/utils';
|
|
6
|
+
import { isUserMuted, shouldRenderMessageActions } from '../Message/utils';
|
|
5
7
|
import { useChatContext } from '../../context/ChatContext';
|
|
6
8
|
import { useMessageContext } from '../../context/MessageContext';
|
|
7
|
-
import {
|
|
8
|
-
import { useTranslationContext } from '../../context';
|
|
9
|
+
import { useComponentContext, useTranslationContext } from '../../context';
|
|
9
10
|
export const MessageActions = (props) => {
|
|
10
|
-
const { ActionsIcon = DefaultActionsIcon, customWrapperClass = '', getMessageActions: propGetMessageActions, handleDelete: propHandleDelete, handleFlag: propHandleFlag, handleMarkUnread: propHandleMarkUnread, handleMute: propHandleMute, handlePin: propHandlePin, inline, message: propMessage,
|
|
11
|
+
const { ActionsIcon = DefaultActionsIcon, customWrapperClass = '', getMessageActions: propGetMessageActions, handleDelete: propHandleDelete, handleFlag: propHandleFlag, handleMarkUnread: propHandleMarkUnread, handleMute: propHandleMute, handlePin: propHandlePin, inline, message: propMessage, mine, } = props;
|
|
11
12
|
const { mutes } = useChatContext('MessageActions');
|
|
12
|
-
const { customMessageActions, getMessageActions: contextGetMessageActions, handleDelete: contextHandleDelete, handleFlag: contextHandleFlag, handleMarkUnread: contextHandleMarkUnread, handleMute: contextHandleMute, handlePin: contextHandlePin, isMyMessage, message: contextMessage, setEditingState, } = useMessageContext('MessageActions');
|
|
13
|
+
const { customMessageActions, getMessageActions: contextGetMessageActions, handleDelete: contextHandleDelete, handleFlag: contextHandleFlag, handleMarkUnread: contextHandleMarkUnread, handleMute: contextHandleMute, handlePin: contextHandlePin, isMyMessage, message: contextMessage, setEditingState, threadList, } = useMessageContext('MessageActions');
|
|
14
|
+
const { CustomMessageActionsList } = useComponentContext('MessageActions');
|
|
13
15
|
const { t } = useTranslationContext('MessageActions');
|
|
14
16
|
const getMessageActions = propGetMessageActions || contextGetMessageActions;
|
|
15
17
|
const handleDelete = propHandleDelete || contextHandleDelete;
|
|
@@ -19,64 +21,33 @@ export const MessageActions = (props) => {
|
|
|
19
21
|
const handlePin = propHandlePin || contextHandlePin;
|
|
20
22
|
const message = propMessage || contextMessage;
|
|
21
23
|
const isMine = mine ? mine() : isMyMessage();
|
|
22
|
-
const [actionsBoxOpen, setActionsBoxOpen] = useState(false);
|
|
23
24
|
const isMuted = useCallback(() => isUserMuted(message, mutes), [message, mutes]);
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
setActionsBoxOpen(false);
|
|
29
|
-
}, []);
|
|
25
|
+
const dialogId = `message-actions--${message.id}`;
|
|
26
|
+
const dialog = useDialog({ id: dialogId });
|
|
27
|
+
const dialogIsOpen = useDialogIsOpen(dialogId);
|
|
30
28
|
const messageActions = getMessageActions();
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}, [hideOptions, messageWrapperRef]);
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (messageDeletedAt) {
|
|
39
|
-
document.removeEventListener('click', hideOptions);
|
|
40
|
-
}
|
|
41
|
-
}, [hideOptions, messageDeletedAt]);
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
if (!actionsBoxOpen)
|
|
44
|
-
return;
|
|
45
|
-
document.addEventListener('click', hideOptions);
|
|
46
|
-
document.addEventListener('keyup', hideOptions);
|
|
47
|
-
return () => {
|
|
48
|
-
document.removeEventListener('click', hideOptions);
|
|
49
|
-
document.removeEventListener('keyup', hideOptions);
|
|
50
|
-
};
|
|
51
|
-
}, [actionsBoxOpen, hideOptions]);
|
|
52
|
-
const actionsBoxButtonRef = useRef(null);
|
|
53
|
-
const { attributes, popperElementRef, styles } = useMessageActionsBoxPopper({
|
|
54
|
-
open: actionsBoxOpen,
|
|
55
|
-
placement: isMine ? 'top-end' : 'top-start',
|
|
56
|
-
referenceElement: actionsBoxButtonRef.current,
|
|
29
|
+
const renderMessageActions = shouldRenderMessageActions({
|
|
30
|
+
customMessageActions,
|
|
31
|
+
CustomMessageActionsList,
|
|
32
|
+
inThread: threadList,
|
|
33
|
+
messageActions,
|
|
57
34
|
});
|
|
58
|
-
|
|
35
|
+
const actionsBoxButtonRef = useRef(null);
|
|
36
|
+
if (!renderMessageActions)
|
|
59
37
|
return null;
|
|
60
|
-
return (React.createElement(MessageActionsWrapper, { customWrapperClass: customWrapperClass, inline: inline,
|
|
61
|
-
React.createElement(
|
|
62
|
-
|
|
38
|
+
return (React.createElement(MessageActionsWrapper, { customWrapperClass: customWrapperClass, inline: inline, toggleOpen: dialog?.toggle },
|
|
39
|
+
React.createElement(DialogAnchor, { id: dialogId, placement: isMine ? 'top-end' : 'top-start', referenceElement: actionsBoxButtonRef.current, trapFocus: true },
|
|
40
|
+
React.createElement(MessageActionsBox, { getMessageActions: getMessageActions, handleDelete: handleDelete, handleEdit: setEditingState, handleFlag: handleFlag, handleMarkUnread: handleMarkUnread, handleMute: handleMute, handlePin: handlePin, isUserMuted: isMuted, mine: isMine, open: dialogIsOpen })),
|
|
41
|
+
React.createElement("button", { "aria-expanded": dialogIsOpen, "aria-haspopup": 'true', "aria-label": t('aria/Open Message Actions Menu'), className: 'str-chat__message-actions-box-button', "data-testid": 'message-actions-toggle-button', ref: actionsBoxButtonRef },
|
|
63
42
|
React.createElement(ActionsIcon, { className: 'str-chat__message-action-icon' }))));
|
|
64
43
|
};
|
|
65
44
|
const MessageActionsWrapper = (props) => {
|
|
66
|
-
const { children, customWrapperClass, inline,
|
|
67
|
-
const defaultWrapperClass =
|
|
68
|
-
str-chat__message-simple__actions__action
|
|
69
|
-
str-chat__message-simple__actions__action--options
|
|
70
|
-
str-chat__message-actions-container`;
|
|
71
|
-
const wrapperClass = customWrapperClass || defaultWrapperClass;
|
|
72
|
-
const onClickOptionsAction = (event) => {
|
|
73
|
-
event.stopPropagation();
|
|
74
|
-
setActionsBoxOpen((prev) => !prev);
|
|
75
|
-
};
|
|
45
|
+
const { children, customWrapperClass, inline, toggleOpen } = props;
|
|
46
|
+
const defaultWrapperClass = clsx('str-chat__message-simple__actions__action', 'str-chat__message-simple__actions__action--options', 'str-chat__message-actions-container');
|
|
76
47
|
const wrapperProps = {
|
|
77
|
-
className:
|
|
48
|
+
className: customWrapperClass || defaultWrapperClass,
|
|
78
49
|
'data-testid': 'message-actions',
|
|
79
|
-
onClick:
|
|
50
|
+
onClick: toggleOpen,
|
|
80
51
|
};
|
|
81
52
|
if (inline)
|
|
82
53
|
return React.createElement("span", { ...wrapperProps }, children);
|
|
@@ -10,5 +10,5 @@ export type MessageActionsBoxProps<StreamChatGenerics extends DefaultStreamChatG
|
|
|
10
10
|
/**
|
|
11
11
|
* A popup box that displays the available actions on a message, such as edit, delete, pin, etc.
|
|
12
12
|
*/
|
|
13
|
-
export declare const MessageActionsBox:
|
|
13
|
+
export declare const MessageActionsBox: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(props: MessageActionsBoxProps<StreamChatGenerics>) => React.JSX.Element;
|
|
14
14
|
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
2
|
+
import React from 'react';
|
|
3
3
|
import { MESSAGE_ACTIONS } from '../Message/utils';
|
|
4
4
|
import { useChannelActionContext, useComponentContext, useMessageContext, useTranslationContext, } from '../../context';
|
|
5
5
|
import { CustomMessageActionsList as DefaultCustomMessageActionsList } from './CustomMessageActionsList';
|
|
6
|
-
const UnMemoizedMessageActionsBox =
|
|
7
|
-
const { getMessageActions, handleDelete, handleEdit, handleFlag, handleMarkUnread, handleMute, handlePin, isUserMuted, mine, open
|
|
6
|
+
const UnMemoizedMessageActionsBox = (props) => {
|
|
7
|
+
const { className, getMessageActions, handleDelete, handleEdit, handleFlag, handleMarkUnread, handleMute, handlePin, isUserMuted, mine, open, ...restDivProps } = props;
|
|
8
8
|
const { CustomMessageActionsList = DefaultCustomMessageActionsList, } = useComponentContext('MessageActionsBox');
|
|
9
9
|
const { setQuotedMessage } = useChannelActionContext('MessageActionsBox');
|
|
10
10
|
const { customMessageActions, message, threadList } = useMessageContext('MessageActionsBox');
|
|
@@ -20,11 +20,11 @@ const UnMemoizedMessageActionsBox = React.forwardRef((props, ref) => {
|
|
|
20
20
|
textarea.focus();
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
const rootClassName = clsx('str-chat__message-actions-box', {
|
|
23
|
+
const rootClassName = clsx('str-chat__message-actions-box', className, {
|
|
24
24
|
'str-chat__message-actions-box--open': open,
|
|
25
25
|
});
|
|
26
26
|
const buttonClassName = 'str-chat__message-actions-list-item str-chat__message-actions-list-item-button';
|
|
27
|
-
return (React.createElement("div", { ...restDivProps, className: rootClassName, "data-testid": 'message-actions-box'
|
|
27
|
+
return (React.createElement("div", { ...restDivProps, className: rootClassName, "data-testid": 'message-actions-box' },
|
|
28
28
|
React.createElement("div", { "aria-label": t('aria/Message Options'), className: 'str-chat__message-actions-list', role: 'listbox' },
|
|
29
29
|
React.createElement(CustomMessageActionsList, { customMessageActions: customMessageActions, message: message }),
|
|
30
30
|
messageActions.indexOf(MESSAGE_ACTIONS.quote) > -1 && (React.createElement("button", { "aria-selected": 'false', className: buttonClassName, onClick: handleQuote, role: 'option' }, t('Reply'))),
|
|
@@ -34,7 +34,7 @@ const UnMemoizedMessageActionsBox = React.forwardRef((props, ref) => {
|
|
|
34
34
|
messageActions.indexOf(MESSAGE_ACTIONS.mute) > -1 && (React.createElement("button", { "aria-selected": 'false', className: buttonClassName, onClick: handleMute, role: 'option' }, isUserMuted() ? t('Unmute') : t('Mute'))),
|
|
35
35
|
messageActions.indexOf(MESSAGE_ACTIONS.edit) > -1 && (React.createElement("button", { "aria-selected": 'false', className: buttonClassName, onClick: handleEdit, role: 'option' }, t('Edit Message'))),
|
|
36
36
|
messageActions.indexOf(MESSAGE_ACTIONS.delete) > -1 && (React.createElement("button", { "aria-selected": 'false', className: buttonClassName, onClick: handleDelete, role: 'option' }, t('Delete'))))));
|
|
37
|
-
}
|
|
37
|
+
};
|
|
38
38
|
/**
|
|
39
39
|
* A popup box that displays the available actions on a message, such as edit, delete, pin, etc.
|
|
40
40
|
*/
|
|
@@ -20,7 +20,7 @@ import { useMessageInputContext } from '../../context/MessageInputContext';
|
|
|
20
20
|
import { useComponentContext } from '../../context/ComponentContext';
|
|
21
21
|
export const MessageInputFlat = () => {
|
|
22
22
|
const { t } = useTranslationContext('MessageInputFlat');
|
|
23
|
-
const { asyncMessagesMultiSendEnabled, attachments, cooldownRemaining, findAndEnqueueURLsToEnrich, handleSubmit, hideSendButton, isUploadEnabled, linkPreviews, maxFilesLeft, message, numberOfUploads, recordingController, setCooldownRemaining, text, uploadNewFiles, } = useMessageInputContext('MessageInputFlat');
|
|
23
|
+
const { asyncMessagesMultiSendEnabled, attachments, cooldownRemaining, findAndEnqueueURLsToEnrich, handleSubmit, hideSendButton, isUploadEnabled, linkPreviews, maxFilesLeft, message, numberOfUploads, parent, recordingController, setCooldownRemaining, text, uploadNewFiles, } = useMessageInputContext('MessageInputFlat');
|
|
24
24
|
const { AudioRecorder = DefaultAudioRecorder, AttachmentPreviewList = DefaultAttachmentPreviewList, CooldownTimer = DefaultCooldownTimer, FileUploadIcon = DefaultUploadIcon, LinkPreviewList = DefaultLinkPreviewList, QuotedMessagePreview = DefaultQuotedMessagePreview, RecordingPermissionDeniedNotification = DefaultRecordingPermissionDeniedNotification, SendButton = DefaultSendButton, StartRecordingAudioButton = DefaultStartRecordingAudioButton, EmojiPicker, } = useComponentContext('MessageInputFlat');
|
|
25
25
|
const { acceptedFiles = [], multipleUploads, quotedMessage, } = useChannelStateContext('MessageInputFlat');
|
|
26
26
|
const { setQuotedMessage } = useChannelActionContext('MessageInputFlat');
|
|
@@ -64,7 +64,7 @@ export const MessageInputFlat = () => {
|
|
|
64
64
|
return React.createElement(AudioRecorder, null);
|
|
65
65
|
// TODO: "!message" condition is a temporary fix for shared
|
|
66
66
|
// state when editing a message (fix shared state issue)
|
|
67
|
-
const displayQuotedMessage = !message && quotedMessage &&
|
|
67
|
+
const displayQuotedMessage = !message && quotedMessage && quotedMessage.parent_id === parent?.id;
|
|
68
68
|
const recordingEnabled = !!(recordingController.recorder && navigator.mediaDevices); // account for requirement on iOS as per this bug report: https://bugs.webkit.org/show_bug.cgi?id=252303
|
|
69
69
|
const isRecording = !!recordingController.recordingState;
|
|
70
70
|
return (React.createElement(React.Fragment, null,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
+
import { Attachment as DefaultAttachment } from '../Attachment';
|
|
2
3
|
import { Avatar as DefaultAvatar } from '../Avatar';
|
|
3
4
|
import { CloseIcon } from './icons';
|
|
4
5
|
import { useChannelActionContext } from '../../context/ChannelActionContext';
|
|
@@ -13,7 +14,7 @@ export const QuotedMessagePreviewHeader = () => {
|
|
|
13
14
|
React.createElement(CloseIcon, null))));
|
|
14
15
|
};
|
|
15
16
|
export const QuotedMessagePreview = ({ quotedMessage, }) => {
|
|
16
|
-
const { Attachment, Avatar = DefaultAvatar } = useComponentContext('QuotedMessagePreview');
|
|
17
|
+
const { Attachment = DefaultAttachment, Avatar = DefaultAvatar, } = useComponentContext('QuotedMessagePreview');
|
|
17
18
|
const { userLanguage } = useTranslationContext('QuotedMessagePreview');
|
|
18
19
|
const quotedMessageText = quotedMessage.i18n?.[`${userLanguage}_text`] ||
|
|
19
20
|
quotedMessage.text;
|
|
@@ -52,7 +52,6 @@ export const useUserTrigger = (params) => {
|
|
|
52
52
|
// @ts-expect-error
|
|
53
53
|
{
|
|
54
54
|
$or: [{ id: { $autocomplete: query } }, { name: { $autocomplete: query } }],
|
|
55
|
-
id: { $ne: client.userID },
|
|
56
55
|
...(typeof mentionQueryParams.filters === 'function'
|
|
57
56
|
? mentionQueryParams.filters(query)
|
|
58
57
|
: mentionQueryParams.filters),
|
|
@@ -7,6 +7,7 @@ import { MessageListNotifications as DefaultMessageListNotifications } from './M
|
|
|
7
7
|
import { UnreadMessagesNotification as DefaultUnreadMessagesNotification } from './UnreadMessagesNotification';
|
|
8
8
|
import { useChannelActionContext, } from '../../context/ChannelActionContext';
|
|
9
9
|
import { useChannelStateContext, } from '../../context/ChannelStateContext';
|
|
10
|
+
import { DialogManagerProvider } from '../../context';
|
|
10
11
|
import { useChatContext } from '../../context/ChatContext';
|
|
11
12
|
import { useComponentContext } from '../../context/ComponentContext';
|
|
12
13
|
import { MessageListContextProvider } from '../../context/MessageListContext';
|
|
@@ -15,7 +16,7 @@ import { InfiniteScroll } from '../InfiniteScrollPaginator/InfiniteScroll';
|
|
|
15
16
|
import { LoadingIndicator as DefaultLoadingIndicator } from '../Loading';
|
|
16
17
|
import { defaultPinPermissions, MESSAGE_ACTIONS } from '../Message/utils';
|
|
17
18
|
import { TypingIndicator as DefaultTypingIndicator } from '../TypingIndicator';
|
|
18
|
-
import { MessageListMainPanel } from './MessageListMainPanel';
|
|
19
|
+
import { MessageListMainPanel as DefaultMessageListMainPanel } from './MessageListMainPanel';
|
|
19
20
|
import { defaultRenderMessages } from './renderMessages';
|
|
20
21
|
import { DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD, DEFAULT_NEXT_CHANNEL_PAGE_SIZE, } from '../../constants/limits';
|
|
21
22
|
const MessageListWithContext = (props) => {
|
|
@@ -24,7 +25,7 @@ const MessageListWithContext = (props) => {
|
|
|
24
25
|
const [listElement, setListElement] = React.useState(null);
|
|
25
26
|
const [ulElement, setUlElement] = React.useState(null);
|
|
26
27
|
const { customClasses } = useChatContext('MessageList');
|
|
27
|
-
const { EmptyStateIndicator = DefaultEmptyStateIndicator, LoadingIndicator = DefaultLoadingIndicator, MessageListNotifications = DefaultMessageListNotifications, MessageNotification = DefaultMessageNotification, TypingIndicator = DefaultTypingIndicator, UnreadMessagesNotification = DefaultUnreadMessagesNotification, } = useComponentContext('MessageList');
|
|
28
|
+
const { EmptyStateIndicator = DefaultEmptyStateIndicator, LoadingIndicator = DefaultLoadingIndicator, MessageListNotifications = DefaultMessageListNotifications, MessageNotification = DefaultMessageNotification, TypingIndicator = DefaultTypingIndicator, UnreadMessagesNotification = DefaultUnreadMessagesNotification, MessageListMainPanel = DefaultMessageListMainPanel, } = useComponentContext('MessageList');
|
|
28
29
|
const { hasNewMessages, isMessageListScrolledToBottom, onScroll, scrollToBottom, wrapperRect, } = useScrollLocationLogic({
|
|
29
30
|
hasMoreNewer,
|
|
30
31
|
listElement,
|
|
@@ -126,13 +127,12 @@ const MessageListWithContext = (props) => {
|
|
|
126
127
|
const showEmptyStateIndicator = elements.length === 0 && !threadList;
|
|
127
128
|
return (React.createElement(MessageListContextProvider, { value: { listElement, scrollToBottom } },
|
|
128
129
|
React.createElement(MessageListMainPanel, null,
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
React.createElement("div", { key: 'bottom' }))))),
|
|
130
|
+
React.createElement(DialogManagerProvider, { id: 'message-list-dialog-manager' },
|
|
131
|
+
!threadList && showUnreadMessagesNotification && (React.createElement(UnreadMessagesNotification, { unreadCount: channelUnreadUiState?.unread_messages })),
|
|
132
|
+
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 },
|
|
133
|
+
React.createElement("ul", { className: 'str-chat__ul', ref: setUlElement }, elements),
|
|
134
|
+
React.createElement(TypingIndicator, { threadList: threadList }),
|
|
135
|
+
React.createElement("div", { key: 'bottom' })))))),
|
|
136
136
|
React.createElement(MessageListNotifications, { hasNewMessages: hasNewMessages, isMessageListScrolledToBottom: isMessageListScrolledToBottom, isNotAtLatestMessageSet: hasMoreNewer, MessageNotification: MessageNotification, notifications: notifications, scrollToBottom: scrollToBottomFromNotification, threadList: threadList, unreadCount: threadList ? undefined : channelUnreadUiState?.unread_messages })));
|
|
137
137
|
};
|
|
138
138
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { PropsWithChildrenOnly } from '../../types/types';
|
|
3
|
-
export declare const MESSAGE_LIST_MAIN_PANEL_CLASS: "str-chat__main-panel-inner";
|
|
3
|
+
export declare const MESSAGE_LIST_MAIN_PANEL_CLASS: "str-chat__main-panel-inner str-chat__message-list-main-panel";
|
|
4
4
|
export declare const MessageListMainPanel: ({ children }: PropsWithChildrenOnly) => React.JSX.Element;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export const MESSAGE_LIST_MAIN_PANEL_CLASS = 'str-chat__main-panel-inner';
|
|
2
|
+
export const MESSAGE_LIST_MAIN_PANEL_CLASS = 'str-chat__main-panel-inner str-chat__message-list-main-panel';
|
|
3
3
|
export const MessageListMainPanel = ({ children }) => (React.createElement("div", { className: MESSAGE_LIST_MAIN_PANEL_CLASS }, children));
|
|
@@ -3,7 +3,7 @@ import { ScrollSeekConfiguration, ScrollSeekPlaceholderProps, VirtuosoHandle, Vi
|
|
|
3
3
|
import { GroupStyle, ProcessMessagesParams } from './utils';
|
|
4
4
|
import { MessageProps, MessageUIComponentProps } from '../Message';
|
|
5
5
|
import { ChannelActionContextValue } from '../../context/ChannelActionContext';
|
|
6
|
-
import { StreamMessage } from '../../context/ChannelStateContext';
|
|
6
|
+
import { ChannelStateContextValue, StreamMessage } from '../../context/ChannelStateContext';
|
|
7
7
|
import { ChatContextValue } from '../../context/ChatContext';
|
|
8
8
|
import { ComponentContextValue } from '../../context/ComponentContext';
|
|
9
9
|
import type { UserResponse } from 'stream-chat';
|
|
@@ -40,6 +40,7 @@ type PropsDrilledToMessage = 'additionalMessageInputProps' | 'customMessageActio
|
|
|
40
40
|
export type VirtualizedMessageListProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Partial<Pick<MessageProps<StreamChatGenerics>, PropsDrilledToMessage>> & {
|
|
41
41
|
/** Additional props to be passed the underlying [`react-virtuoso` virtualized list dependency](https://virtuoso.dev/virtuoso-api-reference/) */
|
|
42
42
|
additionalVirtuosoProps?: VirtuosoProps<UnknownType, VirtuosoContext<StreamChatGenerics>>;
|
|
43
|
+
channelUnreadUiState?: ChannelStateContextValue['channelUnreadUiState'];
|
|
43
44
|
/** If true, picking a reaction from the `ReactionSelector` component will close the selector */
|
|
44
45
|
closeReactionSelectorOnClick?: boolean;
|
|
45
46
|
/** Custom render function, if passed, certain UI props are ignored */
|