Skip to content

Commit 1466646

Browse files
authored
Merge branch 'master' into fix/extend-default-channel-data
2 parents a08f10c + fad4407 commit 1466646

File tree

12 files changed

+105
-27
lines changed

12 files changed

+105
-27
lines changed

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
## [13.8.0](https://github.com/GetStream/stream-chat-react/compare/v13.7.0...v13.8.0) (2025-10-08)
2+
3+
### Bug Fixes
4+
5+
* add CustomMessageComposerData redeclaration ([#2833](https://github.com/GetStream/stream-chat-react/issues/2833)) ([641cdd3](https://github.com/GetStream/stream-chat-react/commit/641cdd346e5e4ed1ff8410f65a28c25f39aa5b58))
6+
* add notification translator for notification validation:attachment:upload:in-progress ([#2842](https://github.com/GetStream/stream-chat-react/issues/2842)) ([7c2a965](https://github.com/GetStream/stream-chat-react/commit/7c2a965ce6664bb8f17682b277c704bcdee24ff4))
7+
* **ChannelPreview:** call getLatestMessagePreview on every relevant WS event ([#2838](https://github.com/GetStream/stream-chat-react/issues/2838)) ([386ef55](https://github.com/GetStream/stream-chat-react/commit/386ef55b291520b6fcc9a6063d93d1a119941627))
8+
* check cast-poll-vote permission to show "Suggest an option" poll action ([#2835](https://github.com/GetStream/stream-chat-react/issues/2835)) ([a14367e](https://github.com/GetStream/stream-chat-react/commit/a14367e0134a92326aaaa188484a09ff4e6852d0))
9+
* **giphy:** allow using actions in quoted messages ([#2849](https://github.com/GetStream/stream-chat-react/issues/2849)) ([8052bd7](https://github.com/GetStream/stream-chat-react/commit/8052bd7fc639158eea5a2b7f9f2c4f479f5db238))
10+
* **TextareaComposer:** check sendable data before allowing message submission ([#2852](https://github.com/GetStream/stream-chat-react/issues/2852)) ([4300ed6](https://github.com/GetStream/stream-chat-react/commit/4300ed686482ea73c532da6b0e50931c7aa76a6d))
11+
* **useMessageComposer:** keep editing message composer with up-to-date edited message reference ([#2851](https://github.com/GetStream/stream-chat-react/issues/2851)) ([d4eb2d7](https://github.com/GetStream/stream-chat-react/commit/d4eb2d712e19e42e0828b2bad9ab15f756309580))
12+
13+
### Features
14+
15+
* allow to override EditMessageModal and thus its additionalMessageInputProps ([#2853](https://github.com/GetStream/stream-chat-react/issues/2853)) ([50e3c62](https://github.com/GetStream/stream-chat-react/commit/50e3c6253653079c393a4282c5ff20108e7eca79))
16+
17+
### Chores
18+
19+
* **deps:** upgrade stream-chat to v9.20.3 ([51ea875](https://github.com/GetStream/stream-chat-react/commit/51ea8758941208ccd6263b582e523bb97d697ec7))
20+
121
## [13.7.0](https://github.com/GetStream/stream-chat-react/compare/v13.6.6...v13.7.0) (2025-09-18)
222

323
### Features

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
"emoji-mart": "^5.4.0",
142142
"react": "^19.0.0 || ^18.0.0 || ^17.0.0 || ^16.14.0",
143143
"react-dom": "^19.0.0 || ^18.0.0 || ^17.0.0 || ^16.14.0",
144-
"stream-chat": "^9.19.0"
144+
"stream-chat": "^9.21.0"
145145
},
146146
"peerDependenciesMeta": {
147147
"@breezystack/lamejs": {
@@ -235,7 +235,7 @@
235235
"react": "^19.0.0",
236236
"react-dom": "^19.0.0",
237237
"semantic-release": "^24.2.3",
238-
"stream-chat": "^9.19.0",
238+
"stream-chat": "^9.21.0",
239239
"ts-jest": "^29.2.5",
240240
"typescript": "^5.4.5",
241241
"typescript-eslint": "^8.17.0"

src/components/Channel/Channel.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ type ChannelPropsForwardedToComponentContext = Pick<
106106
| 'CustomMessageActionsList'
107107
| 'DateSeparator'
108108
| 'EditMessageInput'
109+
| 'EditMessageModal'
109110
| 'EmojiPicker'
110111
| 'emojiSearchIndex'
111112
| 'EmptyStateIndicator'
@@ -1207,6 +1208,7 @@ const ChannelInner = (
12071208
CustomMessageActionsList: props.CustomMessageActionsList,
12081209
DateSeparator: props.DateSeparator,
12091210
EditMessageInput: props.EditMessageInput,
1211+
EditMessageModal: props.EditMessageModal,
12101212
EmojiPicker: props.EmojiPicker,
12111213
emojiSearchIndex: props.emojiSearchIndex,
12121214
EmptyStateIndicator: props.EmptyStateIndicator,
@@ -1276,6 +1278,7 @@ const ChannelInner = (
12761278
props.CustomMessageActionsList,
12771279
props.DateSeparator,
12781280
props.EditMessageInput,
1281+
props.EditMessageModal,
12791282
props.EmojiPicker,
12801283
props.emojiSearchIndex,
12811284
props.EmptyStateIndicator,

src/components/Message/MessageSimple.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626

2727
import { Avatar as DefaultAvatar } from '../Avatar';
2828
import { Attachment as DefaultAttachment } from '../Attachment';
29-
import { EditMessageModal } from '../MessageInput';
29+
import { EditMessageModal as DefaultEditMessageModal } from '../MessageInput';
3030
import { Poll } from '../Poll';
3131
import { ReactionsList as DefaultReactionList } from '../Reactions';
3232
import { MessageBounceModal } from '../MessageBounce/MessageBounceModal';
@@ -69,6 +69,7 @@ const MessageSimpleWithContext = (props: MessageSimpleWithContextProps) => {
6969
const {
7070
Attachment = DefaultAttachment,
7171
Avatar = DefaultAvatar,
72+
EditMessageModal = DefaultEditMessageModal,
7273
MessageOptions = DefaultMessageOptions,
7374
// TODO: remove this "passthrough" in the next
7475
// major release and use the new default instead

src/components/Message/QuotedMessage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useTranslationContext } from '../../context/TranslationContext';
1212
import { useChannelActionContext } from '../../context/ChannelActionContext';
1313
import { renderText as defaultRenderText } from './renderText';
1414
import type { MessageContextValue } from '../../context/MessageContext';
15+
import { useActionHandler } from './';
1516

1617
export type QuotedMessageProps = Pick<MessageContextValue, 'renderText'>;
1718

@@ -26,6 +27,7 @@ export const QuotedMessage = ({ renderText: propsRenderText }: QuotedMessageProp
2627
} = useMessageContext('QuotedMessage');
2728
const { t, userLanguage } = useTranslationContext('QuotedMessage');
2829
const { jumpToMessage } = useChannelActionContext('QuotedMessage');
30+
const actionHandler = useActionHandler(message);
2931

3032
const renderText = propsRenderText ?? contextRenderText ?? defaultRenderText;
3133

@@ -96,7 +98,7 @@ export const QuotedMessage = ({ renderText: propsRenderText }: QuotedMessageProp
9698
</div>
9799
</div>
98100
{message.attachments?.length ? (
99-
<Attachment attachments={message.attachments} />
101+
<Attachment actionHandler={actionHandler} attachments={message.attachments} />
100102
) : null}
101103
</>
102104
);

src/components/Message/hooks/useActionHandler.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useChannelStateContext } from '../../../context/ChannelStateContext';
33

44
import type React from 'react';
55
import type { LocalMessage } from 'stream-chat';
6+
import { useStableCallback } from '../../../utils/useStableCallback';
67

78
export type FormData = Record<string, string>;
89

@@ -19,15 +20,15 @@ export function useActionHandler(message?: LocalMessage): ActionHandlerReturnTyp
1920
const { removeMessage, updateMessage } = useChannelActionContext('useActionHandler');
2021
const { channel } = useChannelStateContext('useActionHandler');
2122

22-
return async (dataOrName, value, event) => {
23+
return useStableCallback(async (dataOrName, value, event) => {
2324
if (event) event.preventDefault();
2425

2526
if (!message || !updateMessage || !removeMessage || !channel) {
2627
console.warn(handleActionWarning);
2728
return;
2829
}
2930

30-
const messageID = message.id;
31+
const messageId = message.id;
3132
let formData: FormData = {};
3233

3334
// deprecated: value&name should be removed in favor of data obj
@@ -37,14 +38,14 @@ export function useActionHandler(message?: LocalMessage): ActionHandlerReturnTyp
3738
formData = { ...dataOrName };
3839
}
3940

40-
if (messageID) {
41-
const data = await channel.sendAction(messageID, formData);
41+
if (messageId) {
42+
const data = await channel.sendAction(messageId, formData);
4243

4344
if (data?.message) {
4445
updateMessage(data.message);
4546
} else {
4647
removeMessage(message);
4748
}
4849
}
49-
};
50+
});
5051
}

src/components/MessageInput/EditMessageForm.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,14 @@ export const EditMessageForm = () => {
6868
);
6969
};
7070

71+
export type EditMessageModalProps = Pick<
72+
MessageUIComponentProps,
73+
'additionalMessageInputProps'
74+
>;
75+
7176
export const EditMessageModal = ({
7277
additionalMessageInputProps,
73-
}: Pick<MessageUIComponentProps, 'additionalMessageInputProps'>) => {
78+
}: EditMessageModalProps) => {
7479
const { EditMessageInput = EditMessageForm, Modal = DefaultModal } =
7580
useComponentContext();
7681
const { clearEditingState } = useMessageContext();

src/components/MessageInput/hooks/useMessageComposer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ export const useMessageComposer = () => {
4040
const tag = MessageComposer.constructTag(cachedEditedMessage);
4141

4242
const cachedComposer = queueCache.get(tag);
43-
if (cachedComposer) return cachedComposer;
43+
if (cachedComposer) {
44+
cachedComposer.editedMessage = cachedEditedMessage;
45+
return cachedComposer;
46+
}
4447

4548
return new MessageComposer({
4649
client,

src/components/TextareaComposer/TextareaComposer.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,11 @@ export const TextareaComposer = ({
194194
return nextIndex;
195195
});
196196
}
197-
} else if (shouldSubmit(event) && textareaRef.current) {
197+
} else if (
198+
shouldSubmit(event) &&
199+
textareaRef.current &&
200+
messageComposer.hasSendableData
201+
) {
198202
if (event.key === 'Enter') {
199203
// prevent adding newline when submitting a message with
200204
event.preventDefault();
@@ -205,6 +209,7 @@ export const TextareaComposer = ({
205209
[
206210
focusedItemIndex,
207211
handleSubmit,
212+
messageComposer,
208213
onKeyDown,
209214
shouldSubmit,
210215
suggestions,

src/context/ComponentContext.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
CooldownTimerProps,
1111
CustomMessageActionsListProps,
1212
DateSeparatorProps,
13+
EditMessageModalProps,
1314
EmojiSearchIndex,
1415
EmptyStateIndicatorProps,
1516
EventComponentProps,
@@ -96,6 +97,8 @@ export type ComponentContextValue = {
9697
DateSeparator?: React.ComponentType<DateSeparatorProps>;
9798
/** Custom UI component to override default edit message input, defaults to and accepts same props as: [EditMessageForm](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/EditMessageForm.tsx) */
9899
EditMessageInput?: React.ComponentType<MessageInputProps>;
100+
/** Custom UI component to override default EditMessageModal, defaults to and accepts same props as: [EditMessageModal](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/EditMessageForm.tsx) */
101+
EditMessageModal?: React.ComponentType<EditMessageModalProps>;
99102
/** Custom UI component for rendering button with emoji picker in MessageInput */
100103
EmojiPicker?: React.ComponentType;
101104
/** Mechanism to be used with autocomplete and text replace features of the `MessageInput` component, see [emoji-mart `SearchIndex`](https://github.com/missive/emoji-mart#%EF%B8%8F%EF%B8%8F-headless-search) */

0 commit comments

Comments
 (0)