stream-chat-react 13.13.5 → 13.14.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 +2 -6
- package/dist/components/ChannelList/ChannelList.js +2 -3
- package/dist/components/ChannelList/hooks/usePaginatedChannels.js +1 -5
- package/dist/components/ChannelList/utils.d.ts +0 -1
- package/dist/components/ChannelList/utils.js +0 -1
- package/dist/components/Chat/hooks/useChat.js +1 -1
- package/dist/constants/limits.d.ts +3 -5
- package/dist/constants/limits.js +3 -5
- package/dist/experimental/index.browser.cjs +6 -5
- package/dist/experimental/index.browser.cjs.map +3 -3
- package/dist/experimental/index.node.cjs +6 -5
- package/dist/experimental/index.node.cjs.map +3 -3
- package/dist/i18n/utils.js +4 -2
- package/dist/index.browser.cjs +101 -112
- package/dist/index.browser.cjs.map +4 -4
- package/dist/index.node.cjs +101 -113
- package/dist/index.node.cjs.map +4 -4
- package/dist/plugins/Emojis/index.browser.cjs.map +2 -2
- package/dist/plugins/Emojis/index.node.cjs.map +2 -2
- package/package.json +1 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/Emojis/index.ts", "../../../src/plugins/Emojis/EmojiPicker.tsx", "../../../src/plugins/Emojis/icons.tsx", "../../../src/context/ChannelStateContext.tsx", "../../../src/context/ChatContext.tsx", "../../../src/context/MessageContext.tsx", "../../../src/context/TranslationContext.tsx", "../../../src/i18n/utils.ts", "../../../src/components/MessageInput/hooks/useMessageComposer.ts", "../../../src/components/Threads/ThreadContext.tsx", "../../../src/components/Dialog/hooks/usePopoverPosition.ts", "../../../src/components/Thread/LegacyThreadContext.ts", "../../../src/context/MessageInputContext.tsx", "../../../src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts"],
|
|
4
|
-
"sourcesContent": ["export * from './EmojiPicker';\nexport * from './middleware';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport Picker from '@emoji-mart/react';\n\nimport { EmojiPickerIcon } from './icons';\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { useMessageComposer } from '../../components';\nimport type { PopperLikePlacement } from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n /**\n * Deprecated: Popper options, use `placement` instead.\n */\n popperOptions?: Partial<{ placement: PopperLikePlacement }>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageInputContext('EmojiPicker');\n const { textComposer } = useMessageComposer();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n", "import type { PropsWithChildren } from 'react';\nimport React, { useContext } from 'react';\nimport type {\n Channel,\n ChannelConfigWithInfo,\n LocalMessage,\n Mute,\n ChannelState as StreamChannelState,\n} from 'stream-chat';\n\nimport type {\n ChannelUnreadUiState,\n GiphyVersions,\n ImageAttachmentSizeHandler,\n UnknownType,\n VideoAttachmentSizeHandler,\n} from '../types/types';\n\nexport type ChannelNotifications = Array<{\n id: string;\n text: string;\n type: 'success' | 'error';\n}>;\n\nexport type ChannelState = {\n suppressAutoscroll: boolean;\n error?: Error | null;\n hasMore?: boolean;\n hasMoreNewer?: boolean;\n highlightedMessageId?: string;\n loading?: boolean;\n loadingMore?: boolean;\n loadingMoreNewer?: boolean;\n members?: StreamChannelState['members'];\n messages?: LocalMessage[];\n pinnedMessages?: LocalMessage[];\n read?: StreamChannelState['read'];\n thread?: LocalMessage | null;\n threadHasMore?: boolean;\n threadLoadingMore?: boolean;\n threadMessages?: LocalMessage[];\n threadSuppressAutoscroll?: boolean;\n typing?: StreamChannelState['typing'];\n watcherCount?: number;\n watchers?: StreamChannelState['watchers'];\n};\n\nexport type ChannelStateContextValue = Omit<ChannelState, 'typing'> & {\n channel: Channel;\n channelCapabilities: Record<string, boolean>;\n channelConfig: ChannelConfigWithInfo | undefined;\n imageAttachmentSizeHandler: ImageAttachmentSizeHandler;\n notifications: ChannelNotifications;\n shouldGenerateVideoThumbnail: boolean;\n videoAttachmentSizeHandler: VideoAttachmentSizeHandler;\n channelUnreadUiState?: ChannelUnreadUiState;\n giphyVersion?: GiphyVersions;\n mutes?: Array<Mute>;\n watcher_count?: number;\n};\n\nexport const ChannelStateContext = React.createContext<\n ChannelStateContextValue | undefined\n>(undefined);\n\nexport const ChannelStateProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelStateContextValue;\n}>) => (\n <ChannelStateContext.Provider value={value as unknown as ChannelStateContextValue}>\n {children}\n </ChannelStateContext.Provider>\n);\n\nexport const useChannelStateContext = (componentName?: string) => {\n const contextValue = useContext(ChannelStateContext);\n\n if (!contextValue) {\n console.warn(\n `The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChannelStateContextValue;\n }\n\n return contextValue as unknown as ChannelStateContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if ChannelStateContext\n * typing is desired while using the HOC withChannelStateContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChannelStateContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChannelStateContextComponent = (\n props: Omit<P, keyof ChannelStateContextValue>,\n ) => {\n const channelStateContext = useChannelStateContext();\n\n return <Component {...(props as P)} {...channelStateContext} />;\n };\n\n WithChannelStateContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithChannelStateContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\nimport type {\n AppSettingsAPIResponse,\n Channel,\n Mute,\n SearchController,\n} from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport type { ChatProps } from '../components/Chat/Chat';\nimport type { UnknownType } from '../types/types';\nimport type { ChannelsQueryState } from '../components/Chat/hooks/useChannelsQueryState';\n\ntype CSSClasses =\n | 'chat'\n | 'chatContainer'\n | 'channel'\n | 'channelList'\n | 'message'\n | 'messageList'\n | 'thread'\n | 'threadList'\n | 'virtualMessage'\n | 'virtualizedMessageList';\n\nexport type CustomClasses = Partial<Record<CSSClasses, string>>;\n\ntype ChannelConfId = string; // e.g.: \"messaging:general\"\n\nexport type ChatContextValue = {\n /**\n * Indicates, whether a channels query has been triggered within ChannelList by its channels pagination controller.\n */\n channelsQueryState: ChannelsQueryState;\n closeMobileNav: () => void;\n getAppSettings: () => Promise<AppSettingsAPIResponse> | null;\n latestMessageDatesByChannels: Record<ChannelConfId, Date>;\n mutes: Array<Mute>;\n openMobileNav: () => void;\n /** Instance of SearchController class that allows to control all the search operations. */\n searchController: SearchController;\n /**\n * Sets active channel to be rendered within Channel component.\n * @param newChannel\n * @param watchers\n * @param event\n */\n setActiveChannel: (\n newChannel?: Channel,\n watchers?: { limit?: number; offset?: number },\n event?: React.BaseSyntheticEvent,\n ) => void;\n useImageFlagEmojisOnWindows: boolean;\n /**\n * Active channel used to render the contents of the Channel component.\n */\n channel?: Channel;\n /**\n * Object through which custom classes can be set for main container components of the SDK.\n */\n customClasses?: CustomClasses;\n navOpen?: boolean;\n} & Partial<Pick<ChatProps, 'isMessageAIGenerated'>> &\n Required<Pick<ChatProps, 'theme' | 'client'>>;\n\nexport const ChatContext = React.createContext<ChatContextValue | undefined>(undefined);\n\nexport const ChatProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChatContextValue;\n}>) => (\n <ChatContext.Provider value={value as unknown as ChatContextValue}>\n {children}\n </ChatContext.Provider>\n);\n\nexport const useChatContext = (componentName?: string) => {\n const contextValue = useContext(ChatContext);\n\n if (!contextValue) {\n console.warn(\n `The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChatContextValue;\n }\n\n return contextValue as unknown as ChatContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference so if ChatContext\n * typing is desired while using the HOC withChatContext the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChatContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChatContextComponent = (props: Omit<P, keyof ChatContextValue>) => {\n const chatContext = useChatContext();\n\n return <Component {...(props as P)} {...chatContext} />;\n };\n WithChatContextComponent.displayName = `WithChatContext${getDisplayName(Component)}`;\n return WithChatContextComponent;\n};\n", "import type { BaseSyntheticEvent, PropsWithChildren, ReactNode } from 'react';\nimport React, { useContext } from 'react';\n\nimport type {\n DeleteMessageOptions,\n LocalMessage,\n Mute,\n ReactionResponse,\n ReactionSort,\n UserResponse,\n} from 'stream-chat';\n\nimport type { ChannelActionContextValue } from './ChannelActionContext';\n\nimport type { ActionHandlerReturnType } from '../components/Message/hooks/useActionHandler';\nimport type { PinPermissions } from '../components/Message/hooks/usePinHandler';\nimport type { ReactEventHandler } from '../components/Message/types';\nimport type { MessageActionsArray } from '../components/Message/utils';\nimport type { MessageInputProps } from '../components/MessageInput/MessageInput';\nimport type { GroupStyle } from '../components/MessageList/utils';\nimport type {\n ReactionDetailsComparator,\n ReactionsComparator,\n ReactionType,\n} from '../components/Reactions/types';\n\nimport type { RenderTextOptions } from '../components/Message/renderText';\nimport type { UnknownType } from '../types/types';\n\nexport type CustomMessageActions = {\n [key: string]: (\n message: LocalMessage,\n event: React.BaseSyntheticEvent,\n ) => Promise<void> | void;\n};\n\nexport type MessageContextValue = {\n /** If actions such as edit, delete, flag, mute are enabled on Message */\n actionsEnabled: boolean;\n /** Function to exit edit state */\n clearEditingState: (event?: React.BaseSyntheticEvent) => void;\n /** If the Message is in edit state */\n editing: boolean;\n /**\n * Returns all allowed actions on message by current user e.g., ['edit', 'delete', 'flag', 'mute', 'pin', 'quote', 'react', 'reply'].\n * Please check [Message](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message.tsx) component for default implementation.\n */\n getMessageActions: () => MessageActionsArray<string>;\n /** Function to send an action in a Channel */\n handleAction: ActionHandlerReturnType;\n /** Function to delete a message in a Channel */\n handleDelete: (\n event: BaseSyntheticEvent,\n options?: DeleteMessageOptions,\n ) => Promise<void> | void;\n /** Function to edit a message in a Channel */\n handleEdit: ReactEventHandler;\n /** Function to fetch the message reactions */\n handleFetchReactions: (\n reactionType?: ReactionType,\n sort?: ReactionSort,\n ) => Promise<Array<ReactionResponse>>;\n /** Function to flag a message in a Channel */\n handleFlag: ReactEventHandler;\n /** Function to mark message and the messages that follow it as unread in a Channel */\n handleMarkUnread: ReactEventHandler;\n /** Function to mute a user in a Channel */\n handleMute: ReactEventHandler;\n /** Function to open a Thread on a Message */\n handleOpenThread: ReactEventHandler;\n /** Function to pin a Message in a Channel */\n handlePin: ReactEventHandler;\n /** Function to post a reaction on a Message */\n handleReaction: (\n reactionType: string,\n event: React.BaseSyntheticEvent,\n ) => Promise<void>;\n /** Function to retry sending a Message */\n handleRetry: ChannelActionContextValue['retrySendMessage'];\n /** Function that returns whether the Message belongs to the current user */\n isMyMessage: () => boolean;\n /** The message object */\n message: LocalMessage;\n /** Indicates whether a message has not been read yet or has been marked unread */\n messageIsUnread: boolean;\n /** Handler function for a click event on an @mention in Message */\n onMentionsClickMessage: ReactEventHandler;\n /** Handler function for a hover event on an @mention in Message */\n onMentionsHoverMessage: ReactEventHandler;\n /** Handler function for a click event on the user that posted the Message */\n onUserClick: ReactEventHandler;\n /** Handler function for a hover event on the user that posted the Message */\n onUserHover: ReactEventHandler;\n /** Function to toggle the edit state on a Message */\n setEditingState: ReactEventHandler;\n /** Additional props for underlying MessageInput component, [available props](https://getstream.io/chat/docs/sdk/react/message-input-components/message_input/#props) */\n additionalMessageInputProps?: MessageInputProps;\n /** Call this function to keep message list scrolled to the bottom when the scroll height increases, e.g. an element appears below the last message (only used in the `VirtualizedMessageList`) */\n autoscrollToBottom?: () => void;\n /** Message component configuration prop. If true, picking a reaction from the `ReactionSelector` component will close the selector */\n closeReactionSelectorOnClick?: boolean;\n /** Object containing custom message actions and function handlers */\n customMessageActions?: CustomMessageActions;\n /** An array of user IDs that have confirmed the message delivery to their device */\n deliveredTo?: UserResponse[];\n /** If true, the message is the last one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n endOfGroup?: boolean;\n /** If true, the message is the first one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n firstOfGroup?: boolean;\n /** Override the default formatting of the date. This is a function that has access to the original date object, returns a string */\n formatDate?: (date: Date) => string;\n /** If true, group messages sent by each user (only used in the `VirtualizedMessageList`) */\n groupedByUser?: boolean;\n /** A list of styles to apply to this message, ie. top, bottom, single */\n groupStyles?: GroupStyle[];\n /** Whether to highlight and focus the message on load */\n highlighted?: boolean;\n /** Whether the threaded message is the first in the thread list */\n initialMessage?: boolean;\n /**\n * A factory function that determines whether a message is AI generated or not.\n */\n isMessageAIGenerated?: (message: LocalMessage) => boolean;\n /** Latest own message in currently displayed message set. */\n lastOwnMessage?: LocalMessage;\n /** Latest message id on current channel */\n lastReceivedId?: string | null;\n /** DOMRect object for parent MessageList component */\n messageListRect?: DOMRect;\n /** Array of muted users coming from [ChannelStateContext](https://getstream.io/chat/docs/sdk/react/contexts/channel_state_context/#mutes) */\n mutes?: Mute[];\n /** @deprecated in favor of `channelCapabilities - The user roles allowed to pin Messages in various channel types */\n pinPermissions?: PinPermissions;\n /** Sort options to provide to a reactions query */\n reactionDetailsSort?: ReactionSort;\n /** A list of users that have read this Message */\n readBy?: UserResponse[];\n /** Custom function to render message text content, defaults to the renderText function: [utils](https://github.com/GetStream/stream-chat-react/blob/master/src/utils.tsx) */\n renderText?: (\n text?: string,\n mentioned_users?: UserResponse[],\n options?: RenderTextOptions,\n ) => ReactNode;\n /** Keep track of read receipts for each message sent by the user. When disabled, only the last own message delivery / read status is rendered. */\n returnAllReadData?: boolean;\n /** Comparator function to sort the list of reacted users\n * @deprecated use `reactionDetailsSort` instead\n */\n sortReactionDetails?: ReactionDetailsComparator;\n /** Comparator function to sort reactions, defaults to chronological order */\n sortReactions?: ReactionsComparator;\n /** Whether or not the Message is in a Thread */\n threadList?: boolean;\n /** render HTML instead of markdown. Posting HTML is only allowed server-side */\n unsafeHTML?: boolean;\n};\n\nexport const MessageContext = React.createContext<MessageContextValue | undefined>(\n undefined,\n);\n\nexport const MessageProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageContextValue;\n}>) => (\n <MessageContext.Provider value={value as unknown as MessageContextValue}>\n {children}\n </MessageContext.Provider>\n);\n\nexport const useMessageContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _componentName?: string,\n) => {\n const contextValue = useContext(MessageContext);\n\n if (!contextValue) {\n return {} as MessageContextValue;\n }\n\n return contextValue as unknown as MessageContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if MessageContext\n * typing is desired while using the HOC withMessageContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withMessageContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithMessageContextComponent = (props: Omit<P, keyof MessageContextValue>) => {\n const messageContext = useMessageContext();\n\n return <Component {...(props as P)} {...messageContext} />;\n };\n\n WithMessageContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithMessageContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport type { PropsWithChildren } from 'react';\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs, { isDayjs } from 'dayjs';\nimport type { Duration as DayjsDuration } from 'dayjs/plugin/duration';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n DurationFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: unknown): output is Date =>\n output !== null &&\n typeof output === 'object' &&\n typeof (output as Date).getTime === 'function';\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n durationFormatter:\n (streamI18n) =>\n (value, _, { format, withSuffix }: DurationFormatterOptions) => {\n if (format && isDayjs(streamI18n.DateTimeParser)) {\n return (streamI18n.DateTimeParser.duration(value) as DayjsDuration).format(\n format,\n );\n }\n return streamI18n.DateTimeParser.duration(value).humanize(!!withSuffix);\n },\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction = ((key: string) => key) as TFunction;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import { useEffect, useMemo } from 'react';\nimport { FixedSizeQueueCache, MessageComposer } from 'stream-chat';\nimport { useThreadContext } from '../../Threads';\nimport {\n useChannelStateContext,\n useChatContext,\n useMessageContext,\n} from '../../../context';\nimport { useLegacyThreadContext } from '../../Thread';\n\nconst queueCache = new FixedSizeQueueCache<string, MessageComposer>(64);\n\nexport const useMessageComposer = () => {\n const { client } = useChatContext();\n const { channel } = useChannelStateContext();\n const { editing, message: editedMessage } = useMessageContext();\n // legacy thread will receive new composer\n const { legacyThread: parentMessage } = useLegacyThreadContext();\n const threadInstance = useThreadContext();\n\n const cachedEditedMessage = useMemo(() => {\n if (!editedMessage) return undefined;\n\n return editedMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editedMessage?.id]);\n\n const cachedParentMessage = useMemo(() => {\n if (!parentMessage) return undefined;\n\n return parentMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [parentMessage?.id]);\n\n // composer hierarchy\n // edited message (always new) -> thread instance (own) -> thread message (always new) -> channel (own)\n // editedMessage ?? thread ?? parentMessage ?? channel;\n const messageComposer = useMemo(() => {\n if (editing && cachedEditedMessage) {\n const tag = MessageComposer.constructTag(cachedEditedMessage);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) {\n cachedComposer.editedMessage = cachedEditedMessage;\n return cachedComposer;\n }\n\n return new MessageComposer({\n client,\n composition: cachedEditedMessage,\n compositionContext: cachedEditedMessage,\n });\n } else if (threadInstance) {\n return threadInstance.messageComposer;\n } else if (cachedParentMessage) {\n const compositionContext = {\n ...cachedParentMessage,\n legacyThreadId: cachedParentMessage.id,\n };\n\n const tag = MessageComposer.constructTag(compositionContext);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) return cachedComposer;\n\n return new MessageComposer({\n client,\n compositionContext,\n });\n } else {\n return channel.messageComposer;\n }\n }, [\n cachedEditedMessage,\n cachedParentMessage,\n channel,\n client,\n editing,\n threadInstance,\n ]);\n\n if (\n (['legacy_thread', 'message'] as MessageComposer['contextType'][]).includes(\n messageComposer.contextType,\n ) &&\n !queueCache.peek(messageComposer.tag)\n ) {\n queueCache.add(messageComposer.tag, messageComposer);\n }\n\n useEffect(() => {\n const unsubscribe = messageComposer.registerSubscriptions();\n return () => {\n unsubscribe();\n };\n }, [messageComposer]);\n\n return messageComposer;\n};\n", "import React, { createContext, useContext } from 'react';\n\nimport { Channel } from '../../components';\n\nimport type { PropsWithChildren } from 'react';\nimport type { Thread } from 'stream-chat';\n\nexport type ThreadContextValue = Thread | undefined;\n\nexport const ThreadContext = createContext<ThreadContextValue>(undefined);\n\nexport const useThreadContext = () => useContext(ThreadContext);\n\nexport const ThreadProvider = ({\n children,\n thread,\n}: PropsWithChildren<{ thread?: Thread }>) => (\n <ThreadContext.Provider value={thread}>\n <Channel channel={thread?.channel}>{children}</Channel>\n </ThreadContext.Provider>\n);\n", "import {\n autoPlacement,\n autoUpdate,\n flip as flipMw,\n offset as offsetMw,\n type Placement,\n shift as shiftMw,\n size as sizeMw,\n useFloating,\n} from '@floating-ui/react';\nimport type { AutoPlacementOptions } from '@floating-ui/core';\n\nconst hasResizeObserver = typeof window !== 'undefined' && 'ResizeObserver' in window;\n\nexport type PopperLikePlacement = Placement | 'auto' | 'auto-start' | 'auto-end';\n\nfunction autoMiddlewareFor(p: PopperLikePlacement) {\n if (!String(p).startsWith('auto')) return null;\n const alignment: AutoPlacementOptions['alignment'] =\n p === 'auto-start' ? 'start' : p === 'auto-end' ? 'end' : undefined;\n return autoPlacement({ alignment });\n}\n\ntype OffsetOpt =\n | number\n | { mainAxis?: number; crossAxis?: number; alignmentAxis?: number }\n | [crossAxis: number, mainAxis: number]; // keep your tuple compat\n\nfunction toOffsetMw(opt?: OffsetOpt) {\n if (opt == null) return null;\n if (Array.isArray(opt)) {\n const [crossAxis, mainAxis] = opt;\n return offsetMw({ crossAxis, mainAxis });\n }\n if (typeof opt === 'number') return offsetMw(opt);\n return offsetMw(opt);\n}\n\nexport type UsePopoverParams = {\n placement?: PopperLikePlacement;\n /** Add flip() when placement is not 'auto*' */\n allowFlip?: boolean;\n /** Keep in viewport; default true to match common popper setups */\n allowShift?: boolean;\n /** The floating UI is fitted to the available space (by constraining its max size) instead of letting it overflow; default false */\n fitAvailableSpace?: boolean;\n /** Offset (number, object, or [crossAxis, mainAxis] tuple) */\n offset?: OffsetOpt;\n /**\n * Freeze behavior like Popper's eventListeners: { scroll:false, resize:false }.\n * If true \u2192 no autoUpdate (you can call `update()` manually).\n */\n freeze?: boolean;\n /**\n * Fine-grained control of autoUpdate triggers (only if freeze=false).\n * Defaults match Popper's \"disabled\" example when all set to false.\n */\n autoUpdateOptions?: Partial<Parameters<typeof autoUpdate>[3]>;\n};\n\nexport function usePopoverPosition({\n allowFlip = true,\n allowShift = true,\n autoUpdateOptions,\n fitAvailableSpace = false,\n freeze = false,\n offset,\n placement = 'bottom-start',\n}: UsePopoverParams) {\n const autoMw = autoMiddlewareFor(placement);\n const offsetMiddleware = toOffsetMw(offset);\n const isSidePlacement = placement.startsWith('left') || placement.startsWith('right');\n\n const middleware = [\n // offset first (mirrors common Popper setups)\n ...(offsetMiddleware ? [offsetMiddleware] : []),\n\n // choose between autoPlacement (Popper's \"auto*\") OR flip()\n // only allow flip when not explicitly 'left*' or 'right*'\n ...(autoMw ? [autoMw] : allowFlip && !isSidePlacement ? [flipMw()] : []),\n\n // viewport collision adjustments\n ...(allowShift ? [shiftMw({ padding: 8 })] : []),\n\n // optional size constraining\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n ...(fitAvailableSpace ? [sizeMw({ apply: () => {} })] : []),\n ];\n\n // if placement is 'auto*', seed with any static placement; autoPlacement will pick the final one\n const seedPlacement: Placement = String(placement).startsWith('auto')\n ? 'bottom'\n : (placement as Placement);\n\n return useFloating({\n middleware,\n placement: seedPlacement,\n strategy: 'fixed',\n whileElementsMounted: freeze\n ? undefined\n : (reference, floating, update) =>\n autoUpdate(reference, floating, update, {\n ancestorResize: true,\n ancestorScroll: true,\n animationFrame: false,\n elementResize: hasResizeObserver,\n ...autoUpdateOptions,\n }),\n });\n}\n", "import React, { useContext } from 'react';\nimport type { LocalMessage } from 'stream-chat';\n\nexport const LegacyThreadContext = React.createContext<{\n legacyThread: LocalMessage | undefined;\n}>({ legacyThread: undefined });\n\nexport const useLegacyThreadContext = () => useContext(LegacyThreadContext);\n", "import React, { createContext, useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type { MessageInputHookProps } from '../components/MessageInput/hooks/useMessageInputControls';\n\nexport type MessageInputContextValue = MessageInputHookProps &\n Omit<MessageInputProps, 'Input'> &\n CooldownTimerState;\n\nexport const MessageInputContext = createContext<MessageInputHookProps | undefined>(\n undefined,\n);\n\nexport const MessageInputContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue;\n}>) => (\n <MessageInputContext.Provider value={value as unknown as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n return {} as MessageInputContextValue;\n }\n\n return contextValue as unknown as MessageInputContextValue;\n};\n", "import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageInput';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAA2C;AAC3C,IAAAA,iBAAmB;;;ACDnB,mBAAkB;AAEX,IAAM,kBAAkB,MAC7B,6BAAAC,QAAA;AAAA,EAAC;AAAA;AAAA,IACC,qBAAoB;AAAA,IACpB,SAAQ;AAAA,IACR,OAAM;AAAA,IACN,OAAM;AAAA;AAAA,EAEN,6BAAAA,QAAA,cAAC,OAAE,UAAS,WAAU,UAAS,aAC7B,6BAAAA,QAAA,cAAC,UAAK,GAAE,0dAAyd,CACne;AACF;;;ACXF,IAAAC,gBAAkC;AA4D3B,IAAM,sBAAsB,cAAAC,QAAM,cAEvC,MAAS;AAaJ,IAAM,yBAAyB,CAAC,kBAA2B;AAChE,QAAM,mBAAe,0BAAW,mBAAmB;AAEnD,MAAI,CAAC,cAAc;AACjB,YAAQ;AAAA,MACN,qMAAqM,aAAa;AAAA,IACpN;AAEA,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;;;ACxFA,IAAAC,gBAAkC;AAkE3B,IAAM,cAAc,cAAAC,QAAM,cAA4C,MAAS;AAa/E,IAAM,iBAAiB,CAAC,kBAA2B;AACxD,QAAM,mBAAe,0BAAW,WAAW;AAE3C,MAAI,CAAC,cAAc;AACjB,YAAQ;AAAA,MACN,kLAAkL,aAAa;AAAA,IACjM;AAEA,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;;;AC1FA,IAAAC,gBAAkC;AA4J3B,IAAM,iBAAiB,cAAAC,QAAM;AAAA,EAClC;AACF;AAaO,IAAM,oBAAoB,CAE/B,mBACG;AACH,QAAM,mBAAe,0BAAW,cAAc;AAE9C,MAAI,CAAC,cAAc;AACjB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;;;ACvLA,IAAAC,gBAAkC;AAClC,IAAAC,gBAAkB;AAClB,sBAAqB;AACrB,6BAA4B;;;ACH5B,
|
|
4
|
+
"sourcesContent": ["export * from './EmojiPicker';\nexport * from './middleware';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport Picker from '@emoji-mart/react';\n\nimport { EmojiPickerIcon } from './icons';\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { useMessageComposer } from '../../components';\nimport type { PopperLikePlacement } from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n /**\n * Deprecated: Popper options, use `placement` instead.\n */\n popperOptions?: Partial<{ placement: PopperLikePlacement }>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageInputContext('EmojiPicker');\n const { textComposer } = useMessageComposer();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n", "import type { PropsWithChildren } from 'react';\nimport React, { useContext } from 'react';\nimport type {\n Channel,\n ChannelConfigWithInfo,\n LocalMessage,\n Mute,\n ChannelState as StreamChannelState,\n} from 'stream-chat';\n\nimport type {\n ChannelUnreadUiState,\n GiphyVersions,\n ImageAttachmentSizeHandler,\n UnknownType,\n VideoAttachmentSizeHandler,\n} from '../types/types';\n\nexport type ChannelNotifications = Array<{\n id: string;\n text: string;\n type: 'success' | 'error';\n}>;\n\nexport type ChannelState = {\n suppressAutoscroll: boolean;\n error?: Error | null;\n hasMore?: boolean;\n hasMoreNewer?: boolean;\n highlightedMessageId?: string;\n loading?: boolean;\n loadingMore?: boolean;\n loadingMoreNewer?: boolean;\n members?: StreamChannelState['members'];\n messages?: LocalMessage[];\n pinnedMessages?: LocalMessage[];\n read?: StreamChannelState['read'];\n thread?: LocalMessage | null;\n threadHasMore?: boolean;\n threadLoadingMore?: boolean;\n threadMessages?: LocalMessage[];\n threadSuppressAutoscroll?: boolean;\n typing?: StreamChannelState['typing'];\n watcherCount?: number;\n watchers?: StreamChannelState['watchers'];\n};\n\nexport type ChannelStateContextValue = Omit<ChannelState, 'typing'> & {\n channel: Channel;\n channelCapabilities: Record<string, boolean>;\n channelConfig: ChannelConfigWithInfo | undefined;\n imageAttachmentSizeHandler: ImageAttachmentSizeHandler;\n notifications: ChannelNotifications;\n shouldGenerateVideoThumbnail: boolean;\n videoAttachmentSizeHandler: VideoAttachmentSizeHandler;\n channelUnreadUiState?: ChannelUnreadUiState;\n giphyVersion?: GiphyVersions;\n mutes?: Array<Mute>;\n watcher_count?: number;\n};\n\nexport const ChannelStateContext = React.createContext<\n ChannelStateContextValue | undefined\n>(undefined);\n\nexport const ChannelStateProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelStateContextValue;\n}>) => (\n <ChannelStateContext.Provider value={value as unknown as ChannelStateContextValue}>\n {children}\n </ChannelStateContext.Provider>\n);\n\nexport const useChannelStateContext = (componentName?: string) => {\n const contextValue = useContext(ChannelStateContext);\n\n if (!contextValue) {\n console.warn(\n `The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChannelStateContextValue;\n }\n\n return contextValue as unknown as ChannelStateContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if ChannelStateContext\n * typing is desired while using the HOC withChannelStateContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChannelStateContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChannelStateContextComponent = (\n props: Omit<P, keyof ChannelStateContextValue>,\n ) => {\n const channelStateContext = useChannelStateContext();\n\n return <Component {...(props as P)} {...channelStateContext} />;\n };\n\n WithChannelStateContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithChannelStateContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\nimport type {\n AppSettingsAPIResponse,\n Channel,\n Mute,\n SearchController,\n} from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport type { ChatProps } from '../components/Chat/Chat';\nimport type { UnknownType } from '../types/types';\nimport type { ChannelsQueryState } from '../components/Chat/hooks/useChannelsQueryState';\n\ntype CSSClasses =\n | 'chat'\n | 'chatContainer'\n | 'channel'\n | 'channelList'\n | 'message'\n | 'messageList'\n | 'thread'\n | 'threadList'\n | 'virtualMessage'\n | 'virtualizedMessageList';\n\nexport type CustomClasses = Partial<Record<CSSClasses, string>>;\n\ntype ChannelConfId = string; // e.g.: \"messaging:general\"\n\nexport type ChatContextValue = {\n /**\n * Indicates, whether a channels query has been triggered within ChannelList by its channels pagination controller.\n */\n channelsQueryState: ChannelsQueryState;\n closeMobileNav: () => void;\n getAppSettings: () => Promise<AppSettingsAPIResponse> | null;\n latestMessageDatesByChannels: Record<ChannelConfId, Date>;\n mutes: Array<Mute>;\n openMobileNav: () => void;\n /** Instance of SearchController class that allows to control all the search operations. */\n searchController: SearchController;\n /**\n * Sets active channel to be rendered within Channel component.\n * @param newChannel\n * @param watchers\n * @param event\n */\n setActiveChannel: (\n newChannel?: Channel,\n watchers?: { limit?: number; offset?: number },\n event?: React.BaseSyntheticEvent,\n ) => void;\n useImageFlagEmojisOnWindows: boolean;\n /**\n * Active channel used to render the contents of the Channel component.\n */\n channel?: Channel;\n /**\n * Object through which custom classes can be set for main container components of the SDK.\n */\n customClasses?: CustomClasses;\n navOpen?: boolean;\n} & Partial<Pick<ChatProps, 'isMessageAIGenerated'>> &\n Required<Pick<ChatProps, 'theme' | 'client'>>;\n\nexport const ChatContext = React.createContext<ChatContextValue | undefined>(undefined);\n\nexport const ChatProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChatContextValue;\n}>) => (\n <ChatContext.Provider value={value as unknown as ChatContextValue}>\n {children}\n </ChatContext.Provider>\n);\n\nexport const useChatContext = (componentName?: string) => {\n const contextValue = useContext(ChatContext);\n\n if (!contextValue) {\n console.warn(\n `The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChatContextValue;\n }\n\n return contextValue as unknown as ChatContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference so if ChatContext\n * typing is desired while using the HOC withChatContext the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChatContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChatContextComponent = (props: Omit<P, keyof ChatContextValue>) => {\n const chatContext = useChatContext();\n\n return <Component {...(props as P)} {...chatContext} />;\n };\n WithChatContextComponent.displayName = `WithChatContext${getDisplayName(Component)}`;\n return WithChatContextComponent;\n};\n", "import type { BaseSyntheticEvent, PropsWithChildren, ReactNode } from 'react';\nimport React, { useContext } from 'react';\n\nimport type {\n DeleteMessageOptions,\n LocalMessage,\n Mute,\n ReactionResponse,\n ReactionSort,\n UserResponse,\n} from 'stream-chat';\n\nimport type { ChannelActionContextValue } from './ChannelActionContext';\n\nimport type { ActionHandlerReturnType } from '../components/Message/hooks/useActionHandler';\nimport type { PinPermissions } from '../components/Message/hooks/usePinHandler';\nimport type { ReactEventHandler } from '../components/Message/types';\nimport type { MessageActionsArray } from '../components/Message/utils';\nimport type { MessageInputProps } from '../components/MessageInput/MessageInput';\nimport type { GroupStyle } from '../components/MessageList/utils';\nimport type {\n ReactionDetailsComparator,\n ReactionsComparator,\n ReactionType,\n} from '../components/Reactions/types';\n\nimport type { RenderTextOptions } from '../components/Message/renderText';\nimport type { UnknownType } from '../types/types';\n\nexport type CustomMessageActions = {\n [key: string]: (\n message: LocalMessage,\n event: React.BaseSyntheticEvent,\n ) => Promise<void> | void;\n};\n\nexport type MessageContextValue = {\n /** If actions such as edit, delete, flag, mute are enabled on Message */\n actionsEnabled: boolean;\n /** Function to exit edit state */\n clearEditingState: (event?: React.BaseSyntheticEvent) => void;\n /** If the Message is in edit state */\n editing: boolean;\n /**\n * Returns all allowed actions on message by current user e.g., ['edit', 'delete', 'flag', 'mute', 'pin', 'quote', 'react', 'reply'].\n * Please check [Message](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message.tsx) component for default implementation.\n */\n getMessageActions: () => MessageActionsArray<string>;\n /** Function to send an action in a Channel */\n handleAction: ActionHandlerReturnType;\n /** Function to delete a message in a Channel */\n handleDelete: (\n event: BaseSyntheticEvent,\n options?: DeleteMessageOptions,\n ) => Promise<void> | void;\n /** Function to edit a message in a Channel */\n handleEdit: ReactEventHandler;\n /** Function to fetch the message reactions */\n handleFetchReactions: (\n reactionType?: ReactionType,\n sort?: ReactionSort,\n ) => Promise<Array<ReactionResponse>>;\n /** Function to flag a message in a Channel */\n handleFlag: ReactEventHandler;\n /** Function to mark message and the messages that follow it as unread in a Channel */\n handleMarkUnread: ReactEventHandler;\n /** Function to mute a user in a Channel */\n handleMute: ReactEventHandler;\n /** Function to open a Thread on a Message */\n handleOpenThread: ReactEventHandler;\n /** Function to pin a Message in a Channel */\n handlePin: ReactEventHandler;\n /** Function to post a reaction on a Message */\n handleReaction: (\n reactionType: string,\n event: React.BaseSyntheticEvent,\n ) => Promise<void>;\n /** Function to retry sending a Message */\n handleRetry: ChannelActionContextValue['retrySendMessage'];\n /** Function that returns whether the Message belongs to the current user */\n isMyMessage: () => boolean;\n /** The message object */\n message: LocalMessage;\n /** Indicates whether a message has not been read yet or has been marked unread */\n messageIsUnread: boolean;\n /** Handler function for a click event on an @mention in Message */\n onMentionsClickMessage: ReactEventHandler;\n /** Handler function for a hover event on an @mention in Message */\n onMentionsHoverMessage: ReactEventHandler;\n /** Handler function for a click event on the user that posted the Message */\n onUserClick: ReactEventHandler;\n /** Handler function for a hover event on the user that posted the Message */\n onUserHover: ReactEventHandler;\n /** Function to toggle the edit state on a Message */\n setEditingState: ReactEventHandler;\n /** Additional props for underlying MessageInput component, [available props](https://getstream.io/chat/docs/sdk/react/message-input-components/message_input/#props) */\n additionalMessageInputProps?: MessageInputProps;\n /** Call this function to keep message list scrolled to the bottom when the scroll height increases, e.g. an element appears below the last message (only used in the `VirtualizedMessageList`) */\n autoscrollToBottom?: () => void;\n /** Message component configuration prop. If true, picking a reaction from the `ReactionSelector` component will close the selector */\n closeReactionSelectorOnClick?: boolean;\n /** Object containing custom message actions and function handlers */\n customMessageActions?: CustomMessageActions;\n /** An array of user IDs that have confirmed the message delivery to their device */\n deliveredTo?: UserResponse[];\n /** If true, the message is the last one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n endOfGroup?: boolean;\n /** If true, the message is the first one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n firstOfGroup?: boolean;\n /** Override the default formatting of the date. This is a function that has access to the original date object, returns a string */\n formatDate?: (date: Date) => string;\n /** If true, group messages sent by each user (only used in the `VirtualizedMessageList`) */\n groupedByUser?: boolean;\n /** A list of styles to apply to this message, ie. top, bottom, single */\n groupStyles?: GroupStyle[];\n /** Whether to highlight and focus the message on load */\n highlighted?: boolean;\n /** Whether the threaded message is the first in the thread list */\n initialMessage?: boolean;\n /**\n * A factory function that determines whether a message is AI generated or not.\n */\n isMessageAIGenerated?: (message: LocalMessage) => boolean;\n /** Latest own message in currently displayed message set. */\n lastOwnMessage?: LocalMessage;\n /** Latest message id on current channel */\n lastReceivedId?: string | null;\n /** DOMRect object for parent MessageList component */\n messageListRect?: DOMRect;\n /** Array of muted users coming from [ChannelStateContext](https://getstream.io/chat/docs/sdk/react/contexts/channel_state_context/#mutes) */\n mutes?: Mute[];\n /** @deprecated in favor of `channelCapabilities - The user roles allowed to pin Messages in various channel types */\n pinPermissions?: PinPermissions;\n /** Sort options to provide to a reactions query */\n reactionDetailsSort?: ReactionSort;\n /** A list of users that have read this Message */\n readBy?: UserResponse[];\n /** Custom function to render message text content, defaults to the renderText function: [utils](https://github.com/GetStream/stream-chat-react/blob/master/src/utils.tsx) */\n renderText?: (\n text?: string,\n mentioned_users?: UserResponse[],\n options?: RenderTextOptions,\n ) => ReactNode;\n /** Keep track of read receipts for each message sent by the user. When disabled, only the last own message delivery / read status is rendered. */\n returnAllReadData?: boolean;\n /** Comparator function to sort the list of reacted users\n * @deprecated use `reactionDetailsSort` instead\n */\n sortReactionDetails?: ReactionDetailsComparator;\n /** Comparator function to sort reactions, defaults to chronological order */\n sortReactions?: ReactionsComparator;\n /** Whether or not the Message is in a Thread */\n threadList?: boolean;\n /** render HTML instead of markdown. Posting HTML is only allowed server-side */\n unsafeHTML?: boolean;\n};\n\nexport const MessageContext = React.createContext<MessageContextValue | undefined>(\n undefined,\n);\n\nexport const MessageProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageContextValue;\n}>) => (\n <MessageContext.Provider value={value as unknown as MessageContextValue}>\n {children}\n </MessageContext.Provider>\n);\n\nexport const useMessageContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _componentName?: string,\n) => {\n const contextValue = useContext(MessageContext);\n\n if (!contextValue) {\n return {} as MessageContextValue;\n }\n\n return contextValue as unknown as MessageContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if MessageContext\n * typing is desired while using the HOC withMessageContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withMessageContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithMessageContextComponent = (props: Omit<P, keyof MessageContextValue>) => {\n const messageContext = useMessageContext();\n\n return <Component {...(props as P)} {...messageContext} />;\n };\n\n WithMessageContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithMessageContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport type { PropsWithChildren } from 'react';\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs from 'dayjs';\nimport type { Duration as DayjsDuration } from 'dayjs/plugin/duration';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n DurationFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: unknown): output is Date =>\n output !== null &&\n typeof output === 'object' &&\n typeof (output as Date).getTime === 'function';\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n durationFormatter:\n (streamI18n) =>\n (value, _, { format, withSuffix }: DurationFormatterOptions) => {\n // NOTE: isDayjs is not exported in \"dayjs\" package for ESM, hence we access\n // `isDayjs` from Dayjs instance\n if (format && Dayjs.isDayjs(streamI18n.DateTimeParser)) {\n return (streamI18n.DateTimeParser.duration(value) as DayjsDuration).format(\n format,\n );\n }\n return streamI18n.DateTimeParser.duration(value).humanize(!!withSuffix);\n },\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction = ((key: string) => key) as TFunction;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import { useEffect, useMemo } from 'react';\nimport { FixedSizeQueueCache, MessageComposer } from 'stream-chat';\nimport { useThreadContext } from '../../Threads';\nimport {\n useChannelStateContext,\n useChatContext,\n useMessageContext,\n} from '../../../context';\nimport { useLegacyThreadContext } from '../../Thread';\n\nconst queueCache = new FixedSizeQueueCache<string, MessageComposer>(64);\n\nexport const useMessageComposer = () => {\n const { client } = useChatContext();\n const { channel } = useChannelStateContext();\n const { editing, message: editedMessage } = useMessageContext();\n // legacy thread will receive new composer\n const { legacyThread: parentMessage } = useLegacyThreadContext();\n const threadInstance = useThreadContext();\n\n const cachedEditedMessage = useMemo(() => {\n if (!editedMessage) return undefined;\n\n return editedMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editedMessage?.id]);\n\n const cachedParentMessage = useMemo(() => {\n if (!parentMessage) return undefined;\n\n return parentMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [parentMessage?.id]);\n\n // composer hierarchy\n // edited message (always new) -> thread instance (own) -> thread message (always new) -> channel (own)\n // editedMessage ?? thread ?? parentMessage ?? channel;\n const messageComposer = useMemo(() => {\n if (editing && cachedEditedMessage) {\n const tag = MessageComposer.constructTag(cachedEditedMessage);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) {\n cachedComposer.editedMessage = cachedEditedMessage;\n return cachedComposer;\n }\n\n return new MessageComposer({\n client,\n composition: cachedEditedMessage,\n compositionContext: cachedEditedMessage,\n });\n } else if (threadInstance) {\n return threadInstance.messageComposer;\n } else if (cachedParentMessage) {\n const compositionContext = {\n ...cachedParentMessage,\n legacyThreadId: cachedParentMessage.id,\n };\n\n const tag = MessageComposer.constructTag(compositionContext);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) return cachedComposer;\n\n return new MessageComposer({\n client,\n compositionContext,\n });\n } else {\n return channel.messageComposer;\n }\n }, [\n cachedEditedMessage,\n cachedParentMessage,\n channel,\n client,\n editing,\n threadInstance,\n ]);\n\n if (\n (['legacy_thread', 'message'] as MessageComposer['contextType'][]).includes(\n messageComposer.contextType,\n ) &&\n !queueCache.peek(messageComposer.tag)\n ) {\n queueCache.add(messageComposer.tag, messageComposer);\n }\n\n useEffect(() => {\n const unsubscribe = messageComposer.registerSubscriptions();\n return () => {\n unsubscribe();\n };\n }, [messageComposer]);\n\n return messageComposer;\n};\n", "import React, { createContext, useContext } from 'react';\n\nimport { Channel } from '../../components';\n\nimport type { PropsWithChildren } from 'react';\nimport type { Thread } from 'stream-chat';\n\nexport type ThreadContextValue = Thread | undefined;\n\nexport const ThreadContext = createContext<ThreadContextValue>(undefined);\n\nexport const useThreadContext = () => useContext(ThreadContext);\n\nexport const ThreadProvider = ({\n children,\n thread,\n}: PropsWithChildren<{ thread?: Thread }>) => (\n <ThreadContext.Provider value={thread}>\n <Channel channel={thread?.channel}>{children}</Channel>\n </ThreadContext.Provider>\n);\n", "import {\n autoPlacement,\n autoUpdate,\n flip as flipMw,\n offset as offsetMw,\n type Placement,\n shift as shiftMw,\n size as sizeMw,\n useFloating,\n} from '@floating-ui/react';\nimport type { AutoPlacementOptions } from '@floating-ui/core';\n\nconst hasResizeObserver = typeof window !== 'undefined' && 'ResizeObserver' in window;\n\nexport type PopperLikePlacement = Placement | 'auto' | 'auto-start' | 'auto-end';\n\nfunction autoMiddlewareFor(p: PopperLikePlacement) {\n if (!String(p).startsWith('auto')) return null;\n const alignment: AutoPlacementOptions['alignment'] =\n p === 'auto-start' ? 'start' : p === 'auto-end' ? 'end' : undefined;\n return autoPlacement({ alignment });\n}\n\ntype OffsetOpt =\n | number\n | { mainAxis?: number; crossAxis?: number; alignmentAxis?: number }\n | [crossAxis: number, mainAxis: number]; // keep your tuple compat\n\nfunction toOffsetMw(opt?: OffsetOpt) {\n if (opt == null) return null;\n if (Array.isArray(opt)) {\n const [crossAxis, mainAxis] = opt;\n return offsetMw({ crossAxis, mainAxis });\n }\n if (typeof opt === 'number') return offsetMw(opt);\n return offsetMw(opt);\n}\n\nexport type UsePopoverParams = {\n placement?: PopperLikePlacement;\n /** Add flip() when placement is not 'auto*' */\n allowFlip?: boolean;\n /** Keep in viewport; default true to match common popper setups */\n allowShift?: boolean;\n /** The floating UI is fitted to the available space (by constraining its max size) instead of letting it overflow; default false */\n fitAvailableSpace?: boolean;\n /** Offset (number, object, or [crossAxis, mainAxis] tuple) */\n offset?: OffsetOpt;\n /**\n * Freeze behavior like Popper's eventListeners: { scroll:false, resize:false }.\n * If true \u2192 no autoUpdate (you can call `update()` manually).\n */\n freeze?: boolean;\n /**\n * Fine-grained control of autoUpdate triggers (only if freeze=false).\n * Defaults match Popper's \"disabled\" example when all set to false.\n */\n autoUpdateOptions?: Partial<Parameters<typeof autoUpdate>[3]>;\n};\n\nexport function usePopoverPosition({\n allowFlip = true,\n allowShift = true,\n autoUpdateOptions,\n fitAvailableSpace = false,\n freeze = false,\n offset,\n placement = 'bottom-start',\n}: UsePopoverParams) {\n const autoMw = autoMiddlewareFor(placement);\n const offsetMiddleware = toOffsetMw(offset);\n const isSidePlacement = placement.startsWith('left') || placement.startsWith('right');\n\n const middleware = [\n // offset first (mirrors common Popper setups)\n ...(offsetMiddleware ? [offsetMiddleware] : []),\n\n // choose between autoPlacement (Popper's \"auto*\") OR flip()\n // only allow flip when not explicitly 'left*' or 'right*'\n ...(autoMw ? [autoMw] : allowFlip && !isSidePlacement ? [flipMw()] : []),\n\n // viewport collision adjustments\n ...(allowShift ? [shiftMw({ padding: 8 })] : []),\n\n // optional size constraining\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n ...(fitAvailableSpace ? [sizeMw({ apply: () => {} })] : []),\n ];\n\n // if placement is 'auto*', seed with any static placement; autoPlacement will pick the final one\n const seedPlacement: Placement = String(placement).startsWith('auto')\n ? 'bottom'\n : (placement as Placement);\n\n return useFloating({\n middleware,\n placement: seedPlacement,\n strategy: 'fixed',\n whileElementsMounted: freeze\n ? undefined\n : (reference, floating, update) =>\n autoUpdate(reference, floating, update, {\n ancestorResize: true,\n ancestorScroll: true,\n animationFrame: false,\n elementResize: hasResizeObserver,\n ...autoUpdateOptions,\n }),\n });\n}\n", "import React, { useContext } from 'react';\nimport type { LocalMessage } from 'stream-chat';\n\nexport const LegacyThreadContext = React.createContext<{\n legacyThread: LocalMessage | undefined;\n}>({ legacyThread: undefined });\n\nexport const useLegacyThreadContext = () => useContext(LegacyThreadContext);\n", "import React, { createContext, useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type { MessageInputHookProps } from '../components/MessageInput/hooks/useMessageInputControls';\n\nexport type MessageInputContextValue = MessageInputHookProps &\n Omit<MessageInputProps, 'Input'> &\n CooldownTimerState;\n\nexport const MessageInputContext = createContext<MessageInputHookProps | undefined>(\n undefined,\n);\n\nexport const MessageInputContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue;\n}>) => (\n <MessageInputContext.Provider value={value as unknown as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n return {} as MessageInputContextValue;\n }\n\n return contextValue as unknown as MessageInputContextValue;\n};\n", "import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageInput';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_react", "React", "import_react", "React", "import_react", "React", "import_react", "React", "import_react", "import_dayjs", "Dayjs", "Dayjs", "calendar", "localizedFormat", "React", "import_react", "import_react", "import_react", "offsetMw", "flipMw", "shiftMw", "sizeMw", "import_react", "React", "import_react", "React", "Picker", "import_stream_chat", "mergeWith"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/plugins/Emojis/index.ts", "../../../src/plugins/Emojis/EmojiPicker.tsx", "../../../src/plugins/Emojis/icons.tsx", "../../../src/context/ChannelStateContext.tsx", "../../../src/context/ChatContext.tsx", "../../../src/context/MessageContext.tsx", "../../../src/context/TranslationContext.tsx", "../../../src/i18n/utils.ts", "../../../src/components/MessageInput/hooks/useMessageComposer.ts", "../../../src/components/Threads/ThreadContext.tsx", "../../../src/components/Dialog/hooks/usePopoverPosition.ts", "../../../src/components/Thread/LegacyThreadContext.ts", "../../../src/context/MessageInputContext.tsx", "../../../src/plugins/Emojis/middleware/textComposerEmojiMiddleware.ts"],
|
|
4
|
-
"sourcesContent": ["export * from './EmojiPicker';\nexport * from './middleware';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport Picker from '@emoji-mart/react';\n\nimport { EmojiPickerIcon } from './icons';\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { useMessageComposer } from '../../components';\nimport type { PopperLikePlacement } from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n /**\n * Deprecated: Popper options, use `placement` instead.\n */\n popperOptions?: Partial<{ placement: PopperLikePlacement }>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageInputContext('EmojiPicker');\n const { textComposer } = useMessageComposer();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n", "import type { PropsWithChildren } from 'react';\nimport React, { useContext } from 'react';\nimport type {\n Channel,\n ChannelConfigWithInfo,\n LocalMessage,\n Mute,\n ChannelState as StreamChannelState,\n} from 'stream-chat';\n\nimport type {\n ChannelUnreadUiState,\n GiphyVersions,\n ImageAttachmentSizeHandler,\n UnknownType,\n VideoAttachmentSizeHandler,\n} from '../types/types';\n\nexport type ChannelNotifications = Array<{\n id: string;\n text: string;\n type: 'success' | 'error';\n}>;\n\nexport type ChannelState = {\n suppressAutoscroll: boolean;\n error?: Error | null;\n hasMore?: boolean;\n hasMoreNewer?: boolean;\n highlightedMessageId?: string;\n loading?: boolean;\n loadingMore?: boolean;\n loadingMoreNewer?: boolean;\n members?: StreamChannelState['members'];\n messages?: LocalMessage[];\n pinnedMessages?: LocalMessage[];\n read?: StreamChannelState['read'];\n thread?: LocalMessage | null;\n threadHasMore?: boolean;\n threadLoadingMore?: boolean;\n threadMessages?: LocalMessage[];\n threadSuppressAutoscroll?: boolean;\n typing?: StreamChannelState['typing'];\n watcherCount?: number;\n watchers?: StreamChannelState['watchers'];\n};\n\nexport type ChannelStateContextValue = Omit<ChannelState, 'typing'> & {\n channel: Channel;\n channelCapabilities: Record<string, boolean>;\n channelConfig: ChannelConfigWithInfo | undefined;\n imageAttachmentSizeHandler: ImageAttachmentSizeHandler;\n notifications: ChannelNotifications;\n shouldGenerateVideoThumbnail: boolean;\n videoAttachmentSizeHandler: VideoAttachmentSizeHandler;\n channelUnreadUiState?: ChannelUnreadUiState;\n giphyVersion?: GiphyVersions;\n mutes?: Array<Mute>;\n watcher_count?: number;\n};\n\nexport const ChannelStateContext = React.createContext<\n ChannelStateContextValue | undefined\n>(undefined);\n\nexport const ChannelStateProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelStateContextValue;\n}>) => (\n <ChannelStateContext.Provider value={value as unknown as ChannelStateContextValue}>\n {children}\n </ChannelStateContext.Provider>\n);\n\nexport const useChannelStateContext = (componentName?: string) => {\n const contextValue = useContext(ChannelStateContext);\n\n if (!contextValue) {\n console.warn(\n `The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChannelStateContextValue;\n }\n\n return contextValue as unknown as ChannelStateContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if ChannelStateContext\n * typing is desired while using the HOC withChannelStateContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChannelStateContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChannelStateContextComponent = (\n props: Omit<P, keyof ChannelStateContextValue>,\n ) => {\n const channelStateContext = useChannelStateContext();\n\n return <Component {...(props as P)} {...channelStateContext} />;\n };\n\n WithChannelStateContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithChannelStateContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\nimport type {\n AppSettingsAPIResponse,\n Channel,\n Mute,\n SearchController,\n} from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport type { ChatProps } from '../components/Chat/Chat';\nimport type { UnknownType } from '../types/types';\nimport type { ChannelsQueryState } from '../components/Chat/hooks/useChannelsQueryState';\n\ntype CSSClasses =\n | 'chat'\n | 'chatContainer'\n | 'channel'\n | 'channelList'\n | 'message'\n | 'messageList'\n | 'thread'\n | 'threadList'\n | 'virtualMessage'\n | 'virtualizedMessageList';\n\nexport type CustomClasses = Partial<Record<CSSClasses, string>>;\n\ntype ChannelConfId = string; // e.g.: \"messaging:general\"\n\nexport type ChatContextValue = {\n /**\n * Indicates, whether a channels query has been triggered within ChannelList by its channels pagination controller.\n */\n channelsQueryState: ChannelsQueryState;\n closeMobileNav: () => void;\n getAppSettings: () => Promise<AppSettingsAPIResponse> | null;\n latestMessageDatesByChannels: Record<ChannelConfId, Date>;\n mutes: Array<Mute>;\n openMobileNav: () => void;\n /** Instance of SearchController class that allows to control all the search operations. */\n searchController: SearchController;\n /**\n * Sets active channel to be rendered within Channel component.\n * @param newChannel\n * @param watchers\n * @param event\n */\n setActiveChannel: (\n newChannel?: Channel,\n watchers?: { limit?: number; offset?: number },\n event?: React.BaseSyntheticEvent,\n ) => void;\n useImageFlagEmojisOnWindows: boolean;\n /**\n * Active channel used to render the contents of the Channel component.\n */\n channel?: Channel;\n /**\n * Object through which custom classes can be set for main container components of the SDK.\n */\n customClasses?: CustomClasses;\n navOpen?: boolean;\n} & Partial<Pick<ChatProps, 'isMessageAIGenerated'>> &\n Required<Pick<ChatProps, 'theme' | 'client'>>;\n\nexport const ChatContext = React.createContext<ChatContextValue | undefined>(undefined);\n\nexport const ChatProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChatContextValue;\n}>) => (\n <ChatContext.Provider value={value as unknown as ChatContextValue}>\n {children}\n </ChatContext.Provider>\n);\n\nexport const useChatContext = (componentName?: string) => {\n const contextValue = useContext(ChatContext);\n\n if (!contextValue) {\n console.warn(\n `The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChatContextValue;\n }\n\n return contextValue as unknown as ChatContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference so if ChatContext\n * typing is desired while using the HOC withChatContext the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChatContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChatContextComponent = (props: Omit<P, keyof ChatContextValue>) => {\n const chatContext = useChatContext();\n\n return <Component {...(props as P)} {...chatContext} />;\n };\n WithChatContextComponent.displayName = `WithChatContext${getDisplayName(Component)}`;\n return WithChatContextComponent;\n};\n", "import type { BaseSyntheticEvent, PropsWithChildren, ReactNode } from 'react';\nimport React, { useContext } from 'react';\n\nimport type {\n DeleteMessageOptions,\n LocalMessage,\n Mute,\n ReactionResponse,\n ReactionSort,\n UserResponse,\n} from 'stream-chat';\n\nimport type { ChannelActionContextValue } from './ChannelActionContext';\n\nimport type { ActionHandlerReturnType } from '../components/Message/hooks/useActionHandler';\nimport type { PinPermissions } from '../components/Message/hooks/usePinHandler';\nimport type { ReactEventHandler } from '../components/Message/types';\nimport type { MessageActionsArray } from '../components/Message/utils';\nimport type { MessageInputProps } from '../components/MessageInput/MessageInput';\nimport type { GroupStyle } from '../components/MessageList/utils';\nimport type {\n ReactionDetailsComparator,\n ReactionsComparator,\n ReactionType,\n} from '../components/Reactions/types';\n\nimport type { RenderTextOptions } from '../components/Message/renderText';\nimport type { UnknownType } from '../types/types';\n\nexport type CustomMessageActions = {\n [key: string]: (\n message: LocalMessage,\n event: React.BaseSyntheticEvent,\n ) => Promise<void> | void;\n};\n\nexport type MessageContextValue = {\n /** If actions such as edit, delete, flag, mute are enabled on Message */\n actionsEnabled: boolean;\n /** Function to exit edit state */\n clearEditingState: (event?: React.BaseSyntheticEvent) => void;\n /** If the Message is in edit state */\n editing: boolean;\n /**\n * Returns all allowed actions on message by current user e.g., ['edit', 'delete', 'flag', 'mute', 'pin', 'quote', 'react', 'reply'].\n * Please check [Message](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message.tsx) component for default implementation.\n */\n getMessageActions: () => MessageActionsArray<string>;\n /** Function to send an action in a Channel */\n handleAction: ActionHandlerReturnType;\n /** Function to delete a message in a Channel */\n handleDelete: (\n event: BaseSyntheticEvent,\n options?: DeleteMessageOptions,\n ) => Promise<void> | void;\n /** Function to edit a message in a Channel */\n handleEdit: ReactEventHandler;\n /** Function to fetch the message reactions */\n handleFetchReactions: (\n reactionType?: ReactionType,\n sort?: ReactionSort,\n ) => Promise<Array<ReactionResponse>>;\n /** Function to flag a message in a Channel */\n handleFlag: ReactEventHandler;\n /** Function to mark message and the messages that follow it as unread in a Channel */\n handleMarkUnread: ReactEventHandler;\n /** Function to mute a user in a Channel */\n handleMute: ReactEventHandler;\n /** Function to open a Thread on a Message */\n handleOpenThread: ReactEventHandler;\n /** Function to pin a Message in a Channel */\n handlePin: ReactEventHandler;\n /** Function to post a reaction on a Message */\n handleReaction: (\n reactionType: string,\n event: React.BaseSyntheticEvent,\n ) => Promise<void>;\n /** Function to retry sending a Message */\n handleRetry: ChannelActionContextValue['retrySendMessage'];\n /** Function that returns whether the Message belongs to the current user */\n isMyMessage: () => boolean;\n /** The message object */\n message: LocalMessage;\n /** Indicates whether a message has not been read yet or has been marked unread */\n messageIsUnread: boolean;\n /** Handler function for a click event on an @mention in Message */\n onMentionsClickMessage: ReactEventHandler;\n /** Handler function for a hover event on an @mention in Message */\n onMentionsHoverMessage: ReactEventHandler;\n /** Handler function for a click event on the user that posted the Message */\n onUserClick: ReactEventHandler;\n /** Handler function for a hover event on the user that posted the Message */\n onUserHover: ReactEventHandler;\n /** Function to toggle the edit state on a Message */\n setEditingState: ReactEventHandler;\n /** Additional props for underlying MessageInput component, [available props](https://getstream.io/chat/docs/sdk/react/message-input-components/message_input/#props) */\n additionalMessageInputProps?: MessageInputProps;\n /** Call this function to keep message list scrolled to the bottom when the scroll height increases, e.g. an element appears below the last message (only used in the `VirtualizedMessageList`) */\n autoscrollToBottom?: () => void;\n /** Message component configuration prop. If true, picking a reaction from the `ReactionSelector` component will close the selector */\n closeReactionSelectorOnClick?: boolean;\n /** Object containing custom message actions and function handlers */\n customMessageActions?: CustomMessageActions;\n /** An array of user IDs that have confirmed the message delivery to their device */\n deliveredTo?: UserResponse[];\n /** If true, the message is the last one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n endOfGroup?: boolean;\n /** If true, the message is the first one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n firstOfGroup?: boolean;\n /** Override the default formatting of the date. This is a function that has access to the original date object, returns a string */\n formatDate?: (date: Date) => string;\n /** If true, group messages sent by each user (only used in the `VirtualizedMessageList`) */\n groupedByUser?: boolean;\n /** A list of styles to apply to this message, ie. top, bottom, single */\n groupStyles?: GroupStyle[];\n /** Whether to highlight and focus the message on load */\n highlighted?: boolean;\n /** Whether the threaded message is the first in the thread list */\n initialMessage?: boolean;\n /**\n * A factory function that determines whether a message is AI generated or not.\n */\n isMessageAIGenerated?: (message: LocalMessage) => boolean;\n /** Latest own message in currently displayed message set. */\n lastOwnMessage?: LocalMessage;\n /** Latest message id on current channel */\n lastReceivedId?: string | null;\n /** DOMRect object for parent MessageList component */\n messageListRect?: DOMRect;\n /** Array of muted users coming from [ChannelStateContext](https://getstream.io/chat/docs/sdk/react/contexts/channel_state_context/#mutes) */\n mutes?: Mute[];\n /** @deprecated in favor of `channelCapabilities - The user roles allowed to pin Messages in various channel types */\n pinPermissions?: PinPermissions;\n /** Sort options to provide to a reactions query */\n reactionDetailsSort?: ReactionSort;\n /** A list of users that have read this Message */\n readBy?: UserResponse[];\n /** Custom function to render message text content, defaults to the renderText function: [utils](https://github.com/GetStream/stream-chat-react/blob/master/src/utils.tsx) */\n renderText?: (\n text?: string,\n mentioned_users?: UserResponse[],\n options?: RenderTextOptions,\n ) => ReactNode;\n /** Keep track of read receipts for each message sent by the user. When disabled, only the last own message delivery / read status is rendered. */\n returnAllReadData?: boolean;\n /** Comparator function to sort the list of reacted users\n * @deprecated use `reactionDetailsSort` instead\n */\n sortReactionDetails?: ReactionDetailsComparator;\n /** Comparator function to sort reactions, defaults to chronological order */\n sortReactions?: ReactionsComparator;\n /** Whether or not the Message is in a Thread */\n threadList?: boolean;\n /** render HTML instead of markdown. Posting HTML is only allowed server-side */\n unsafeHTML?: boolean;\n};\n\nexport const MessageContext = React.createContext<MessageContextValue | undefined>(\n undefined,\n);\n\nexport const MessageProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageContextValue;\n}>) => (\n <MessageContext.Provider value={value as unknown as MessageContextValue}>\n {children}\n </MessageContext.Provider>\n);\n\nexport const useMessageContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _componentName?: string,\n) => {\n const contextValue = useContext(MessageContext);\n\n if (!contextValue) {\n return {} as MessageContextValue;\n }\n\n return contextValue as unknown as MessageContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if MessageContext\n * typing is desired while using the HOC withMessageContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withMessageContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithMessageContextComponent = (props: Omit<P, keyof MessageContextValue>) => {\n const messageContext = useMessageContext();\n\n return <Component {...(props as P)} {...messageContext} />;\n };\n\n WithMessageContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithMessageContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport type { PropsWithChildren } from 'react';\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs, { isDayjs } from 'dayjs';\nimport type { Duration as DayjsDuration } from 'dayjs/plugin/duration';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n DurationFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: unknown): output is Date =>\n output !== null &&\n typeof output === 'object' &&\n typeof (output as Date).getTime === 'function';\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n durationFormatter:\n (streamI18n) =>\n (value, _, { format, withSuffix }: DurationFormatterOptions) => {\n if (format && isDayjs(streamI18n.DateTimeParser)) {\n return (streamI18n.DateTimeParser.duration(value) as DayjsDuration).format(\n format,\n );\n }\n return streamI18n.DateTimeParser.duration(value).humanize(!!withSuffix);\n },\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction = ((key: string) => key) as TFunction;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import { useEffect, useMemo } from 'react';\nimport { FixedSizeQueueCache, MessageComposer } from 'stream-chat';\nimport { useThreadContext } from '../../Threads';\nimport {\n useChannelStateContext,\n useChatContext,\n useMessageContext,\n} from '../../../context';\nimport { useLegacyThreadContext } from '../../Thread';\n\nconst queueCache = new FixedSizeQueueCache<string, MessageComposer>(64);\n\nexport const useMessageComposer = () => {\n const { client } = useChatContext();\n const { channel } = useChannelStateContext();\n const { editing, message: editedMessage } = useMessageContext();\n // legacy thread will receive new composer\n const { legacyThread: parentMessage } = useLegacyThreadContext();\n const threadInstance = useThreadContext();\n\n const cachedEditedMessage = useMemo(() => {\n if (!editedMessage) return undefined;\n\n return editedMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editedMessage?.id]);\n\n const cachedParentMessage = useMemo(() => {\n if (!parentMessage) return undefined;\n\n return parentMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [parentMessage?.id]);\n\n // composer hierarchy\n // edited message (always new) -> thread instance (own) -> thread message (always new) -> channel (own)\n // editedMessage ?? thread ?? parentMessage ?? channel;\n const messageComposer = useMemo(() => {\n if (editing && cachedEditedMessage) {\n const tag = MessageComposer.constructTag(cachedEditedMessage);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) {\n cachedComposer.editedMessage = cachedEditedMessage;\n return cachedComposer;\n }\n\n return new MessageComposer({\n client,\n composition: cachedEditedMessage,\n compositionContext: cachedEditedMessage,\n });\n } else if (threadInstance) {\n return threadInstance.messageComposer;\n } else if (cachedParentMessage) {\n const compositionContext = {\n ...cachedParentMessage,\n legacyThreadId: cachedParentMessage.id,\n };\n\n const tag = MessageComposer.constructTag(compositionContext);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) return cachedComposer;\n\n return new MessageComposer({\n client,\n compositionContext,\n });\n } else {\n return channel.messageComposer;\n }\n }, [\n cachedEditedMessage,\n cachedParentMessage,\n channel,\n client,\n editing,\n threadInstance,\n ]);\n\n if (\n (['legacy_thread', 'message'] as MessageComposer['contextType'][]).includes(\n messageComposer.contextType,\n ) &&\n !queueCache.peek(messageComposer.tag)\n ) {\n queueCache.add(messageComposer.tag, messageComposer);\n }\n\n useEffect(() => {\n const unsubscribe = messageComposer.registerSubscriptions();\n return () => {\n unsubscribe();\n };\n }, [messageComposer]);\n\n return messageComposer;\n};\n", "import React, { createContext, useContext } from 'react';\n\nimport { Channel } from '../../components';\n\nimport type { PropsWithChildren } from 'react';\nimport type { Thread } from 'stream-chat';\n\nexport type ThreadContextValue = Thread | undefined;\n\nexport const ThreadContext = createContext<ThreadContextValue>(undefined);\n\nexport const useThreadContext = () => useContext(ThreadContext);\n\nexport const ThreadProvider = ({\n children,\n thread,\n}: PropsWithChildren<{ thread?: Thread }>) => (\n <ThreadContext.Provider value={thread}>\n <Channel channel={thread?.channel}>{children}</Channel>\n </ThreadContext.Provider>\n);\n", "import {\n autoPlacement,\n autoUpdate,\n flip as flipMw,\n offset as offsetMw,\n type Placement,\n shift as shiftMw,\n size as sizeMw,\n useFloating,\n} from '@floating-ui/react';\nimport type { AutoPlacementOptions } from '@floating-ui/core';\n\nconst hasResizeObserver = typeof window !== 'undefined' && 'ResizeObserver' in window;\n\nexport type PopperLikePlacement = Placement | 'auto' | 'auto-start' | 'auto-end';\n\nfunction autoMiddlewareFor(p: PopperLikePlacement) {\n if (!String(p).startsWith('auto')) return null;\n const alignment: AutoPlacementOptions['alignment'] =\n p === 'auto-start' ? 'start' : p === 'auto-end' ? 'end' : undefined;\n return autoPlacement({ alignment });\n}\n\ntype OffsetOpt =\n | number\n | { mainAxis?: number; crossAxis?: number; alignmentAxis?: number }\n | [crossAxis: number, mainAxis: number]; // keep your tuple compat\n\nfunction toOffsetMw(opt?: OffsetOpt) {\n if (opt == null) return null;\n if (Array.isArray(opt)) {\n const [crossAxis, mainAxis] = opt;\n return offsetMw({ crossAxis, mainAxis });\n }\n if (typeof opt === 'number') return offsetMw(opt);\n return offsetMw(opt);\n}\n\nexport type UsePopoverParams = {\n placement?: PopperLikePlacement;\n /** Add flip() when placement is not 'auto*' */\n allowFlip?: boolean;\n /** Keep in viewport; default true to match common popper setups */\n allowShift?: boolean;\n /** The floating UI is fitted to the available space (by constraining its max size) instead of letting it overflow; default false */\n fitAvailableSpace?: boolean;\n /** Offset (number, object, or [crossAxis, mainAxis] tuple) */\n offset?: OffsetOpt;\n /**\n * Freeze behavior like Popper's eventListeners: { scroll:false, resize:false }.\n * If true \u2192 no autoUpdate (you can call `update()` manually).\n */\n freeze?: boolean;\n /**\n * Fine-grained control of autoUpdate triggers (only if freeze=false).\n * Defaults match Popper's \"disabled\" example when all set to false.\n */\n autoUpdateOptions?: Partial<Parameters<typeof autoUpdate>[3]>;\n};\n\nexport function usePopoverPosition({\n allowFlip = true,\n allowShift = true,\n autoUpdateOptions,\n fitAvailableSpace = false,\n freeze = false,\n offset,\n placement = 'bottom-start',\n}: UsePopoverParams) {\n const autoMw = autoMiddlewareFor(placement);\n const offsetMiddleware = toOffsetMw(offset);\n const isSidePlacement = placement.startsWith('left') || placement.startsWith('right');\n\n const middleware = [\n // offset first (mirrors common Popper setups)\n ...(offsetMiddleware ? [offsetMiddleware] : []),\n\n // choose between autoPlacement (Popper's \"auto*\") OR flip()\n // only allow flip when not explicitly 'left*' or 'right*'\n ...(autoMw ? [autoMw] : allowFlip && !isSidePlacement ? [flipMw()] : []),\n\n // viewport collision adjustments\n ...(allowShift ? [shiftMw({ padding: 8 })] : []),\n\n // optional size constraining\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n ...(fitAvailableSpace ? [sizeMw({ apply: () => {} })] : []),\n ];\n\n // if placement is 'auto*', seed with any static placement; autoPlacement will pick the final one\n const seedPlacement: Placement = String(placement).startsWith('auto')\n ? 'bottom'\n : (placement as Placement);\n\n return useFloating({\n middleware,\n placement: seedPlacement,\n strategy: 'fixed',\n whileElementsMounted: freeze\n ? undefined\n : (reference, floating, update) =>\n autoUpdate(reference, floating, update, {\n ancestorResize: true,\n ancestorScroll: true,\n animationFrame: false,\n elementResize: hasResizeObserver,\n ...autoUpdateOptions,\n }),\n });\n}\n", "import React, { useContext } from 'react';\nimport type { LocalMessage } from 'stream-chat';\n\nexport const LegacyThreadContext = React.createContext<{\n legacyThread: LocalMessage | undefined;\n}>({ legacyThread: undefined });\n\nexport const useLegacyThreadContext = () => useContext(LegacyThreadContext);\n", "import React, { createContext, useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type { MessageInputHookProps } from '../components/MessageInput/hooks/useMessageInputControls';\n\nexport type MessageInputContextValue = MessageInputHookProps &\n Omit<MessageInputProps, 'Input'> &\n CooldownTimerState;\n\nexport const MessageInputContext = createContext<MessageInputHookProps | undefined>(\n undefined,\n);\n\nexport const MessageInputContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue;\n}>) => (\n <MessageInputContext.Provider value={value as unknown as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n return {} as MessageInputContextValue;\n }\n\n return contextValue as unknown as MessageInputContextValue;\n};\n", "import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageInput';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,iBAA2C;AAC3C,IAAAA,iBAAmB;;;ACDnB,mBAAkB;AAEX,IAAM,kBAAkB,MAC7B,6BAAAC,QAAA;AAAA,EAAC;AAAA;AAAA,IACC,qBAAoB;AAAA,IACpB,SAAQ;AAAA,IACR,OAAM;AAAA,IACN,OAAM;AAAA;AAAA,EAEN,6BAAAA,QAAA,cAAC,OAAE,UAAS,WAAU,UAAS,aAC7B,6BAAAA,QAAA,cAAC,UAAK,GAAE,0dAAyd,CACne;AACF;;;ACXF,IAAAC,gBAAkC;AA4D3B,IAAM,sBAAsB,cAAAC,QAAM,cAEvC,MAAS;AAaJ,IAAM,yBAAyB,CAAC,kBAA2B;AAChE,QAAM,mBAAe,0BAAW,mBAAmB;AAEnD,MAAI,CAAC,cAAc;AACjB,YAAQ;AAAA,MACN,qMAAqM,aAAa;AAAA,IACpN;AAEA,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;;;ACxFA,IAAAC,gBAAkC;AAkE3B,IAAM,cAAc,cAAAC,QAAM,cAA4C,MAAS;AAa/E,IAAM,iBAAiB,CAAC,kBAA2B;AACxD,QAAM,mBAAe,0BAAW,WAAW;AAE3C,MAAI,CAAC,cAAc;AACjB,YAAQ;AAAA,MACN,kLAAkL,aAAa;AAAA,IACjM;AAEA,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;;;AC1FA,IAAAC,gBAAkC;AA4J3B,IAAM,iBAAiB,cAAAC,QAAM;AAAA,EAClC;AACF;AAaO,IAAM,oBAAoB,CAE/B,mBACG;AACH,QAAM,mBAAe,0BAAW,cAAc;AAE9C,MAAI,CAAC,cAAc;AACjB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;;;ACvLA,IAAAC,gBAAkC;AAClC,IAAAC,gBAAkB;AAClB,sBAAqB;AACrB,6BAA4B;;;ACH5B,
|
|
4
|
+
"sourcesContent": ["export * from './EmojiPicker';\nexport * from './middleware';\nexport { EmojiPickerIcon } from './icons';\n", "import React, { useEffect, useState } from 'react';\nimport Picker from '@emoji-mart/react';\n\nimport { EmojiPickerIcon } from './icons';\nimport { useMessageInputContext, useTranslationContext } from '../../context';\nimport { useMessageComposer } from '../../components';\nimport type { PopperLikePlacement } from '../../components';\nimport { usePopoverPosition } from '../../components/Dialog/hooks/usePopoverPosition';\n\nconst isShadowRoot = (node: Node): node is ShadowRoot => !!(node as ShadowRoot).host;\n\nexport type EmojiPickerProps = {\n ButtonIconComponent?: React.ComponentType;\n buttonClassName?: string;\n pickerContainerClassName?: string;\n wrapperClassName?: string;\n closeOnEmojiSelect?: boolean;\n /**\n * Untyped [properties](https://github.com/missive/emoji-mart/tree/v5.5.2#options--props) to be\n * passed down to the [emoji-mart `Picker`](https://github.com/missive/emoji-mart/tree/v5.5.2#-picker) component\n */\n pickerProps?: Partial<{ theme: 'auto' | 'light' | 'dark' } & Record<string, unknown>>;\n /**\n * Floating UI placement (default: 'top-end') for the picker popover\n */\n placement?: PopperLikePlacement;\n /**\n * Deprecated: Popper options, use `placement` instead.\n */\n popperOptions?: Partial<{ placement: PopperLikePlacement }>;\n};\n\nconst classNames: EmojiPickerProps = {\n buttonClassName: 'str-chat__emoji-picker-button',\n pickerContainerClassName: 'str-chat__message-textarea-emoji-picker-container',\n wrapperClassName: 'str-chat__message-textarea-emoji-picker',\n};\n\nexport const EmojiPicker = (props: EmojiPickerProps) => {\n const { t } = useTranslationContext('EmojiPicker');\n const { textareaRef } = useMessageInputContext('EmojiPicker');\n const { textComposer } = useMessageComposer();\n const [displayPicker, setDisplayPicker] = useState(false);\n const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(\n null,\n );\n const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);\n const { refs, strategy, x, y } = usePopoverPosition({\n placement: props.placement ?? 'top-end',\n });\n\n useEffect(() => {\n refs.setReference(referenceElement);\n }, [referenceElement, refs]);\n useEffect(() => {\n refs.setFloating(popperElement);\n }, [popperElement, refs]);\n\n const { buttonClassName, pickerContainerClassName, wrapperClassName } = classNames;\n\n const { ButtonIconComponent = EmojiPickerIcon } = props;\n\n useEffect(() => {\n if (!popperElement || !referenceElement) return;\n\n const handlePointerDown = (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n\n const rootNode = target.getRootNode();\n\n if (\n popperElement.contains(isShadowRoot(rootNode) ? rootNode.host : target) ||\n referenceElement.contains(target)\n ) {\n return;\n }\n\n setDisplayPicker(false);\n };\n\n window.addEventListener('pointerdown', handlePointerDown);\n return () => window.removeEventListener('pointerdown', handlePointerDown);\n }, [referenceElement, popperElement]);\n\n return (\n <div className={props.wrapperClassName ?? wrapperClassName}>\n {displayPicker && (\n <div\n className={props.pickerContainerClassName ?? pickerContainerClassName}\n ref={setPopperElement}\n style={{ left: x ?? 0, position: strategy, top: y ?? 0 }}\n >\n <Picker\n data={async () => (await import('@emoji-mart/data')).default}\n onEmojiSelect={(e: { native: string }) => {\n const textarea = textareaRef.current;\n if (!textarea) return;\n textComposer.insertText({ text: e.native });\n textarea.focus();\n if (props.closeOnEmojiSelect) {\n setDisplayPicker(false);\n }\n }}\n {...props.pickerProps}\n />\n </div>\n )}\n <button\n aria-expanded={displayPicker}\n aria-label={t('aria/Emoji picker')}\n className={props.buttonClassName ?? buttonClassName}\n onClick={() => setDisplayPicker((cv) => !cv)}\n ref={setReferenceElement}\n type='button'\n >\n {ButtonIconComponent && <ButtonIconComponent />}\n </button>\n </div>\n );\n};\n", "import React from 'react';\n\nexport const EmojiPickerIcon = () => (\n <svg\n preserveAspectRatio='xMinYMin'\n viewBox='0 0 28 28'\n width='100%'\n xmlns='http://www.w3.org/2000/svg'\n >\n <g clipRule='evenodd' fillRule='evenodd'>\n <path d='M14 4.4C8.6 4.4 4.4 8.6 4.4 14c0 5.4 4.2 9.6 9.6 9.6c5.4 0 9.6-4.2 9.6-9.6c0-5.4-4.2-9.6-9.6-9.6zM2 14c0-6.6 5.4-12 12-12s12 5.4 12 12s-5.4 12-12 12s-12-5.4-12-12zM12.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM18.8 11c0 1-.8 1.8-1.8 1.8s-1.8-.8-1.8-1.8s.8-1.8 1.8-1.8s1.8.8 1.8 1.8zM8.6 15.4c.6-.4 1.2-.2 1.6.2c.6.8 1.6 1.8 3 2c1.2.4 2.8.2 4.8-2c.4-.4 1.2-.6 1.6 0c.4.4.6 1.2 0 1.6c-2.2 2.6-4.8 3.4-7 3c-2-.4-3.6-1.8-4.4-3c-.4-.6-.2-1.2.4-1.8z'></path>\n </g>\n </svg>\n);\n", "import type { PropsWithChildren } from 'react';\nimport React, { useContext } from 'react';\nimport type {\n Channel,\n ChannelConfigWithInfo,\n LocalMessage,\n Mute,\n ChannelState as StreamChannelState,\n} from 'stream-chat';\n\nimport type {\n ChannelUnreadUiState,\n GiphyVersions,\n ImageAttachmentSizeHandler,\n UnknownType,\n VideoAttachmentSizeHandler,\n} from '../types/types';\n\nexport type ChannelNotifications = Array<{\n id: string;\n text: string;\n type: 'success' | 'error';\n}>;\n\nexport type ChannelState = {\n suppressAutoscroll: boolean;\n error?: Error | null;\n hasMore?: boolean;\n hasMoreNewer?: boolean;\n highlightedMessageId?: string;\n loading?: boolean;\n loadingMore?: boolean;\n loadingMoreNewer?: boolean;\n members?: StreamChannelState['members'];\n messages?: LocalMessage[];\n pinnedMessages?: LocalMessage[];\n read?: StreamChannelState['read'];\n thread?: LocalMessage | null;\n threadHasMore?: boolean;\n threadLoadingMore?: boolean;\n threadMessages?: LocalMessage[];\n threadSuppressAutoscroll?: boolean;\n typing?: StreamChannelState['typing'];\n watcherCount?: number;\n watchers?: StreamChannelState['watchers'];\n};\n\nexport type ChannelStateContextValue = Omit<ChannelState, 'typing'> & {\n channel: Channel;\n channelCapabilities: Record<string, boolean>;\n channelConfig: ChannelConfigWithInfo | undefined;\n imageAttachmentSizeHandler: ImageAttachmentSizeHandler;\n notifications: ChannelNotifications;\n shouldGenerateVideoThumbnail: boolean;\n videoAttachmentSizeHandler: VideoAttachmentSizeHandler;\n channelUnreadUiState?: ChannelUnreadUiState;\n giphyVersion?: GiphyVersions;\n mutes?: Array<Mute>;\n watcher_count?: number;\n};\n\nexport const ChannelStateContext = React.createContext<\n ChannelStateContextValue | undefined\n>(undefined);\n\nexport const ChannelStateProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChannelStateContextValue;\n}>) => (\n <ChannelStateContext.Provider value={value as unknown as ChannelStateContextValue}>\n {children}\n </ChannelStateContext.Provider>\n);\n\nexport const useChannelStateContext = (componentName?: string) => {\n const contextValue = useContext(ChannelStateContext);\n\n if (!contextValue) {\n console.warn(\n `The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChannelStateContextValue;\n }\n\n return contextValue as unknown as ChannelStateContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if ChannelStateContext\n * typing is desired while using the HOC withChannelStateContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChannelStateContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChannelStateContextComponent = (\n props: Omit<P, keyof ChannelStateContextValue>,\n ) => {\n const channelStateContext = useChannelStateContext();\n\n return <Component {...(props as P)} {...channelStateContext} />;\n };\n\n WithChannelStateContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithChannelStateContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\nimport type {\n AppSettingsAPIResponse,\n Channel,\n Mute,\n SearchController,\n} from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport type { ChatProps } from '../components/Chat/Chat';\nimport type { UnknownType } from '../types/types';\nimport type { ChannelsQueryState } from '../components/Chat/hooks/useChannelsQueryState';\n\ntype CSSClasses =\n | 'chat'\n | 'chatContainer'\n | 'channel'\n | 'channelList'\n | 'message'\n | 'messageList'\n | 'thread'\n | 'threadList'\n | 'virtualMessage'\n | 'virtualizedMessageList';\n\nexport type CustomClasses = Partial<Record<CSSClasses, string>>;\n\ntype ChannelConfId = string; // e.g.: \"messaging:general\"\n\nexport type ChatContextValue = {\n /**\n * Indicates, whether a channels query has been triggered within ChannelList by its channels pagination controller.\n */\n channelsQueryState: ChannelsQueryState;\n closeMobileNav: () => void;\n getAppSettings: () => Promise<AppSettingsAPIResponse> | null;\n latestMessageDatesByChannels: Record<ChannelConfId, Date>;\n mutes: Array<Mute>;\n openMobileNav: () => void;\n /** Instance of SearchController class that allows to control all the search operations. */\n searchController: SearchController;\n /**\n * Sets active channel to be rendered within Channel component.\n * @param newChannel\n * @param watchers\n * @param event\n */\n setActiveChannel: (\n newChannel?: Channel,\n watchers?: { limit?: number; offset?: number },\n event?: React.BaseSyntheticEvent,\n ) => void;\n useImageFlagEmojisOnWindows: boolean;\n /**\n * Active channel used to render the contents of the Channel component.\n */\n channel?: Channel;\n /**\n * Object through which custom classes can be set for main container components of the SDK.\n */\n customClasses?: CustomClasses;\n navOpen?: boolean;\n} & Partial<Pick<ChatProps, 'isMessageAIGenerated'>> &\n Required<Pick<ChatProps, 'theme' | 'client'>>;\n\nexport const ChatContext = React.createContext<ChatContextValue | undefined>(undefined);\n\nexport const ChatProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: ChatContextValue;\n}>) => (\n <ChatContext.Provider value={value as unknown as ChatContextValue}>\n {children}\n </ChatContext.Provider>\n);\n\nexport const useChatContext = (componentName?: string) => {\n const contextValue = useContext(ChatContext);\n\n if (!contextValue) {\n console.warn(\n `The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as ChatContextValue;\n }\n\n return contextValue as unknown as ChatContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference so if ChatContext\n * typing is desired while using the HOC withChatContext the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withChatContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithChatContextComponent = (props: Omit<P, keyof ChatContextValue>) => {\n const chatContext = useChatContext();\n\n return <Component {...(props as P)} {...chatContext} />;\n };\n WithChatContextComponent.displayName = `WithChatContext${getDisplayName(Component)}`;\n return WithChatContextComponent;\n};\n", "import type { BaseSyntheticEvent, PropsWithChildren, ReactNode } from 'react';\nimport React, { useContext } from 'react';\n\nimport type {\n DeleteMessageOptions,\n LocalMessage,\n Mute,\n ReactionResponse,\n ReactionSort,\n UserResponse,\n} from 'stream-chat';\n\nimport type { ChannelActionContextValue } from './ChannelActionContext';\n\nimport type { ActionHandlerReturnType } from '../components/Message/hooks/useActionHandler';\nimport type { PinPermissions } from '../components/Message/hooks/usePinHandler';\nimport type { ReactEventHandler } from '../components/Message/types';\nimport type { MessageActionsArray } from '../components/Message/utils';\nimport type { MessageInputProps } from '../components/MessageInput/MessageInput';\nimport type { GroupStyle } from '../components/MessageList/utils';\nimport type {\n ReactionDetailsComparator,\n ReactionsComparator,\n ReactionType,\n} from '../components/Reactions/types';\n\nimport type { RenderTextOptions } from '../components/Message/renderText';\nimport type { UnknownType } from '../types/types';\n\nexport type CustomMessageActions = {\n [key: string]: (\n message: LocalMessage,\n event: React.BaseSyntheticEvent,\n ) => Promise<void> | void;\n};\n\nexport type MessageContextValue = {\n /** If actions such as edit, delete, flag, mute are enabled on Message */\n actionsEnabled: boolean;\n /** Function to exit edit state */\n clearEditingState: (event?: React.BaseSyntheticEvent) => void;\n /** If the Message is in edit state */\n editing: boolean;\n /**\n * Returns all allowed actions on message by current user e.g., ['edit', 'delete', 'flag', 'mute', 'pin', 'quote', 'react', 'reply'].\n * Please check [Message](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message.tsx) component for default implementation.\n */\n getMessageActions: () => MessageActionsArray<string>;\n /** Function to send an action in a Channel */\n handleAction: ActionHandlerReturnType;\n /** Function to delete a message in a Channel */\n handleDelete: (\n event: BaseSyntheticEvent,\n options?: DeleteMessageOptions,\n ) => Promise<void> | void;\n /** Function to edit a message in a Channel */\n handleEdit: ReactEventHandler;\n /** Function to fetch the message reactions */\n handleFetchReactions: (\n reactionType?: ReactionType,\n sort?: ReactionSort,\n ) => Promise<Array<ReactionResponse>>;\n /** Function to flag a message in a Channel */\n handleFlag: ReactEventHandler;\n /** Function to mark message and the messages that follow it as unread in a Channel */\n handleMarkUnread: ReactEventHandler;\n /** Function to mute a user in a Channel */\n handleMute: ReactEventHandler;\n /** Function to open a Thread on a Message */\n handleOpenThread: ReactEventHandler;\n /** Function to pin a Message in a Channel */\n handlePin: ReactEventHandler;\n /** Function to post a reaction on a Message */\n handleReaction: (\n reactionType: string,\n event: React.BaseSyntheticEvent,\n ) => Promise<void>;\n /** Function to retry sending a Message */\n handleRetry: ChannelActionContextValue['retrySendMessage'];\n /** Function that returns whether the Message belongs to the current user */\n isMyMessage: () => boolean;\n /** The message object */\n message: LocalMessage;\n /** Indicates whether a message has not been read yet or has been marked unread */\n messageIsUnread: boolean;\n /** Handler function for a click event on an @mention in Message */\n onMentionsClickMessage: ReactEventHandler;\n /** Handler function for a hover event on an @mention in Message */\n onMentionsHoverMessage: ReactEventHandler;\n /** Handler function for a click event on the user that posted the Message */\n onUserClick: ReactEventHandler;\n /** Handler function for a hover event on the user that posted the Message */\n onUserHover: ReactEventHandler;\n /** Function to toggle the edit state on a Message */\n setEditingState: ReactEventHandler;\n /** Additional props for underlying MessageInput component, [available props](https://getstream.io/chat/docs/sdk/react/message-input-components/message_input/#props) */\n additionalMessageInputProps?: MessageInputProps;\n /** Call this function to keep message list scrolled to the bottom when the scroll height increases, e.g. an element appears below the last message (only used in the `VirtualizedMessageList`) */\n autoscrollToBottom?: () => void;\n /** Message component configuration prop. If true, picking a reaction from the `ReactionSelector` component will close the selector */\n closeReactionSelectorOnClick?: boolean;\n /** Object containing custom message actions and function handlers */\n customMessageActions?: CustomMessageActions;\n /** An array of user IDs that have confirmed the message delivery to their device */\n deliveredTo?: UserResponse[];\n /** If true, the message is the last one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n endOfGroup?: boolean;\n /** If true, the message is the first one in a group sent by a specific user (only used in the `VirtualizedMessageList`) */\n firstOfGroup?: boolean;\n /** Override the default formatting of the date. This is a function that has access to the original date object, returns a string */\n formatDate?: (date: Date) => string;\n /** If true, group messages sent by each user (only used in the `VirtualizedMessageList`) */\n groupedByUser?: boolean;\n /** A list of styles to apply to this message, ie. top, bottom, single */\n groupStyles?: GroupStyle[];\n /** Whether to highlight and focus the message on load */\n highlighted?: boolean;\n /** Whether the threaded message is the first in the thread list */\n initialMessage?: boolean;\n /**\n * A factory function that determines whether a message is AI generated or not.\n */\n isMessageAIGenerated?: (message: LocalMessage) => boolean;\n /** Latest own message in currently displayed message set. */\n lastOwnMessage?: LocalMessage;\n /** Latest message id on current channel */\n lastReceivedId?: string | null;\n /** DOMRect object for parent MessageList component */\n messageListRect?: DOMRect;\n /** Array of muted users coming from [ChannelStateContext](https://getstream.io/chat/docs/sdk/react/contexts/channel_state_context/#mutes) */\n mutes?: Mute[];\n /** @deprecated in favor of `channelCapabilities - The user roles allowed to pin Messages in various channel types */\n pinPermissions?: PinPermissions;\n /** Sort options to provide to a reactions query */\n reactionDetailsSort?: ReactionSort;\n /** A list of users that have read this Message */\n readBy?: UserResponse[];\n /** Custom function to render message text content, defaults to the renderText function: [utils](https://github.com/GetStream/stream-chat-react/blob/master/src/utils.tsx) */\n renderText?: (\n text?: string,\n mentioned_users?: UserResponse[],\n options?: RenderTextOptions,\n ) => ReactNode;\n /** Keep track of read receipts for each message sent by the user. When disabled, only the last own message delivery / read status is rendered. */\n returnAllReadData?: boolean;\n /** Comparator function to sort the list of reacted users\n * @deprecated use `reactionDetailsSort` instead\n */\n sortReactionDetails?: ReactionDetailsComparator;\n /** Comparator function to sort reactions, defaults to chronological order */\n sortReactions?: ReactionsComparator;\n /** Whether or not the Message is in a Thread */\n threadList?: boolean;\n /** render HTML instead of markdown. Posting HTML is only allowed server-side */\n unsafeHTML?: boolean;\n};\n\nexport const MessageContext = React.createContext<MessageContextValue | undefined>(\n undefined,\n);\n\nexport const MessageProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageContextValue;\n}>) => (\n <MessageContext.Provider value={value as unknown as MessageContextValue}>\n {children}\n </MessageContext.Provider>\n);\n\nexport const useMessageContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _componentName?: string,\n) => {\n const contextValue = useContext(MessageContext);\n\n if (!contextValue) {\n return {} as MessageContextValue;\n }\n\n return contextValue as unknown as MessageContextValue;\n};\n\n/**\n * Typescript currently does not support partial inference, so if MessageContext\n * typing is desired while using the HOC withMessageContext, the Props for the\n * wrapped component must be provided as the first generic.\n */\nexport const withMessageContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithMessageContextComponent = (props: Omit<P, keyof MessageContextValue>) => {\n const messageContext = useMessageContext();\n\n return <Component {...(props as P)} {...messageContext} />;\n };\n\n WithMessageContextComponent.displayName = (\n Component.displayName ||\n Component.name ||\n 'Component'\n ).replace('Base', '');\n\n return WithMessageContextComponent;\n};\n", "import React, { useContext } from 'react';\nimport Dayjs from 'dayjs';\nimport calendar from 'dayjs/plugin/calendar';\nimport localizedFormat from 'dayjs/plugin/localizedFormat';\nimport type { PropsWithChildren } from 'react';\nimport type { TFunction } from 'i18next';\nimport type { TranslationLanguages } from 'stream-chat';\n\nimport { getDisplayName } from './utils/getDisplayName';\nimport { defaultDateTimeParser, defaultTranslatorFunction } from '../i18n/utils';\nimport type { UnknownType } from '../types/types';\nimport type { TDateTimeParser } from '../i18n/types';\n\nDayjs.extend(calendar);\nDayjs.extend(localizedFormat);\n\nexport type TranslationContextValue = {\n t: TFunction;\n tDateTimeParser: TDateTimeParser;\n userLanguage: TranslationLanguages;\n};\n\nexport const TranslationContext = React.createContext<TranslationContextValue>({\n t: defaultTranslatorFunction,\n tDateTimeParser: defaultDateTimeParser,\n userLanguage: 'en',\n});\n\nexport const TranslationProvider = ({\n children,\n value,\n}: PropsWithChildren<{ value: TranslationContextValue }>) => (\n <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>\n);\n\nexport const useTranslationContext = (componentName?: string) => {\n const contextValue = useContext(TranslationContext);\n\n if (!contextValue) {\n console.warn(\n `The useTranslationContext hook was called outside of the TranslationContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ${componentName} component.`,\n );\n\n return {} as TranslationContextValue;\n }\n\n return contextValue;\n};\n\nexport const withTranslationContext = <P extends UnknownType>(\n Component: React.ComponentType<P>,\n) => {\n const WithTranslationContextComponent = (\n props: Omit<P, keyof TranslationContextValue>,\n ) => {\n const translationContext = useTranslationContext();\n\n return <Component {...(props as P)} {...translationContext} />;\n };\n\n WithTranslationContextComponent.displayName = `WithTranslationContext${getDisplayName(\n Component,\n )}`;\n\n return WithTranslationContextComponent;\n};\n", "import Dayjs from 'dayjs';\nimport type { Duration as DayjsDuration } from 'dayjs/plugin/duration';\n\nimport type { TFunction } from 'i18next';\nimport type { Moment } from 'moment-timezone';\nimport type {\n DateFormatterOptions,\n DurationFormatterOptions,\n PredefinedFormatters,\n SupportedTranslations,\n TDateTimeParserInput,\n TDateTimeParserOutput,\n TimestampFormatterOptions,\n} from './types';\n\nexport const notValidDateWarning =\n 'MessageTimestamp was called without a message, or message has invalid created_at date.';\nexport const noParsingFunctionWarning =\n 'MessageTimestamp was called but there is no datetime parsing function available';\n\nexport const isNumberOrString = (\n output: TDateTimeParserOutput,\n): output is number | string => typeof output === 'string' || typeof output === 'number';\n\nexport const isDayOrMoment = (\n output: TDateTimeParserOutput,\n): output is Dayjs.Dayjs | Moment => !!(output as Dayjs.Dayjs | Moment)?.isSame;\n\nexport const isDate = (output: unknown): output is Date =>\n output !== null &&\n typeof output === 'object' &&\n typeof (output as Date).getTime === 'function';\n\nexport function getDateString({\n calendar,\n calendarFormats,\n format,\n formatDate,\n messageCreatedAt,\n t,\n tDateTimeParser,\n timestampTranslationKey,\n}: DateFormatterOptions): string | number | null {\n if (\n !messageCreatedAt ||\n (typeof messageCreatedAt === 'string' && !Date.parse(messageCreatedAt))\n ) {\n console.warn(notValidDateWarning);\n return null;\n }\n\n if (typeof formatDate === 'function') {\n return formatDate(new Date(messageCreatedAt));\n }\n\n if (t && timestampTranslationKey) {\n const options: TimestampFormatterOptions = {};\n if (typeof calendar !== 'undefined' && calendar !== null) options.calendar = calendar;\n if (typeof calendarFormats !== 'undefined' && calendarFormats !== null)\n options.calendarFormats = calendarFormats;\n if (typeof format !== 'undefined' && format !== null) options.format = format;\n\n const translatedTimestamp = t(timestampTranslationKey, {\n ...options,\n timestamp: new Date(messageCreatedAt),\n });\n const translationKeyFound = timestampTranslationKey !== translatedTimestamp;\n if (translationKeyFound) return translatedTimestamp;\n }\n\n if (!tDateTimeParser) {\n console.warn(noParsingFunctionWarning);\n return null;\n }\n\n const parsedTime = tDateTimeParser(messageCreatedAt);\n\n if (isDayOrMoment(parsedTime)) {\n /**\n * parsedTime.calendar is guaranteed on the type but is only\n * available when a user calls dayjs.extend(calendar)\n */\n return calendar && parsedTime.calendar\n ? parsedTime.calendar(undefined, calendarFormats || undefined)\n : parsedTime.format(format || undefined);\n }\n\n if (isDate(parsedTime)) {\n return parsedTime.toDateString();\n }\n\n if (isNumberOrString(parsedTime)) {\n return parsedTime;\n }\n\n return null;\n}\n\nexport const predefinedFormatters: PredefinedFormatters = {\n durationFormatter:\n (streamI18n) =>\n (value, _, { format, withSuffix }: DurationFormatterOptions) => {\n // NOTE: isDayjs is not exported in \"dayjs\" package for ESM, hence we access\n // `isDayjs` from Dayjs instance\n if (format && Dayjs.isDayjs(streamI18n.DateTimeParser)) {\n return (streamI18n.DateTimeParser.duration(value) as DayjsDuration).format(\n format,\n );\n }\n return streamI18n.DateTimeParser.duration(value).humanize(!!withSuffix);\n },\n timestampFormatter:\n (streamI18n) =>\n (\n value,\n _,\n {\n calendarFormats,\n ...options\n }: Pick<TimestampFormatterOptions, 'calendar' | 'format'> & {\n calendarFormats?: Record<string, string> | string;\n },\n ) => {\n let parsedCalendarFormats;\n try {\n if (!options.calendar) {\n parsedCalendarFormats = {};\n } else if (typeof calendarFormats === 'string') {\n parsedCalendarFormats = JSON.parse(calendarFormats);\n } else if (typeof calendarFormats === 'object') {\n parsedCalendarFormats = calendarFormats;\n }\n } catch (e) {\n console.error('[TIMESTAMP FORMATTER]', e);\n }\n\n const result = getDateString({\n ...options,\n calendarFormats: parsedCalendarFormats,\n messageCreatedAt: value,\n tDateTimeParser: streamI18n.tDateTimeParser,\n });\n if (!result || typeof result === 'number') {\n return JSON.stringify(value);\n }\n return result;\n },\n};\n\nexport const defaultTranslatorFunction = ((key: string) => key) as TFunction;\n\nexport const defaultDateTimeParser = (input?: TDateTimeParserInput) => Dayjs(input);\n\nexport const isLanguageSupported = (\n language: string,\n): language is SupportedTranslations => {\n const translations = [\n 'de',\n 'en',\n 'es',\n 'fr',\n 'hi',\n 'it',\n 'ja',\n 'ko',\n 'nl',\n 'pt',\n 'ru',\n 'tr',\n ];\n return translations.some((translation) => language === translation);\n};\n", "import { useEffect, useMemo } from 'react';\nimport { FixedSizeQueueCache, MessageComposer } from 'stream-chat';\nimport { useThreadContext } from '../../Threads';\nimport {\n useChannelStateContext,\n useChatContext,\n useMessageContext,\n} from '../../../context';\nimport { useLegacyThreadContext } from '../../Thread';\n\nconst queueCache = new FixedSizeQueueCache<string, MessageComposer>(64);\n\nexport const useMessageComposer = () => {\n const { client } = useChatContext();\n const { channel } = useChannelStateContext();\n const { editing, message: editedMessage } = useMessageContext();\n // legacy thread will receive new composer\n const { legacyThread: parentMessage } = useLegacyThreadContext();\n const threadInstance = useThreadContext();\n\n const cachedEditedMessage = useMemo(() => {\n if (!editedMessage) return undefined;\n\n return editedMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editedMessage?.id]);\n\n const cachedParentMessage = useMemo(() => {\n if (!parentMessage) return undefined;\n\n return parentMessage;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [parentMessage?.id]);\n\n // composer hierarchy\n // edited message (always new) -> thread instance (own) -> thread message (always new) -> channel (own)\n // editedMessage ?? thread ?? parentMessage ?? channel;\n const messageComposer = useMemo(() => {\n if (editing && cachedEditedMessage) {\n const tag = MessageComposer.constructTag(cachedEditedMessage);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) {\n cachedComposer.editedMessage = cachedEditedMessage;\n return cachedComposer;\n }\n\n return new MessageComposer({\n client,\n composition: cachedEditedMessage,\n compositionContext: cachedEditedMessage,\n });\n } else if (threadInstance) {\n return threadInstance.messageComposer;\n } else if (cachedParentMessage) {\n const compositionContext = {\n ...cachedParentMessage,\n legacyThreadId: cachedParentMessage.id,\n };\n\n const tag = MessageComposer.constructTag(compositionContext);\n\n const cachedComposer = queueCache.get(tag);\n if (cachedComposer) return cachedComposer;\n\n return new MessageComposer({\n client,\n compositionContext,\n });\n } else {\n return channel.messageComposer;\n }\n }, [\n cachedEditedMessage,\n cachedParentMessage,\n channel,\n client,\n editing,\n threadInstance,\n ]);\n\n if (\n (['legacy_thread', 'message'] as MessageComposer['contextType'][]).includes(\n messageComposer.contextType,\n ) &&\n !queueCache.peek(messageComposer.tag)\n ) {\n queueCache.add(messageComposer.tag, messageComposer);\n }\n\n useEffect(() => {\n const unsubscribe = messageComposer.registerSubscriptions();\n return () => {\n unsubscribe();\n };\n }, [messageComposer]);\n\n return messageComposer;\n};\n", "import React, { createContext, useContext } from 'react';\n\nimport { Channel } from '../../components';\n\nimport type { PropsWithChildren } from 'react';\nimport type { Thread } from 'stream-chat';\n\nexport type ThreadContextValue = Thread | undefined;\n\nexport const ThreadContext = createContext<ThreadContextValue>(undefined);\n\nexport const useThreadContext = () => useContext(ThreadContext);\n\nexport const ThreadProvider = ({\n children,\n thread,\n}: PropsWithChildren<{ thread?: Thread }>) => (\n <ThreadContext.Provider value={thread}>\n <Channel channel={thread?.channel}>{children}</Channel>\n </ThreadContext.Provider>\n);\n", "import {\n autoPlacement,\n autoUpdate,\n flip as flipMw,\n offset as offsetMw,\n type Placement,\n shift as shiftMw,\n size as sizeMw,\n useFloating,\n} from '@floating-ui/react';\nimport type { AutoPlacementOptions } from '@floating-ui/core';\n\nconst hasResizeObserver = typeof window !== 'undefined' && 'ResizeObserver' in window;\n\nexport type PopperLikePlacement = Placement | 'auto' | 'auto-start' | 'auto-end';\n\nfunction autoMiddlewareFor(p: PopperLikePlacement) {\n if (!String(p).startsWith('auto')) return null;\n const alignment: AutoPlacementOptions['alignment'] =\n p === 'auto-start' ? 'start' : p === 'auto-end' ? 'end' : undefined;\n return autoPlacement({ alignment });\n}\n\ntype OffsetOpt =\n | number\n | { mainAxis?: number; crossAxis?: number; alignmentAxis?: number }\n | [crossAxis: number, mainAxis: number]; // keep your tuple compat\n\nfunction toOffsetMw(opt?: OffsetOpt) {\n if (opt == null) return null;\n if (Array.isArray(opt)) {\n const [crossAxis, mainAxis] = opt;\n return offsetMw({ crossAxis, mainAxis });\n }\n if (typeof opt === 'number') return offsetMw(opt);\n return offsetMw(opt);\n}\n\nexport type UsePopoverParams = {\n placement?: PopperLikePlacement;\n /** Add flip() when placement is not 'auto*' */\n allowFlip?: boolean;\n /** Keep in viewport; default true to match common popper setups */\n allowShift?: boolean;\n /** The floating UI is fitted to the available space (by constraining its max size) instead of letting it overflow; default false */\n fitAvailableSpace?: boolean;\n /** Offset (number, object, or [crossAxis, mainAxis] tuple) */\n offset?: OffsetOpt;\n /**\n * Freeze behavior like Popper's eventListeners: { scroll:false, resize:false }.\n * If true \u2192 no autoUpdate (you can call `update()` manually).\n */\n freeze?: boolean;\n /**\n * Fine-grained control of autoUpdate triggers (only if freeze=false).\n * Defaults match Popper's \"disabled\" example when all set to false.\n */\n autoUpdateOptions?: Partial<Parameters<typeof autoUpdate>[3]>;\n};\n\nexport function usePopoverPosition({\n allowFlip = true,\n allowShift = true,\n autoUpdateOptions,\n fitAvailableSpace = false,\n freeze = false,\n offset,\n placement = 'bottom-start',\n}: UsePopoverParams) {\n const autoMw = autoMiddlewareFor(placement);\n const offsetMiddleware = toOffsetMw(offset);\n const isSidePlacement = placement.startsWith('left') || placement.startsWith('right');\n\n const middleware = [\n // offset first (mirrors common Popper setups)\n ...(offsetMiddleware ? [offsetMiddleware] : []),\n\n // choose between autoPlacement (Popper's \"auto*\") OR flip()\n // only allow flip when not explicitly 'left*' or 'right*'\n ...(autoMw ? [autoMw] : allowFlip && !isSidePlacement ? [flipMw()] : []),\n\n // viewport collision adjustments\n ...(allowShift ? [shiftMw({ padding: 8 })] : []),\n\n // optional size constraining\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n ...(fitAvailableSpace ? [sizeMw({ apply: () => {} })] : []),\n ];\n\n // if placement is 'auto*', seed with any static placement; autoPlacement will pick the final one\n const seedPlacement: Placement = String(placement).startsWith('auto')\n ? 'bottom'\n : (placement as Placement);\n\n return useFloating({\n middleware,\n placement: seedPlacement,\n strategy: 'fixed',\n whileElementsMounted: freeze\n ? undefined\n : (reference, floating, update) =>\n autoUpdate(reference, floating, update, {\n ancestorResize: true,\n ancestorScroll: true,\n animationFrame: false,\n elementResize: hasResizeObserver,\n ...autoUpdateOptions,\n }),\n });\n}\n", "import React, { useContext } from 'react';\nimport type { LocalMessage } from 'stream-chat';\n\nexport const LegacyThreadContext = React.createContext<{\n legacyThread: LocalMessage | undefined;\n}>({ legacyThread: undefined });\n\nexport const useLegacyThreadContext = () => useContext(LegacyThreadContext);\n", "import React, { createContext, useContext } from 'react';\nimport type { PropsWithChildren } from 'react';\n\nimport type { CooldownTimerState, MessageInputProps } from '../components/MessageInput';\nimport type { MessageInputHookProps } from '../components/MessageInput/hooks/useMessageInputControls';\n\nexport type MessageInputContextValue = MessageInputHookProps &\n Omit<MessageInputProps, 'Input'> &\n CooldownTimerState;\n\nexport const MessageInputContext = createContext<MessageInputHookProps | undefined>(\n undefined,\n);\n\nexport const MessageInputContextProvider = ({\n children,\n value,\n}: PropsWithChildren<{\n value: MessageInputContextValue;\n}>) => (\n <MessageInputContext.Provider value={value as unknown as MessageInputContextValue}>\n {children}\n </MessageInputContext.Provider>\n);\n\nexport const useMessageInputContext = (\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentName?: string,\n) => {\n const contextValue = useContext(MessageInputContext);\n\n if (!contextValue) {\n return {} as MessageInputContextValue;\n }\n\n return contextValue as unknown as MessageInputContextValue;\n};\n", "import mergeWith from 'lodash.mergewith';\nimport type {\n Middleware,\n SearchSourceOptions,\n SearchSourceType,\n TextComposerMiddlewareExecutorState,\n TextComposerMiddlewareOptions,\n TextComposerSuggestion,\n} from 'stream-chat';\nimport {\n BaseSearchSource,\n getTokenizedSuggestionDisplayName,\n getTriggerCharWithToken,\n insertItemWithTrigger,\n replaceWordWithEntity,\n} from 'stream-chat';\nimport type {\n EmojiSearchIndex,\n EmojiSearchIndexResult,\n} from '../../../components/MessageInput';\n\nexport type EmojiSuggestion<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n TextComposerSuggestion<T>;\n\nclass EmojiSearchSource<\n T extends TextComposerSuggestion<EmojiSearchIndexResult>,\n> extends BaseSearchSource<T> {\n readonly type: SearchSourceType = 'emoji';\n private emojiSearchIndex: EmojiSearchIndex;\n\n constructor(emojiSearchIndex: EmojiSearchIndex, options?: SearchSourceOptions) {\n super(options);\n this.emojiSearchIndex = emojiSearchIndex;\n }\n\n async query(searchQuery: string) {\n if (searchQuery.length === 0) {\n return { items: [] as T[], next: null };\n }\n const emojis = (await this.emojiSearchIndex.search(searchQuery)) ?? [];\n\n // emojiIndex.search sometimes returns undefined values, so filter those out first\n return {\n items: emojis\n .filter(Boolean)\n .slice(0, 7)\n .map(({ emoticons = [], id, name, native, skins = [] }) => {\n const [firstSkin] = skins;\n\n return {\n emoticons,\n id,\n name,\n native: native ?? firstSkin.native,\n };\n }) as T[],\n next: null, // todo: generate cursor\n };\n }\n\n protected filterQueryResults(items: T[]): T[] | Promise<T[]> {\n return items.map((item) => ({\n ...item,\n ...getTokenizedSuggestionDisplayName({\n displayName: item.id,\n searchToken: this.searchQuery,\n }),\n }));\n }\n}\n\nconst DEFAULT_OPTIONS: TextComposerMiddlewareOptions = { minChars: 1, trigger: ':' };\n\nexport type EmojiMiddleware<T extends EmojiSearchIndexResult = EmojiSearchIndexResult> =\n Middleware<\n TextComposerMiddlewareExecutorState<EmojiSuggestion<T>>,\n 'onChange' | 'onSuggestionItemSelect'\n >;\n\n/**\n * TextComposer middleware for mentions\n * Usage:\n *\n * const textComposer = new TextComposer(options);\n *\n * textComposer.use(new createTextComposerEmojiMiddleware(emojiSearchIndex, {\n * minChars: 2\n * }));\n *\n * @param emojiSearchIndex\n * @param {{\n * minChars: number;\n * trigger: string;\n * }} options\n * @returns\n */\nexport const createTextComposerEmojiMiddleware = (\n emojiSearchIndex: EmojiSearchIndex,\n options?: Partial<TextComposerMiddlewareOptions>,\n): EmojiMiddleware => {\n const finalOptions = mergeWith(DEFAULT_OPTIONS, options ?? {});\n const emojiSearchSource = new EmojiSearchSource(emojiSearchIndex);\n emojiSearchSource.activate();\n\n return {\n id: 'stream-io/emoji-middleware',\n // eslint-disable-next-line sort-keys\n handlers: {\n onChange: async ({ complete, forward, next, state }) => {\n if (!state.selection) return forward();\n\n const triggerWithToken = getTriggerCharWithToken({\n acceptTrailingSpaces: false,\n text: state.text.slice(0, state.selection.end),\n trigger: finalOptions.trigger,\n });\n\n const triggerWasRemoved =\n !triggerWithToken || triggerWithToken.length < finalOptions.minChars;\n\n if (triggerWasRemoved) {\n const hasSuggestionsForTrigger =\n state.suggestions?.trigger === finalOptions.trigger;\n const newState = { ...state };\n if (hasSuggestionsForTrigger && newState.suggestions) {\n delete newState.suggestions;\n }\n return next(newState);\n }\n\n const newSearchTriggerred =\n triggerWithToken && triggerWithToken === finalOptions.trigger;\n\n if (newSearchTriggerred) {\n emojiSearchSource.resetStateAndActivate();\n }\n\n const textWithReplacedWord = await replaceWordWithEntity({\n caretPosition: state.selection.end,\n getEntityString: async (word: string) => {\n const { items } = await emojiSearchSource.query(word);\n\n const emoji = items\n .filter(Boolean)\n .slice(0, 10)\n .find(({ emoticons }) => !!emoticons?.includes(word));\n\n if (!emoji) return null;\n\n const [firstSkin] = emoji.skins ?? [];\n\n return emoji.native ?? firstSkin.native;\n },\n text: state.text,\n });\n\n if (textWithReplacedWord !== state.text) {\n return complete({\n ...state,\n suggestions: undefined, // to prevent the TextComposerMiddlewareExecutor to run the first page query\n text: textWithReplacedWord,\n });\n }\n\n return complete({\n ...state,\n suggestions: {\n query: triggerWithToken.slice(1),\n searchSource: emojiSearchSource,\n trigger: finalOptions.trigger,\n },\n });\n },\n onSuggestionItemSelect: ({ complete, forward, state }) => {\n const { selectedSuggestion } = state.change ?? {};\n if (!selectedSuggestion || state.suggestions?.trigger !== finalOptions.trigger)\n return forward();\n\n emojiSearchSource.resetStateAndActivate();\n return complete({\n ...state,\n ...insertItemWithTrigger({\n insertText: `${'native' in selectedSuggestion ? selectedSuggestion.native : ''} `,\n selection: state.selection,\n text: state.text,\n trigger: finalOptions.trigger,\n }),\n suggestions: undefined, // Clear suggestions after selection\n });\n },\n },\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["import_react", "React", "import_react", "React", "import_react", "React", "import_react", "React", "import_react", "import_dayjs", "Dayjs", "Dayjs", "calendar", "localizedFormat", "React", "import_react", "import_react", "import_react", "offsetMw", "flipMw", "shiftMw", "sizeMw", "import_react", "React", "import_react", "React", "Picker", "import_stream_chat", "mergeWith"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stream-chat-react",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.14.0",
|
|
4
4
|
"description": "React components to create chat conversations or livestream style chat",
|
|
5
5
|
"author": "GetStream",
|
|
6
6
|
"homepage": "https://getstream.io/chat/",
|
|
@@ -112,7 +112,6 @@
|
|
|
112
112
|
"i18next": "^25.2.1",
|
|
113
113
|
"linkifyjs": "^4.3.2",
|
|
114
114
|
"lodash.debounce": "^4.0.8",
|
|
115
|
-
"lodash.defaultsdeep": "^4.6.1",
|
|
116
115
|
"lodash.mergewith": "^4.6.2",
|
|
117
116
|
"lodash.throttle": "^4.1.1",
|
|
118
117
|
"lodash.uniqby": "^4.7.0",
|