stream-chat-react 13.3.0 → 13.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Channel/Channel.js +5 -0
- package/dist/components/ChannelPreview/ChannelPreview.js +7 -2
- package/dist/components/Chat/hooks/useChat.js +1 -1
- package/dist/components/Message/renderText/renderText.d.ts +1 -1
- package/dist/components/Message/renderText/renderText.js +1 -1
- package/dist/components/MessageInput/AttachmentPreviewList/index.d.ts +1 -0
- package/dist/components/MessageInput/index.d.ts +1 -1
- package/dist/components/Modal/Modal.d.ts +8 -3
- package/dist/components/Modal/Modal.js +19 -8
- package/dist/components/Poll/PollCreationDialog/PollCreationDialogControls.js +4 -1
- package/dist/experimental/index.browser.cjs +6 -2
- package/dist/experimental/index.browser.cjs.map +2 -2
- package/dist/experimental/index.node.cjs +6 -2
- package/dist/experimental/index.node.cjs.map +2 -2
- package/dist/i18n/Streami18n.d.ts +1 -0
- package/dist/i18n/TranslationBuilder/notifications/NotificationTranslationTopic.js +2 -0
- package/dist/i18n/TranslationBuilder/notifications/pollVoteCountTrespass.d.ts +3 -0
- package/dist/i18n/TranslationBuilder/notifications/pollVoteCountTrespass.js +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 +1 -0
- package/dist/i18n/nl.json +1 -0
- 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 +1168 -1128
- package/dist/index.browser.cjs.map +3 -3
- package/dist/index.node.cjs +1168 -1128
- package/dist/index.node.cjs.map +3 -3
- package/dist/types/types.d.ts +3 -0
- package/package.json +5 -5
|
@@ -134,6 +134,10 @@ const ChannelInner = (props) => {
|
|
|
134
134
|
type: 'updateThreadOnEvent',
|
|
135
135
|
});
|
|
136
136
|
}
|
|
137
|
+
// ignore the event if it is not targeted at the current channel.
|
|
138
|
+
// Event targeted at this channel or globally targeted event should lead to state refresh
|
|
139
|
+
if (event.type === 'user.messages.deleted' && event.cid && event.cid !== channel.cid)
|
|
140
|
+
return;
|
|
137
141
|
if (event.type === 'user.watching.start' || event.type === 'user.watching.stop')
|
|
138
142
|
return;
|
|
139
143
|
if (event.type === 'typing.start' || event.type === 'typing.stop') {
|
|
@@ -257,6 +261,7 @@ const ChannelInner = (props) => {
|
|
|
257
261
|
client.on('connection.recovered', handleEvent);
|
|
258
262
|
client.on('user.updated', handleEvent);
|
|
259
263
|
client.on('user.deleted', handleEvent);
|
|
264
|
+
client.on('user.messages.deleted', handleEvent);
|
|
260
265
|
channel.on(handleEvent);
|
|
261
266
|
}
|
|
262
267
|
})();
|
|
@@ -55,23 +55,28 @@ export const ChannelPreview = (props) => {
|
|
|
55
55
|
}, 400), [channel, muted]);
|
|
56
56
|
useEffect(() => {
|
|
57
57
|
refreshUnreadCount();
|
|
58
|
-
const handleEvent = () => {
|
|
58
|
+
const handleEvent = (event) => {
|
|
59
|
+
const deletedMessagesInAnotherChannel = event.type === 'user.messages.deleted' && event.cid && event.cid !== channel.cid;
|
|
60
|
+
if (deletedMessagesInAnotherChannel)
|
|
61
|
+
return;
|
|
59
62
|
setLastMessage(channel.state.latestMessages[channel.state.latestMessages.length - 1]);
|
|
60
63
|
refreshUnreadCount();
|
|
61
64
|
};
|
|
62
65
|
channel.on('message.new', handleEvent);
|
|
63
66
|
channel.on('message.updated', handleEvent);
|
|
64
67
|
channel.on('message.deleted', handleEvent);
|
|
68
|
+
client.on('user.messages.deleted', handleEvent);
|
|
65
69
|
channel.on('message.undeleted', handleEvent);
|
|
66
70
|
channel.on('channel.truncated', handleEvent);
|
|
67
71
|
return () => {
|
|
68
72
|
channel.off('message.new', handleEvent);
|
|
69
73
|
channel.off('message.updated', handleEvent);
|
|
70
74
|
channel.off('message.deleted', handleEvent);
|
|
75
|
+
client.off('user.messages.deleted', handleEvent);
|
|
71
76
|
channel.off('message.undeleted', handleEvent);
|
|
72
77
|
channel.off('channel.truncated', handleEvent);
|
|
73
78
|
};
|
|
74
|
-
}, [channel, refreshUnreadCount, channelUpdateCount]);
|
|
79
|
+
}, [channel, client, refreshUnreadCount, channelUpdateCount]);
|
|
75
80
|
if (!Preview)
|
|
76
81
|
return null;
|
|
77
82
|
const latestMessagePreview = getLatestMessagePreview(channel, t, userLanguage, isMessageAIGenerated);
|
|
@@ -24,7 +24,7 @@ export const useChat = ({ client, defaultLanguage = 'en', i18nInstance, initialN
|
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
if (!client)
|
|
26
26
|
return;
|
|
27
|
-
const version = "13.
|
|
27
|
+
const version = "13.5.0";
|
|
28
28
|
const userAgent = client.getUserAgent();
|
|
29
29
|
if (!userAgent.includes('stream-chat-react')) {
|
|
30
30
|
// result looks like: 'stream-chat-react-2.3.2-stream-chat-javascript-client-browser-2.2.2'
|
|
@@ -16,4 +16,4 @@ export type RenderTextOptions = {
|
|
|
16
16
|
getRehypePlugins?: RenderTextPluginConfigurator;
|
|
17
17
|
getRemarkPlugins?: RenderTextPluginConfigurator;
|
|
18
18
|
};
|
|
19
|
-
export declare const renderText: (text?: string, mentionedUsers?: UserResponse[], { allowedTagNames, customMarkDownRenderers, getRehypePlugins, getRemarkPlugins, }?: RenderTextOptions) => React.JSX.Element | null
|
|
19
|
+
export declare const renderText: (text?: string, mentionedUsers?: UserResponse[], { allowedTagNames, customMarkDownRenderers, getRehypePlugins, getRemarkPlugins, }?: RenderTextOptions) => React.JSX.Element | null;
|
|
@@ -83,7 +83,7 @@ export const renderText = (text, mentionedUsers, { allowedTagNames = defaultAllo
|
|
|
83
83
|
return strippedHref.includes(strippedText) || strippedText.includes(strippedHref);
|
|
84
84
|
});
|
|
85
85
|
if (noParsingNeeded.length > 0 || linkIsInBlock)
|
|
86
|
-
|
|
86
|
+
continue;
|
|
87
87
|
try {
|
|
88
88
|
// special case for mentions:
|
|
89
89
|
// it could happen that a user's name matches with an e-mail format pattern.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './AttachmentPreviewList';
|
|
2
2
|
export type { FileAttachmentPreviewProps } from './FileAttachmentPreview';
|
|
3
|
+
export type { GeolocationPreviewProps } from './GeolocationPreview';
|
|
3
4
|
export type { ImageAttachmentPreviewProps } from './ImageAttachmentPreview';
|
|
4
5
|
export type { UploadAttachmentPreviewProps as AttachmentPreviewProps } from './types';
|
|
5
6
|
export type { UnsupportedAttachmentPreviewProps } from './UnsupportedAttachmentPreview';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './AttachmentSelector';
|
|
2
2
|
export { AttachmentPreviewList } from './AttachmentPreviewList';
|
|
3
|
-
export type { AttachmentPreviewListProps, FileAttachmentPreviewProps, ImageAttachmentPreviewProps, AttachmentPreviewProps, UnsupportedAttachmentPreviewProps, VoiceRecordingPreviewProps, } from './AttachmentPreviewList';
|
|
3
|
+
export type { AttachmentPreviewListProps, FileAttachmentPreviewProps, GeolocationPreviewProps, ImageAttachmentPreviewProps, AttachmentPreviewProps, UnsupportedAttachmentPreviewProps, VoiceRecordingPreviewProps, } from './AttachmentPreviewList';
|
|
4
4
|
export * from './CooldownTimer';
|
|
5
5
|
export * from './EditMessageForm';
|
|
6
6
|
export * from './hooks';
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PropsWithChildren } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
type CloseEvent = KeyboardEvent | React.KeyboardEvent | React.MouseEvent<HTMLButtonElement | HTMLDivElement>;
|
|
4
|
+
export type ModalCloseSource = 'overlay' | 'button' | 'escape';
|
|
3
5
|
export type ModalProps = {
|
|
4
6
|
/** If true, modal is opened or visible. */
|
|
5
7
|
open: boolean;
|
|
6
8
|
/** Custom class to be applied to the modal root div */
|
|
7
9
|
className?: string;
|
|
8
10
|
/** Callback handler for closing of modal. */
|
|
9
|
-
onClose?: (event:
|
|
11
|
+
onClose?: (event: CloseEvent) => void;
|
|
12
|
+
/** Optional handler to intercept closing logic. Return false to prevent onClose. */
|
|
13
|
+
onCloseAttempt?: (source: ModalCloseSource, event: CloseEvent) => boolean;
|
|
10
14
|
};
|
|
11
|
-
export declare const Modal: ({ children, className, onClose, open, }: PropsWithChildren<ModalProps>) => React.JSX.Element | null;
|
|
15
|
+
export declare const Modal: ({ children, className, onClose, onCloseAttempt, open, }: PropsWithChildren<ModalProps>) => React.JSX.Element | null;
|
|
16
|
+
export {};
|
|
@@ -1,34 +1,45 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
+
import { useCallback } from 'react';
|
|
2
3
|
import React, { useEffect, useRef } from 'react';
|
|
3
4
|
import { FocusScope } from '@react-aria/focus';
|
|
4
5
|
import { CloseIconRound } from './icons';
|
|
5
6
|
import { useTranslationContext } from '../../context';
|
|
6
|
-
export const Modal = ({ children, className, onClose, open, }) => {
|
|
7
|
+
export const Modal = ({ children, className, onClose, onCloseAttempt, open, }) => {
|
|
7
8
|
const { t } = useTranslationContext('Modal');
|
|
8
9
|
const innerRef = useRef(null);
|
|
9
|
-
const
|
|
10
|
+
const closeButtonRef = useRef(null);
|
|
11
|
+
const maybeClose = useCallback((source, event) => {
|
|
12
|
+
const allow = onCloseAttempt?.(source, event);
|
|
13
|
+
if (allow !== false) {
|
|
14
|
+
onClose?.(event);
|
|
15
|
+
}
|
|
16
|
+
}, [onClose, onCloseAttempt]);
|
|
10
17
|
const handleClick = (event) => {
|
|
11
18
|
const target = event.target;
|
|
12
|
-
if (!innerRef.current || !
|
|
19
|
+
if (!innerRef.current || !closeButtonRef.current)
|
|
13
20
|
return;
|
|
14
|
-
if (
|
|
15
|
-
|
|
21
|
+
if (closeButtonRef.current.contains(target)) {
|
|
22
|
+
maybeClose('button', event);
|
|
23
|
+
}
|
|
24
|
+
else if (!innerRef.current.contains(target)) {
|
|
25
|
+
maybeClose('overlay', event);
|
|
26
|
+
}
|
|
16
27
|
};
|
|
17
28
|
useEffect(() => {
|
|
18
29
|
if (!open)
|
|
19
30
|
return;
|
|
20
31
|
const handleKeyDown = (event) => {
|
|
21
32
|
if (event.key === 'Escape')
|
|
22
|
-
|
|
33
|
+
maybeClose('escape', event);
|
|
23
34
|
};
|
|
24
35
|
document.addEventListener('keydown', handleKeyDown);
|
|
25
36
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
26
|
-
}, [
|
|
37
|
+
}, [maybeClose, open]);
|
|
27
38
|
if (!open)
|
|
28
39
|
return null;
|
|
29
40
|
return (React.createElement("div", { className: clsx('str-chat__modal str-chat__modal--open', className), onClick: handleClick },
|
|
30
41
|
React.createElement(FocusScope, { autoFocus: true, contain: true },
|
|
31
|
-
React.createElement("button", { className: 'str-chat__modal__close-button', ref:
|
|
42
|
+
React.createElement("button", { className: 'str-chat__modal__close-button', ref: closeButtonRef, title: t('Close') },
|
|
32
43
|
React.createElement(CloseIconRound, null)),
|
|
33
44
|
React.createElement("div", { className: 'str-chat__modal__inner str-chat-react__modal__inner', ref: innerRef }, children))));
|
|
34
45
|
};
|
|
@@ -15,7 +15,10 @@ export const PollCreationDialogControls = ({ close, }) => {
|
|
|
15
15
|
messageComposer
|
|
16
16
|
.createPoll()
|
|
17
17
|
.then(() => handleSubmitMessage())
|
|
18
|
-
.then(
|
|
18
|
+
.then(() => {
|
|
19
|
+
messageComposer.pollComposer.initState();
|
|
20
|
+
close();
|
|
21
|
+
})
|
|
19
22
|
.catch(console.error);
|
|
20
23
|
}, type: 'submit' }, t('Create'))));
|
|
21
24
|
};
|
|
@@ -10720,7 +10720,9 @@ var ChannelPreview = (props) => {
|
|
|
10720
10720
|
);
|
|
10721
10721
|
(0, import_react23.useEffect)(() => {
|
|
10722
10722
|
refreshUnreadCount();
|
|
10723
|
-
const handleEvent = () => {
|
|
10723
|
+
const handleEvent = (event) => {
|
|
10724
|
+
const deletedMessagesInAnotherChannel = event.type === "user.messages.deleted" && event.cid && event.cid !== channel.cid;
|
|
10725
|
+
if (deletedMessagesInAnotherChannel) return;
|
|
10724
10726
|
setLastMessage(
|
|
10725
10727
|
channel.state.latestMessages[channel.state.latestMessages.length - 1]
|
|
10726
10728
|
);
|
|
@@ -10729,16 +10731,18 @@ var ChannelPreview = (props) => {
|
|
|
10729
10731
|
channel.on("message.new", handleEvent);
|
|
10730
10732
|
channel.on("message.updated", handleEvent);
|
|
10731
10733
|
channel.on("message.deleted", handleEvent);
|
|
10734
|
+
client.on("user.messages.deleted", handleEvent);
|
|
10732
10735
|
channel.on("message.undeleted", handleEvent);
|
|
10733
10736
|
channel.on("channel.truncated", handleEvent);
|
|
10734
10737
|
return () => {
|
|
10735
10738
|
channel.off("message.new", handleEvent);
|
|
10736
10739
|
channel.off("message.updated", handleEvent);
|
|
10737
10740
|
channel.off("message.deleted", handleEvent);
|
|
10741
|
+
client.off("user.messages.deleted", handleEvent);
|
|
10738
10742
|
channel.off("message.undeleted", handleEvent);
|
|
10739
10743
|
channel.off("channel.truncated", handleEvent);
|
|
10740
10744
|
};
|
|
10741
|
-
}, [channel, refreshUnreadCount, channelUpdateCount]);
|
|
10745
|
+
}, [channel, client, refreshUnreadCount, channelUpdateCount]);
|
|
10742
10746
|
if (!Preview) return null;
|
|
10743
10747
|
const latestMessagePreview = getLatestMessagePreview2(
|
|
10744
10748
|
channel,
|