stream-chat-react 13.0.0-rc.2 → 13.0.1
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/Channel/Channel.d.ts +1 -1
- package/dist/components/Channel/Channel.js +2 -0
- package/dist/components/Chat/hooks/useChat.js +1 -1
- package/dist/components/MessageInput/EditMessageForm.js +1 -1
- package/dist/components/MessageInput/MessageInput.d.ts +1 -3
- package/dist/components/MessageInput/MessageInputFlat.js +2 -2
- package/dist/components/MessageInput/hooks/useCreateMessageInputContext.js +1 -3
- package/dist/components/MessageInput/hooks/useMessageInputControls.d.ts +0 -1
- package/dist/components/MessageInput/hooks/useMessageInputControls.js +3 -4
- package/dist/components/MessageInput/hooks/usePasteHandler.d.ts +1 -1
- package/dist/components/MessageInput/hooks/usePasteHandler.js +4 -4
- package/dist/components/MessageInput/hooks/useSubmitHandler.js +31 -1
- package/dist/components/MessageInput/hooks/{useMessageInputText.d.ts → useTextareaRef.d.ts} +1 -2
- package/dist/components/MessageInput/hooks/useTextareaRef.js +14 -0
- package/dist/components/Poll/PollActions/PollResults/PollResults.js +1 -1
- package/dist/components/Poll/PollCreationDialog/MultipleAnswersField.js +9 -2
- package/dist/components/TextareaComposer/TextareaComposer.d.ts +3 -5
- package/dist/components/TextareaComposer/TextareaComposer.js +15 -13
- package/dist/context/ComponentContext.d.ts +3 -3
- package/dist/css/v2/index.css +1 -1
- package/dist/css/v2/index.layout.css +1 -1
- package/dist/experimental/index.browser.cjs.map +2 -2
- package/dist/experimental/index.node.cjs.map +2 -2
- package/dist/i18n/Streami18n.d.ts +1 -0
- package/dist/i18n/de.json +1 -0
- package/dist/i18n/en.json +1 -0
- package/dist/i18n/es.json +1 -0
- package/dist/i18n/fr.json +1 -0
- package/dist/i18n/hi.json +1 -0
- package/dist/i18n/it.json +1 -0
- package/dist/i18n/ja.json +1 -0
- package/dist/i18n/ko.json +2 -1
- package/dist/i18n/nl.json +2 -1
- package/dist/i18n/pt.json +1 -0
- package/dist/i18n/ru.json +1 -0
- package/dist/i18n/tr.json +1 -0
- package/dist/index.browser.cjs +348 -323
- package/dist/index.browser.cjs.map +4 -4
- package/dist/index.node.cjs +348 -323
- package/dist/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/EmojiPicker.js +9 -4
- package/dist/plugins/Emojis/index.browser.cjs +208 -96
- package/dist/plugins/Emojis/index.browser.cjs.map +4 -4
- package/dist/plugins/Emojis/index.node.cjs +208 -96
- package/dist/plugins/Emojis/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/middleware/textComposerEmojiMiddleware.d.ts +4 -48
- package/dist/plugins/Emojis/middleware/textComposerEmojiMiddleware.js +52 -58
- package/dist/scss/v2/MessageInput/MessageInput-layout.scss +5 -0
- package/package.json +4 -4
- package/dist/components/MessageInput/hooks/useMessageInputText.js +0 -44
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { usePopper } from 'react-popper';
|
|
3
3
|
import Picker from '@emoji-mart/react';
|
|
4
|
-
import { useMessageInputContext, useTranslationContext } from '../../context';
|
|
5
4
|
import { EmojiPickerIcon } from './icons';
|
|
5
|
+
import { useMessageInputContext, useTranslationContext } from '../../context';
|
|
6
|
+
import { useMessageComposer } from '../../components';
|
|
6
7
|
const isShadowRoot = (node) => !!node.host;
|
|
7
8
|
const classNames = {
|
|
8
9
|
buttonClassName: 'str-chat__emoji-picker-button',
|
|
@@ -11,7 +12,8 @@ const classNames = {
|
|
|
11
12
|
};
|
|
12
13
|
export const EmojiPicker = (props) => {
|
|
13
14
|
const { t } = useTranslationContext('EmojiPicker');
|
|
14
|
-
const {
|
|
15
|
+
const { textareaRef } = useMessageInputContext('EmojiPicker');
|
|
16
|
+
const { textComposer } = useMessageComposer();
|
|
15
17
|
const [displayPicker, setDisplayPicker] = useState(false);
|
|
16
18
|
const [referenceElement, setReferenceElement] = useState(null);
|
|
17
19
|
const [popperElement, setPopperElement] = useState(null);
|
|
@@ -39,8 +41,11 @@ export const EmojiPicker = (props) => {
|
|
|
39
41
|
return (React.createElement("div", { className: props.wrapperClassName ?? wrapperClassName },
|
|
40
42
|
displayPicker && (React.createElement("div", { className: props.pickerContainerClassName ?? pickerContainerClassName, style: styles.popper, ...attributes.popper, ref: setPopperElement },
|
|
41
43
|
React.createElement(Picker, { data: async () => (await import('@emoji-mart/data')).default, onEmojiSelect: (e) => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const textarea = textareaRef.current;
|
|
45
|
+
if (!textarea)
|
|
46
|
+
return;
|
|
47
|
+
textComposer.insertText({ text: e.native });
|
|
48
|
+
textarea.focus();
|
|
44
49
|
if (props.closeOnEmojiSelect) {
|
|
45
50
|
setDisplayPicker(false);
|
|
46
51
|
}
|
|
@@ -37,12 +37,66 @@ __export(Emojis_exports, {
|
|
|
37
37
|
module.exports = __toCommonJS(Emojis_exports);
|
|
38
38
|
|
|
39
39
|
// src/plugins/Emojis/EmojiPicker.tsx
|
|
40
|
-
var
|
|
40
|
+
var import_react10 = __toESM(require("react"));
|
|
41
41
|
var import_react_popper = require("react-popper");
|
|
42
|
-
var
|
|
42
|
+
var import_react11 = __toESM(require("@emoji-mart/react"));
|
|
43
43
|
|
|
44
|
-
// src/
|
|
44
|
+
// src/plugins/Emojis/icons.tsx
|
|
45
45
|
var import_react = __toESM(require("react"));
|
|
46
|
+
var EmojiPickerIcon = () => /* @__PURE__ */ import_react.default.createElement(
|
|
47
|
+
"svg",
|
|
48
|
+
{
|
|
49
|
+
preserveAspectRatio: "xMinYMin",
|
|
50
|
+
viewBox: "0 0 28 28",
|
|
51
|
+
width: "100%",
|
|
52
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
53
|
+
},
|
|
54
|
+
/* @__PURE__ */ import_react.default.createElement("g", { clipRule: "evenodd", fillRule: "evenodd" }, /* @__PURE__ */ import_react.default.createElement("path", { d: "M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z" }))
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// src/context/ChannelStateContext.tsx
|
|
58
|
+
var import_react2 = __toESM(require("react"));
|
|
59
|
+
var ChannelStateContext = import_react2.default.createContext(void 0);
|
|
60
|
+
var useChannelStateContext = (componentName) => {
|
|
61
|
+
const contextValue = (0, import_react2.useContext)(ChannelStateContext);
|
|
62
|
+
if (!contextValue) {
|
|
63
|
+
console.warn(
|
|
64
|
+
`The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ${componentName} component.`
|
|
65
|
+
);
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
return contextValue;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/context/ChatContext.tsx
|
|
72
|
+
var import_react3 = __toESM(require("react"));
|
|
73
|
+
var ChatContext = import_react3.default.createContext(void 0);
|
|
74
|
+
var useChatContext = (componentName) => {
|
|
75
|
+
const contextValue = (0, import_react3.useContext)(ChatContext);
|
|
76
|
+
if (!contextValue) {
|
|
77
|
+
console.warn(
|
|
78
|
+
`The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`
|
|
79
|
+
);
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
return contextValue;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// src/context/MessageContext.tsx
|
|
86
|
+
var import_react4 = __toESM(require("react"));
|
|
87
|
+
var MessageContext = import_react4.default.createContext(
|
|
88
|
+
void 0
|
|
89
|
+
);
|
|
90
|
+
var useMessageContext = (_componentName) => {
|
|
91
|
+
const contextValue = (0, import_react4.useContext)(MessageContext);
|
|
92
|
+
if (!contextValue) {
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
return contextValue;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// src/context/TranslationContext.tsx
|
|
99
|
+
var import_react5 = __toESM(require("react"));
|
|
46
100
|
var import_dayjs2 = __toESM(require("dayjs"));
|
|
47
101
|
var import_calendar = __toESM(require("dayjs/plugin/calendar"));
|
|
48
102
|
var import_localizedFormat = __toESM(require("dayjs/plugin/localizedFormat"));
|
|
@@ -55,13 +109,13 @@ var defaultDateTimeParser = (input) => (0, import_dayjs.default)(input);
|
|
|
55
109
|
// src/context/TranslationContext.tsx
|
|
56
110
|
import_dayjs2.default.extend(import_calendar.default);
|
|
57
111
|
import_dayjs2.default.extend(import_localizedFormat.default);
|
|
58
|
-
var TranslationContext =
|
|
112
|
+
var TranslationContext = import_react5.default.createContext({
|
|
59
113
|
t: defaultTranslatorFunction,
|
|
60
114
|
tDateTimeParser: defaultDateTimeParser,
|
|
61
115
|
userLanguage: "en"
|
|
62
116
|
});
|
|
63
117
|
var useTranslationContext = (componentName) => {
|
|
64
|
-
const contextValue = (0,
|
|
118
|
+
const contextValue = (0, import_react5.useContext)(TranslationContext);
|
|
65
119
|
if (!contextValue) {
|
|
66
120
|
console.warn(
|
|
67
121
|
`The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`
|
|
@@ -71,32 +125,99 @@ var useTranslationContext = (componentName) => {
|
|
|
71
125
|
return contextValue;
|
|
72
126
|
};
|
|
73
127
|
|
|
128
|
+
// src/components/MessageInput/hooks/useMessageComposer.ts
|
|
129
|
+
var import_react8 = require("react");
|
|
130
|
+
var import_stream_chat = require("stream-chat");
|
|
131
|
+
|
|
132
|
+
// src/components/Threads/ThreadContext.tsx
|
|
133
|
+
var import_react6 = __toESM(require("react"));
|
|
134
|
+
var ThreadContext = (0, import_react6.createContext)(void 0);
|
|
135
|
+
var useThreadContext = () => (0, import_react6.useContext)(ThreadContext);
|
|
136
|
+
|
|
137
|
+
// src/components/Thread/Thread.tsx
|
|
138
|
+
var import_react7 = __toESM(require("react"));
|
|
139
|
+
var import_clsx = __toESM(require("clsx"));
|
|
140
|
+
var LegacyThreadContext = import_react7.default.createContext({ legacyThread: void 0 });
|
|
141
|
+
var useLegacyThreadContext = () => (0, import_react7.useContext)(LegacyThreadContext);
|
|
142
|
+
|
|
143
|
+
// src/components/MessageInput/hooks/useMessageComposer.ts
|
|
144
|
+
var queueCache = new import_stream_chat.FixedSizeQueueCache(64);
|
|
145
|
+
var useMessageComposer = () => {
|
|
146
|
+
const { client } = useChatContext();
|
|
147
|
+
const { channel } = useChannelStateContext();
|
|
148
|
+
const { editing, message: editedMessage } = useMessageContext();
|
|
149
|
+
const { legacyThread: parentMessage } = useLegacyThreadContext();
|
|
150
|
+
const threadInstance = useThreadContext();
|
|
151
|
+
const cachedEditedMessage = (0, import_react8.useMemo)(() => {
|
|
152
|
+
if (!editedMessage) return void 0;
|
|
153
|
+
return editedMessage;
|
|
154
|
+
}, [editedMessage?.id]);
|
|
155
|
+
const cachedParentMessage = (0, import_react8.useMemo)(() => {
|
|
156
|
+
if (!parentMessage) return void 0;
|
|
157
|
+
return parentMessage;
|
|
158
|
+
}, [parentMessage?.id]);
|
|
159
|
+
const messageComposer = (0, import_react8.useMemo)(() => {
|
|
160
|
+
if (editing && cachedEditedMessage) {
|
|
161
|
+
const tag = import_stream_chat.MessageComposer.constructTag(cachedEditedMessage);
|
|
162
|
+
const cachedComposer = queueCache.get(tag);
|
|
163
|
+
if (cachedComposer) return cachedComposer;
|
|
164
|
+
return new import_stream_chat.MessageComposer({
|
|
165
|
+
client,
|
|
166
|
+
composition: cachedEditedMessage,
|
|
167
|
+
compositionContext: cachedEditedMessage
|
|
168
|
+
});
|
|
169
|
+
} else if (threadInstance) {
|
|
170
|
+
return threadInstance.messageComposer;
|
|
171
|
+
} else if (cachedParentMessage) {
|
|
172
|
+
const compositionContext = {
|
|
173
|
+
...cachedParentMessage,
|
|
174
|
+
legacyThreadId: cachedParentMessage.id
|
|
175
|
+
};
|
|
176
|
+
const tag = import_stream_chat.MessageComposer.constructTag(compositionContext);
|
|
177
|
+
const cachedComposer = queueCache.get(tag);
|
|
178
|
+
if (cachedComposer) return cachedComposer;
|
|
179
|
+
return new import_stream_chat.MessageComposer({
|
|
180
|
+
client,
|
|
181
|
+
compositionContext
|
|
182
|
+
});
|
|
183
|
+
} else {
|
|
184
|
+
return channel.messageComposer;
|
|
185
|
+
}
|
|
186
|
+
}, [
|
|
187
|
+
cachedEditedMessage,
|
|
188
|
+
cachedParentMessage,
|
|
189
|
+
channel,
|
|
190
|
+
client,
|
|
191
|
+
editing,
|
|
192
|
+
threadInstance
|
|
193
|
+
]);
|
|
194
|
+
if (["legacy_thread", "message"].includes(
|
|
195
|
+
messageComposer.contextType
|
|
196
|
+
) && !queueCache.peek(messageComposer.tag)) {
|
|
197
|
+
queueCache.add(messageComposer.tag, messageComposer);
|
|
198
|
+
}
|
|
199
|
+
(0, import_react8.useEffect)(() => {
|
|
200
|
+
const unsubscribe = messageComposer.registerSubscriptions();
|
|
201
|
+
return () => {
|
|
202
|
+
unsubscribe();
|
|
203
|
+
};
|
|
204
|
+
}, [messageComposer]);
|
|
205
|
+
return messageComposer;
|
|
206
|
+
};
|
|
207
|
+
|
|
74
208
|
// src/context/MessageInputContext.tsx
|
|
75
|
-
var
|
|
76
|
-
var MessageInputContext = (0,
|
|
209
|
+
var import_react9 = __toESM(require("react"));
|
|
210
|
+
var MessageInputContext = (0, import_react9.createContext)(
|
|
77
211
|
void 0
|
|
78
212
|
);
|
|
79
213
|
var useMessageInputContext = (componentName) => {
|
|
80
|
-
const contextValue = (0,
|
|
214
|
+
const contextValue = (0, import_react9.useContext)(MessageInputContext);
|
|
81
215
|
if (!contextValue) {
|
|
82
216
|
return {};
|
|
83
217
|
}
|
|
84
218
|
return contextValue;
|
|
85
219
|
};
|
|
86
220
|
|
|
87
|
-
// src/plugins/Emojis/icons.tsx
|
|
88
|
-
var import_react3 = __toESM(require("react"));
|
|
89
|
-
var EmojiPickerIcon = () => /* @__PURE__ */ import_react3.default.createElement(
|
|
90
|
-
"svg",
|
|
91
|
-
{
|
|
92
|
-
preserveAspectRatio: "xMinYMin",
|
|
93
|
-
viewBox: "0 0 28 28",
|
|
94
|
-
width: "100%",
|
|
95
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
96
|
-
},
|
|
97
|
-
/* @__PURE__ */ import_react3.default.createElement("g", { clipRule: "evenodd", fillRule: "evenodd" }, /* @__PURE__ */ import_react3.default.createElement("path", { d: "M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z" }))
|
|
98
|
-
);
|
|
99
|
-
|
|
100
221
|
// src/plugins/Emojis/EmojiPicker.tsx
|
|
101
222
|
var isShadowRoot = (node) => !!node.host;
|
|
102
223
|
var classNames = {
|
|
@@ -106,19 +227,20 @@ var classNames = {
|
|
|
106
227
|
};
|
|
107
228
|
var EmojiPicker = (props) => {
|
|
108
229
|
const { t } = useTranslationContext("EmojiPicker");
|
|
109
|
-
const {
|
|
110
|
-
const
|
|
111
|
-
const [
|
|
230
|
+
const { textareaRef } = useMessageInputContext("EmojiPicker");
|
|
231
|
+
const { textComposer } = useMessageComposer();
|
|
232
|
+
const [displayPicker, setDisplayPicker] = (0, import_react10.useState)(false);
|
|
233
|
+
const [referenceElement, setReferenceElement] = (0, import_react10.useState)(
|
|
112
234
|
null
|
|
113
235
|
);
|
|
114
|
-
const [popperElement, setPopperElement] = (0,
|
|
236
|
+
const [popperElement, setPopperElement] = (0, import_react10.useState)(null);
|
|
115
237
|
const { attributes, styles } = (0, import_react_popper.usePopper)(referenceElement, popperElement, {
|
|
116
238
|
placement: "top-end",
|
|
117
239
|
...props.popperOptions
|
|
118
240
|
});
|
|
119
241
|
const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;
|
|
120
242
|
const { ButtonIconComponent = EmojiPickerIcon } = props;
|
|
121
|
-
(0,
|
|
243
|
+
(0, import_react10.useEffect)(() => {
|
|
122
244
|
if (!popperElement || !referenceElement) return;
|
|
123
245
|
const handlePointerDown = (e) => {
|
|
124
246
|
const target = e.target;
|
|
@@ -131,7 +253,7 @@ var EmojiPicker = (props) => {
|
|
|
131
253
|
window.addEventListener("pointerdown", handlePointerDown);
|
|
132
254
|
return () => window.removeEventListener("pointerdown", handlePointerDown);
|
|
133
255
|
}, [referenceElement, popperElement]);
|
|
134
|
-
return /* @__PURE__ */
|
|
256
|
+
return /* @__PURE__ */ import_react10.default.createElement("div", { className: props.wrapperClassName ?? wrapperClassName }, displayPicker && /* @__PURE__ */ import_react10.default.createElement(
|
|
135
257
|
"div",
|
|
136
258
|
{
|
|
137
259
|
className: props.pickerContainerClassName ?? pickerContainerClassName,
|
|
@@ -139,13 +261,15 @@ var EmojiPicker = (props) => {
|
|
|
139
261
|
...attributes.popper,
|
|
140
262
|
ref: setPopperElement
|
|
141
263
|
},
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
|
|
264
|
+
/* @__PURE__ */ import_react10.default.createElement(
|
|
265
|
+
import_react11.default,
|
|
144
266
|
{
|
|
145
267
|
data: async () => (await import("@emoji-mart/data")).default,
|
|
146
268
|
onEmojiSelect: (e) => {
|
|
147
|
-
|
|
148
|
-
|
|
269
|
+
const textarea = textareaRef.current;
|
|
270
|
+
if (!textarea) return;
|
|
271
|
+
textComposer.insertText({ text: e.native });
|
|
272
|
+
textarea.focus();
|
|
149
273
|
if (props.closeOnEmojiSelect) {
|
|
150
274
|
setDisplayPicker(false);
|
|
151
275
|
}
|
|
@@ -153,7 +277,7 @@ var EmojiPicker = (props) => {
|
|
|
153
277
|
...props.pickerProps
|
|
154
278
|
}
|
|
155
279
|
)
|
|
156
|
-
), /* @__PURE__ */
|
|
280
|
+
), /* @__PURE__ */ import_react10.default.createElement(
|
|
157
281
|
"button",
|
|
158
282
|
{
|
|
159
283
|
"aria-expanded": displayPicker,
|
|
@@ -163,14 +287,14 @@ var EmojiPicker = (props) => {
|
|
|
163
287
|
ref: setReferenceElement,
|
|
164
288
|
type: "button"
|
|
165
289
|
},
|
|
166
|
-
ButtonIconComponent && /* @__PURE__ */
|
|
290
|
+
ButtonIconComponent && /* @__PURE__ */ import_react10.default.createElement(ButtonIconComponent, null)
|
|
167
291
|
));
|
|
168
292
|
};
|
|
169
293
|
|
|
170
294
|
// src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts
|
|
171
295
|
var import_lodash = __toESM(require("lodash.mergewith"));
|
|
172
|
-
var
|
|
173
|
-
var EmojiSearchSource = class extends
|
|
296
|
+
var import_stream_chat2 = require("stream-chat");
|
|
297
|
+
var EmojiSearchSource = class extends import_stream_chat2.BaseSearchSource {
|
|
174
298
|
constructor(emojiSearchIndex, options) {
|
|
175
299
|
super(options);
|
|
176
300
|
this.type = "emoji";
|
|
@@ -198,7 +322,7 @@ var EmojiSearchSource = class extends import_stream_chat.BaseSearchSource {
|
|
|
198
322
|
filterQueryResults(items) {
|
|
199
323
|
return items.map((item) => ({
|
|
200
324
|
...item,
|
|
201
|
-
...(0,
|
|
325
|
+
...(0, import_stream_chat2.getTokenizedSuggestionDisplayName)({
|
|
202
326
|
displayName: item.id,
|
|
203
327
|
searchToken: this.searchQuery
|
|
204
328
|
})
|
|
@@ -212,76 +336,64 @@ var createTextComposerEmojiMiddleware = (emojiSearchIndex, options) => {
|
|
|
212
336
|
emojiSearchSource.activate();
|
|
213
337
|
return {
|
|
214
338
|
id: "stream-io/emoji-middleware",
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
339
|
+
// eslint-disable-next-line sort-keys
|
|
340
|
+
handlers: {
|
|
341
|
+
onChange: async ({ complete, forward, next, state }) => {
|
|
342
|
+
if (!state.selection) return forward();
|
|
343
|
+
const triggerWithToken = (0, import_stream_chat2.getTriggerCharWithToken)({
|
|
344
|
+
acceptTrailingSpaces: false,
|
|
345
|
+
text: state.text.slice(0, state.selection.end),
|
|
346
|
+
trigger: finalOptions.trigger
|
|
347
|
+
});
|
|
348
|
+
const triggerWasRemoved = !triggerWithToken || triggerWithToken.length < finalOptions.minChars;
|
|
349
|
+
if (triggerWasRemoved) {
|
|
350
|
+
const hasSuggestionsForTrigger = state.suggestions?.trigger === finalOptions.trigger;
|
|
351
|
+
const newState = { ...state };
|
|
352
|
+
if (hasSuggestionsForTrigger && newState.suggestions) {
|
|
353
|
+
delete newState.suggestions;
|
|
354
|
+
}
|
|
355
|
+
return next(newState);
|
|
229
356
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if (textWithReplacedWord !== state.text) {
|
|
248
|
-
return {
|
|
249
|
-
state: {
|
|
357
|
+
const newSearchTriggerred = triggerWithToken && triggerWithToken === finalOptions.trigger;
|
|
358
|
+
if (newSearchTriggerred) {
|
|
359
|
+
emojiSearchSource.resetStateAndActivate();
|
|
360
|
+
}
|
|
361
|
+
const textWithReplacedWord = await (0, import_stream_chat2.replaceWordWithEntity)({
|
|
362
|
+
caretPosition: state.selection.end,
|
|
363
|
+
getEntityString: async (word) => {
|
|
364
|
+
const { items } = await emojiSearchSource.query(word);
|
|
365
|
+
const emoji = items.filter(Boolean).slice(0, 10).find(({ emoticons }) => !!emoticons?.includes(word));
|
|
366
|
+
if (!emoji) return null;
|
|
367
|
+
const [firstSkin] = emoji.skins ?? [];
|
|
368
|
+
return emoji.native ?? firstSkin.native;
|
|
369
|
+
},
|
|
370
|
+
text: state.text
|
|
371
|
+
});
|
|
372
|
+
if (textWithReplacedWord !== state.text) {
|
|
373
|
+
return complete({
|
|
250
374
|
...state,
|
|
251
375
|
suggestions: void 0,
|
|
252
376
|
// to prevent the TextComposerMiddlewareExecutor to run the first page query
|
|
253
377
|
text: textWithReplacedWord
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
return {
|
|
260
|
-
state: {
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
return complete({
|
|
261
381
|
...state,
|
|
262
382
|
suggestions: {
|
|
263
383
|
query: triggerWithToken.slice(1),
|
|
264
384
|
searchSource: emojiSearchSource,
|
|
265
385
|
trigger: finalOptions.trigger
|
|
266
386
|
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
selectedSuggestion
|
|
276
|
-
}) => {
|
|
277
|
-
const { state } = input;
|
|
278
|
-
if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)
|
|
279
|
-
return nextHandler(input);
|
|
280
|
-
emojiSearchSource.resetStateAndActivate();
|
|
281
|
-
return Promise.resolve({
|
|
282
|
-
state: {
|
|
387
|
+
});
|
|
388
|
+
},
|
|
389
|
+
onSuggestionItemSelect: ({ complete, forward, state }) => {
|
|
390
|
+
const { selectedSuggestion } = state.change ?? {};
|
|
391
|
+
if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)
|
|
392
|
+
return forward();
|
|
393
|
+
emojiSearchSource.resetStateAndActivate();
|
|
394
|
+
return complete({
|
|
283
395
|
...state,
|
|
284
|
-
...(0,
|
|
396
|
+
...(0, import_stream_chat2.insertItemWithTrigger)({
|
|
285
397
|
insertText: `${"native" in selectedSuggestion ? selectedSuggestion.native : ""} `,
|
|
286
398
|
selection: state.selection,
|
|
287
399
|
text: state.text,
|
|
@@ -289,8 +401,8 @@ var createTextComposerEmojiMiddleware = (emojiSearchIndex, options) => {
|
|
|
289
401
|
}),
|
|
290
402
|
suggestions: void 0
|
|
291
403
|
// Clear suggestions after selection
|
|
292
|
-
}
|
|
293
|
-
}
|
|
404
|
+
});
|
|
405
|
+
}
|
|
294
406
|
}
|
|
295
407
|
};
|
|
296
408
|
};
|