/// import React from "react"; import { ReactNode, FC, Component, ReactElement } from "react"; import { UUIDMetadataObject, ChannelMetadataObject, ObjectCustom, FetchMessagesResponse, BaseObjectsEvent, FileEvent, MessageActionEvent, PresenceEvent, SignalEvent, StatusEvent, FetchMessagesParameters, HereNowParameters, HereNowResponse, GetUUIDMetadataParameters, SubscribeParameters, GetAllMetadataParameters, GetChannelMembersParameters, GetMembershipsParametersv2, UriFileInput } from "pubnub"; import { ImageStyle, TextStyle, ViewStyle, Animated, TextInputProps, NativeScrollEvent, NativeSyntheticEvent } from "react-native"; type Themes = "light" | "dark" | "support" | "support-dark" | "event" | "event-dark"; type ChannelEntity = ChannelMetadataObject; type UserEntity = UUIDMetadataObject; type ChannelEntityWithMembership = ChannelEntity & { membership?: ObjectCustom; }; type UserEntityWithMembership = UserEntity & { membership?: ObjectCustom; }; interface MessageEnvelope { channel?: string; message: MessagePayload | FilePayload; timetoken: string | number; messageType?: string | number; publisher?: string; uuid?: string; meta?: { [key: string]: unknown; }; actions?: { [type: string]: { [value: string]: Array<{ uuid: string; actionTimetoken: string | number; }>; }; }; } interface MessagePayload { id: string; type?: string; text?: string; sender?: UUIDMetadataObject; attachments?: Array; createdAt?: string; [key: string]: unknown; } interface FilePayload { message?: MessagePayload; file: FileAttachment; } interface FileAttachment { id: string; name: string; url?: string; } interface ImageAttachment { type: "image"; image: { source: string; }; } interface LinkAttachment { type: "link"; description?: string; title?: string; icon?: { source: string; }; image: { source: string; }; provider?: { name: string; url: string; }; } interface RetryOptions { maxRetries: number; timeout: number; exponentialFactor: number; } interface ProperFetchMessagesResponse extends FetchMessagesResponse { error: boolean; error_message: string; status: number; more?: { max: number; start: string; url: string; }; } interface CommonChannelListProps { children?: ReactNode; /** Option to pass a list of channels, including metadata, to render on the list. */ channels: ChannelEntity[] | string[]; /** Channels are sorted alphabetically by default, you can override that by providing a sorter function */ sort?: (a: ChannelEntity, b: ChannelEntity) => -1 | 0 | 1; /** Option to provide an extra actions renderer to add custom action buttons to each channel. */ extraActionsRenderer?: (channel: ChannelEntity) => JSX.Element; /** Option to provide a custom channel renderer to override default themes and CSS variables. */ channelRenderer?: (channel: ChannelEntity) => JSX.Element; /** Callback run when a user clicked one of the channels. Can be used to switch the current channel. */ onChannelSwitched?: (channel: ChannelEntity) => unknown; } /** * Renders an interactive list of channels. * * It can represent all channels of the application, only * channels joined by the current user, all channels available to be joined, or whatever else is * passed into it. A common pattern in chat applications is to render two instances of the * component - one visible all the time to show joined channels, and another one hidden inside a * modal with channels available to join. Make sure to handle the onChannelSwitched event to switch * the current channel passed to the Chat provider. */ declare const useChannelListCore: (props: CommonChannelListProps) => { channelFromString: (channel: ChannelEntity | string) => ChannelEntity | { id: string; name: string; }; channelSorter: (a: ChannelEntity, b: ChannelEntity) => number; isChannelActive: (ch: ChannelEntity) => boolean; switchChannel: (channel: ChannelEntity) => void; theme: "" | Themes; }; interface ChatProps { children?: ReactNode; /** General theme to be used by the components. * Exact looks can be tweaked later on with the use of CSS variables. */ theme?: Themes; /** Current channel to display the messages and members from. */ currentChannel: string; /** Array of channels to subscribe to get events. Allows up to 50 channels. Setting this option will disable the auto subscription when switching the current channel. */ channels?: string[]; /** Array of channel groups to subscribe to get events. Allows up to 50 channel groups. Setting this option will disable the auto subscription when switching the current channel group. */ channelGroups?: string[]; /** Option to disable presence events when set to "false." OccupancyIndicator and MemberList components will only work with memberships in that case. */ enablePresence?: boolean; /** Option to provide an external list of user metadata. It's used to display information about senders on MessageList and TypingIndicator. */ users?: UserEntity[]; /** Pass a callback function that will be called to get a User metadata in case it's not passed to the users option */ getUser?: (userId: string) => UserEntity | Promise; /** Option to define a timeout in seconds for typing indicators to hide after the last typed character. */ typingIndicatorTimeout?: number; /** Options for automatic retries on errors. */ retryOptions?: RetryOptions; /** Callback run on new messages. */ onMessage?: (message: MessageEnvelope) => unknown; /** Callback run on signals. */ onSignal?: (message: SignalEvent) => unknown; /** Callback run on message actions. */ onMessageAction?: (event: MessageActionEvent) => unknown; /** Callback run on presence events. */ onPresence?: (event: PresenceEvent) => unknown; /** Callback run on object events. */ onUser?: (event: BaseObjectsEvent) => unknown; /** Callback run on object events. */ onChannel?: (event: BaseObjectsEvent) => unknown; /** Callback run on object events. */ onMembership?: (event: BaseObjectsEvent) => unknown; /** Callback run on file events. */ onFile?: (event: FileEvent) => unknown; /** Callback run on status events. */ onStatus?: (event: StatusEvent) => unknown; /** Callback run on any type of errors raised by the components. */ onError?: (error: Error) => unknown; } /** * Chat provider is used to configure various common options and feed the components with data. * It expects at least a "current" channel to display within components. * * Chat itself is supposed to be wrapped with a PubNubProvider component that is a part of the * PubNub React SDK. You should use it to pre-configure your PubNub instance. Please see Getting * Started page for details. */ declare class Chat extends Component { constructor(props: ChatProps); static defaultProps: { channels: any[]; channelGroups: any[]; theme: "light"; enablePresence: boolean; typingIndicatorTimeout: number; users: any[]; retryOptions: { maxRetries: number; timeout: number; exponentialFactor: number; }; onError: () => void; }; static getDerivedStateFromError(error: Error): { error: Error; }; componentDidCatch(error: Error): void; render(): JSX.Element; } /** * * Internal Chat wrapper with all business logic * */ declare const ChatInternal: FC; declare const getNameInitials: (name: string) => string; declare const getPredefinedColor: (uuid: string) => string; declare const usePrevious: (value: T) => T; declare function isFilePayload(message: MessagePayload | FilePayload): message is FilePayload; interface MessagesByChannel { [channel: string]: MessageEnvelope[]; } type HookReturnValue = [ MessagesByChannel, () => Promise, Error ]; declare const useMessages: (options: FetchMessagesParameters) => HookReturnValue; type ChannelsOccupancy = HereNowResponse["channels"]; type HookReturnValue$0 = [ ChannelsOccupancy, () => void, number, Error, boolean ]; declare const usePresence: (options?: HereNowParameters) => HookReturnValue$0; declare const useUser: (options?: GetUUIDMetadataParameters) => [ UserEntity, Error, boolean ]; declare const useSubscribe: (options?: SubscribeParameters) => (() => void); type HookReturnValue$1 = [ UserEntity[], () => void, number, Error, boolean ]; declare const useUsers: (options?: GetAllMetadataParameters) => HookReturnValue$1; type HookReturnValue$2 = [ ChannelEntity[], () => void, number, Error, boolean ]; declare const useChannels: (options?: GetAllMetadataParameters) => HookReturnValue$2; type HookReturnValue$3 = [ UserEntityWithMembership[], () => void, () => void, number, Error, boolean ]; declare const useChannelMembers: (options: GetChannelMembersParameters) => HookReturnValue$3; type HookReturnValue$4 = [ ChannelEntityWithMembership[], () => void, () => void, number, Error, boolean ]; declare const useUserMemberships: (options?: GetMembershipsParametersv2) => HookReturnValue$4; interface CommonMemberListProps { children?: ReactNode; /** Option to pass a list of members, including metadata, to render on the list. */ members: UserEntity[] | string[]; /** Option to pass a list of present member IDs to mark them with a presence indicator. */ presentMembers?: string[]; /** This text will be added after current user's name */ selfText?: string; /** Members are sorted by presence and alphabetically by default, you can override that by providing a sorter function */ sort?: (a: UserEntity, b: UserEntity) => -1 | 0 | 1; /** Provide extra actions renderer to add custom action buttons to each member */ extraActionsRenderer?: (member: UserEntity) => JSX.Element; /** Option to provide a custom user renderer to override themes and CSS variables. */ memberRenderer?: (member: UserEntity) => JSX.Element; /** A callback run when user clicked one of the members. */ onMemberClicked?: (member: UserEntity) => unknown; } /** * Renders a list of members. * * It can represent all users of the application, only members of * the current channel, users currently subscribed/present on the channel, or whatever else is passed * into it. Custom memberRenderer can be used to modify how the users are rendered. For example * you can add presence indicators. */ declare const useMemberListCore: (props: CommonMemberListProps) => { clickMember: (member: UserEntity) => void; isOwnMember: (uuid: string) => boolean; isPresentMember: (uuid: string) => boolean; memberFromString: (member: UserEntity | string) => UserEntity | { id: string; name: string; }; memberSorter: (a: any, b: any) => any; theme: "" | Themes; }; interface CommonMessageInputProps { /** Option to set a placeholder message to display in the text window. */ placeholder?: string; /** Option to set a draft message to display in the text window. */ draftMessage?: string; /** Option to attach sender data directly to each message. Enable it for high-throughput environments. * This is an alternative to providing a full list of users directly into the Chat provider. */ senderInfo?: boolean; /** Option to enable/disable firing the typing events when a user is typing a message. */ typingIndicator?: boolean; /** Option to enable/disable the internal file upload capability. */ fileUpload?: "image" | "all"; /** Option to disable the input from composing and sending messages. */ disabled?: boolean; /** Custom UI component to override default display for the Send button. */ sendButton?: JSX.Element | string; /** Option to move action buttons (eg. file upload icon) to the right of the text input. */ actionsAfterInput?: boolean; /** Callback to modify message content before sending it. This only works for text messages, not files. */ onBeforeSend?: (value: MessagePayload) => MessagePayload; /** Callback for extra actions after sending a message. */ onSend?: (value: MessagePayload | File | UriFileInput) => void; /** Option to provide an extra actions renderer to add custom action buttons to the input. */ extraActionsRenderer?: () => JSX.Element; /** Callback to render custom file preview JSX Element */ filePreviewRenderer?: (file: File | UriFileInput) => JSX.Element | null; } /** * Allows users to compose messages using text and emojis * and automatically publish them on PubNub channels upon sending. */ declare const useMessageInputCore: (props: CommonMessageInputProps) => { clearInput: () => void; file: File | UriFileInput; setFile: import("react").Dispatch>; isValidInputText: () => boolean; loader: boolean; onError: (error: Error) => unknown; sendMessage: () => Promise; setText: import("react").Dispatch>; text: string; theme: "" | Themes; startTypingIndicator: () => Promise; stopTypingIndicator: () => Promise; }; interface MessageRendererProps { isOwn: boolean; message: MessageEnvelope; time: string; editedText: string; user?: UserEntity; } interface CommonMessageListProps { children?: ReactNode; /** Set this option to a non-zero value to enable fetching messages from the History API. This feature uses the infinite scrolling pattern and takes a maximum value of 25. */ fetchMessages?: number; /** Option to enable rendering reactions that were added to messages. Make sure to also set up reactionsPicker when this option is enabled. */ enableReactions?: boolean; /** Option to provide custom welcome messages to replace the default ones. Set to "false" to disable it. */ welcomeMessages?: false | MessageEnvelope | MessageEnvelope[]; /** Option to provide an extra actions renderer to add custom action buttons to each message. */ extraActionsRenderer?: (message: MessageEnvelope) => JSX.Element; /** Option to provide a custom message item renderer if themes and CSS variables aren't enough. */ messageRenderer?: (props: MessageRendererProps) => JSX.Element; /** Option to provide a custom message bubble renderer if themes and CSS variables aren't enough. */ bubbleRenderer?: (props: MessageRendererProps) => JSX.Element; /** Option to provide a custom file renderer to change how images and other files are shown. */ fileRenderer?: (file: FileAttachment) => JSX.Element; /** This option only works when you use either `messageRenderer` or `bubbleRenderer`. It allows you to apply one of the custom renderers only to the messages selected by the filter. */ filter?: (message: MessageEnvelope) => boolean; /** Enable this to render deleted messages instead of filtering them out. They can be then customized with one of the renderers. */ renderDeleted?: boolean; } /** * Fetches historical messages using the scrolling pagination pattern and subscribes to the current * channel to stay up to date with new messages. * * It also displays data in an interactive list, including * user names, avatars, the time when a message was sent, and attachments (links, images) and allows to react to * messages with emojis and to show those reactions immediately. */ declare const useMessageListCore: (props: CommonMessageListProps) => { addReaction: (reaction: string, messageTimetoken: string | number) => Promise; channel: string; emojiPickerShown: boolean; fetchHistory: () => Promise; fetchingMessages: boolean; getTime: (timestamp: number) => string; getUser: (uuid: string) => UserEntity; isOwnMessage: (uuid: string) => boolean; messages: MessageEnvelope[]; onError: (error: Error) => unknown; paginationEnd: boolean; prevChannel: string; prevMessages: MessageEnvelope[]; pubnub: import("pubnub"); reactingToMessage: any; removeReaction: (reaction: string, messageTimetoken: any, actionTimetoken: any) => Promise; scrolledBottom: boolean; setEmojiPickerShown: import("react").Dispatch>; setReactingToMessage: import("react").Dispatch; setScrolledBottom: import("react").Dispatch>; setUnreadMessages: import("react").Dispatch>; theme: "" | Themes; unreadMessages: number; users: UserEntity[]; initMessagesLoaded: {}; setInitMessagesLoaded: import("react").Dispatch>; }; declare const ThemeAtom: import("jotai").PrimitiveAtom<"" | Themes> & { init: "" | Themes; }; declare const CurrentChannelAtom: import("jotai").PrimitiveAtom & { init: string; }; declare const SubscribeChannelsAtom: import("jotai").PrimitiveAtom & { init: string[]; }; declare const SubscribeChannelGroupsAtom: import("jotai").PrimitiveAtom & { init: string[]; }; declare const UsersMetaAtom: import("jotai").PrimitiveAtom & { init: UserEntity[]; }; declare const MessagesAtom: import("jotai").PrimitiveAtom<{ [channel: string]: MessageEnvelope[]; }> & { init: { [channel: string]: MessageEnvelope[]; }; }; declare const PaginationAtom: import("jotai").PrimitiveAtom<{ [channel: string]: boolean; }> & { init: { [channel: string]: boolean; }; }; declare const TypingIndicatorAtom: import("jotai").PrimitiveAtom<{}> & { init: {}; }; declare const TypingIndicatorTimeoutAtom: import("jotai").PrimitiveAtom & { init: number; }; declare const RetryFunctionAtom: import("jotai").PrimitiveAtom<{ function: (fn: () => Promise) => Promise; }> & { init: { function: (fn: () => Promise) => Promise; }; }; declare const ErrorFunctionAtom: import("jotai").PrimitiveAtom<{ function: (error: Error) => unknown; }> & { init: { function: (error: Error) => unknown; }; }; declare const MissingUserCallbackAtom: import("jotai").PrimitiveAtom<{ function?: (userId: string) => UserEntity | Promise; }> & { init: { function?: (userId: string) => UserEntity | Promise; }; }; declare const RequestMissingUserAtom: import("jotai").WritableAtom>; declare const CurrentChannelMessagesAtom: import("jotai").WritableAtom; declare const CurrentChannelPaginationAtom: import("jotai").WritableAtom; declare const CurrentChannelTypingIndicatorAtom: import("jotai").WritableAtom; interface CommonTypingIndicatorProps { /** Option to put a typing indicator inside the MessageList component to render indicators as messages. */ showAsMessage?: boolean; } /** Subscribes to events generated by MessageInput to display information about users that are * currently typing messages. * * It can be displayed as a text denoting the user's name, or in a form similar to * a message that can be renderer inside MessageList. */ declare const useTypingIndicatorCore: (props: CommonTypingIndicatorProps) => { activeUUIDs: any[]; getIndicationString: () => string; theme: "" | Themes; users: UserEntity[]; }; interface ChannelListStyle { channelListWrapper?: ViewStyle; channelList?: ViewStyle; channel?: ViewStyle; channelActive?: ViewStyle; channelPressed?: ViewStyle; channelTitle?: ViewStyle; channelName?: TextStyle; channelDescription?: TextStyle; channelThumb?: ImageStyle; channelActions?: ViewStyle; } declare const _default: (theme: Themes) => ChannelListStyle; type ChannelListProps = CommonChannelListProps & { /** Callback run when a user long pressed one of the channels. Can be used for extra actions menu. */ onChannelLongPressed?: (channel: ChannelEntity) => unknown; /** Options to provide custom StyleSheet for the component. It will be merged with the default styles. */ style?: ChannelListStyle; }; /** * Renders an interactive list of channels. * * It can represent all channels of the application, only * channels joined by the current user, all channels available to be joined, or whatever else is * passed into it. A common pattern in chat applications is to render two instances of the * component - one visible all the time to show joined channels, and another one hidden inside a * modal with channels available to join. Make sure to handle the onChannelSwitched event to switch * the current channel passed to the Chat provider. */ declare const ChannelList: FC; interface UseStyleProps { theme: Themes | ""; createDefaultStyle: (theme: Themes | "") => T; customStyle?: T; } declare const useStyle: (props: UseStyleProps) => T; declare const useRotation: (shouldRun?: boolean) => Animated.AnimatedInterpolation; interface MemberListStyle { memberListWrapper?: ViewStyle; memberList?: ViewStyle; member?: ViewStyle; memberPressed?: ViewStyle; memberTitle?: ViewStyle; memberName?: TextStyle; memberDescription?: TextStyle; memberThumb?: ViewStyle; memberThumbImage?: ImageStyle; memberThumbText?: TextStyle; memberActions?: ViewStyle; memberPresence?: ViewStyle; } declare const _default: (theme: Themes) => MemberListStyle; type MemberListProps = CommonMemberListProps & { /** Callback run when a user long pressed one of the members. Can be used for extra actions menu. */ onMemberLongPressed?: (member: UserEntity) => unknown; /** Options to provide custom StyleSheet for the component. It will be merged with the default styles. */ style?: MemberListStyle; }; /** * Renders a list of members. * * It can represent all users of the application, only members of * the current channel, users currently subscribed/present on the channel, or whatever else is passed * into it. Custom memberRenderer can be used to modify how the users are rendered. For example * you can add presence indicators. */ declare const MemberList: FC; interface MessageInputStyle { messageInputWrapper?: ViewStyle; messageInputContent?: ViewStyle; messageInput?: ViewStyle; messageInputPlaceholder?: TextStyle; messageInputFileLabel?: ViewStyle; messageInputRemoveFileLabel?: ViewStyle; sendButton?: ViewStyle; sendButtonActive?: ViewStyle; icon?: ImageStyle; extraActions?: ViewStyle; fileUploadModalContent?: ViewStyle; fileUploadModalSheetContainer?: ViewStyle; fileUploadModalSheetContent?: ViewStyle; fileUploadModalSheetContentHeaderContainer?: ViewStyle; fileUploadModalSheetContentHeaderText?: ViewStyle; fileUploadModalSheetContentCloseIconContainer?: ViewStyle; fileUploadModalSheetContentCloseIcon?: ImageStyle; fileUploadModalSheetContentButton?: ViewStyle; fileUploadModalSheetContentButtonIcon?: ImageStyle; fileUploadModalSheetContentTextStyle?: ViewStyle; filePreviewContainer?: ViewStyle; filePreviewText?: TextStyle; } declare const _default: (theme: Themes) => MessageInputStyle; type MessageInputProps = CommonMessageInputProps & { /** Options to provide custom StyleSheet for the component. It will be merged with the default styles. */ style?: MessageInputStyle; fileModalRenderer?: (params: { pickPhoto: () => Promise; pickDocument: () => Promise; modalVisible: boolean; setModalVisible: React.Dispatch>; }) => JSX.Element; onChange?: (newText: string) => void; sendMessageOnSubmitEditing?: boolean; } & Omit; /** * Allows users to compose messages using text and emojis * and automatically publish them on PubNub channels upon sending. */ declare const MessageInput: FC; interface MessageListStyle { messageList?: ViewStyle; messageListScroller?: ViewStyle; message?: ViewStyle; messagePressed?: ViewStyle; messageOwn?: ViewStyle; messageAvatar?: ViewStyle; messageOwnAvatar?: ViewStyle; messageAvatarImage?: ImageStyle; messageAvatarText?: ViewStyle; messageMain?: ViewStyle; messageOwnMain?: ViewStyle; messageTitle?: ViewStyle; messageOwnTitle?: ViewStyle; messageAuthor?: TextStyle; messageTime?: TextStyle; messageBubble?: TextStyle; reactionWrapper?: ViewStyle; reaction?: ViewStyle; reactionActive?: ViewStyle; reactionText?: TextStyle; spinner?: ImageStyle; spinnerWrapper?: ViewStyle; unread?: ViewStyle; unreadText?: TextStyle; imageFile?: ImageStyle; fileNameText?: TextStyle; downloadIconStyle?: ImageStyle; fileDownloadContainer?: ViewStyle; downloadedSuccessBanner?: ViewStyle; downloadedSuccessBannerContent?: ViewStyle; downloadedSuccessBannerText?: TextStyle; downloadingInProgressIconContainer?: ViewStyle; } declare const _default: (theme: Themes) => MessageListStyle; interface EmojiPickerElementProps { onEmojiSelected?: ({ emoji }: { emoji: string; }) => void; onClose?: () => void; open?: boolean; } type MessageListProps = CommonMessageListProps & { /** Option to pass in a component that will be used for picking message reactions. For more details, refer to the Message Reactions section in the docs. */ reactionsPicker?: ReactElement; /** Callback run on a list scroll. */ onScroll?: (event: NativeSyntheticEvent) => void; /** Options to provide custom StyleSheet for the component. It will be merged with the default styles. */ style?: MessageListStyle; }; /** * Fetches historical messages using the scrolling pagination pattern and subscribes to the current * channel to stay up to date with new messages. * * It also displays data in an interactive list, including * user names, avatars, the time when a message was sent, and attachments (links, images) and allows to react to * messages with emojis and to show those reactions immediately. */ declare const MessageList: FC; interface TypingIndicatorStyle { typingIndicator?: TextStyle; } declare const _default: (theme: Themes) => TypingIndicatorStyle; type TypingIndicatorProps = CommonTypingIndicatorProps & { /** Options to provide custom StyleSheet for the component. It will be merged with the default styles. */ style?: TypingIndicatorStyle & MessageListStyle; }; /** Subscribes to events generated by MessageInput to display information about users that are * currently typing messages. * * It can be displayed as a text denoting the user's name, or in a form similar to * a message that can be renderer inside MessageList. */ declare const TypingIndicator: FC; export { CommonChannelListProps, useChannelListCore, ChatProps, Chat, ChatInternal, getNameInitials, getPredefinedColor, usePrevious, isFilePayload, useMessages, usePresence, useUser, useSubscribe, useUsers, useChannels, useChannelMembers, useUserMemberships, CommonMemberListProps, useMemberListCore, CommonMessageInputProps, useMessageInputCore, MessageRendererProps, CommonMessageListProps, useMessageListCore, ThemeAtom, CurrentChannelAtom, SubscribeChannelsAtom, SubscribeChannelGroupsAtom, UsersMetaAtom, MessagesAtom, PaginationAtom, TypingIndicatorAtom, TypingIndicatorTimeoutAtom, RetryFunctionAtom, ErrorFunctionAtom, MissingUserCallbackAtom, RequestMissingUserAtom, CurrentChannelMessagesAtom, CurrentChannelPaginationAtom, CurrentChannelTypingIndicatorAtom, Themes, ChannelEntity, UserEntity, ChannelEntityWithMembership, UserEntityWithMembership, MessageEnvelope, MessagePayload, FilePayload, FileAttachment, ImageAttachment, LinkAttachment, RetryOptions, ProperFetchMessagesResponse, CommonTypingIndicatorProps, useTypingIndicatorCore, ChannelListProps, ChannelList, ChannelListStyle, _default, UseStyleProps, useStyle, useRotation, MemberListProps, MemberList, MemberListStyle, MessageInputProps, MessageInput, MessageInputStyle, MessageListProps, MessageList, MessageListStyle, EmojiPickerElementProps, TypingIndicatorProps, TypingIndicator, TypingIndicatorStyle };