stream-chat-react 12.0.0-rc.9 → 12.1.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/Avatar/Avatar.js +5 -1
- package/dist/components/Channel/Channel.d.ts +5 -106
- package/dist/components/Channel/Channel.js +76 -24
- package/dist/components/Channel/hooks/useCreateChannelStateContext.js +2 -1
- package/dist/components/ChannelHeader/ChannelHeader.js +4 -5
- package/dist/components/ChannelPreview/hooks/useChannelPreviewInfo.js +14 -16
- package/dist/components/ChannelPreview/utils.js +9 -20
- package/dist/components/ChannelSearch/hooks/useChannelSearch.js +2 -3
- package/dist/components/Chat/Chat.d.ts +1 -1
- package/dist/components/Chat/hooks/useChat.d.ts +2 -2
- package/dist/components/Chat/hooks/useChat.js +11 -8
- package/dist/components/ChatView/ChatView.d.ts +18 -0
- package/dist/components/ChatView/ChatView.js +103 -0
- package/dist/components/ChatView/index.d.ts +1 -0
- package/dist/components/ChatView/index.js +1 -0
- package/dist/components/DateSeparator/DateSeparator.d.ts +1 -1
- package/dist/components/Dialog/DialogAnchor.d.ts +25 -0
- package/dist/components/Dialog/DialogAnchor.js +68 -0
- package/dist/components/Dialog/DialogManager.d.ts +43 -0
- package/dist/components/Dialog/DialogManager.js +98 -0
- package/dist/components/Dialog/DialogPortal.d.ts +7 -0
- package/dist/components/Dialog/DialogPortal.js +25 -0
- package/dist/components/Dialog/hooks/index.d.ts +1 -0
- package/dist/components/Dialog/hooks/index.js +1 -0
- package/dist/components/Dialog/hooks/useDialog.d.ts +4 -0
- package/dist/components/Dialog/hooks/useDialog.js +26 -0
- package/dist/components/Dialog/index.d.ts +4 -0
- package/dist/components/Dialog/index.js +4 -0
- package/dist/components/EventComponent/EventComponent.d.ts +1 -1
- package/dist/components/Message/Message.js +5 -6
- package/dist/components/Message/MessageOptions.d.ts +1 -2
- package/dist/components/Message/MessageOptions.js +14 -11
- package/dist/components/Message/MessageSimple.js +6 -14
- package/dist/components/Message/MessageTimestamp.d.ts +1 -1
- package/dist/components/Message/QuotedMessage.js +2 -1
- package/dist/components/Message/Timestamp.d.ts +1 -1
- package/dist/components/Message/Timestamp.js +2 -2
- package/dist/components/Message/hooks/useReactionHandler.d.ts +1 -7
- package/dist/components/Message/hooks/useReactionHandler.js +8 -63
- package/dist/components/Message/utils.d.ts +10 -1
- package/dist/components/Message/utils.js +19 -7
- package/dist/components/MessageActions/MessageActions.d.ts +1 -2
- package/dist/components/MessageActions/MessageActions.js +26 -55
- package/dist/components/MessageActions/MessageActionsBox.d.ts +1 -1
- package/dist/components/MessageActions/MessageActionsBox.js +6 -6
- package/dist/components/MessageInput/MessageInputFlat.js +2 -2
- package/dist/components/MessageInput/QuotedMessagePreview.js +2 -1
- package/dist/components/MessageInput/hooks/useUserTrigger.js +0 -1
- package/dist/components/MessageList/MessageList.js +9 -9
- package/dist/components/MessageList/MessageListMainPanel.d.ts +1 -1
- package/dist/components/MessageList/MessageListMainPanel.js +1 -1
- package/dist/components/MessageList/VirtualizedMessageList.d.ts +2 -1
- package/dist/components/MessageList/VirtualizedMessageList.js +45 -40
- package/dist/components/MessageList/VirtualizedMessageListComponents.d.ts +1 -1
- package/dist/components/MessageList/VirtualizedMessageListComponents.js +6 -6
- package/dist/components/MessageList/hooks/MessageList/useUnreadMessagesNotification.js +2 -2
- package/dist/components/MessageList/renderMessages.d.ts +2 -2
- package/dist/components/MessageList/renderMessages.js +4 -1
- package/dist/components/MessageList/utils.js +1 -1
- package/dist/components/Reactions/ReactionSelector.d.ts +6 -3
- package/dist/components/Reactions/ReactionSelector.js +34 -24
- package/dist/components/Reactions/ReactionSelectorWithButton.d.ts +13 -0
- package/dist/components/Reactions/ReactionSelectorWithButton.js +22 -0
- package/dist/components/Reactions/ReactionsList.d.ts +4 -4
- package/dist/components/Reactions/hooks/useProcessReactions.js +2 -1
- package/dist/components/Thread/Thread.js +38 -10
- package/dist/components/Threads/ThreadContext.d.ts +9 -0
- package/dist/components/Threads/ThreadContext.js +9 -0
- package/dist/components/Threads/ThreadList/ThreadList.d.ts +9 -0
- package/dist/components/Threads/ThreadList/ThreadList.js +41 -0
- package/dist/components/Threads/ThreadList/ThreadListEmptyPlaceholder.d.ts +2 -0
- package/dist/components/Threads/ThreadList/ThreadListEmptyPlaceholder.js +5 -0
- package/dist/components/Threads/ThreadList/ThreadListItem.d.ts +9 -0
- package/dist/components/Threads/ThreadList/ThreadListItem.js +52 -0
- package/dist/components/Threads/ThreadList/ThreadListItemUI.d.ts +15 -0
- package/dist/components/Threads/ThreadList/ThreadListItemUI.js +75 -0
- package/dist/components/Threads/ThreadList/ThreadListLoadingIndicator.d.ts +2 -0
- package/dist/components/Threads/ThreadList/ThreadListLoadingIndicator.js +14 -0
- package/dist/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.d.ts +2 -0
- package/dist/components/Threads/ThreadList/ThreadListUnseenThreadsBanner.js +16 -0
- package/dist/components/Threads/ThreadList/index.d.ts +3 -0
- package/dist/components/Threads/ThreadList/index.js +3 -0
- package/dist/components/Threads/UnreadCountBadge.d.ts +6 -0
- package/dist/components/Threads/UnreadCountBadge.js +5 -0
- package/dist/components/Threads/hooks/useThreadManagerState.d.ts +2 -0
- package/dist/components/Threads/hooks/useThreadManagerState.js +6 -0
- package/dist/components/Threads/hooks/useThreadState.d.ts +5 -0
- package/dist/components/Threads/hooks/useThreadState.js +11 -0
- package/dist/components/Threads/icons.d.ts +8 -0
- package/dist/components/Threads/icons.js +13 -0
- package/dist/components/Threads/index.d.ts +2 -0
- package/dist/components/Threads/index.js +2 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +3 -0
- package/dist/context/ComponentContext.d.ts +64 -40
- package/dist/context/ComponentContext.js +7 -9
- package/dist/context/DialogManagerContext.d.ts +10 -0
- package/dist/context/DialogManagerContext.js +14 -0
- package/dist/context/MessageContext.d.ts +3 -11
- package/dist/context/MessageContext.js +3 -2
- package/dist/context/TranslationContext.d.ts +1 -11
- package/dist/context/TranslationContext.js +1 -9
- package/dist/context/WithComponents.d.ts +5 -0
- package/dist/context/WithComponents.js +7 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +2 -0
- package/dist/css/v2/index.css +2 -2
- package/dist/css/v2/index.layout.css +2 -2
- package/dist/i18n/Streami18n.d.ts +1 -3
- package/dist/i18n/Streami18n.js +1 -2
- package/dist/i18n/index.d.ts +2 -1
- package/dist/i18n/index.js +2 -0
- package/dist/i18n/types.d.ts +26 -0
- package/dist/i18n/types.js +1 -0
- package/dist/i18n/utils.d.ts +9 -20
- package/dist/i18n/utils.js +10 -1
- package/dist/index.browser.cjs +10823 -10583
- package/dist/index.browser.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.node.cjs +10765 -10541
- package/dist/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/index.browser.cjs +7 -169
- package/dist/plugins/Emojis/index.browser.cjs.map +4 -4
- package/dist/plugins/Emojis/index.node.cjs +7 -169
- package/dist/plugins/Emojis/index.node.cjs.map +4 -4
- package/dist/plugins/encoders/mp3.browser.cjs +2 -4
- package/dist/plugins/encoders/mp3.browser.cjs.map +1 -1
- package/dist/plugins/encoders/mp3.node.cjs +2 -4
- package/dist/plugins/encoders/mp3.node.cjs.map +1 -1
- package/dist/scss/v2/Avatar/Avatar-layout.scss +10 -2
- package/dist/scss/v2/Avatar/Avatar-theme.scss +5 -0
- package/dist/scss/v2/ChatView/ChatView-layout.scss +43 -0
- package/dist/scss/v2/ChatView/ChatView-theme.scss +32 -0
- package/dist/scss/v2/Dialog/Dialog-layout.scss +8 -0
- package/dist/scss/v2/LoadingIndicator/LoadingIndicator-layout.scss +16 -0
- package/dist/scss/v2/Message/Message-layout.scss +8 -0
- package/dist/scss/v2/MessageActionsBox/MessageActionsBox-theme.scss +8 -0
- package/dist/scss/v2/MessageList/MessageList-layout.scss +0 -6
- package/dist/scss/v2/MessageList/VirtualizedMessageList-layout.scss +0 -12
- package/dist/scss/v2/MessageReactions/MessageReactionsSelector-layout.scss +16 -0
- package/dist/scss/v2/MessageReactions/MessageReactionsSelector-theme.scss +6 -0
- package/dist/scss/v2/Thread/Thread-layout.scss +15 -1
- package/dist/scss/v2/ThreadList/ThreadList-layout.scss +152 -0
- package/dist/scss/v2/ThreadList/ThreadList-theme.scss +75 -0
- package/dist/scss/v2/UnreadCountBadge/UnreadCountBadge-layout.scss +49 -0
- package/dist/scss/v2/UnreadCountBadge/UnreadCountBadge-theme.scss +11 -0
- package/dist/scss/v2/_base.scss +31 -0
- package/dist/scss/v2/index.layout.scss +4 -0
- package/dist/scss/v2/index.scss +3 -0
- package/dist/store/hooks/index.d.ts +1 -0
- package/dist/store/hooks/index.js +1 -0
- package/dist/store/hooks/useStateStore.d.ts +3 -0
- package/dist/store/hooks/useStateStore.js +15 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.js +1 -0
- package/package.json +7 -6
- package/dist/assets/Poweredby_100px-White_VertText.png +0 -0
- package/dist/assets/str-chat__reaction-list-sprite@1x.png +0 -0
- package/dist/assets/str-chat__reaction-list-sprite@2x.png +0 -0
- package/dist/assets/str-chat__reaction-list-sprite@3x.png +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import { Icon } from '../Threads/icons';
|
|
3
4
|
import { getWholeChar } from '../../utils';
|
|
4
5
|
/**
|
|
5
6
|
* A round avatar image with fallback to username's first letter
|
|
@@ -15,6 +16,9 @@ export const Avatar = (props) => {
|
|
|
15
16
|
const showImage = image && !error;
|
|
16
17
|
return (React.createElement("div", { className: clsx(`str-chat__avatar str-chat__message-sender-avatar`, className, {
|
|
17
18
|
['str-chat__avatar--multiple-letters']: initials.length > 1,
|
|
19
|
+
['str-chat__avatar--no-letters']: !initials.length,
|
|
18
20
|
['str-chat__avatar--one-letter']: initials.length === 1,
|
|
19
|
-
}), "data-testid": 'avatar', onClick: onClick, onMouseOver: onMouseOver, title: name }, showImage ? (React.createElement("img", { alt: initials, className:
|
|
21
|
+
}), "data-testid": 'avatar', onClick: onClick, onMouseOver: onMouseOver, role: 'button', title: name }, showImage ? (React.createElement("img", { alt: initials, className: 'str-chat__avatar-image', "data-testid": 'avatar-img', onError: () => setError(true), src: image })) : (React.createElement(React.Fragment, null,
|
|
22
|
+
!!initials.length && (React.createElement("div", { className: clsx('str-chat__avatar-fallback'), "data-testid": 'avatar-fallback' }, initials)),
|
|
23
|
+
!initials.length && React.createElement(Icon.User, null)))));
|
|
20
24
|
};
|
|
@@ -2,114 +2,11 @@ import React, { PropsWithChildren } from 'react';
|
|
|
2
2
|
import { ChannelQueryOptions, EventAPIResponse, Message, MessageResponse, Channel as StreamChannel, StreamChat, UpdatedMessage } from 'stream-chat';
|
|
3
3
|
import { OnMentionAction } from './hooks/useMentionsHandlers';
|
|
4
4
|
import { LoadingErrorIndicatorProps } from '../Loading';
|
|
5
|
-
import { StreamMessage } from '../../context
|
|
6
|
-
import {
|
|
7
|
-
import type { UnreadMessagesNotificationProps } from '../MessageList';
|
|
8
|
-
import type { MessageProps } from '../Message/types';
|
|
9
|
-
import type { MessageInputProps } from '../MessageInput/MessageInput';
|
|
5
|
+
import { ComponentContextValue, StreamMessage } from '../../context';
|
|
6
|
+
import type { MessageInputProps } from '../MessageInput';
|
|
10
7
|
import type { ChannelUnreadUiState, CustomTrigger, DefaultStreamChatGenerics, GiphyVersions, ImageAttachmentSizeHandler, SendMessageOptions, UpdateMessageOptions, VideoAttachmentSizeHandler } from '../../types/types';
|
|
11
8
|
import type { URLEnrichmentConfig } from '../MessageInput/hooks/useLinkPreviews';
|
|
12
|
-
|
|
13
|
-
type ChannelPropsForwardedToComponentContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
|
|
14
|
-
/** Custom UI component to display a message attachment, defaults to and accepts same props as: [Attachment](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Attachment/Attachment.tsx) */
|
|
15
|
-
Attachment?: ComponentContextValue<StreamChatGenerics>['Attachment'];
|
|
16
|
-
/** Custom UI component to display an attachment previews in MessageInput, defaults to and accepts same props as: [Attachment](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/AttachmentPreviewList.tsx) */
|
|
17
|
-
AttachmentPreviewList?: ComponentContextValue<StreamChatGenerics>['AttachmentPreviewList'];
|
|
18
|
-
/** Custom UI component to display AudioRecorder in MessageInput, defaults to and accepts same props as: [AudioRecorder](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/AudioRecorder.tsx) */
|
|
19
|
-
AudioRecorder?: ComponentContextValue<StreamChatGenerics>['AudioRecorder'];
|
|
20
|
-
/** Optional UI component to override the default suggestion Item component, defaults to and accepts same props as: [Item](https://github.com/GetStream/stream-chat-react/blob/master/src/components/AutoCompleteTextarea/Item.js) */
|
|
21
|
-
AutocompleteSuggestionItem?: ComponentContextValue<StreamChatGenerics>['AutocompleteSuggestionItem'];
|
|
22
|
-
/** Optional UI component to override the default List component that displays suggestions, defaults to and accepts same props as: [List](https://github.com/GetStream/stream-chat-react/blob/master/src/components/AutoCompleteTextarea/List.js) */
|
|
23
|
-
AutocompleteSuggestionList?: ComponentContextValue<StreamChatGenerics>['AutocompleteSuggestionList'];
|
|
24
|
-
/** UI component to display a user's avatar, defaults to and accepts same props as: [Avatar](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Avatar/Avatar.tsx) */
|
|
25
|
-
Avatar?: ComponentContextValue<StreamChatGenerics>['Avatar'];
|
|
26
|
-
/** Custom UI component to display <img/> elements resp. a fallback in case of load error, defaults to and accepts same props as: [BaseImage](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Gallery/BaseImage.tsx) */
|
|
27
|
-
BaseImage?: ComponentContextValue<StreamChatGenerics>['BaseImage'];
|
|
28
|
-
/** Custom UI component to display the slow mode cooldown timer, defaults to and accepts same props as: [CooldownTimer](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/CooldownTimer.tsx) */
|
|
29
|
-
CooldownTimer?: ComponentContextValue<StreamChatGenerics>['CooldownTimer'];
|
|
30
|
-
/** Custom UI component to render set of buttons to be displayed in the MessageActionsBox, defaults to and accepts same props as: [CustomMessageActionsList](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageActions/CustomMessageActionsList.tsx) */
|
|
31
|
-
CustomMessageActionsList?: ComponentContextValue<StreamChatGenerics>['CustomMessageActionsList'];
|
|
32
|
-
/** Custom UI component for date separators, defaults to and accepts same props as: [DateSeparator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/DateSeparator.tsx) */
|
|
33
|
-
DateSeparator?: ComponentContextValue<StreamChatGenerics>['DateSeparator'];
|
|
34
|
-
/** Custom UI component to override default edit message input, defaults to and accepts same props as: [EditMessageForm](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/EditMessageForm.tsx) */
|
|
35
|
-
EditMessageInput?: ComponentContextValue<StreamChatGenerics>['EditMessageInput'];
|
|
36
|
-
/** Custom UI component for rendering button with emoji picker in MessageInput */
|
|
37
|
-
EmojiPicker?: ComponentContextValue<StreamChatGenerics>['EmojiPicker'];
|
|
38
|
-
/** Mechanism to be used with autocomplete and text replace features of the `MessageInput` component, see [emoji-mart `SearchIndex`](https://github.com/missive/emoji-mart#%EF%B8%8F%EF%B8%8F-headless-search) */
|
|
39
|
-
emojiSearchIndex?: ComponentContextValue<StreamChatGenerics>['emojiSearchIndex'];
|
|
40
|
-
/** Custom UI component to be displayed when the `MessageList` is empty, defaults to and accepts same props as: [EmptyStateIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/EmptyStateIndicator/EmptyStateIndicator.tsx) */
|
|
41
|
-
EmptyStateIndicator?: ComponentContextValue<StreamChatGenerics>['EmptyStateIndicator'];
|
|
42
|
-
/** Custom UI component for file upload icon, defaults to and accepts same props as: [FileUploadIcon](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/icons.tsx) */
|
|
43
|
-
FileUploadIcon?: ComponentContextValue<StreamChatGenerics>['FileUploadIcon'];
|
|
44
|
-
/** Custom UI component to render a Giphy preview in the `VirtualizedMessageList` */
|
|
45
|
-
GiphyPreviewMessage?: ComponentContextValue<StreamChatGenerics>['GiphyPreviewMessage'];
|
|
46
|
-
/** Custom UI component to render at the top of the `MessageList` */
|
|
47
|
-
HeaderComponent?: ComponentContextValue<StreamChatGenerics>['HeaderComponent'];
|
|
48
|
-
/** Custom UI component handling how the message input is rendered, defaults to and accepts the same props as [MessageInputFlat](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/MessageInputFlat.tsx) */
|
|
49
|
-
Input?: ComponentContextValue<StreamChatGenerics>['Input'];
|
|
50
|
-
/** Custom component to render link previews in message input **/
|
|
51
|
-
LinkPreviewList?: ComponentContextValue<StreamChatGenerics>['LinkPreviewList'];
|
|
52
|
-
/** Custom UI component to be shown if the channel query fails, defaults to and accepts same props as: [LoadingErrorIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Loading/LoadingErrorIndicator.tsx) */
|
|
53
|
-
LoadingErrorIndicator?: React.ComponentType<LoadingErrorIndicatorProps>;
|
|
54
|
-
/** Custom UI component to render while the `MessageList` is loading new messages, defaults to and accepts same props as: [LoadingIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Loading/LoadingIndicator.tsx) */
|
|
55
|
-
LoadingIndicator?: ComponentContextValue<StreamChatGenerics>['LoadingIndicator'];
|
|
56
|
-
/** Custom UI component to display a message in the standard `MessageList`, defaults to and accepts the same props as: [MessageSimple](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageSimple.tsx) */
|
|
57
|
-
Message?: ComponentContextValue<StreamChatGenerics>['Message'];
|
|
58
|
-
/** Custom UI component to display the contents of a bounced message modal. Usually it allows to retry, edit, or delete the message. Defaults to and accepts the same props as: [MessageBouncePrompt](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageBounce/MessageBouncePrompt.tsx) */
|
|
59
|
-
MessageBouncePrompt?: ComponentContextValue<StreamChatGenerics>['MessageBouncePrompt'];
|
|
60
|
-
/** Custom UI component for a deleted message, defaults to and accepts same props as: [MessageDeleted](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageDeleted.tsx) */
|
|
61
|
-
MessageDeleted?: ComponentContextValue<StreamChatGenerics>['MessageDeleted'];
|
|
62
|
-
/** Custom UI component that displays message and connection status notifications in the `MessageList`, defaults to and accepts same props as [DefaultMessageListNotifications](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageList/MessageListNotifications.tsx) */
|
|
63
|
-
MessageListNotifications?: ComponentContextValue<StreamChatGenerics>['MessageListNotifications'];
|
|
64
|
-
/** Custom UI component to display a notification when scrolled up the list and new messages arrive, defaults to and accepts same props as [MessageNotification](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageList/MessageNotification.tsx) */
|
|
65
|
-
MessageNotification?: ComponentContextValue<StreamChatGenerics>['MessageNotification'];
|
|
66
|
-
/** Custom UI component for message options popup, defaults to and accepts same props as: [MessageOptions](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageOptions.tsx) */
|
|
67
|
-
MessageOptions?: ComponentContextValue<StreamChatGenerics>['MessageOptions'];
|
|
68
|
-
/** Custom UI component to display message replies, defaults to and accepts same props as: [MessageRepliesCountButton](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageRepliesCountButton.tsx) */
|
|
69
|
-
MessageRepliesCountButton?: ComponentContextValue<StreamChatGenerics>['MessageRepliesCountButton'];
|
|
70
|
-
/** Custom UI component to display message delivery status, defaults to and accepts same props as: [MessageStatus](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageStatus.tsx) */
|
|
71
|
-
MessageStatus?: ComponentContextValue<StreamChatGenerics>['MessageStatus'];
|
|
72
|
-
/** Custom UI component to display system messages, defaults to and accepts same props as: [EventComponent](https://github.com/GetStream/stream-chat-react/blob/master/src/components/EventComponent/EventComponent.tsx) */
|
|
73
|
-
MessageSystem?: ComponentContextValue<StreamChatGenerics>['MessageSystem'];
|
|
74
|
-
/** Custom UI component to display a timestamp on a message, defaults to and accepts same props as: [MessageTimestamp](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageTimestamp.tsx) */
|
|
75
|
-
MessageTimestamp?: ComponentContextValue<StreamChatGenerics>['MessageTimestamp'];
|
|
76
|
-
/** Custom UI component for viewing message's image attachments, defaults to and accepts the same props as [ModalGallery](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Gallery/ModalGallery.tsx) */
|
|
77
|
-
ModalGallery?: ComponentContextValue<StreamChatGenerics>['ModalGallery'];
|
|
78
|
-
/** Custom UI component to override default pinned message indicator, defaults to and accepts same props as: [PinIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/icons.tsx) */
|
|
79
|
-
PinIndicator?: ComponentContextValue<StreamChatGenerics>['PinIndicator'];
|
|
80
|
-
/** Custom UI component to override quoted message UI on a sent message, defaults to and accepts same props as: [QuotedMessage](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/QuotedMessage.tsx) */
|
|
81
|
-
QuotedMessage?: ComponentContextValue<StreamChatGenerics>['QuotedMessage'];
|
|
82
|
-
/** Custom UI component to override the message input's quoted message preview, defaults to and accepts same props as: [QuotedMessagePreview](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/QuotedMessagePreview.tsx) */
|
|
83
|
-
QuotedMessagePreview?: ComponentContextValue<StreamChatGenerics>['QuotedMessagePreview'];
|
|
84
|
-
/** Custom reaction options to be applied to ReactionSelector, ReactionList and SimpleReactionList components */
|
|
85
|
-
reactionOptions?: ReactionOptions;
|
|
86
|
-
/** Custom UI component to display the reaction selector, defaults to and accepts same props as: [ReactionSelector](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/ReactionSelector.tsx) */
|
|
87
|
-
ReactionSelector?: ComponentContextValue<StreamChatGenerics>['ReactionSelector'];
|
|
88
|
-
/** Custom UI component to display the list of reactions on a message, defaults to and accepts same props as: [ReactionsList](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Reactions/ReactionsList.tsx) */
|
|
89
|
-
ReactionsList?: ComponentContextValue<StreamChatGenerics>['ReactionsList'];
|
|
90
|
-
/** Custom UI component for send button, defaults to and accepts same props as: [SendButton](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/icons.tsx) */
|
|
91
|
-
SendButton?: ComponentContextValue<StreamChatGenerics>['SendButton'];
|
|
92
|
-
/** Custom UI component button for initiating audio recording, defaults to and accepts same props as: [StartRecordingAudioButton](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MediaRecorder/AudioRecorder/AudioRecordingButtons.tsx) */
|
|
93
|
-
StartRecordingAudioButton?: ComponentContextValue<StreamChatGenerics>['StartRecordingAudioButton'];
|
|
94
|
-
/** Custom UI component that displays thread's parent or other message at the top of the `MessageList`, defaults to and accepts same props as [MessageSimple](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageSimple.tsx) */
|
|
95
|
-
ThreadHead?: React.ComponentType<MessageProps<StreamChatGenerics>>;
|
|
96
|
-
/** Custom UI component to display the header of a `Thread`, defaults to and accepts same props as: [DefaultThreadHeader](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Thread/Thread.tsx) */
|
|
97
|
-
ThreadHeader?: ComponentContextValue<StreamChatGenerics>['ThreadHeader'];
|
|
98
|
-
/** Custom UI component to display the start of a threaded `MessageList`, defaults to and accepts same props as: [DefaultThreadStart](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Thread/Thread.tsx) */
|
|
99
|
-
ThreadStart?: ComponentContextValue<StreamChatGenerics>['ThreadStart'];
|
|
100
|
-
/** Custom UI component to display a date used in timestamps. It's used internally by the default `MessageTimestamp`, and to display a timestamp for edited messages. */
|
|
101
|
-
Timestamp?: ComponentContextValue<StreamChatGenerics>['Timestamp'];
|
|
102
|
-
/** Optional context provider that lets you override the default autocomplete triggers, defaults to: [DefaultTriggerProvider](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageInput/DefaultTriggerProvider.tsx) */
|
|
103
|
-
TriggerProvider?: ComponentContextValue<StreamChatGenerics>['TriggerProvider'];
|
|
104
|
-
/** Custom UI component for the typing indicator, defaults to and accepts same props as: [TypingIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/TypingIndicator/TypingIndicator.tsx) */
|
|
105
|
-
TypingIndicator?: ComponentContextValue<StreamChatGenerics>['TypingIndicator'];
|
|
106
|
-
/** Custom UI component that indicates a user is viewing unread messages. It disappears once the user scrolls to UnreadMessagesSeparator. Defaults to and accepts same props as: [UnreadMessagesNotification](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageList/UnreadMessagesNotification.tsx) */
|
|
107
|
-
UnreadMessagesNotification?: React.ComponentType<UnreadMessagesNotificationProps>;
|
|
108
|
-
/** Custom UI component that separates read messages from unread, defaults to and accepts same props as: [UnreadMessagesSeparator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/MessageList/UnreadMessagesSeparator.tsx) */
|
|
109
|
-
UnreadMessagesSeparator?: ComponentContextValue<StreamChatGenerics>['UnreadMessagesSeparator'];
|
|
110
|
-
/** Custom UI component to display a message in the `VirtualizedMessageList`, does not have a default implementation */
|
|
111
|
-
VirtualMessage?: ComponentContextValue<StreamChatGenerics>['VirtualMessage'];
|
|
112
|
-
};
|
|
9
|
+
type ChannelPropsForwardedToComponentContext<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Pick<ComponentContextValue<StreamChatGenerics>, 'Attachment' | 'AttachmentPreviewList' | 'AudioRecorder' | 'AutocompleteSuggestionItem' | 'AutocompleteSuggestionList' | 'Avatar' | 'BaseImage' | 'CooldownTimer' | 'CustomMessageActionsList' | 'DateSeparator' | 'EditMessageInput' | 'EmojiPicker' | 'emojiSearchIndex' | 'EmptyStateIndicator' | 'FileUploadIcon' | 'GiphyPreviewMessage' | 'HeaderComponent' | 'Input' | 'LinkPreviewList' | 'LoadingIndicator' | 'Message' | 'MessageBouncePrompt' | 'MessageDeleted' | 'MessageListNotifications' | 'MessageListMainPanel' | 'MessageNotification' | 'MessageOptions' | 'MessageRepliesCountButton' | 'MessageStatus' | 'MessageSystem' | 'MessageTimestamp' | 'ModalGallery' | 'PinIndicator' | 'QuotedMessage' | 'QuotedMessagePreview' | 'reactionOptions' | 'ReactionSelector' | 'ReactionsList' | 'SendButton' | 'StartRecordingAudioButton' | 'ThreadHead' | 'ThreadHeader' | 'ThreadStart' | 'Timestamp' | 'TriggerProvider' | 'TypingIndicator' | 'UnreadMessagesNotification' | 'UnreadMessagesSeparator' | 'VirtualMessage'>;
|
|
113
10
|
export type ChannelProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, V extends CustomTrigger = CustomTrigger> = ChannelPropsForwardedToComponentContext<StreamChatGenerics> & {
|
|
114
11
|
/** List of accepted file types */
|
|
115
12
|
acceptedFiles?: string[];
|
|
@@ -154,6 +51,8 @@ export type ChannelProps<StreamChatGenerics extends DefaultStreamChatGenerics =
|
|
|
154
51
|
* Preventing to initialize the channel on mount allows us to postpone the channel creation to a later point in time.
|
|
155
52
|
*/
|
|
156
53
|
initializeOnMount?: boolean;
|
|
54
|
+
/** Custom UI component to be shown if the channel query fails, defaults to and accepts same props as: [LoadingErrorIndicator](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Loading/LoadingErrorIndicator.tsx) */
|
|
55
|
+
LoadingErrorIndicator?: React.ComponentType<LoadingErrorIndicatorProps>;
|
|
157
56
|
/** Configuration parameter to mark the active channel as read when mounted (opened). By default, the channel is marked read on mount. */
|
|
158
57
|
markReadOnMount?: boolean;
|
|
159
58
|
/** Maximum number of attachments allowed per message */
|
|
@@ -10,26 +10,17 @@ import { useCreateTypingContext } from './hooks/useCreateTypingContext';
|
|
|
10
10
|
import { useEditMessageHandler } from './hooks/useEditMessageHandler';
|
|
11
11
|
import { useIsMounted } from './hooks/useIsMounted';
|
|
12
12
|
import { useMentionsHandlers } from './hooks/useMentionsHandlers';
|
|
13
|
-
import { Attachment as DefaultAttachment } from '../Attachment/Attachment';
|
|
14
13
|
import { LoadingErrorIndicator as DefaultLoadingErrorIndicator, } from '../Loading';
|
|
15
14
|
import { LoadingChannel as DefaultLoadingIndicator } from './LoadingChannel';
|
|
16
|
-
import { MessageSimple } from '../Message/MessageSimple';
|
|
17
15
|
import { DropzoneProvider } from '../MessageInput/DropzoneProvider';
|
|
18
|
-
import { ChannelActionProvider, } from '../../context
|
|
19
|
-
import { ChannelStateProvider, } from '../../context/ChannelStateContext';
|
|
20
|
-
import { ComponentProvider } from '../../context/ComponentContext';
|
|
21
|
-
import { useChatContext } from '../../context/ChatContext';
|
|
22
|
-
import { useTranslationContext } from '../../context/TranslationContext';
|
|
23
|
-
import { TypingProvider } from '../../context/TypingContext';
|
|
16
|
+
import { ChannelActionProvider, ChannelStateProvider, TypingProvider, useChatContext, useTranslationContext, WithComponents, } from '../../context';
|
|
24
17
|
import { DEFAULT_HIGHLIGHT_DURATION, DEFAULT_INITIAL_CHANNEL_PAGE_SIZE, DEFAULT_JUMP_TO_PAGE_SIZE, DEFAULT_NEXT_CHANNEL_PAGE_SIZE, DEFAULT_THREAD_PAGE_SIZE, } from '../../constants/limits';
|
|
25
|
-
import { hasMoreMessagesProbably
|
|
18
|
+
import { hasMoreMessagesProbably } from '../MessageList';
|
|
26
19
|
import { useChannelContainerClasses } from './hooks/useChannelContainerClasses';
|
|
27
20
|
import { findInMsgSetByDate, findInMsgSetById, makeAddNotifications } from './utils';
|
|
28
21
|
import { getChannel } from '../../utils';
|
|
29
22
|
import { getImageAttachmentConfiguration, getVideoAttachmentConfiguration, } from '../Attachment/attachment-sizing';
|
|
30
|
-
import {
|
|
31
|
-
import { EventComponent } from '../EventComponent';
|
|
32
|
-
import { DateSeparator } from '../DateSeparator';
|
|
23
|
+
import { useThreadContext } from '../Threads';
|
|
33
24
|
const isUserResponseArray = (output) => output[0]?.id != null;
|
|
34
25
|
const UnMemoizedChannel = (props) => {
|
|
35
26
|
const { channel: propsChannel, EmptyPlaceholder = null, LoadingErrorIndicator, LoadingIndicator = DefaultLoadingIndicator, } = props;
|
|
@@ -60,6 +51,7 @@ const ChannelInner = (props) => {
|
|
|
60
51
|
const { client, customClasses, latestMessageDatesByChannels, mutes, theme, } = useChatContext('Channel');
|
|
61
52
|
const { t } = useTranslationContext('Channel');
|
|
62
53
|
const { channelClass, chatClass, chatContainerClass, windowsEmojiClass, } = useChannelContainerClasses({ customClasses });
|
|
54
|
+
const thread = useThreadContext();
|
|
63
55
|
const [channelConfig, setChannelConfig] = useState(channel.getConfig());
|
|
64
56
|
const [notifications, setNotifications] = useState([]);
|
|
65
57
|
const [quotedMessage, setQuotedMessage] = useState();
|
|
@@ -565,25 +557,37 @@ const ChannelInner = (props) => {
|
|
|
565
557
|
errorStatusCode: parsedError.status || undefined,
|
|
566
558
|
status: 'failed',
|
|
567
559
|
});
|
|
560
|
+
thread?.upsertReplyLocally({
|
|
561
|
+
// @ts-expect-error
|
|
562
|
+
message: {
|
|
563
|
+
...message,
|
|
564
|
+
error: parsedError,
|
|
565
|
+
errorStatusCode: parsedError.status || undefined,
|
|
566
|
+
status: 'failed',
|
|
567
|
+
},
|
|
568
|
+
});
|
|
568
569
|
}
|
|
569
570
|
}
|
|
570
571
|
};
|
|
571
572
|
const sendMessage = async ({ attachments = [], mentioned_users = [], parent, text = '', }, customMessageData, options) => {
|
|
572
573
|
channel.state.filterErrorMessages();
|
|
573
574
|
const messagePreview = {
|
|
574
|
-
__html: text,
|
|
575
575
|
attachments,
|
|
576
576
|
created_at: new Date(),
|
|
577
577
|
html: text,
|
|
578
578
|
id: customMessageData?.id ?? `${client.userID}-${nanoid()}`,
|
|
579
579
|
mentioned_users,
|
|
580
|
+
parent_id: parent?.id,
|
|
580
581
|
reactions: [],
|
|
581
582
|
status: 'sending',
|
|
582
583
|
text,
|
|
583
584
|
type: 'regular',
|
|
584
585
|
user: client.user,
|
|
585
|
-
...(parent?.id ? { parent_id: parent.id } : null),
|
|
586
586
|
};
|
|
587
|
+
thread?.upsertReplyLocally({
|
|
588
|
+
// @ts-expect-error
|
|
589
|
+
message: messagePreview,
|
|
590
|
+
});
|
|
587
591
|
updateMessage(messagePreview);
|
|
588
592
|
await doSendMessage(messagePreview, customMessageData, options);
|
|
589
593
|
};
|
|
@@ -722,8 +726,9 @@ const ChannelInner = (props) => {
|
|
|
722
726
|
jumpToLatestMessage,
|
|
723
727
|
setChannelUnreadUiState,
|
|
724
728
|
]);
|
|
729
|
+
// @ts-expect-error
|
|
725
730
|
const componentContextValue = useMemo(() => ({
|
|
726
|
-
Attachment: props.Attachment
|
|
731
|
+
Attachment: props.Attachment,
|
|
727
732
|
AttachmentPreviewList: props.AttachmentPreviewList,
|
|
728
733
|
AudioRecorder: props.AudioRecorder,
|
|
729
734
|
AutocompleteSuggestionItem: props.AutocompleteSuggestionItem,
|
|
@@ -732,7 +737,7 @@ const ChannelInner = (props) => {
|
|
|
732
737
|
BaseImage: props.BaseImage,
|
|
733
738
|
CooldownTimer: props.CooldownTimer,
|
|
734
739
|
CustomMessageActionsList: props.CustomMessageActionsList,
|
|
735
|
-
DateSeparator: props.DateSeparator
|
|
740
|
+
DateSeparator: props.DateSeparator,
|
|
736
741
|
EditMessageInput: props.EditMessageInput,
|
|
737
742
|
EmojiPicker: props.EmojiPicker,
|
|
738
743
|
emojiSearchIndex: props.emojiSearchIndex,
|
|
@@ -743,7 +748,7 @@ const ChannelInner = (props) => {
|
|
|
743
748
|
Input: props.Input,
|
|
744
749
|
LinkPreviewList: props.LinkPreviewList,
|
|
745
750
|
LoadingIndicator: props.LoadingIndicator,
|
|
746
|
-
Message: props.Message
|
|
751
|
+
Message: props.Message,
|
|
747
752
|
MessageBouncePrompt: props.MessageBouncePrompt,
|
|
748
753
|
MessageDeleted: props.MessageDeleted,
|
|
749
754
|
MessageListNotifications: props.MessageListNotifications,
|
|
@@ -751,13 +756,13 @@ const ChannelInner = (props) => {
|
|
|
751
756
|
MessageOptions: props.MessageOptions,
|
|
752
757
|
MessageRepliesCountButton: props.MessageRepliesCountButton,
|
|
753
758
|
MessageStatus: props.MessageStatus,
|
|
754
|
-
MessageSystem: props.MessageSystem
|
|
759
|
+
MessageSystem: props.MessageSystem,
|
|
755
760
|
MessageTimestamp: props.MessageTimestamp,
|
|
756
761
|
ModalGallery: props.ModalGallery,
|
|
757
762
|
PinIndicator: props.PinIndicator,
|
|
758
763
|
QuotedMessage: props.QuotedMessage,
|
|
759
764
|
QuotedMessagePreview: props.QuotedMessagePreview,
|
|
760
|
-
reactionOptions: props.reactionOptions
|
|
765
|
+
reactionOptions: props.reactionOptions,
|
|
761
766
|
ReactionSelector: props.ReactionSelector,
|
|
762
767
|
ReactionsList: props.ReactionsList,
|
|
763
768
|
SendButton: props.SendButton,
|
|
@@ -769,11 +774,58 @@ const ChannelInner = (props) => {
|
|
|
769
774
|
TriggerProvider: props.TriggerProvider,
|
|
770
775
|
TypingIndicator: props.TypingIndicator,
|
|
771
776
|
UnreadMessagesNotification: props.UnreadMessagesNotification,
|
|
772
|
-
UnreadMessagesSeparator: props.UnreadMessagesSeparator
|
|
777
|
+
UnreadMessagesSeparator: props.UnreadMessagesSeparator,
|
|
773
778
|
VirtualMessage: props.VirtualMessage,
|
|
774
|
-
}),
|
|
775
|
-
|
|
776
|
-
|
|
779
|
+
}), [
|
|
780
|
+
props.Attachment,
|
|
781
|
+
props.AttachmentPreviewList,
|
|
782
|
+
props.AudioRecorder,
|
|
783
|
+
props.AutocompleteSuggestionItem,
|
|
784
|
+
props.AutocompleteSuggestionList,
|
|
785
|
+
props.Avatar,
|
|
786
|
+
props.BaseImage,
|
|
787
|
+
props.CooldownTimer,
|
|
788
|
+
props.CustomMessageActionsList,
|
|
789
|
+
props.DateSeparator,
|
|
790
|
+
props.EditMessageInput,
|
|
791
|
+
props.EmojiPicker,
|
|
792
|
+
props.EmptyStateIndicator,
|
|
793
|
+
props.FileUploadIcon,
|
|
794
|
+
props.GiphyPreviewMessage,
|
|
795
|
+
props.HeaderComponent,
|
|
796
|
+
props.Input,
|
|
797
|
+
props.LinkPreviewList,
|
|
798
|
+
props.LoadingIndicator,
|
|
799
|
+
props.Message,
|
|
800
|
+
props.MessageBouncePrompt,
|
|
801
|
+
props.MessageDeleted,
|
|
802
|
+
props.MessageListNotifications,
|
|
803
|
+
props.MessageNotification,
|
|
804
|
+
props.MessageOptions,
|
|
805
|
+
props.MessageRepliesCountButton,
|
|
806
|
+
props.MessageStatus,
|
|
807
|
+
props.MessageSystem,
|
|
808
|
+
props.MessageTimestamp,
|
|
809
|
+
props.ModalGallery,
|
|
810
|
+
props.PinIndicator,
|
|
811
|
+
props.QuotedMessage,
|
|
812
|
+
props.QuotedMessagePreview,
|
|
813
|
+
props.ReactionSelector,
|
|
814
|
+
props.ReactionsList,
|
|
815
|
+
props.SendButton,
|
|
816
|
+
props.StartRecordingAudioButton,
|
|
817
|
+
props.ThreadHead,
|
|
818
|
+
props.ThreadHeader,
|
|
819
|
+
props.ThreadStart,
|
|
820
|
+
props.Timestamp,
|
|
821
|
+
props.TriggerProvider,
|
|
822
|
+
props.TypingIndicator,
|
|
823
|
+
props.UnreadMessagesNotification,
|
|
824
|
+
props.UnreadMessagesSeparator,
|
|
825
|
+
props.VirtualMessage,
|
|
826
|
+
props.emojiSearchIndex,
|
|
827
|
+
props.reactionOptions,
|
|
828
|
+
]);
|
|
777
829
|
const typingContextValue = useCreateTypingContext({
|
|
778
830
|
typing,
|
|
779
831
|
});
|
|
@@ -793,7 +845,7 @@ const ChannelInner = (props) => {
|
|
|
793
845
|
return (React.createElement("div", { className: clsx(className, windowsEmojiClass) },
|
|
794
846
|
React.createElement(ChannelStateProvider, { value: channelStateContextValue },
|
|
795
847
|
React.createElement(ChannelActionProvider, { value: channelActionContextValue },
|
|
796
|
-
React.createElement(
|
|
848
|
+
React.createElement(WithComponents, { overrides: componentContextValue },
|
|
797
849
|
React.createElement(TypingProvider, { value: typingContextValue },
|
|
798
850
|
React.createElement("div", { className: `${chatContainerClass}` },
|
|
799
851
|
dragAndDropWindow && (React.createElement(DropzoneProvider, { ...optionalMessageInputProps }, children)),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import { isDate, isDayOrMoment } from '../../../
|
|
2
|
+
import { isDate, isDayOrMoment } from '../../../i18n';
|
|
3
3
|
export const useCreateChannelStateContext = (value) => {
|
|
4
4
|
const { acceptedFiles, channel, channelCapabilitiesArray = [], channelConfig, debounceURLEnrichmentMs, dragAndDropWindow, enrichURLForPreview, giphyVersion, error, findURLFn, hasMore, hasMoreNewer, imageAttachmentSizeHandler, suppressAutoscroll, highlightedMessageId, loading, loadingMore, maxNumberOfFiles, members, messages = [], multipleUploads, mutes, notifications, onLinkPreviewDismissed, pinnedMessages, quotedMessage, read = {}, shouldGenerateVideoThumbnail, skipMessageDataMemoization, thread, threadHasMore, threadLoadingMore, threadMessages = [], channelUnreadUiState, videoAttachmentSizeHandler, watcherCount, watcher_count, watchers, } = value;
|
|
5
5
|
const channelId = channel.cid;
|
|
@@ -67,6 +67,7 @@ export const useCreateChannelStateContext = (value) => {
|
|
|
67
67
|
}),
|
|
68
68
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
69
69
|
[
|
|
70
|
+
channel.data?.name, // otherwise ChannelHeader will not be updated
|
|
70
71
|
channelId,
|
|
71
72
|
channelUnreadUiState,
|
|
72
73
|
debounceURLEnrichmentMs,
|
|
@@ -5,7 +5,10 @@ import { useChannelPreviewInfo } from '../ChannelPreview/hooks/useChannelPreview
|
|
|
5
5
|
import { useChannelStateContext } from '../../context/ChannelStateContext';
|
|
6
6
|
import { useChatContext } from '../../context/ChatContext';
|
|
7
7
|
import { useTranslationContext } from '../../context/TranslationContext';
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The ChannelHeader component renders some basic information about a Channel.
|
|
10
|
+
*/
|
|
11
|
+
export const ChannelHeader = (props) => {
|
|
9
12
|
const { Avatar = DefaultAvatar, MenuIcon = DefaultMenuIcon, image: overrideImage, live, title: overrideTitle, } = props;
|
|
10
13
|
const { channel, watcher_count } = useChannelStateContext('ChannelHeader');
|
|
11
14
|
const { openMobileNav } = useChatContext('ChannelHeader');
|
|
@@ -35,7 +38,3 @@ const UnMemoizedChannelHeader = (props) => {
|
|
|
35
38
|
' ')),
|
|
36
39
|
t('{{ watcherCount }} online', { watcherCount: watcher_count })))));
|
|
37
40
|
};
|
|
38
|
-
/**
|
|
39
|
-
* The ChannelHeader component renders some basic information about a Channel.
|
|
40
|
-
*/
|
|
41
|
-
export const ChannelHeader = React.memo(UnMemoizedChannelHeader);
|
|
@@ -3,26 +3,24 @@ import { getDisplayImage, getDisplayTitle } from '../utils';
|
|
|
3
3
|
import { useChatContext } from '../../../context';
|
|
4
4
|
export const useChannelPreviewInfo = (props) => {
|
|
5
5
|
const { channel, overrideImage, overrideTitle } = props;
|
|
6
|
-
const { client } = useChatContext('
|
|
7
|
-
const [displayTitle, setDisplayTitle] = useState(getDisplayTitle(channel, client.user));
|
|
8
|
-
const [displayImage, setDisplayImage] = useState(getDisplayImage(channel, client.user));
|
|
6
|
+
const { client } = useChatContext('useChannelPreviewInfo');
|
|
7
|
+
const [displayTitle, setDisplayTitle] = useState(() => overrideTitle || getDisplayTitle(channel, client.user));
|
|
8
|
+
const [displayImage, setDisplayImage] = useState(() => overrideImage || getDisplayImage(channel, client.user));
|
|
9
9
|
useEffect(() => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return displayImage !== newDisplayImage ? newDisplayImage : displayImage;
|
|
18
|
-
});
|
|
10
|
+
if (overrideTitle && overrideImage)
|
|
11
|
+
return;
|
|
12
|
+
const updateTitles = () => {
|
|
13
|
+
if (!overrideTitle)
|
|
14
|
+
setDisplayTitle(getDisplayTitle(channel, client.user));
|
|
15
|
+
if (!overrideImage)
|
|
16
|
+
setDisplayImage(getDisplayImage(channel, client.user));
|
|
19
17
|
};
|
|
20
|
-
|
|
18
|
+
updateTitles();
|
|
19
|
+
client.on('user.updated', updateTitles);
|
|
21
20
|
return () => {
|
|
22
|
-
client.off('user.updated',
|
|
21
|
+
client.off('user.updated', updateTitles);
|
|
23
22
|
};
|
|
24
|
-
|
|
25
|
-
}, []);
|
|
23
|
+
}, [channel, channel.data, client, overrideImage, overrideTitle]);
|
|
26
24
|
return {
|
|
27
25
|
displayImage: overrideImage || displayImage,
|
|
28
26
|
displayTitle: overrideTitle || displayTitle,
|
|
@@ -23,25 +23,14 @@ export const getLatestMessagePreview = (channel, t, userLanguage = 'en') => {
|
|
|
23
23
|
}
|
|
24
24
|
return t('Empty message...');
|
|
25
25
|
};
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const getChannelDisplayInfo = (info, channel, currentUser) => {
|
|
27
|
+
if (channel.data?.[info])
|
|
28
|
+
return channel.data[info];
|
|
28
29
|
const members = Object.values(channel.state.members);
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return title;
|
|
36
|
-
};
|
|
37
|
-
export const getDisplayImage = (channel, currentUser) => {
|
|
38
|
-
let image = channel.data?.image;
|
|
39
|
-
const members = Object.values(channel.state.members);
|
|
40
|
-
if (!image && members.length === 2) {
|
|
41
|
-
const otherMember = members.find((member) => member.user?.id !== currentUser?.id);
|
|
42
|
-
if (otherMember?.user?.image) {
|
|
43
|
-
image = otherMember.user.image;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return image;
|
|
30
|
+
if (members.length !== 2)
|
|
31
|
+
return;
|
|
32
|
+
const otherMember = members.find((member) => member.user?.id !== currentUser?.id);
|
|
33
|
+
return otherMember?.user?.[info];
|
|
47
34
|
};
|
|
35
|
+
export const getDisplayTitle = (channel, currentUser) => getChannelDisplayInfo('name', channel, currentUser);
|
|
36
|
+
export const getDisplayImage = (channel, currentUser) => getChannelDisplayInfo('image', channel, currentUser);
|
|
@@ -97,13 +97,12 @@ export const useChannelSearch = ({ channelType = 'messaging', clearSearchOnClick
|
|
|
97
97
|
// @ts-expect-error
|
|
98
98
|
{
|
|
99
99
|
$or: [{ id: { $autocomplete: text } }, { name: { $autocomplete: text } }],
|
|
100
|
-
id: { $ne: client.userID },
|
|
101
100
|
...searchQueryParams?.userFilters?.filters,
|
|
102
101
|
}, { id: 1, ...searchQueryParams?.userFilters?.sort }, { limit: 8, ...searchQueryParams?.userFilters?.options });
|
|
103
102
|
if (!searchForChannels) {
|
|
104
103
|
searchQueryPromiseInProgress.current = userQueryPromise;
|
|
105
104
|
const { users } = await searchQueryPromiseInProgress.current;
|
|
106
|
-
results = users;
|
|
105
|
+
results = users.filter((u) => u.id !== client.user?.id);
|
|
107
106
|
}
|
|
108
107
|
else {
|
|
109
108
|
const channelQueryPromise = client.queryChannels(
|
|
@@ -117,7 +116,7 @@ export const useChannelSearch = ({ channelType = 'messaging', clearSearchOnClick
|
|
|
117
116
|
userQueryPromise,
|
|
118
117
|
]);
|
|
119
118
|
const [channels, { users }] = await searchQueryPromiseInProgress.current;
|
|
120
|
-
results = [...channels, ...users];
|
|
119
|
+
results = [...channels, ...users.filter((u) => u.id !== client.user?.id)];
|
|
121
120
|
}
|
|
122
121
|
}
|
|
123
122
|
catch (error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from 'react';
|
|
2
2
|
import { CustomClasses } from '../../context/ChatContext';
|
|
3
|
-
import { SupportedTranslations } from '../../context/TranslationContext';
|
|
4
3
|
import type { StreamChat } from 'stream-chat';
|
|
4
|
+
import type { SupportedTranslations } from '../../i18n/types';
|
|
5
5
|
import type { Streami18n } from '../../i18n/Streami18n';
|
|
6
6
|
import type { DefaultStreamChatGenerics } from '../../types/types';
|
|
7
7
|
export type ChatProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Streami18n } from '../../../i18n';
|
|
1
|
+
import { TranslationContextValue } from '../../../context/TranslationContext';
|
|
2
|
+
import { Streami18n, SupportedTranslations } from '../../../i18n';
|
|
3
3
|
import type { AppSettingsAPIResponse, Channel, Mute, StreamChat } from 'stream-chat';
|
|
4
4
|
import type { DefaultStreamChatGenerics } from '../../../types/types';
|
|
5
5
|
export type UseChatParams<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { defaultDateTimeParser, isLanguageSupported, } from '../../../
|
|
3
|
-
import { Streami18n } from '../../../i18n';
|
|
2
|
+
import { defaultDateTimeParser, isLanguageSupported, Streami18n, } from '../../../i18n';
|
|
4
3
|
import { version } from '../../../version';
|
|
5
4
|
export const useChat = ({ client, defaultLanguage = 'en', i18nInstance, initialNavOpen, }) => {
|
|
6
5
|
const [translators, setTranslators] = useState({
|
|
@@ -24,13 +23,17 @@ export const useChat = ({ client, defaultLanguage = 'en', i18nInstance, initialN
|
|
|
24
23
|
return appSettings.current;
|
|
25
24
|
};
|
|
26
25
|
useEffect(() => {
|
|
27
|
-
if (client)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
26
|
+
if (!client)
|
|
27
|
+
return;
|
|
28
|
+
const userAgent = client.getUserAgent();
|
|
29
|
+
if (!userAgent.includes('stream-chat-react')) {
|
|
30
|
+
// result looks like: 'stream-chat-react-2.3.2-stream-chat-javascript-client-browser-2.2.2'
|
|
31
|
+
client.setUserAgent(`stream-chat-react-${version}-${userAgent}`);
|
|
33
32
|
}
|
|
33
|
+
client.threads.registerSubscriptions();
|
|
34
|
+
return () => {
|
|
35
|
+
client.threads.unregisterSubscriptions();
|
|
36
|
+
};
|
|
34
37
|
}, [client]);
|
|
35
38
|
useEffect(() => {
|
|
36
39
|
setMutes(clientMutes);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { PropsWithChildren } from 'react';
|
|
3
|
+
import type { Thread } from 'stream-chat';
|
|
4
|
+
export declare const ChatView: {
|
|
5
|
+
({ children }: PropsWithChildren): React.JSX.Element;
|
|
6
|
+
Channels: ({ children }: PropsWithChildren) => React.JSX.Element | null;
|
|
7
|
+
Threads: ({ children }: PropsWithChildren) => React.JSX.Element | null;
|
|
8
|
+
ThreadAdapter: ({ children }: PropsWithChildren) => React.JSX.Element;
|
|
9
|
+
Selector: () => React.JSX.Element;
|
|
10
|
+
};
|
|
11
|
+
export type ThreadsViewContextValue = {
|
|
12
|
+
activeThread: Thread | undefined;
|
|
13
|
+
setActiveThread: (cv: ThreadsViewContextValue['activeThread']) => void;
|
|
14
|
+
};
|
|
15
|
+
export declare const useThreadsViewContext: () => ThreadsViewContextValue;
|
|
16
|
+
export declare const useActiveThread: ({ activeThread }: {
|
|
17
|
+
activeThread?: Thread;
|
|
18
|
+
}) => void;
|