stream-chat-react 14.0.0-beta.2 → 14.0.0-beta.3
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/{WithAudioPlayback-myzUS2m6.js → cjs/WithAudioPlayback.4a84360f.js} +4 -9
- package/dist/cjs/WithAudioPlayback.4a84360f.js.map +1 -0
- package/dist/{audioProcessing-BbOs2wMd.js → cjs/audioProcessing.56e5db9d.js} +1 -1
- package/dist/cjs/audioProcessing.56e5db9d.js.map +1 -0
- package/dist/cjs/emojis.js +1 -1
- package/dist/cjs/index.js +620 -225
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/mp3-encoder.js +1 -1
- package/dist/css/index.css +181 -26
- package/dist/css/index.css.map +1 -1
- package/dist/{WithAudioPlayback-C1hfFIcu.mjs → es/WithAudioPlayback.a3d5a2fc.mjs} +14 -19
- package/dist/es/WithAudioPlayback.a3d5a2fc.mjs.map +1 -0
- package/dist/{audioProcessing-ByEVSjGG.mjs → es/audioProcessing.21cb49e1.mjs} +1 -1
- package/dist/es/audioProcessing.21cb49e1.mjs.map +1 -0
- package/dist/es/emojis.mjs +1 -1
- package/dist/es/index.mjs +632 -237
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/mp3-encoder.mjs +1 -1
- package/dist/types/components/Attachment/Giphy.d.ts.map +1 -1
- package/dist/types/components/Attachment/VoiceRecording.d.ts.map +1 -1
- package/dist/types/components/AudioPlayback/AudioPlayer.d.ts.map +1 -1
- package/dist/types/components/BaseImage/toBaseImageDescriptors.d.ts +1 -1
- package/dist/types/components/BaseImage/toBaseImageDescriptors.d.ts.map +1 -1
- package/dist/types/components/ChannelList/hooks/useMobileNavigation.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.d.ts +3 -1
- package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.defaults.d.ts +6 -3
- package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.defaults.d.ts.map +1 -1
- package/dist/types/components/Chat/hooks/useSplitActionSet.d.ts +5 -0
- package/dist/types/components/Chat/hooks/useSplitActionSet.d.ts.map +1 -1
- package/dist/types/components/Dialog/components/ContextMenu.d.ts +119 -3
- package/dist/types/components/Dialog/components/ContextMenu.d.ts.map +1 -1
- package/dist/types/components/Dialog/hooks/useDialog.d.ts +1 -1
- package/dist/types/components/Dialog/hooks/useDialog.d.ts.map +1 -1
- package/dist/types/components/Dialog/service/DialogAnchor.d.ts +14 -1
- package/dist/types/components/Dialog/service/DialogAnchor.d.ts.map +1 -1
- package/dist/types/components/Dialog/service/DialogManager.d.ts +14 -3
- package/dist/types/components/Dialog/service/DialogManager.d.ts.map +1 -1
- package/dist/types/components/Dialog/service/DialogPortal.d.ts.map +1 -1
- package/dist/types/components/Gallery/GalleryContext.d.ts +1 -1
- package/dist/types/components/Gallery/GalleryContext.d.ts.map +1 -1
- package/dist/types/components/MessageActions/MessageActions.d.ts +14 -3
- package/dist/types/components/MessageActions/MessageActions.d.ts.map +1 -1
- package/dist/types/components/MessageActions/MessageActions.defaults.d.ts +1 -1
- package/dist/types/components/MessageActions/MessageActions.defaults.d.ts.map +1 -1
- package/dist/types/components/MessageActions/QuickMessageActionButton.d.ts.map +1 -1
- package/dist/types/components/MessageActions/hooks/useBaseMessageActionSetFilter.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
- package/dist/types/components/MessageList/hooks/MessageList/useScrollLocationLogic.d.ts +18 -0
- package/dist/types/components/MessageList/hooks/MessageList/useScrollLocationLogic.d.ts.map +1 -1
- package/dist/types/components/Poll/PollActions/PollResults/PollOptionWithVotes.d.ts.map +1 -1
- package/dist/types/components/Reactions/MessageReactions.d.ts.map +1 -1
- package/dist/types/components/Reactions/MessageReactionsDetail.d.ts +1 -0
- package/dist/types/components/Reactions/MessageReactionsDetail.d.ts.map +1 -1
- package/dist/types/components/Reactions/ReactionSelector.d.ts +1 -1
- package/dist/types/components/Reactions/ReactionSelector.d.ts.map +1 -1
- package/dist/types/components/TextareaComposer/SuggestionList/SuggestionList.d.ts.map +1 -1
- package/dist/types/components/TextareaComposer/TextareaComposer.d.ts.map +1 -1
- package/dist/types/context/ChannelListContext.d.ts +1 -1
- package/dist/types/context/ChannelListContext.d.ts.map +1 -1
- package/dist/types/context/ComponentContext.d.ts +5 -1
- package/dist/types/context/ComponentContext.d.ts.map +1 -1
- package/dist/types/context/DialogManagerContext.d.ts +11 -7
- package/dist/types/context/DialogManagerContext.d.ts.map +1 -1
- package/package.json +3 -1
- package/dist/WithAudioPlayback-C1hfFIcu.mjs.map +0 -1
- package/dist/WithAudioPlayback-myzUS2m6.js.map +0 -1
- package/dist/audioProcessing-BbOs2wMd.js.map +0 -1
- package/dist/audioProcessing-ByEVSjGG.mjs.map +0 -1
package/dist/cjs/index.js
CHANGED
|
@@ -4,8 +4,8 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
4
4
|
const clsx = require("clsx");
|
|
5
5
|
const nanoid = require("nanoid");
|
|
6
6
|
const React = require("react");
|
|
7
|
-
const audioProcessing = require("
|
|
8
|
-
const WithAudioPlayback = require("
|
|
7
|
+
const audioProcessing = require("./audioProcessing.56e5db9d.js");
|
|
8
|
+
const WithAudioPlayback = require("./WithAudioPlayback.4a84360f.js");
|
|
9
9
|
const streamChat = require("stream-chat");
|
|
10
10
|
const throttle = require("lodash.throttle");
|
|
11
11
|
const linkify = require("linkifyjs");
|
|
@@ -19,7 +19,6 @@ const unistUtilVisit = require("unist-util-visit");
|
|
|
19
19
|
const i18n = require("i18next");
|
|
20
20
|
const Dayjs = require("dayjs");
|
|
21
21
|
const uniqBy = require("lodash.uniqby");
|
|
22
|
-
const tsPattern = require("ts-pattern");
|
|
23
22
|
const shim = require("use-sync-external-store/shim");
|
|
24
23
|
const debounce = require("lodash.debounce");
|
|
25
24
|
const fixWebmDuration = require("fix-webm-duration");
|
|
@@ -89,10 +88,11 @@ const useAIState = (channel) => {
|
|
|
89
88
|
return { aiState };
|
|
90
89
|
};
|
|
91
90
|
class DialogManager {
|
|
92
|
-
constructor({ id } = {}) {
|
|
91
|
+
constructor({ closeOnClickOutside = true, id } = {}) {
|
|
93
92
|
this.state = new streamChat.StateStore({
|
|
94
93
|
dialogsById: {}
|
|
95
94
|
});
|
|
95
|
+
this.closeOnClickOutside = closeOnClickOutside;
|
|
96
96
|
this.id = id ?? nanoid.nanoid();
|
|
97
97
|
}
|
|
98
98
|
get openDialogCount() {
|
|
@@ -107,13 +107,14 @@ class DialogManager {
|
|
|
107
107
|
get(id) {
|
|
108
108
|
return this.state.getLatestValue().dialogsById[id];
|
|
109
109
|
}
|
|
110
|
-
getOrCreate({ id }) {
|
|
110
|
+
getOrCreate({ closeOnClickOutside, id }) {
|
|
111
111
|
let dialog = this.state.getLatestValue().dialogsById[id];
|
|
112
112
|
if (!dialog) {
|
|
113
113
|
dialog = {
|
|
114
114
|
close: () => {
|
|
115
115
|
this.close(id);
|
|
116
116
|
},
|
|
117
|
+
closeOnClickOutside,
|
|
117
118
|
id,
|
|
118
119
|
isOpen: false,
|
|
119
120
|
open: () => {
|
|
@@ -129,21 +130,22 @@ class DialogManager {
|
|
|
129
130
|
};
|
|
130
131
|
this.state.next((current) => ({
|
|
131
132
|
...current,
|
|
132
|
-
|
|
133
|
+
dialogsById: { ...current.dialogsById, [id]: dialog }
|
|
133
134
|
}));
|
|
134
135
|
}
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
const shouldUpdateDialogSettings = dialog.closeOnClickOutside !== closeOnClickOutside || !!dialog.removalTimeout;
|
|
137
|
+
if (shouldUpdateDialogSettings) {
|
|
138
|
+
if (dialog.removalTimeout) clearTimeout(dialog.removalTimeout);
|
|
139
|
+
dialog = {
|
|
140
|
+
...dialog,
|
|
141
|
+
closeOnClickOutside,
|
|
142
|
+
removalTimeout: void 0
|
|
143
|
+
};
|
|
137
144
|
this.state.next((current) => ({
|
|
138
145
|
...current,
|
|
139
|
-
|
|
140
|
-
dialogsById
|
|
141
|
-
|
|
142
|
-
[id]: {
|
|
143
|
-
...dialog,
|
|
144
|
-
removalTimeout: void 0
|
|
145
|
-
}
|
|
146
|
-
}
|
|
146
|
+
dialogsById: {
|
|
147
|
+
...current.dialogsById,
|
|
148
|
+
[id]: dialog
|
|
147
149
|
}
|
|
148
150
|
}));
|
|
149
151
|
}
|
|
@@ -220,7 +222,11 @@ class DialogManager {
|
|
|
220
222
|
}));
|
|
221
223
|
}
|
|
222
224
|
}
|
|
223
|
-
const useDialog = ({
|
|
225
|
+
const useDialog = ({
|
|
226
|
+
closeOnClickOutside,
|
|
227
|
+
dialogManagerId,
|
|
228
|
+
id
|
|
229
|
+
}) => {
|
|
224
230
|
const { dialogManager } = useDialogManager({ dialogManagerId });
|
|
225
231
|
React.useEffect(
|
|
226
232
|
() => () => {
|
|
@@ -228,7 +234,7 @@ const useDialog = ({ dialogManagerId, id }) => {
|
|
|
228
234
|
},
|
|
229
235
|
[dialogManager, id]
|
|
230
236
|
);
|
|
231
|
-
return dialogManager.getOrCreate({ id });
|
|
237
|
+
return dialogManager.getOrCreate({ closeOnClickOutside, id });
|
|
232
238
|
};
|
|
233
239
|
const useDialogOnNearestManager = ({ id }) => {
|
|
234
240
|
const { dialogManager } = useNearestDialogManagerContext() ?? {};
|
|
@@ -275,9 +281,37 @@ const Portal = ({
|
|
|
275
281
|
if (!portalDestination) return null;
|
|
276
282
|
return reactDom.createPortal(children, portalDestination);
|
|
277
283
|
};
|
|
284
|
+
const shouldCloseOnOutsideClick = ({
|
|
285
|
+
dialog,
|
|
286
|
+
managerCloseOnClickOutside
|
|
287
|
+
}) => dialog.closeOnClickOutside ?? managerCloseOnClickOutside;
|
|
278
288
|
const DialogPortalDestination = () => {
|
|
279
289
|
const { dialogManager } = useNearestDialogManagerContext() ?? {};
|
|
280
290
|
const openedDialogCount = useOpenedDialogCount({ dialogManagerId: dialogManager?.id });
|
|
291
|
+
const [destinationRoot, setDestinationRoot] = React.useState(null);
|
|
292
|
+
React.useEffect(() => {
|
|
293
|
+
if (!destinationRoot || !dialogManager) return;
|
|
294
|
+
const handleDocumentClick = (event) => {
|
|
295
|
+
if (destinationRoot.contains(event.target)) return;
|
|
296
|
+
setTimeout(() => {
|
|
297
|
+
Object.values(dialogManager.state.getLatestValue().dialogsById).forEach(
|
|
298
|
+
(dialog) => {
|
|
299
|
+
if (!dialog.isOpen) return;
|
|
300
|
+
if (!shouldCloseOnOutsideClick({
|
|
301
|
+
dialog,
|
|
302
|
+
managerCloseOnClickOutside: dialogManager.closeOnClickOutside
|
|
303
|
+
}))
|
|
304
|
+
return;
|
|
305
|
+
dialogManager.close(dialog.id);
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
}, 0);
|
|
309
|
+
};
|
|
310
|
+
document.addEventListener("click", handleDocumentClick, { capture: true });
|
|
311
|
+
return () => {
|
|
312
|
+
document.removeEventListener("click", handleDocumentClick, { capture: true });
|
|
313
|
+
};
|
|
314
|
+
}, [destinationRoot, dialogManager]);
|
|
281
315
|
if (!openedDialogCount) return null;
|
|
282
316
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
283
317
|
"div",
|
|
@@ -285,7 +319,22 @@ const DialogPortalDestination = () => {
|
|
|
285
319
|
className: "str-chat__dialog-overlay",
|
|
286
320
|
"data-str-chat__portal-id": dialogManager?.id,
|
|
287
321
|
"data-testid": "str-chat__dialog-overlay",
|
|
288
|
-
onClick: () =>
|
|
322
|
+
onClick: (event) => {
|
|
323
|
+
if (!dialogManager) return;
|
|
324
|
+
if (event.target !== event.currentTarget) return;
|
|
325
|
+
Object.values(dialogManager.state.getLatestValue().dialogsById).forEach(
|
|
326
|
+
(dialog) => {
|
|
327
|
+
if (!dialog.isOpen) return;
|
|
328
|
+
if (!shouldCloseOnOutsideClick({
|
|
329
|
+
dialog,
|
|
330
|
+
managerCloseOnClickOutside: dialogManager.closeOnClickOutside
|
|
331
|
+
}))
|
|
332
|
+
return;
|
|
333
|
+
dialogManager.close(dialog.id);
|
|
334
|
+
}
|
|
335
|
+
);
|
|
336
|
+
},
|
|
337
|
+
ref: setDestinationRoot,
|
|
289
338
|
style: {
|
|
290
339
|
"--str-chat__dialog-overlay-height": openedDialogCount > 0 ? "100%" : "0"
|
|
291
340
|
}
|
|
@@ -307,11 +356,16 @@ const DialogPortalEntry = ({
|
|
|
307
356
|
};
|
|
308
357
|
const dialogManagersRegistry = new streamChat.StateStore({});
|
|
309
358
|
const getDialogManager = (id) => dialogManagersRegistry.getLatestValue()[id];
|
|
310
|
-
const getOrCreateDialogManager = (
|
|
359
|
+
const getOrCreateDialogManager = ({
|
|
360
|
+
closeOnClickOutside,
|
|
361
|
+
id
|
|
362
|
+
}) => {
|
|
311
363
|
let manager = getDialogManager(id);
|
|
312
364
|
if (!manager) {
|
|
313
|
-
manager = new DialogManager({ id });
|
|
365
|
+
manager = new DialogManager({ closeOnClickOutside, id });
|
|
314
366
|
dialogManagersRegistry.partialNext({ [id]: manager });
|
|
367
|
+
} else if (typeof closeOnClickOutside === "boolean") {
|
|
368
|
+
manager.closeOnClickOutside = closeOnClickOutside;
|
|
315
369
|
}
|
|
316
370
|
return manager;
|
|
317
371
|
};
|
|
@@ -322,20 +376,21 @@ const removeDialogManager = (id) => {
|
|
|
322
376
|
const DialogManagerProviderContext = React.createContext(void 0);
|
|
323
377
|
const DialogManagerProvider = ({
|
|
324
378
|
children,
|
|
379
|
+
closeOnClickOutside,
|
|
325
380
|
id
|
|
326
381
|
}) => {
|
|
327
382
|
const [dialogManager, setDialogManager] = React.useState(() => {
|
|
328
383
|
if (id) return getDialogManager(id) ?? null;
|
|
329
|
-
return new DialogManager();
|
|
384
|
+
return new DialogManager({ closeOnClickOutside });
|
|
330
385
|
});
|
|
331
386
|
React.useEffect(() => {
|
|
332
387
|
if (!id) return;
|
|
333
|
-
setDialogManager(getOrCreateDialogManager(id));
|
|
388
|
+
setDialogManager(getOrCreateDialogManager({ closeOnClickOutside, id }));
|
|
334
389
|
return () => {
|
|
335
390
|
removeDialogManager(id);
|
|
336
391
|
setDialogManager(null);
|
|
337
392
|
};
|
|
338
|
-
}, [id]);
|
|
393
|
+
}, [closeOnClickOutside, id]);
|
|
339
394
|
if (!dialogManager) return null;
|
|
340
395
|
return /* @__PURE__ */ jsxRuntime.jsxs(DialogManagerProviderContext.Provider, { value: { dialogManager }, children: [
|
|
341
396
|
children,
|
|
@@ -9054,6 +9109,7 @@ function useDialogAnchor({
|
|
|
9054
9109
|
setPopperElement(null);
|
|
9055
9110
|
}
|
|
9056
9111
|
return {
|
|
9112
|
+
placement: stabilisedChosenPlacement ?? chosenPlacement,
|
|
9057
9113
|
setPopperElement,
|
|
9058
9114
|
styles: {
|
|
9059
9115
|
left: x ?? 0,
|
|
@@ -9066,6 +9122,8 @@ const DialogAnchor = ({
|
|
|
9066
9122
|
allowFlip = true,
|
|
9067
9123
|
children,
|
|
9068
9124
|
className,
|
|
9125
|
+
closeOnClickOutside,
|
|
9126
|
+
closeTransitionMs = 0,
|
|
9069
9127
|
dialogManagerId,
|
|
9070
9128
|
focus: focus$1 = true,
|
|
9071
9129
|
id,
|
|
@@ -9078,12 +9136,44 @@ const DialogAnchor = ({
|
|
|
9078
9136
|
updatePositionOnContentResize,
|
|
9079
9137
|
...restDivProps
|
|
9080
9138
|
}) => {
|
|
9081
|
-
const dialog = useDialog({ dialogManagerId, id });
|
|
9139
|
+
const dialog = useDialog({ closeOnClickOutside, dialogManagerId, id });
|
|
9082
9140
|
const open = useDialogIsOpen(id, dialogManagerId);
|
|
9083
|
-
const
|
|
9141
|
+
const [shouldRender, setShouldRender] = React.useState(open);
|
|
9142
|
+
const closeTimeoutRef = React.useRef(null);
|
|
9143
|
+
const isClosing = !open && shouldRender;
|
|
9144
|
+
React.useEffect(() => {
|
|
9145
|
+
if (open) {
|
|
9146
|
+
setShouldRender(true);
|
|
9147
|
+
if (closeTimeoutRef.current) {
|
|
9148
|
+
clearTimeout(closeTimeoutRef.current);
|
|
9149
|
+
closeTimeoutRef.current = null;
|
|
9150
|
+
}
|
|
9151
|
+
return;
|
|
9152
|
+
}
|
|
9153
|
+
if (!shouldRender) return;
|
|
9154
|
+
if (!closeTransitionMs) {
|
|
9155
|
+
setShouldRender(false);
|
|
9156
|
+
return;
|
|
9157
|
+
}
|
|
9158
|
+
closeTimeoutRef.current = setTimeout(() => {
|
|
9159
|
+
setShouldRender(false);
|
|
9160
|
+
closeTimeoutRef.current = null;
|
|
9161
|
+
}, closeTransitionMs);
|
|
9162
|
+
}, [closeTransitionMs, open, shouldRender]);
|
|
9163
|
+
React.useEffect(
|
|
9164
|
+
() => () => {
|
|
9165
|
+
if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);
|
|
9166
|
+
},
|
|
9167
|
+
[]
|
|
9168
|
+
);
|
|
9169
|
+
const {
|
|
9170
|
+
placement: chosenPlacement,
|
|
9171
|
+
setPopperElement,
|
|
9172
|
+
styles
|
|
9173
|
+
} = useDialogAnchor({
|
|
9084
9174
|
allowFlip,
|
|
9085
9175
|
offset,
|
|
9086
|
-
open,
|
|
9176
|
+
open: shouldRender,
|
|
9087
9177
|
placement,
|
|
9088
9178
|
referenceElement,
|
|
9089
9179
|
updateKey,
|
|
@@ -9100,7 +9190,7 @@ const DialogAnchor = ({
|
|
|
9100
9190
|
document.removeEventListener("keyup", hideOnEscape);
|
|
9101
9191
|
};
|
|
9102
9192
|
}, [dialog, open]);
|
|
9103
|
-
if (!
|
|
9193
|
+
if (!shouldRender) {
|
|
9104
9194
|
return null;
|
|
9105
9195
|
}
|
|
9106
9196
|
return /* @__PURE__ */ jsxRuntime.jsx(DialogPortalEntry, { dialogId: id, dialogManagerId, children: /* @__PURE__ */ jsxRuntime.jsx(focus.FocusScope, { autoFocus: focus$1, contain: trapFocus, restoreFocus: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9108,6 +9198,8 @@ const DialogAnchor = ({
|
|
|
9108
9198
|
{
|
|
9109
9199
|
...restDivProps,
|
|
9110
9200
|
className: clsx("str-chat__dialog-contents", className),
|
|
9201
|
+
"data-str-chat-dialog-state": isClosing ? "closing" : "open",
|
|
9202
|
+
"data-str-chat-placement": chosenPlacement,
|
|
9111
9203
|
"data-testid": "str-chat__dialog-contents",
|
|
9112
9204
|
ref: setPopperElement,
|
|
9113
9205
|
style: styles,
|
|
@@ -9450,16 +9542,152 @@ const EmojiContextMenuButton = ({
|
|
|
9450
9542
|
]
|
|
9451
9543
|
}
|
|
9452
9544
|
);
|
|
9453
|
-
const
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9545
|
+
const ContextMenuButtonWithSubmenu = ({
|
|
9546
|
+
children,
|
|
9547
|
+
className,
|
|
9548
|
+
Submenu,
|
|
9549
|
+
submenuContainerProps,
|
|
9550
|
+
submenuPlacement = "right-start",
|
|
9551
|
+
submenuRollAxis = "x",
|
|
9552
|
+
...buttonProps
|
|
9457
9553
|
}) => {
|
|
9554
|
+
const { className: submenuClassName, ...submenuContainerRestProps } = submenuContainerProps ?? {};
|
|
9555
|
+
const buttonRef = React.useRef(null);
|
|
9556
|
+
const [dialogContainer, setDialogContainer] = React.useState(null);
|
|
9557
|
+
const keepSubmenuOpenFlag = React.useRef(false);
|
|
9558
|
+
const dialogCloseTimeout = React.useRef(null);
|
|
9559
|
+
const dialogId2 = React.useMemo(() => `submenu-${Math.random().toString(36).slice(2)}`, []);
|
|
9560
|
+
const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId2 });
|
|
9561
|
+
const dialogIsOpen = useDialogIsOpen(dialogId2, dialogManager?.id);
|
|
9562
|
+
const {
|
|
9563
|
+
placement: chosenPlacement,
|
|
9564
|
+
setPopperElement,
|
|
9565
|
+
styles
|
|
9566
|
+
} = useDialogAnchor({
|
|
9567
|
+
open: dialogIsOpen,
|
|
9568
|
+
placement: submenuPlacement,
|
|
9569
|
+
referenceElement: buttonRef.current
|
|
9570
|
+
});
|
|
9571
|
+
const closeDialogLazily = React.useCallback(() => {
|
|
9572
|
+
if (dialogCloseTimeout.current) clearTimeout(dialogCloseTimeout.current);
|
|
9573
|
+
dialogCloseTimeout.current = setTimeout(() => {
|
|
9574
|
+
if (keepSubmenuOpenFlag.current) return;
|
|
9575
|
+
dialog.close();
|
|
9576
|
+
}, 100);
|
|
9577
|
+
}, [dialog]);
|
|
9578
|
+
const keepSubmenuOpen = React.useCallback(() => {
|
|
9579
|
+
keepSubmenuOpenFlag.current = true;
|
|
9580
|
+
}, []);
|
|
9581
|
+
const allowToCloseSubmenu = React.useCallback(() => {
|
|
9582
|
+
keepSubmenuOpenFlag.current = false;
|
|
9583
|
+
}, []);
|
|
9584
|
+
const closeSubmenu = React.useCallback(() => {
|
|
9585
|
+
allowToCloseSubmenu();
|
|
9586
|
+
closeDialogLazily();
|
|
9587
|
+
}, [allowToCloseSubmenu, closeDialogLazily]);
|
|
9588
|
+
const handleClose = React.useCallback(
|
|
9589
|
+
(event) => {
|
|
9590
|
+
const parentButton = buttonRef.current;
|
|
9591
|
+
if (!dialogIsOpen || !parentButton) return;
|
|
9592
|
+
event.stopPropagation();
|
|
9593
|
+
closeDialogLazily();
|
|
9594
|
+
parentButton.focus();
|
|
9595
|
+
},
|
|
9596
|
+
[closeDialogLazily, dialogIsOpen, buttonRef]
|
|
9597
|
+
);
|
|
9598
|
+
const handleFocusParentButton = () => {
|
|
9599
|
+
if (dialogIsOpen) return;
|
|
9600
|
+
dialog.open();
|
|
9601
|
+
keepSubmenuOpen();
|
|
9602
|
+
};
|
|
9603
|
+
React.useEffect(() => {
|
|
9604
|
+
const parentButton = buttonRef.current;
|
|
9605
|
+
if (!dialogIsOpen || !parentButton) return;
|
|
9606
|
+
const hideOnEscape = (event) => {
|
|
9607
|
+
if (event.key !== "Escape") return;
|
|
9608
|
+
handleClose(event);
|
|
9609
|
+
closeSubmenu();
|
|
9610
|
+
};
|
|
9611
|
+
document.addEventListener("keyup", hideOnEscape, { capture: true });
|
|
9612
|
+
return () => {
|
|
9613
|
+
document.removeEventListener("keyup", hideOnEscape, { capture: true });
|
|
9614
|
+
};
|
|
9615
|
+
}, [dialogIsOpen, handleClose, closeSubmenu]);
|
|
9616
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
9617
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9618
|
+
BaseContextMenuButton,
|
|
9619
|
+
{
|
|
9620
|
+
"aria-selected": "false",
|
|
9621
|
+
className: clsx(className, "str_chat__button-with-submenu", {
|
|
9622
|
+
"str_chat__button-with-submenu--submenu-open": dialogIsOpen
|
|
9623
|
+
}),
|
|
9624
|
+
hasSubMenu: true,
|
|
9625
|
+
onBlur: closeSubmenu,
|
|
9626
|
+
onClick: (event) => {
|
|
9627
|
+
event.stopPropagation();
|
|
9628
|
+
dialog.toggle();
|
|
9629
|
+
},
|
|
9630
|
+
onFocus: handleFocusParentButton,
|
|
9631
|
+
onMouseEnter: handleFocusParentButton,
|
|
9632
|
+
onMouseLeave: closeSubmenu,
|
|
9633
|
+
role: "option",
|
|
9634
|
+
...buttonProps,
|
|
9635
|
+
ref: buttonRef,
|
|
9636
|
+
children
|
|
9637
|
+
}
|
|
9638
|
+
),
|
|
9639
|
+
dialogIsOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9640
|
+
"div",
|
|
9641
|
+
{
|
|
9642
|
+
className: clsx("str-chat__context-menu__submenu-container", submenuClassName),
|
|
9643
|
+
"data-str-chat-placement": chosenPlacement,
|
|
9644
|
+
"data-str-chat-roll-axis": submenuRollAxis,
|
|
9645
|
+
onBlur: (event) => {
|
|
9646
|
+
const isBlurredDescendant = event.relatedTarget instanceof Node && dialogContainer?.contains(event.relatedTarget);
|
|
9647
|
+
if (isBlurredDescendant) return;
|
|
9648
|
+
closeSubmenu();
|
|
9649
|
+
},
|
|
9650
|
+
onFocus: keepSubmenuOpen,
|
|
9651
|
+
onMouseEnter: keepSubmenuOpen,
|
|
9652
|
+
onMouseLeave: closeSubmenu,
|
|
9653
|
+
ref: (element) => {
|
|
9654
|
+
setPopperElement(element);
|
|
9655
|
+
setDialogContainer(element);
|
|
9656
|
+
},
|
|
9657
|
+
style: styles,
|
|
9658
|
+
tabIndex: -1,
|
|
9659
|
+
...submenuContainerRestProps,
|
|
9660
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Submenu, {})
|
|
9661
|
+
}
|
|
9662
|
+
)
|
|
9663
|
+
] });
|
|
9664
|
+
};
|
|
9665
|
+
const ContextMenuButton = (props) => {
|
|
9666
|
+
const {
|
|
9667
|
+
Submenu,
|
|
9668
|
+
submenuContainerProps,
|
|
9669
|
+
submenuPlacement,
|
|
9670
|
+
submenuRollAxis,
|
|
9671
|
+
...buttonProps
|
|
9672
|
+
} = props;
|
|
9458
9673
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
9674
|
+
if (Submenu) {
|
|
9675
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9676
|
+
ContextMenuButtonWithSubmenu,
|
|
9677
|
+
{
|
|
9678
|
+
...buttonProps,
|
|
9679
|
+
Submenu,
|
|
9680
|
+
submenuContainerProps,
|
|
9681
|
+
submenuPlacement,
|
|
9682
|
+
submenuRollAxis
|
|
9683
|
+
}
|
|
9684
|
+
);
|
|
9685
|
+
}
|
|
9686
|
+
const { onBlur, onFocus, ...baseButtonProps } = buttonProps;
|
|
9459
9687
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9460
9688
|
BaseContextMenuButton,
|
|
9461
9689
|
{
|
|
9462
|
-
...
|
|
9690
|
+
...baseButtonProps,
|
|
9463
9691
|
"aria-selected": isFocused ? "true" : "false",
|
|
9464
9692
|
onBlur: (e) => {
|
|
9465
9693
|
setIsFocused(false);
|
|
@@ -9508,12 +9736,14 @@ function ContextMenuContent({
|
|
|
9508
9736
|
backLabel = "Back",
|
|
9509
9737
|
children,
|
|
9510
9738
|
className,
|
|
9739
|
+
enableAnimations = true,
|
|
9511
9740
|
Header: Header2,
|
|
9512
9741
|
items,
|
|
9513
9742
|
ItemsWrapper,
|
|
9514
9743
|
menuClassName,
|
|
9515
9744
|
onClose,
|
|
9516
9745
|
onMenuLevelChange,
|
|
9746
|
+
transitionDirection,
|
|
9517
9747
|
...props
|
|
9518
9748
|
}) {
|
|
9519
9749
|
const rootLevel = React.useMemo(
|
|
@@ -9526,6 +9756,7 @@ function ContextMenuContent({
|
|
|
9526
9756
|
[Header2, items, ItemsWrapper, menuClassName]
|
|
9527
9757
|
);
|
|
9528
9758
|
const [menuStack, setMenuStack] = React.useState(() => [rootLevel]);
|
|
9759
|
+
const [menuBodyAnimationKey, setMenuBodyAnimationKey] = React.useState(0);
|
|
9529
9760
|
const activeMenu = menuStack[menuStack.length - 1];
|
|
9530
9761
|
const ActiveMenuItemsWrapper = activeMenu.ItemsWrapper ?? React.Fragment;
|
|
9531
9762
|
const closeMenu = React.useCallback(() => {
|
|
@@ -9549,10 +9780,9 @@ function ContextMenuContent({
|
|
|
9549
9780
|
[ItemsWrapper]
|
|
9550
9781
|
);
|
|
9551
9782
|
const returnToParentMenu = React.useCallback(() => {
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
}, []);
|
|
9783
|
+
if (menuStack.length <= 1) return;
|
|
9784
|
+
setMenuStack((current) => current.slice(0, current.length - 1));
|
|
9785
|
+
}, [menuStack.length]);
|
|
9556
9786
|
React.useEffect(() => {
|
|
9557
9787
|
setMenuStack((current) => {
|
|
9558
9788
|
if (current.length === 1 && current[0] === rootLevel) return current;
|
|
@@ -9562,42 +9792,116 @@ function ContextMenuContent({
|
|
|
9562
9792
|
React.useEffect(() => {
|
|
9563
9793
|
onMenuLevelChange?.(menuStack.length);
|
|
9564
9794
|
}, [menuStack.length, onMenuLevelChange]);
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9795
|
+
React.useEffect(() => {
|
|
9796
|
+
if (!transitionDirection) return;
|
|
9797
|
+
setMenuBodyAnimationKey((value) => value + 1);
|
|
9798
|
+
}, [transitionDirection, menuStack.length]);
|
|
9799
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ContextMenuContext.Provider, { value: { closeMenu, openSubmenu, returnToParentMenu }, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9800
|
+
ContextMenuRoot,
|
|
9801
|
+
{
|
|
9802
|
+
className: clsx(className, activeMenu.menuClassName),
|
|
9803
|
+
"data-str-chat-enable-animations": enableAnimations,
|
|
9804
|
+
...props,
|
|
9805
|
+
children: [
|
|
9806
|
+
activeMenu.Header ? /* @__PURE__ */ jsxRuntime.jsx(activeMenu.Header, {}) : menuStack.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx(ContextMenuHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(ContextMenuBackButton, { onClick: returnToParentMenu, children: [
|
|
9807
|
+
/* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconChevronLeft, {}),
|
|
9808
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: backLabel })
|
|
9809
|
+
] }) }) : null,
|
|
9810
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9811
|
+
ContextMenuBody,
|
|
9812
|
+
{
|
|
9813
|
+
className: clsx({
|
|
9814
|
+
"str-chat__context-menu__body--submenu-backward": transitionDirection === "backward",
|
|
9815
|
+
"str-chat__context-menu__body--submenu-forward": transitionDirection === "forward"
|
|
9816
|
+
}),
|
|
9817
|
+
children: activeMenu.Submenu ? /* @__PURE__ */ jsxRuntime.jsx(activeMenu.Submenu, {}) : /* @__PURE__ */ jsxRuntime.jsx(ActiveMenuItemsWrapper, { children: typeof children !== "undefined" ? children : activeMenu.items?.map((Item2, index) => /* @__PURE__ */ jsxRuntime.jsx(Item2, {}, `context-menu-item-${index}`)) })
|
|
9818
|
+
},
|
|
9819
|
+
`context-menu-body-${menuStack.length}-${menuBodyAnimationKey}`
|
|
9820
|
+
)
|
|
9821
|
+
]
|
|
9822
|
+
}
|
|
9823
|
+
) });
|
|
9572
9824
|
}
|
|
9573
9825
|
const ContextMenu = (props) => {
|
|
9826
|
+
const { ContextMenuContent: ContextMenuContentComponent = ContextMenuContent } = WithAudioPlayback.useComponentContext();
|
|
9574
9827
|
const {
|
|
9575
9828
|
allowFlip,
|
|
9829
|
+
closeOnClickOutside,
|
|
9830
|
+
closeTransitionMs = 130,
|
|
9576
9831
|
dialogManagerId,
|
|
9577
9832
|
focus: focus2,
|
|
9578
9833
|
id,
|
|
9579
9834
|
placement,
|
|
9580
9835
|
referenceElement,
|
|
9836
|
+
submenuTransitionDurationMs,
|
|
9581
9837
|
tabIndex,
|
|
9582
9838
|
trapFocus,
|
|
9583
9839
|
...menuProps
|
|
9584
9840
|
} = props;
|
|
9841
|
+
const resolvedSubmenuTransitionDurationMs = submenuTransitionDurationMs ?? 460;
|
|
9585
9842
|
const isAnchored = id != null;
|
|
9586
9843
|
const [menuLevel, setMenuLevel] = React.useState(1);
|
|
9844
|
+
const [transitionDirection, setTransitionDirection] = React.useState(void 0);
|
|
9845
|
+
const [contentResetToken, setContentResetToken] = React.useState(0);
|
|
9846
|
+
const transitionTimeoutRef = React.useRef(null);
|
|
9847
|
+
const previousMenuLevelRef = React.useRef(1);
|
|
9587
9848
|
const open = useDialogIsOpen(id ?? "", dialogManagerId);
|
|
9849
|
+
const previousOpenRef = React.useRef(open);
|
|
9588
9850
|
React.useEffect(() => {
|
|
9589
|
-
if (isAnchored
|
|
9851
|
+
if (!isAnchored) return;
|
|
9852
|
+
if (previousOpenRef.current && !open) {
|
|
9853
|
+
setMenuLevel(1);
|
|
9854
|
+
setTransitionDirection(void 0);
|
|
9855
|
+
setContentResetToken((value) => value + 1);
|
|
9856
|
+
previousMenuLevelRef.current = 1;
|
|
9857
|
+
if (transitionTimeoutRef.current) {
|
|
9858
|
+
clearTimeout(transitionTimeoutRef.current);
|
|
9859
|
+
transitionTimeoutRef.current = null;
|
|
9860
|
+
}
|
|
9861
|
+
}
|
|
9862
|
+
previousOpenRef.current = open;
|
|
9590
9863
|
}, [isAnchored, open]);
|
|
9591
|
-
|
|
9592
|
-
|
|
9864
|
+
React.useEffect(
|
|
9865
|
+
() => () => {
|
|
9866
|
+
if (transitionTimeoutRef.current) {
|
|
9867
|
+
clearTimeout(transitionTimeoutRef.current);
|
|
9868
|
+
}
|
|
9869
|
+
},
|
|
9870
|
+
[]
|
|
9871
|
+
);
|
|
9872
|
+
const handleMenuLevelChange = React.useCallback(
|
|
9873
|
+
(level) => {
|
|
9874
|
+
if (isAnchored) {
|
|
9875
|
+
const previousLevel = previousMenuLevelRef.current;
|
|
9876
|
+
if (level !== previousLevel) {
|
|
9877
|
+
setTransitionDirection(level > previousLevel ? "forward" : "backward");
|
|
9878
|
+
if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
|
|
9879
|
+
transitionTimeoutRef.current = setTimeout(() => {
|
|
9880
|
+
setTransitionDirection(void 0);
|
|
9881
|
+
transitionTimeoutRef.current = null;
|
|
9882
|
+
}, resolvedSubmenuTransitionDurationMs);
|
|
9883
|
+
}
|
|
9884
|
+
previousMenuLevelRef.current = level;
|
|
9885
|
+
setMenuLevel(level);
|
|
9886
|
+
return;
|
|
9887
|
+
}
|
|
9888
|
+
menuProps.onMenuLevelChange?.(level);
|
|
9889
|
+
},
|
|
9890
|
+
[isAnchored, menuProps, resolvedSubmenuTransitionDurationMs]
|
|
9891
|
+
);
|
|
9892
|
+
const content = /* @__PURE__ */ React.createElement(
|
|
9893
|
+
ContextMenuContentComponent,
|
|
9593
9894
|
{
|
|
9594
9895
|
...menuProps,
|
|
9595
|
-
|
|
9896
|
+
key: `context-menu-content-${contentResetToken}`,
|
|
9897
|
+
onMenuLevelChange: handleMenuLevelChange,
|
|
9898
|
+
transitionDirection
|
|
9596
9899
|
}
|
|
9597
9900
|
);
|
|
9598
9901
|
if (isAnchored) {
|
|
9599
9902
|
const {
|
|
9600
9903
|
backLabel: _b,
|
|
9904
|
+
enableAnimations: _ea,
|
|
9601
9905
|
Header: _h,
|
|
9602
9906
|
items: _i,
|
|
9603
9907
|
ItemsWrapper: _w,
|
|
@@ -9610,6 +9914,8 @@ const ContextMenu = (props) => {
|
|
|
9610
9914
|
DialogAnchor,
|
|
9611
9915
|
{
|
|
9612
9916
|
allowFlip,
|
|
9917
|
+
closeOnClickOutside,
|
|
9918
|
+
closeTransitionMs,
|
|
9613
9919
|
dialogManagerId,
|
|
9614
9920
|
focus: focus2,
|
|
9615
9921
|
id,
|
|
@@ -9947,7 +10253,9 @@ const useBaseMessageActionSetFilter = (messageActionSet, disable = false) => {
|
|
|
9947
10253
|
if (isBounced || isInitialMessage || // not sure whether this thing even works anymore
|
|
9948
10254
|
!message.type || message.type === "system" || message.type === "ephemeral" || message.status === "sending")
|
|
9949
10255
|
return [];
|
|
9950
|
-
return messageActionSet.filter((
|
|
10256
|
+
return messageActionSet.filter((action) => {
|
|
10257
|
+
if (action.placement === "quick-dropdown-toggle") return true;
|
|
10258
|
+
const type = action.type;
|
|
9951
10259
|
if (WithAudioPlayback.ACTIONS_NOT_WORKING_IN_THREAD.includes(type) && isMessageThreadReply)
|
|
9952
10260
|
return false;
|
|
9953
10261
|
if (message.error) {
|
|
@@ -11855,6 +12163,7 @@ const toBaseImageDescriptors = (attachment, options = {}) => {
|
|
|
11855
12163
|
title: attachment.title
|
|
11856
12164
|
};
|
|
11857
12165
|
}
|
|
12166
|
+
return void 0;
|
|
11858
12167
|
};
|
|
11859
12168
|
const BASE_FILE_ICON_CLASSNAME = "str-chat__file-icon";
|
|
11860
12169
|
const FILE_ICON_GRAPHIC_CLASSNAME = "str-chat__file-icon__graphic";
|
|
@@ -14692,7 +15001,8 @@ const PollOptionWithVotes = ({
|
|
|
14692
15001
|
"div",
|
|
14693
15002
|
{
|
|
14694
15003
|
className: clsx("str-chat__poll-option", {
|
|
14695
|
-
"str-chat__poll-option--has-more-votes": isVotesPreview && voteCount > countVotesPreview
|
|
15004
|
+
"str-chat__poll-option--has-more-votes": isVotesPreview && voteCount > countVotesPreview,
|
|
15005
|
+
"str-chat__poll-option--has-votes": voteCount
|
|
14696
15006
|
}),
|
|
14697
15007
|
children: [
|
|
14698
15008
|
/* @__PURE__ */ jsxRuntime.jsx(PollOptionWithVotesHeader, { option, optionOrderNumber: orderNumber }),
|
|
@@ -15705,7 +16015,7 @@ const AttachmentSelector = ({
|
|
|
15705
16015
|
getModalPortalDestination
|
|
15706
16016
|
}) => {
|
|
15707
16017
|
const { t } = WithAudioPlayback.useTranslationContext();
|
|
15708
|
-
const { Modal = GlobalModal } = WithAudioPlayback.useComponentContext();
|
|
16018
|
+
const { ContextMenu: ContextMenuComponent = ContextMenu, Modal = GlobalModal } = WithAudioPlayback.useComponentContext();
|
|
15709
16019
|
const { channelCapabilities } = WithAudioPlayback.useChannelStateContext();
|
|
15710
16020
|
const messageComposer = WithAudioPlayback.useMessageComposerController();
|
|
15711
16021
|
const isCooldownActive = WithAudioPlayback.useIsCooldownActive();
|
|
@@ -15765,7 +16075,7 @@ const AttachmentSelector = ({
|
|
|
15765
16075
|
}
|
|
15766
16076
|
),
|
|
15767
16077
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15768
|
-
|
|
16078
|
+
ContextMenuComponent,
|
|
15769
16079
|
{
|
|
15770
16080
|
allowFlip: true,
|
|
15771
16081
|
backLabel: t("Back"),
|
|
@@ -17795,7 +18105,10 @@ const SuggestionList = ({
|
|
|
17795
18105
|
setFocusedItemIndex,
|
|
17796
18106
|
suggestionItemComponents = defaultComponents
|
|
17797
18107
|
}) => {
|
|
17798
|
-
const {
|
|
18108
|
+
const {
|
|
18109
|
+
AutocompleteSuggestionItem = SuggestionListItem,
|
|
18110
|
+
ContextMenu: ContextMenuComponent = ContextMenu
|
|
18111
|
+
} = WithAudioPlayback.useComponentContext();
|
|
17799
18112
|
const { textareaRef } = WithAudioPlayback.useMessageComposerContext();
|
|
17800
18113
|
const messageComposer = WithAudioPlayback.useMessageComposerController();
|
|
17801
18114
|
const { textComposer } = messageComposer;
|
|
@@ -17913,7 +18226,7 @@ const SuggestionList = ({
|
|
|
17913
18226
|
zIndex: 1e3
|
|
17914
18227
|
},
|
|
17915
18228
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17916
|
-
|
|
18229
|
+
ContextMenuComponent,
|
|
17917
18230
|
{
|
|
17918
18231
|
className: clsx("str-chat__suggestion-list", className),
|
|
17919
18232
|
Header: suggestions.searchSource.type === "commands" ? CommandsMenuHeader : void 0,
|
|
@@ -18139,12 +18452,6 @@ const TextareaComposer = ({
|
|
|
18139
18452
|
if (!textareaRef.current || textareaIsFocused || !focus2) return;
|
|
18140
18453
|
textareaRef.current.focus();
|
|
18141
18454
|
}, [attachments, focus2, quotedMessage, textareaRef]);
|
|
18142
|
-
React.useEffect(
|
|
18143
|
-
() => () => {
|
|
18144
|
-
messageComposer.clear();
|
|
18145
|
-
},
|
|
18146
|
-
[messageComposer]
|
|
18147
|
-
);
|
|
18148
18455
|
React.useLayoutEffect(() => {
|
|
18149
18456
|
const textarea = textareaRef.current;
|
|
18150
18457
|
if (!textarea || isComposing) return;
|
|
@@ -18598,7 +18905,7 @@ const MessageComposerProvider = (props) => {
|
|
|
18598
18905
|
const messageComposer = WithAudioPlayback.useMessageComposerController();
|
|
18599
18906
|
React.useEffect(
|
|
18600
18907
|
() => () => {
|
|
18601
|
-
messageComposer.createDraft();
|
|
18908
|
+
messageComposer.createDraft().finally(() => messageComposer.clear());
|
|
18602
18909
|
},
|
|
18603
18910
|
[messageComposer]
|
|
18604
18911
|
);
|
|
@@ -18916,7 +19223,7 @@ const useChat = ({
|
|
|
18916
19223
|
};
|
|
18917
19224
|
React.useEffect(() => {
|
|
18918
19225
|
if (!client) return;
|
|
18919
|
-
const version = "14.0.0-beta.
|
|
19226
|
+
const version = "14.0.0-beta.3";
|
|
18920
19227
|
const userAgent = client.getUserAgent();
|
|
18921
19228
|
if (!userAgent.includes("stream-chat-react")) {
|
|
18922
19229
|
client.setUserAgent(`stream-chat-react-${version}-${userAgent}`);
|
|
@@ -19417,10 +19724,10 @@ const ReactionSelector = (props) => {
|
|
|
19417
19724
|
) })
|
|
19418
19725
|
] });
|
|
19419
19726
|
};
|
|
19420
|
-
ReactionSelector.getDialogId = (
|
|
19727
|
+
ReactionSelector.getDialogId = ({ messageId, threadList }) => {
|
|
19421
19728
|
const dialogIdNamespace = threadList ? "-thread" : "";
|
|
19422
|
-
return `reaction-selector${dialogIdNamespace}
|
|
19423
|
-
}
|
|
19729
|
+
return `reaction-selector${dialogIdNamespace}-${messageId}`;
|
|
19730
|
+
};
|
|
19424
19731
|
ReactionSelector.displayName = "ReactionSelector";
|
|
19425
19732
|
const ReactionSelectorWithButton = ({
|
|
19426
19733
|
ReactionIcon
|
|
@@ -19505,6 +19812,7 @@ const QuickMessageActionsButton = ({ className, ...props }) => /* @__PURE__ */ j
|
|
|
19505
19812
|
appearance: "ghost",
|
|
19506
19813
|
circular: true,
|
|
19507
19814
|
className: clsx("str-chat__message-actions-box-button", className),
|
|
19815
|
+
size: "sm",
|
|
19508
19816
|
variant: "secondary",
|
|
19509
19817
|
...props
|
|
19510
19818
|
}
|
|
@@ -19865,6 +20173,32 @@ const DefaultMessageActionComponents = {
|
|
|
19865
20173
|
}
|
|
19866
20174
|
},
|
|
19867
20175
|
quick: {
|
|
20176
|
+
// eslint-disable-next-line react/display-name
|
|
20177
|
+
DropdownToggle: React.forwardRef((_, ref) => {
|
|
20178
|
+
const { t } = WithAudioPlayback.useTranslationContext();
|
|
20179
|
+
const { message } = useMessageContext();
|
|
20180
|
+
const dropdownDialogIsOpen = useDialogIsOpen(
|
|
20181
|
+
MessageActions.getDialogId({ messageId: message.id })
|
|
20182
|
+
);
|
|
20183
|
+
const { dialog } = useDialogOnNearestManager({
|
|
20184
|
+
id: MessageActions.getDialogId({ messageId: message.id })
|
|
20185
|
+
});
|
|
20186
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
20187
|
+
QuickMessageActionsButton,
|
|
20188
|
+
{
|
|
20189
|
+
"aria-expanded": dropdownDialogIsOpen,
|
|
20190
|
+
"aria-haspopup": "true",
|
|
20191
|
+
"aria-label": t("aria/Open Message Actions Menu"),
|
|
20192
|
+
className: "str-chat__message-actions-box-button",
|
|
20193
|
+
"data-testid": "message-actions-toggle-button",
|
|
20194
|
+
onClick: () => {
|
|
20195
|
+
dialog?.toggle();
|
|
20196
|
+
},
|
|
20197
|
+
ref,
|
|
20198
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconDotGrid1x3Horizontal, { className: "str-chat__message-action-icon" })
|
|
20199
|
+
}
|
|
20200
|
+
);
|
|
20201
|
+
}),
|
|
19868
20202
|
React() {
|
|
19869
20203
|
return /* @__PURE__ */ jsxRuntime.jsx(ReactionSelectorWithButton, { ReactionIcon: WithAudioPlayback.IconEmojiSmile });
|
|
19870
20204
|
},
|
|
@@ -19885,7 +20219,10 @@ const DefaultMessageActionComponents = {
|
|
|
19885
20219
|
}
|
|
19886
20220
|
};
|
|
19887
20221
|
const defaultMessageActionSet = [
|
|
19888
|
-
|
|
20222
|
+
{
|
|
20223
|
+
Component: DefaultMessageActionComponents.quick.DropdownToggle,
|
|
20224
|
+
placement: "quick-dropdown-toggle"
|
|
20225
|
+
},
|
|
19889
20226
|
{
|
|
19890
20227
|
Component: DefaultMessageActionComponents.quick.Reply,
|
|
19891
20228
|
placement: "quick",
|
|
@@ -19975,14 +20312,14 @@ function useFetchReactions(options) {
|
|
|
19975
20312
|
const handleFetchReactions = propHandleFetchReactions ?? contextHandleFetchReactions;
|
|
19976
20313
|
const [refetchNonce, setRefetchNonce] = React.useState(null);
|
|
19977
20314
|
React.useEffect(() => {
|
|
19978
|
-
if (!shouldFetch
|
|
20315
|
+
if (!shouldFetch) {
|
|
19979
20316
|
return;
|
|
19980
20317
|
}
|
|
19981
20318
|
let cancel = false;
|
|
19982
20319
|
(async () => {
|
|
19983
20320
|
try {
|
|
19984
20321
|
setIsLoading(true);
|
|
19985
|
-
const reactions2 = await handleFetchReactions(reactionType, sort);
|
|
20322
|
+
const reactions2 = await handleFetchReactions(reactionType ?? void 0, sort);
|
|
19986
20323
|
if (!cancel) {
|
|
19987
20324
|
setReactions(reactions2);
|
|
19988
20325
|
}
|
|
@@ -20006,6 +20343,16 @@ function useFetchReactions(options) {
|
|
|
20006
20343
|
return { isLoading, reactions, refetch };
|
|
20007
20344
|
}
|
|
20008
20345
|
const defaultReactionDetailsSort = { created_at: -1 };
|
|
20346
|
+
const MessageReactionsDetailLoadingIndicator = () => {
|
|
20347
|
+
const elements = React.useMemo(
|
|
20348
|
+
() => Array.from({ length: 3 }, (_, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-reactions-detail__skeleton-item", children: [
|
|
20349
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-avatar" }),
|
|
20350
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-line" })
|
|
20351
|
+
] }, index)),
|
|
20352
|
+
[]
|
|
20353
|
+
);
|
|
20354
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: elements });
|
|
20355
|
+
};
|
|
20009
20356
|
function MessageReactionsDetail({
|
|
20010
20357
|
handleFetchReactions,
|
|
20011
20358
|
onSelectedReactionTypeChange,
|
|
@@ -20016,7 +20363,11 @@ function MessageReactionsDetail({
|
|
|
20016
20363
|
totalReactionCount
|
|
20017
20364
|
}) {
|
|
20018
20365
|
const { client } = WithAudioPlayback.useChatContext();
|
|
20019
|
-
const {
|
|
20366
|
+
const {
|
|
20367
|
+
Avatar: Avatar$1 = Avatar,
|
|
20368
|
+
LoadingIndicator: LoadingIndicator2 = MessageReactionsDetailLoadingIndicator,
|
|
20369
|
+
reactionOptions = defaultReactionOptions
|
|
20370
|
+
} = WithAudioPlayback.useComponentContext(MessageReactionsDetail.name);
|
|
20020
20371
|
const { t } = WithAudioPlayback.useTranslationContext();
|
|
20021
20372
|
const {
|
|
20022
20373
|
handleReaction: contextHandleReaction,
|
|
@@ -20043,7 +20394,7 @@ function MessageReactionsDetail({
|
|
|
20043
20394
|
"div",
|
|
20044
20395
|
{
|
|
20045
20396
|
className: "str-chat__message-reactions-detail",
|
|
20046
|
-
"data-testid": "reactions-
|
|
20397
|
+
"data-testid": "message-reactions-detail",
|
|
20047
20398
|
children: [
|
|
20048
20399
|
typeof totalReactionCount === "number" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__total-count", children: t("{{ count }} reactions", { count: totalReactionCount }) }),
|
|
20049
20400
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__reaction-type-list-container", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "str-chat__message-reactions-detail__reaction-type-list", children: reactions.map(
|
|
@@ -20056,7 +20407,9 @@ function MessageReactionsDetail({
|
|
|
20056
20407
|
{
|
|
20057
20408
|
"aria-pressed": reactionType === selectedReactionType,
|
|
20058
20409
|
className: "str-chat__message-reactions-detail__reaction-type-list-item-button",
|
|
20059
|
-
onClick: () => onSelectedReactionTypeChange?.(
|
|
20410
|
+
onClick: () => onSelectedReactionTypeChange?.(
|
|
20411
|
+
selectedReactionType === reactionType ? null : reactionType
|
|
20412
|
+
),
|
|
20060
20413
|
children: [
|
|
20061
20414
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "str-chat__message-reactions-detail__reaction-type-list-item-icon", children: /* @__PURE__ */ jsxRuntime.jsx(EmojiComponent, {}) }),
|
|
20062
20415
|
reactionCount > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -20080,22 +20433,10 @@ function MessageReactionsDetail({
|
|
|
20080
20433
|
className: "str-chat__message-reactions-detail__user-list",
|
|
20081
20434
|
"data-testid": "all-reacting-users",
|
|
20082
20435
|
children: [
|
|
20083
|
-
areReactionsLoading && /* @__PURE__ */ jsxRuntime.
|
|
20084
|
-
|
|
20085
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-avatar" }),
|
|
20086
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-line" })
|
|
20087
|
-
] }),
|
|
20088
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-reactions-detail__skeleton-item", children: [
|
|
20089
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-avatar" }),
|
|
20090
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-line" })
|
|
20091
|
-
] }),
|
|
20092
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-reactions-detail__skeleton-item", children: [
|
|
20093
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-avatar" }),
|
|
20094
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-detail__skeleton-line" })
|
|
20095
|
-
] })
|
|
20096
|
-
] }),
|
|
20097
|
-
!areReactionsLoading && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: reactionDetailsWithLegacyFallback.map(({ user }) => {
|
|
20436
|
+
areReactionsLoading && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator2, {}),
|
|
20437
|
+
!areReactionsLoading && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: reactionDetailsWithLegacyFallback.map(({ type, user }) => {
|
|
20098
20438
|
const belongsToCurrentUser = client.user?.id === user?.id;
|
|
20439
|
+
const EmojiComponent = Array.isArray(reactionOptions) ? void 0 : reactionOptions.quick[type]?.Component ?? reactionOptions.extended?.[type]?.Component;
|
|
20099
20440
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20100
20441
|
"div",
|
|
20101
20442
|
{
|
|
@@ -20120,23 +20461,23 @@ function MessageReactionsDetail({
|
|
|
20120
20461
|
children: belongsToCurrentUser ? t("You") : user?.name || user?.id
|
|
20121
20462
|
}
|
|
20122
20463
|
),
|
|
20123
|
-
belongsToCurrentUser &&
|
|
20464
|
+
belongsToCurrentUser && /* @__PURE__ */ jsxRuntime.jsx(
|
|
20124
20465
|
"button",
|
|
20125
20466
|
{
|
|
20126
20467
|
className: "str-chat__message-reactions-detail__user-list-item-button",
|
|
20127
20468
|
"data-testid": "remove-reaction-button",
|
|
20128
|
-
onClick: (e) => {
|
|
20129
|
-
contextHandleReaction(
|
|
20130
|
-
|
|
20131
|
-
});
|
|
20469
|
+
onClick: async (e) => {
|
|
20470
|
+
await contextHandleReaction(type, e);
|
|
20471
|
+
refetch();
|
|
20132
20472
|
},
|
|
20133
20473
|
children: t("Tap to remove")
|
|
20134
20474
|
}
|
|
20135
20475
|
)
|
|
20136
|
-
] })
|
|
20476
|
+
] }),
|
|
20477
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "str-chat__message-reactions-detail__user-list-item-icon", children: EmojiComponent && !selectedReactionType && /* @__PURE__ */ jsxRuntime.jsx(EmojiComponent, {}) })
|
|
20137
20478
|
]
|
|
20138
20479
|
},
|
|
20139
|
-
user?.id
|
|
20480
|
+
`${user?.id}-${type}`
|
|
20140
20481
|
);
|
|
20141
20482
|
}) })
|
|
20142
20483
|
]
|
|
@@ -20285,6 +20626,7 @@ const UnMemoizedMessageReactions = (props) => {
|
|
|
20285
20626
|
const divRef = React.useRef(null);
|
|
20286
20627
|
const dialogId2 = `message-reactions-detail-${message.id}`;
|
|
20287
20628
|
const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId2 });
|
|
20629
|
+
const isDialogOpen = useDialogIsOpen(dialogId2, dialogManager?.id);
|
|
20288
20630
|
const handleReactionButtonClick = (reactionType) => {
|
|
20289
20631
|
if (totalReactionCount > MAX_MESSAGE_REACTIONS_TO_FETCH) {
|
|
20290
20632
|
return;
|
|
@@ -20319,6 +20661,8 @@ const UnMemoizedMessageReactions = (props) => {
|
|
|
20319
20661
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20320
20662
|
FragmentOrButton,
|
|
20321
20663
|
{
|
|
20664
|
+
"aria-expanded": isDialogOpen,
|
|
20665
|
+
"aria-pressed": isDialogOpen,
|
|
20322
20666
|
buttonIf: visualStyle === "clustered",
|
|
20323
20667
|
className: "str-chat__message-reactions__list-button",
|
|
20324
20668
|
onClick: () => handleReactionButtonClick(existingReactions[0]?.reactionType ?? null),
|
|
@@ -20356,9 +20700,7 @@ const UnMemoizedMessageReactions = (props) => {
|
|
|
20356
20700
|
"button",
|
|
20357
20701
|
{
|
|
20358
20702
|
className: "str-chat__message-reactions__list-item-button",
|
|
20359
|
-
onClick: () => handleReactionButtonClick(
|
|
20360
|
-
existingReactions.at(-1)?.reactionType ?? null
|
|
20361
|
-
),
|
|
20703
|
+
onClick: () => handleReactionButtonClick(null),
|
|
20362
20704
|
children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "str-chat__message-reactions__overflow-count", children: [
|
|
20363
20705
|
"+",
|
|
20364
20706
|
totalReactionCount - cappedExistingReactions.reactionCountToDisplay
|
|
@@ -20483,91 +20825,74 @@ const StreamEmoji = ({
|
|
|
20483
20825
|
const useSplitActionSet = (actionSet) => React.useMemo(() => {
|
|
20484
20826
|
const quickActionSet = [];
|
|
20485
20827
|
const dropdownActionSet = [];
|
|
20828
|
+
let quickDropdownToggleAction;
|
|
20486
20829
|
for (const action of actionSet) {
|
|
20487
20830
|
if (action.placement === "quick")
|
|
20488
20831
|
quickActionSet.push(action);
|
|
20489
20832
|
if (action.placement === "dropdown")
|
|
20490
20833
|
dropdownActionSet.push(action);
|
|
20834
|
+
if (action.placement === "quick-dropdown-toggle") {
|
|
20835
|
+
quickDropdownToggleAction ?? (quickDropdownToggleAction = action);
|
|
20836
|
+
}
|
|
20491
20837
|
}
|
|
20492
|
-
return { dropdownActionSet, quickActionSet };
|
|
20838
|
+
return { dropdownActionSet, quickActionSet, quickDropdownToggleAction };
|
|
20493
20839
|
}, [actionSet]);
|
|
20494
20840
|
const MessageActions = ({
|
|
20495
20841
|
disableBaseMessageActionSetFilter = false,
|
|
20496
20842
|
messageActionSet = defaultMessageActionSet
|
|
20497
20843
|
}) => {
|
|
20498
|
-
const { theme } = WithAudioPlayback.useChatContext();
|
|
20499
20844
|
const { isMyMessage, message, threadList } = useMessageContext();
|
|
20845
|
+
const { ContextMenu: ContextMenuComponent = ContextMenu } = WithAudioPlayback.useComponentContext();
|
|
20500
20846
|
const { t } = WithAudioPlayback.useTranslationContext();
|
|
20501
20847
|
const [actionsBoxButtonElement, setActionsBoxButtonElement] = React.useState(null);
|
|
20502
20848
|
const filteredMessageActionSet = useBaseMessageActionSetFilter(
|
|
20503
20849
|
messageActionSet,
|
|
20504
20850
|
disableBaseMessageActionSetFilter
|
|
20505
20851
|
);
|
|
20506
|
-
const { dropdownActionSet, quickActionSet } = useSplitActionSet(
|
|
20507
|
-
|
|
20508
|
-
);
|
|
20509
|
-
const dropdownDialogId = `message-actions--${message.id}`;
|
|
20852
|
+
const { dropdownActionSet, quickActionSet, quickDropdownToggleAction } = useSplitActionSet(filteredMessageActionSet);
|
|
20853
|
+
const messageActionsDialogId = MessageActions.getDialogId({ messageId: message.id });
|
|
20510
20854
|
const reactionSelectorDialogId = ReactionSelector.getDialogId({
|
|
20511
20855
|
messageId: message.id,
|
|
20512
20856
|
threadList
|
|
20513
20857
|
});
|
|
20514
|
-
const { dialog, dialogManager } = useDialogOnNearestManager({
|
|
20515
|
-
|
|
20858
|
+
const { dialog, dialogManager } = useDialogOnNearestManager({
|
|
20859
|
+
id: messageActionsDialogId
|
|
20860
|
+
});
|
|
20861
|
+
const messageActionsDialogIsOpen = useDialogIsOpen(
|
|
20862
|
+
messageActionsDialogId,
|
|
20863
|
+
dialogManager?.id
|
|
20864
|
+
);
|
|
20516
20865
|
const reactionSelectorDialogIsOpen = useDialogIsOpen(
|
|
20517
20866
|
reactionSelectorDialogId,
|
|
20518
20867
|
dialogManager?.id
|
|
20519
20868
|
);
|
|
20520
|
-
const contextMenuItems = React.useMemo(
|
|
20521
|
-
() => dropdownActionSet.map(({ Component }) => {
|
|
20522
|
-
const ActionItem = (menuProps) => /* @__PURE__ */ jsxRuntime.jsx(Component, { ...menuProps });
|
|
20523
|
-
return ActionItem;
|
|
20524
|
-
}),
|
|
20525
|
-
[dropdownActionSet]
|
|
20526
|
-
);
|
|
20527
20869
|
if (dropdownActionSet.length + quickActionSet.length === 0) {
|
|
20528
20870
|
return null;
|
|
20529
20871
|
}
|
|
20530
20872
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
20531
20873
|
"div",
|
|
20532
20874
|
{
|
|
20533
|
-
className: clsx(
|
|
20534
|
-
"str-chat__message-options--active":
|
|
20875
|
+
className: clsx("str-chat__message-options", {
|
|
20876
|
+
"str-chat__message-options--active": messageActionsDialogIsOpen || reactionSelectorDialogIsOpen
|
|
20535
20877
|
}),
|
|
20536
20878
|
children: [
|
|
20537
|
-
dropdownActionSet.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20538
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20539
|
-
WithAudioPlayback.Button,
|
|
20540
|
-
{
|
|
20541
|
-
appearance: "ghost",
|
|
20542
|
-
"aria-expanded": dropdownDialogIsOpen,
|
|
20543
|
-
"aria-haspopup": "true",
|
|
20544
|
-
"aria-label": t("aria/Open Message Actions Menu"),
|
|
20545
|
-
circular: true,
|
|
20546
|
-
className: "str-chat__message-actions-box-button",
|
|
20547
|
-
"data-testid": "message-actions-toggle-button",
|
|
20548
|
-
onClick: () => {
|
|
20549
|
-
dialog?.toggle();
|
|
20550
|
-
},
|
|
20551
|
-
ref: setActionsBoxButtonElement,
|
|
20552
|
-
variant: "secondary",
|
|
20553
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconDotGrid1x3Horizontal, { className: "str-chat__message-action-icon" })
|
|
20554
|
-
}
|
|
20555
|
-
),
|
|
20879
|
+
quickDropdownToggleAction && dropdownActionSet.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
20880
|
+
/* @__PURE__ */ jsxRuntime.jsx(quickDropdownToggleAction.Component, { ref: setActionsBoxButtonElement }),
|
|
20556
20881
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
20557
|
-
|
|
20882
|
+
ContextMenuComponent,
|
|
20558
20883
|
{
|
|
20559
20884
|
backLabel: t("Back"),
|
|
20560
20885
|
className: clsx("str-chat__message-actions-box", {
|
|
20561
|
-
"str-chat__message-actions-box--open":
|
|
20886
|
+
"str-chat__message-actions-box--open": messageActionsDialogIsOpen
|
|
20562
20887
|
}),
|
|
20563
20888
|
dialogManagerId: dialogManager?.id,
|
|
20564
|
-
id:
|
|
20565
|
-
items: contextMenuItems,
|
|
20889
|
+
id: messageActionsDialogId,
|
|
20566
20890
|
onClose: dialog?.close,
|
|
20567
20891
|
placement: isMyMessage() ? "top-end" : "top-start",
|
|
20568
20892
|
referenceElement: actionsBoxButtonElement,
|
|
20569
20893
|
tabIndex: -1,
|
|
20570
|
-
trapFocus: true
|
|
20894
|
+
trapFocus: true,
|
|
20895
|
+
children: dropdownActionSet.map(({ Component, type }) => /* @__PURE__ */ jsxRuntime.jsx(Component, {}, type))
|
|
20571
20896
|
}
|
|
20572
20897
|
)
|
|
20573
20898
|
] }),
|
|
@@ -20576,6 +20901,8 @@ const MessageActions = ({
|
|
|
20576
20901
|
}
|
|
20577
20902
|
);
|
|
20578
20903
|
};
|
|
20904
|
+
MessageActions.getDialogId = ({ messageId }) => `message-actions-${messageId}`;
|
|
20905
|
+
MessageActions.displayName = "MessageActions";
|
|
20579
20906
|
const MessageUIWithContext = ({
|
|
20580
20907
|
endOfGroup,
|
|
20581
20908
|
firstOfGroup,
|
|
@@ -21402,6 +21729,7 @@ const useScrollLocationLogic = (params) => {
|
|
|
21402
21729
|
const closeToBottom = React.useRef(false);
|
|
21403
21730
|
const closeToTop = React.useRef(false);
|
|
21404
21731
|
const previousScrollTopRef = React.useRef(0);
|
|
21732
|
+
const previousMessagesLengthRef = React.useRef(messages.length);
|
|
21405
21733
|
const anchorRestoreCleanupRef = React.useRef(null);
|
|
21406
21734
|
const captureAnchor = React.useCallback(() => {
|
|
21407
21735
|
if (!listElement) return null;
|
|
@@ -21553,6 +21881,60 @@ const useScrollLocationLogic = (params) => {
|
|
|
21553
21881
|
scrollToBottom();
|
|
21554
21882
|
}
|
|
21555
21883
|
}, [disableAutoScrollToBottom, justReachedLatestMessageSet, listElement, hasMoreNewer]);
|
|
21884
|
+
React.useLayoutEffect(() => {
|
|
21885
|
+
if (!listElement || disableAutoScrollToBottom || hasMoreNewer || suppressAutoscroll || justReachedLatestMessageSet || isRestoringOlderAnchorRef.current) {
|
|
21886
|
+
return;
|
|
21887
|
+
}
|
|
21888
|
+
const initialDistanceToBottom = listElement.scrollHeight - (listElement.scrollTop + listElement.clientHeight);
|
|
21889
|
+
const messagesHydrated = previousMessagesLengthRef.current === 0 && messages.length > 0;
|
|
21890
|
+
if (initialDistanceToBottom > scrolledUpThreshold && !messagesHydrated) {
|
|
21891
|
+
return;
|
|
21892
|
+
}
|
|
21893
|
+
let keepPinnedToBottom = true;
|
|
21894
|
+
const maybeScrollToBottom = () => {
|
|
21895
|
+
if (keepPinnedToBottom) {
|
|
21896
|
+
scrollToBottom();
|
|
21897
|
+
}
|
|
21898
|
+
};
|
|
21899
|
+
maybeScrollToBottom();
|
|
21900
|
+
const settleDelays = [80, messagesHydrated ? 260 : 420, 900, 1700];
|
|
21901
|
+
const settleTimeoutIds = settleDelays.map(
|
|
21902
|
+
(delay) => setTimeout(maybeScrollToBottom, delay)
|
|
21903
|
+
);
|
|
21904
|
+
const stopKeepingPinnedToBottom = () => {
|
|
21905
|
+
keepPinnedToBottom = false;
|
|
21906
|
+
};
|
|
21907
|
+
listElement.addEventListener("pointerdown", stopKeepingPinnedToBottom, {
|
|
21908
|
+
passive: true
|
|
21909
|
+
});
|
|
21910
|
+
listElement.addEventListener("touchstart", stopKeepingPinnedToBottom, {
|
|
21911
|
+
passive: true
|
|
21912
|
+
});
|
|
21913
|
+
listElement.addEventListener("wheel", stopKeepingPinnedToBottom, {
|
|
21914
|
+
passive: true
|
|
21915
|
+
});
|
|
21916
|
+
listElement.addEventListener("keydown", stopKeepingPinnedToBottom);
|
|
21917
|
+
const pinWindowTimeoutId = setTimeout(() => {
|
|
21918
|
+
stopKeepingPinnedToBottom();
|
|
21919
|
+
}, 2200);
|
|
21920
|
+
return () => {
|
|
21921
|
+
settleTimeoutIds.forEach(clearTimeout);
|
|
21922
|
+
clearTimeout(pinWindowTimeoutId);
|
|
21923
|
+
listElement.removeEventListener("pointerdown", stopKeepingPinnedToBottom);
|
|
21924
|
+
listElement.removeEventListener("touchstart", stopKeepingPinnedToBottom);
|
|
21925
|
+
listElement.removeEventListener("wheel", stopKeepingPinnedToBottom);
|
|
21926
|
+
listElement.removeEventListener("keydown", stopKeepingPinnedToBottom);
|
|
21927
|
+
};
|
|
21928
|
+
}, [
|
|
21929
|
+
disableAutoScrollToBottom,
|
|
21930
|
+
hasMoreNewer,
|
|
21931
|
+
justReachedLatestMessageSet,
|
|
21932
|
+
listElement,
|
|
21933
|
+
messages.length,
|
|
21934
|
+
scrollToBottom,
|
|
21935
|
+
scrolledUpThreshold,
|
|
21936
|
+
suppressAutoscroll
|
|
21937
|
+
]);
|
|
21556
21938
|
const updateScrollTop = useMessageListScrollManager({
|
|
21557
21939
|
captureAnchor,
|
|
21558
21940
|
disableScrollManagement: disableScrollManagement || isRestoringOlderAnchorRef.current,
|
|
@@ -21579,6 +21961,9 @@ const useScrollLocationLogic = (params) => {
|
|
|
21579
21961
|
React.useLayoutEffect(() => {
|
|
21580
21962
|
previousHasMoreNewerRef.current = hasMoreNewer;
|
|
21581
21963
|
}, [hasMoreNewer]);
|
|
21964
|
+
React.useLayoutEffect(() => {
|
|
21965
|
+
previousMessagesLengthRef.current = messages.length;
|
|
21966
|
+
}, [messages.length]);
|
|
21582
21967
|
const onScroll = React.useCallback(
|
|
21583
21968
|
(event) => {
|
|
21584
21969
|
const element = event.target;
|
|
@@ -21587,8 +21972,10 @@ const useScrollLocationLogic = (params) => {
|
|
|
21587
21972
|
updateScrollTop(scrollTop, captureAnchor);
|
|
21588
21973
|
const offsetHeight = element.offsetHeight;
|
|
21589
21974
|
const scrollHeight = element.scrollHeight;
|
|
21975
|
+
const distanceToBottom = scrollHeight - (scrollTop + offsetHeight);
|
|
21976
|
+
const bottomEnterThreshold = Math.max(Math.floor(scrolledUpThreshold * 0.6), 24);
|
|
21590
21977
|
const prevCloseToBottom = closeToBottom.current;
|
|
21591
|
-
closeToBottom.current =
|
|
21978
|
+
closeToBottom.current = prevCloseToBottom ? distanceToBottom < scrolledUpThreshold : distanceToBottom < bottomEnterThreshold;
|
|
21592
21979
|
closeToTop.current = scrollTop < scrolledUpThreshold;
|
|
21593
21980
|
if (closeToBottom.current) {
|
|
21594
21981
|
setHasNewMessages(false);
|
|
@@ -23523,11 +23910,17 @@ const useConnectionRecoveredListener = (forceUpdate) => {
|
|
|
23523
23910
|
const MOBILE_NAV_BREAKPOINT = 768;
|
|
23524
23911
|
const useMobileNavigation = (channelListRef, navOpen, closeMobileNav) => {
|
|
23525
23912
|
React.useEffect(() => {
|
|
23913
|
+
const isClickInsideChannelList = (event) => {
|
|
23914
|
+
const channelListElement = channelListRef.current;
|
|
23915
|
+
if (!channelListElement) return false;
|
|
23916
|
+
const eventPath = event.composedPath();
|
|
23917
|
+
return eventPath.includes(channelListElement);
|
|
23918
|
+
};
|
|
23526
23919
|
const handleClickOutside = (event) => {
|
|
23527
23920
|
if (typeof window !== "undefined" && window.innerWidth >= MOBILE_NAV_BREAKPOINT) {
|
|
23528
23921
|
return;
|
|
23529
23922
|
}
|
|
23530
|
-
if (closeMobileNav && channelListRef.current && !
|
|
23923
|
+
if (closeMobileNav && channelListRef.current && !isClickInsideChannelList(event) && navOpen) {
|
|
23531
23924
|
closeMobileNav();
|
|
23532
23925
|
}
|
|
23533
23926
|
};
|
|
@@ -24657,7 +25050,7 @@ const UnMemoizedLoadMoreButton = ({
|
|
|
24657
25050
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__load-more-button", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
24658
25051
|
WithAudioPlayback.Button,
|
|
24659
25052
|
{
|
|
24660
|
-
appearance: "
|
|
25053
|
+
appearance: "ghost",
|
|
24661
25054
|
"aria-label": t("aria/Load More Channels"),
|
|
24662
25055
|
"data-testid": "load-more-button",
|
|
24663
25056
|
disabled: loading,
|
|
@@ -25265,6 +25658,36 @@ const useArchiveActionButtonBehavior = () => {
|
|
|
25265
25658
|
};
|
|
25266
25659
|
};
|
|
25267
25660
|
const defaultChannelActionSet = [
|
|
25661
|
+
{
|
|
25662
|
+
// eslint-disable-next-line react/display-name
|
|
25663
|
+
Component: React.forwardRef((_, ref) => {
|
|
25664
|
+
const { channel } = useChannelListItemContext();
|
|
25665
|
+
const dialogId2 = ChannelListItemActionButtons.getDialogId({
|
|
25666
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
25667
|
+
channelId: channel.id
|
|
25668
|
+
});
|
|
25669
|
+
const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId2 });
|
|
25670
|
+
const dialogIsOpen = useDialogIsOpen(dialogId2, dialogManager?.id);
|
|
25671
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
25672
|
+
WithAudioPlayback.Button,
|
|
25673
|
+
{
|
|
25674
|
+
appearance: "ghost",
|
|
25675
|
+
"aria-expanded": dialogIsOpen,
|
|
25676
|
+
"aria-pressed": dialogIsOpen,
|
|
25677
|
+
circular: true,
|
|
25678
|
+
onClick: (e) => {
|
|
25679
|
+
e.stopPropagation();
|
|
25680
|
+
dialog.toggle();
|
|
25681
|
+
},
|
|
25682
|
+
ref,
|
|
25683
|
+
size: "sm",
|
|
25684
|
+
variant: "secondary",
|
|
25685
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconDotGrid1x3Horizontal, {})
|
|
25686
|
+
}
|
|
25687
|
+
);
|
|
25688
|
+
}),
|
|
25689
|
+
placement: "quick-dropdown-toggle"
|
|
25690
|
+
},
|
|
25268
25691
|
{
|
|
25269
25692
|
Component() {
|
|
25270
25693
|
const behaviorProps = useArchiveActionButtonBehavior();
|
|
@@ -25397,7 +25820,7 @@ const defaultChannelActionSet = [
|
|
|
25397
25820
|
const membership = useChannelMembershipState(channel);
|
|
25398
25821
|
const dialogId2 = ChannelListItemActionButtons.getDialogId(
|
|
25399
25822
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
25400
|
-
channel.id
|
|
25823
|
+
{ channelId: channel.id }
|
|
25401
25824
|
);
|
|
25402
25825
|
const { dialog } = useDialogOnNearestManager({ id: dialogId2 });
|
|
25403
25826
|
const [inProgress, setInProgress] = React.useState(false);
|
|
@@ -25499,59 +25922,23 @@ const useBaseChannelActionSetFilter = (channelActionSet) => {
|
|
|
25499
25922
|
const connectedUserIsMember = typeof membership.user !== "undefined";
|
|
25500
25923
|
const ownCapabilities = channel.data?.own_capabilities;
|
|
25501
25924
|
return React.useMemo(() => {
|
|
25502
|
-
const filtered = channelActionSet.filter(
|
|
25503
|
-
(action)
|
|
25504
|
-
|
|
25505
|
-
|
|
25506
|
-
|
|
25507
|
-
|
|
25508
|
-
|
|
25509
|
-
|
|
25510
|
-
|
|
25511
|
-
|
|
25512
|
-
|
|
25513
|
-
|
|
25514
|
-
|
|
25515
|
-
|
|
25516
|
-
|
|
25517
|
-
|
|
25518
|
-
|
|
25519
|
-
},
|
|
25520
|
-
isDirectMessageChannel: false
|
|
25521
|
-
},
|
|
25522
|
-
{
|
|
25523
|
-
action: { placement: "dropdown", type: "mute" },
|
|
25524
|
-
isDirectMessageChannel: true,
|
|
25525
|
-
ownCapabilities: tsPattern.P.when(
|
|
25526
|
-
(capabilities) => capabilities?.includes("mute-channel")
|
|
25527
|
-
)
|
|
25528
|
-
},
|
|
25529
|
-
{
|
|
25530
|
-
action: { placement: "quick", type: "mute" },
|
|
25531
|
-
isDirectMessageChannel: false,
|
|
25532
|
-
ownCapabilities: tsPattern.P.when(
|
|
25533
|
-
(capabilities) => capabilities?.includes("mute-channel")
|
|
25534
|
-
)
|
|
25535
|
-
},
|
|
25536
|
-
{
|
|
25537
|
-
action: { type: "ban" },
|
|
25538
|
-
memberCount: tsPattern.P.number.gt(0).and(tsPattern.P.number.lte(2)),
|
|
25539
|
-
ownCapabilities: tsPattern.P.when(
|
|
25540
|
-
(capabilities) => capabilities?.includes("ban-channel-members")
|
|
25541
|
-
)
|
|
25542
|
-
},
|
|
25543
|
-
{
|
|
25544
|
-
action: { type: "leave" },
|
|
25545
|
-
ownCapabilities: tsPattern.P.when(
|
|
25546
|
-
(capabilities) => capabilities?.includes("leave-channel")
|
|
25547
|
-
)
|
|
25548
|
-
},
|
|
25549
|
-
{
|
|
25550
|
-
action: { connectedUserIsMember: true, type: "pin" }
|
|
25551
|
-
},
|
|
25552
|
-
() => true
|
|
25553
|
-
).otherwise(() => false)
|
|
25554
|
-
);
|
|
25925
|
+
const filtered = channelActionSet.filter((action) => {
|
|
25926
|
+
if (action.placement === "quick-dropdown-toggle") return true;
|
|
25927
|
+
switch (action.type) {
|
|
25928
|
+
case "archive":
|
|
25929
|
+
return connectedUserIsMember && (action.placement === "quick" && isDirectMessageChannel || action.placement === "dropdown" && !isDirectMessageChannel);
|
|
25930
|
+
case "mute":
|
|
25931
|
+
return ownCapabilities?.includes("mute-channel") && (action.placement === "dropdown" && isDirectMessageChannel || action.placement === "quick" && !isDirectMessageChannel);
|
|
25932
|
+
case "ban":
|
|
25933
|
+
return memberCount > 0 && memberCount <= 2 && ownCapabilities?.includes("ban-channel-members");
|
|
25934
|
+
case "leave":
|
|
25935
|
+
return ownCapabilities?.includes("leave-channel");
|
|
25936
|
+
case "pin":
|
|
25937
|
+
return connectedUserIsMember;
|
|
25938
|
+
default:
|
|
25939
|
+
return true;
|
|
25940
|
+
}
|
|
25941
|
+
});
|
|
25555
25942
|
return filtered;
|
|
25556
25943
|
}, [
|
|
25557
25944
|
channelActionSet,
|
|
@@ -25562,17 +25949,18 @@ const useBaseChannelActionSetFilter = (channelActionSet) => {
|
|
|
25562
25949
|
]);
|
|
25563
25950
|
};
|
|
25564
25951
|
const ChannelListItemActionButtons = () => {
|
|
25952
|
+
const { ContextMenu: ContextMenuComponent = ContextMenu } = WithAudioPlayback.useComponentContext();
|
|
25565
25953
|
const { channel } = useChannelListItemContext();
|
|
25566
25954
|
const [referenceElement, setReferenceElement] = React.useState(null);
|
|
25567
|
-
const dialogId2 = ChannelListItemActionButtons.getDialogId(
|
|
25955
|
+
const dialogId2 = ChannelListItemActionButtons.getDialogId({
|
|
25568
25956
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
25569
|
-
channel.id
|
|
25570
|
-
);
|
|
25957
|
+
channelId: channel.id
|
|
25958
|
+
});
|
|
25571
25959
|
const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId2 });
|
|
25572
25960
|
const dialogIsOpen = useDialogIsOpen(dialogId2, dialogManager?.id);
|
|
25573
25961
|
const filteredActionSet = useBaseChannelActionSetFilter(defaultChannelActionSet);
|
|
25574
|
-
const
|
|
25575
|
-
if (
|
|
25962
|
+
const { dropdownActionSet, quickActionSet, quickDropdownToggleAction } = useSplitActionSet(filteredActionSet);
|
|
25963
|
+
if (quickActionSet.length + dropdownActionSet.length === 0) {
|
|
25576
25964
|
return null;
|
|
25577
25965
|
}
|
|
25578
25966
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -25582,26 +25970,10 @@ const ChannelListItemActionButtons = () => {
|
|
|
25582
25970
|
"str-chat__channel-list-item__action-buttons--active": dialogIsOpen
|
|
25583
25971
|
}),
|
|
25584
25972
|
children: [
|
|
25585
|
-
|
|
25586
|
-
|
|
25587
|
-
{
|
|
25588
|
-
appearance: "ghost",
|
|
25589
|
-
"aria-expanded": dialogIsOpen,
|
|
25590
|
-
"aria-pressed": dialogIsOpen,
|
|
25591
|
-
circular: true,
|
|
25592
|
-
onClick: (e) => {
|
|
25593
|
-
e.stopPropagation();
|
|
25594
|
-
dialog.toggle();
|
|
25595
|
-
},
|
|
25596
|
-
ref: setReferenceElement,
|
|
25597
|
-
size: "sm",
|
|
25598
|
-
variant: "secondary",
|
|
25599
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconDotGrid1x3Horizontal, {})
|
|
25600
|
-
}
|
|
25601
|
-
),
|
|
25602
|
-
splitActionSet.quickActionSet.map(({ Component, type }) => /* @__PURE__ */ jsxRuntime.jsx(Component, {}, type)),
|
|
25973
|
+
quickDropdownToggleAction && dropdownActionSet.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(quickDropdownToggleAction.Component, { ref: setReferenceElement }),
|
|
25974
|
+
quickActionSet.map(({ Component, type }) => /* @__PURE__ */ jsxRuntime.jsx(Component, {}, type)),
|
|
25603
25975
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
25604
|
-
|
|
25976
|
+
ContextMenuComponent,
|
|
25605
25977
|
{
|
|
25606
25978
|
className: "str-chat__channel-list-item__action-buttons-context-menu",
|
|
25607
25979
|
dialogManagerId: dialogManager?.id,
|
|
@@ -25611,14 +25983,14 @@ const ChannelListItemActionButtons = () => {
|
|
|
25611
25983
|
referenceElement,
|
|
25612
25984
|
tabIndex: -1,
|
|
25613
25985
|
trapFocus: true,
|
|
25614
|
-
children:
|
|
25986
|
+
children: dropdownActionSet.map(({ Component, type }) => /* @__PURE__ */ jsxRuntime.jsx(Component, {}, type))
|
|
25615
25987
|
}
|
|
25616
25988
|
)
|
|
25617
25989
|
]
|
|
25618
25990
|
}
|
|
25619
25991
|
);
|
|
25620
25992
|
};
|
|
25621
|
-
ChannelListItemActionButtons.getDialogId = (channelId) => `channel-action-buttons-${channelId}`;
|
|
25993
|
+
ChannelListItemActionButtons.getDialogId = ({ channelId }) => `channel-action-buttons-${channelId}`;
|
|
25622
25994
|
ChannelListItemActionButtons.displayName = "ChannelListItemActionButtons";
|
|
25623
25995
|
function ChannelListItemTimestamp({ lastMessage }) {
|
|
25624
25996
|
const { t, tDateTimeParser } = WithAudioPlayback.useTranslationContext("ChannelListItemTimestamp");
|
|
@@ -26944,7 +27316,7 @@ const VoiceRecordingPlayerUI = ({ audioPlayer }) => {
|
|
|
26944
27316
|
secondsElapsed
|
|
26945
27317
|
} = WithAudioPlayback.useStateStore(audioPlayer?.state, audioPlayerStateSelector) ?? {};
|
|
26946
27318
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rootClassName, "data-testid": "voice-recording-widget", children: [
|
|
26947
|
-
/* @__PURE__ */ jsxRuntime.jsx(PlayButton, { isPlaying: !!isPlaying, onClick: audioPlayer.togglePlay }),
|
|
27319
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-attachment__voice-recording-widget__play-button-container", children: /* @__PURE__ */ jsxRuntime.jsx(PlayButton, { isPlaying: !!isPlaying, onClick: audioPlayer.togglePlay }) }),
|
|
26948
27320
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-attachment__voice-recording-widget__metadata", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-attachment__voice-recording-widget__audio-state", children: [
|
|
26949
27321
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-attachment__voice-recording-widget__timer", children: durationSeconds ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
26950
27322
|
DurationDisplay,
|
|
@@ -27353,23 +27725,44 @@ const FileAttachment = ({ attachment }) => {
|
|
|
27353
27725
|
);
|
|
27354
27726
|
};
|
|
27355
27727
|
const Giphy = ({ attachment }) => {
|
|
27356
|
-
const { giphyVersion: giphyVersionName } = WithAudioPlayback.useChannelStateContext();
|
|
27728
|
+
const { giphyVersion: giphyVersionName, imageAttachmentSizeHandler } = WithAudioPlayback.useChannelStateContext();
|
|
27357
27729
|
const { BaseImage: BaseImage$1 = BaseImage } = WithAudioPlayback.useComponentContext();
|
|
27358
27730
|
const { t } = WithAudioPlayback.useTranslationContext();
|
|
27359
27731
|
const usesDefaultBaseImage = BaseImage$1 === BaseImage;
|
|
27732
|
+
const imageElement = React.useRef(null);
|
|
27733
|
+
const [attachmentConfiguration, setAttachmentConfiguration] = React.useState(void 0);
|
|
27360
27734
|
const imageDescriptors = React.useMemo(
|
|
27361
27735
|
() => toGalleryItemDescriptors(attachment, { giphyVersionName }),
|
|
27362
27736
|
[attachment, giphyVersionName]
|
|
27363
27737
|
);
|
|
27364
|
-
|
|
27365
|
-
const
|
|
27738
|
+
const alt = imageDescriptors && imageDescriptors.alt;
|
|
27739
|
+
const dimensions = imageDescriptors && imageDescriptors.dimensions;
|
|
27740
|
+
const imageUrl = imageDescriptors && imageDescriptors.imageUrl;
|
|
27741
|
+
const title = imageDescriptors && imageDescriptors.title;
|
|
27742
|
+
const resolvedImageUrl = attachmentConfiguration?.url || imageUrl;
|
|
27743
|
+
const imageStyleVariables = React.useMemo(() => {
|
|
27744
|
+
const originalHeight = Number(dimensions?.height);
|
|
27745
|
+
const originalWidth = Number(dimensions?.width);
|
|
27746
|
+
return {
|
|
27747
|
+
"--original-height": String(originalHeight > 1 ? originalHeight : 1e6),
|
|
27748
|
+
"--original-width": String(originalWidth > 1 ? originalWidth : 1e6)
|
|
27749
|
+
};
|
|
27750
|
+
}, [dimensions?.height, dimensions?.width]);
|
|
27751
|
+
React.useLayoutEffect(() => {
|
|
27752
|
+
if (!imageElement.current || !imageAttachmentSizeHandler) return;
|
|
27753
|
+
const config = imageAttachmentSizeHandler(attachment, imageElement.current);
|
|
27754
|
+
setAttachmentConfiguration(config);
|
|
27755
|
+
}, [attachment, imageAttachmentSizeHandler]);
|
|
27756
|
+
if (!imageUrl) return null;
|
|
27366
27757
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx(`str-chat__message-attachment-giphy`), children: [
|
|
27367
27758
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
27368
27759
|
BaseImage$1,
|
|
27369
27760
|
{
|
|
27370
27761
|
alt: alt ?? title ?? t("User uploaded content"),
|
|
27371
27762
|
height: dimensions?.height,
|
|
27372
|
-
|
|
27763
|
+
ref: imageElement,
|
|
27764
|
+
src: resolvedImageUrl,
|
|
27765
|
+
style: imageStyleVariables,
|
|
27373
27766
|
width: dimensions?.width,
|
|
27374
27767
|
...usesDefaultBaseImage ? { showDownloadButtonOnError: false } : {}
|
|
27375
27768
|
}
|
|
@@ -28266,6 +28659,7 @@ exports.ContextMenu = ContextMenu;
|
|
|
28266
28659
|
exports.ContextMenuBackButton = ContextMenuBackButton;
|
|
28267
28660
|
exports.ContextMenuBody = ContextMenuBody;
|
|
28268
28661
|
exports.ContextMenuButton = ContextMenuButton;
|
|
28662
|
+
exports.ContextMenuContent = ContextMenuContent;
|
|
28269
28663
|
exports.ContextMenuHeader = ContextMenuHeader;
|
|
28270
28664
|
exports.ContextMenuRoot = ContextMenuRoot;
|
|
28271
28665
|
exports.CooldownTimer = CooldownTimer;
|
|
@@ -28338,6 +28732,7 @@ exports.MessageListContextProvider = MessageListContextProvider;
|
|
|
28338
28732
|
exports.MessageProvider = MessageProvider;
|
|
28339
28733
|
exports.MessageReactions = MessageReactions;
|
|
28340
28734
|
exports.MessageReactionsDetail = MessageReactionsDetail;
|
|
28735
|
+
exports.MessageReactionsDetailLoadingIndicator = MessageReactionsDetailLoadingIndicator;
|
|
28341
28736
|
exports.MessageRepliesCountButton = MessageRepliesCountButton;
|
|
28342
28737
|
exports.MessageSearchResultItem = MessageSearchResultItem;
|
|
28343
28738
|
exports.MessageStatus = MessageStatus;
|