stream-chat-react 13.6.0 → 13.6.2
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/Message/utils.js +2 -2
- package/dist/components/TextareaComposer/TextareaComposer.js +20 -19
- package/dist/experimental/index.browser.cjs.map +1 -1
- package/dist/experimental/index.node.cjs.map +1 -1
- package/dist/index.browser.cjs +16 -16
- package/dist/index.browser.cjs.map +3 -3
- package/dist/index.node.cjs +16 -16
- package/dist/index.node.cjs.map +3 -3
- package/package.json +3 -3
|
@@ -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.6.
|
|
27
|
+
const version = "13.6.2";
|
|
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'
|
|
@@ -135,14 +135,14 @@ export const getMessageActions = (actions, { canDelete, canEdit, canFlag, canMar
|
|
|
135
135
|
messageActionsAfterPermission.push(MESSAGE_ACTIONS.react);
|
|
136
136
|
}
|
|
137
137
|
if (channelConfig?.['user_message_reminders'] &&
|
|
138
|
-
messageActions.indexOf(MESSAGE_ACTIONS.remindMe)) {
|
|
138
|
+
messageActions.indexOf(MESSAGE_ACTIONS.remindMe) > -1) {
|
|
139
139
|
messageActionsAfterPermission.push(MESSAGE_ACTIONS.remindMe);
|
|
140
140
|
}
|
|
141
141
|
if (canReply && messageActions.indexOf(MESSAGE_ACTIONS.reply) > -1) {
|
|
142
142
|
messageActionsAfterPermission.push(MESSAGE_ACTIONS.reply);
|
|
143
143
|
}
|
|
144
144
|
if (channelConfig?.['user_message_reminders'] &&
|
|
145
|
-
messageActions.indexOf(MESSAGE_ACTIONS.saveForLater)) {
|
|
145
|
+
messageActions.indexOf(MESSAGE_ACTIONS.saveForLater) > -1) {
|
|
146
146
|
messageActionsAfterPermission.push(MESSAGE_ACTIONS.saveForLater);
|
|
147
147
|
}
|
|
148
148
|
return messageActionsAfterPermission;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
3
|
import Textarea from 'react-textarea-autosize';
|
|
4
4
|
import { useMessageComposer } from '../MessageInput';
|
|
5
5
|
import { useComponentContext, useMessageInputContext, useTranslationContext, } from '../../context';
|
|
@@ -116,7 +116,6 @@ export const TextareaComposer = ({ className, closeSuggestionsOnClickOutside, co
|
|
|
116
116
|
event.preventDefault();
|
|
117
117
|
}
|
|
118
118
|
handleSubmit();
|
|
119
|
-
textareaRef.current.selectionEnd = 0;
|
|
120
119
|
}
|
|
121
120
|
}, [
|
|
122
121
|
focusedItemIndex,
|
|
@@ -135,23 +134,13 @@ export const TextareaComposer = ({ className, closeSuggestionsOnClickOutside, co
|
|
|
135
134
|
textComposer.closeSuggestions();
|
|
136
135
|
}
|
|
137
136
|
}, [onScroll, textComposer]);
|
|
138
|
-
const
|
|
137
|
+
const setSelection = useCallback((e) => {
|
|
139
138
|
onSelect?.(e);
|
|
140
139
|
textComposer.setSelection({
|
|
141
140
|
end: e.target.selectionEnd,
|
|
142
141
|
start: e.target.selectionStart,
|
|
143
142
|
});
|
|
144
143
|
}, [onSelect, textComposer]);
|
|
145
|
-
useEffect(() => {
|
|
146
|
-
// FIXME: find the real reason for cursor being set to the end on each change
|
|
147
|
-
// This is a workaround to prevent the cursor from jumping
|
|
148
|
-
// to the end of the textarea when the user is typing
|
|
149
|
-
// at the position that is not at the end of the textarea value.
|
|
150
|
-
if (textareaRef.current && !isComposing) {
|
|
151
|
-
textareaRef.current.selectionStart = selection.start;
|
|
152
|
-
textareaRef.current.selectionEnd = selection.end;
|
|
153
|
-
}
|
|
154
|
-
}, [text, textareaRef, selection.start, selection.end, isComposing]);
|
|
155
144
|
useEffect(() => {
|
|
156
145
|
if (textComposer.suggestions) {
|
|
157
146
|
setFocusedItemIndex(0);
|
|
@@ -163,7 +152,14 @@ export const TextareaComposer = ({ className, closeSuggestionsOnClickOutside, co
|
|
|
163
152
|
return;
|
|
164
153
|
textareaRef.current.focus();
|
|
165
154
|
}, [attachments, focus, quotedMessage, textareaRef]);
|
|
166
|
-
|
|
155
|
+
useLayoutEffect(() => {
|
|
156
|
+
/**
|
|
157
|
+
* It is important to perform set text and after that the range
|
|
158
|
+
* to prevent cursor reset to the end of the textarea if doing it in separate effects.
|
|
159
|
+
*/
|
|
160
|
+
const textarea = textareaRef.current;
|
|
161
|
+
if (!textarea || isComposing)
|
|
162
|
+
return;
|
|
167
163
|
/**
|
|
168
164
|
* The textarea value has to be overridden outside the render cycle so that the events like compositionend can be triggered.
|
|
169
165
|
* If we have overridden the value during the component rendering, the compositionend event would not be triggered, and
|
|
@@ -171,15 +167,20 @@ export const TextareaComposer = ({ className, closeSuggestionsOnClickOutside, co
|
|
|
171
167
|
* On the other hand, just removing the value override via prop (value={text}) would not allow us to change the text based on
|
|
172
168
|
* middleware results (e.g. replace characters with emojis)
|
|
173
169
|
*/
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
if (textarea.value !== text) {
|
|
171
|
+
textarea.value = text;
|
|
172
|
+
}
|
|
173
|
+
const length = textarea.value.length;
|
|
174
|
+
const start = Math.max(0, Math.min(selection.start, length));
|
|
175
|
+
const end = Math.max(start, Math.min(selection.end, length));
|
|
176
|
+
if (textarea.selectionStart === start && textarea.selectionEnd === end)
|
|
176
177
|
return;
|
|
177
|
-
textarea.
|
|
178
|
-
}, [
|
|
178
|
+
textarea.setSelectionRange(start, end, 'forward');
|
|
179
|
+
}, [text, selection.start, selection.end, isComposing, textareaRef]);
|
|
179
180
|
return (React.createElement("div", { className: clsx('rta', 'str-chat__textarea str-chat__message-textarea-react-host', containerClassName, {
|
|
180
181
|
['rta--loading']: isLoadingItems,
|
|
181
182
|
}), ref: containerRef },
|
|
182
|
-
React.createElement(Textarea, { ...additionalTextareaProps, ...restTextareaProps, "aria-label": cooldownRemaining ? t('Slow Mode ON') : placeholder, className: clsx('rta__textarea', 'str-chat__textarea__textarea str-chat__message-textarea', className), "data-testid": 'message-input', disabled: !enabled || !!cooldownRemaining, maxRows: maxRows, minRows: minRows, onBlur: onBlur, onChange: changeHandler, onCompositionEnd: onCompositionEnd, onCompositionStart: onCompositionStart, onKeyDown: keyDownHandler, onPaste: onPaste, onScroll: scrollHandler, onSelect:
|
|
183
|
+
React.createElement(Textarea, { ...additionalTextareaProps, ...restTextareaProps, "aria-label": cooldownRemaining ? t('Slow Mode ON') : placeholder, className: clsx('rta__textarea', 'str-chat__textarea__textarea str-chat__message-textarea', className), "data-testid": 'message-input', disabled: !enabled || !!cooldownRemaining, maxRows: maxRows, minRows: minRows, onBlur: onBlur, onChange: changeHandler, onCompositionEnd: onCompositionEnd, onCompositionStart: onCompositionStart, onKeyDown: keyDownHandler, onPaste: onPaste, onScroll: scrollHandler, onSelect: setSelection, placeholder: placeholder || t('Type your message'), ref: (ref) => {
|
|
183
184
|
textareaRef.current = ref;
|
|
184
185
|
} }),
|
|
185
186
|
!isComposing && (React.createElement(AutocompleteSuggestionList, { className: listClassName, closeOnClickOutside: closeSuggestionsOnClickOutside, focusedItemIndex: focusedItemIndex, setFocusedItemIndex: setFocusedItemIndex }))));
|