@gifyourgame/stream-chat-react
Version:
React components to create chat conversations or livestream style chat
1,294 lines (1,192 loc) • 41.6 kB
TypeScript
// TypeScript Version: 2.8
/** Components */
import * as React from 'react';
import * as Client from 'stream-chat';
import SeamlessImmutable, {
ImmutableArray,
ImmutableObject,
} from 'seamless-immutable';
import { MessageResponse } from 'stream-chat';
import ReactMarkdown from 'react-markdown';
import * as i18next from 'i18next';
import * as Dayjs from 'dayjs';
export interface ChatContextValue {
client: Client.StreamChat;
channel?: Client.Channel;
setActiveChannel?(
channel: Client.Channel,
watchers?: SeamlessImmutable.Immutable<{ [user_id: string]: Client.User }>,
event?: React.SyntheticEvent,
): void;
openNav?: boolean;
openMobileNav?(): void;
closeMobileNav?(): void;
theme?: string;
mutes?: Client.Mute[];
}
export interface ChannelContextValue extends ChatContextValue {
Message?: React.ElementType<MessageUIComponentProps>;
Attachment?: React.ElementType<AttachmentUIComponentProps>;
Avatar?: React.ElementType<AvatarProps>;
messages?: Client.MessageResponse[];
online?: boolean;
typing?: SeamlessImmutable.Immutable<{
[user_id: string]: Client.Event<Client.TypingStartEvent>;
}>;
watcher_count?: number;
watchers?: SeamlessImmutable.Immutable<{ [user_id: string]: Client.User }>;
members?: SeamlessImmutable.Immutable<{ [user_id: string]: Client.Member }>;
read?: {
[user_id: string]: SeamlessImmutable.Immutable<{
last_read: string;
user: Client.UserResponse;
}>;
};
error?: boolean | Error;
// Loading the intial content of the channel
loading?: boolean;
// Loading more messages
loadingMore?: boolean;
hasMore?: boolean;
threadLoadingMore?: boolean;
threadHasMore?: boolean;
eventHistory?: {
[lastMessageId: string]: (
| Client.MemberAddedEvent
| Client.MemberRemovedEvent
)[];
};
thread?: Client.MessageResponse | null;
threadMessages?: Client.MessageResponse[];
multipleUploads?: boolean;
acceptedFiles?: string[];
maxNumberOfFiles?: number;
sendMessage?(message: Client.Message): Promise<any>;
editMessage?(updatedMessage: Client.Message): Promise<any>;
/** Via Context: The function to update a message, handled by the Channel component */
updateMessage?(
updatedMessage: Client.MessageResponse,
extraState?: object,
): void;
/** Function executed when user clicks on link to open thread */
retrySendMessage?(message: Client.Message): Promise<void>;
removeMessage?(updatedMessage: Client.MessageResponse): void;
/** Function to be called when a @mention is clicked. Function has access to the DOM event and the target user object */
onMentionsClick?(e: React.MouseEvent, user: Client.UserResponse[]): void;
/** Function to be called when hovering over a @mention. Function has access to the DOM event and the target user object */
onMentionsHover?(e: React.MouseEvent, user: Client.UserResponse[]): void;
openThread?(
message: Client.MessageResponse,
event: React.SyntheticEvent,
): void;
loadMore?(): void;
// thread related
closeThread(event: React.SyntheticEvent): void;
loadMoreThread?(): void;
/** Via Context: The function is called when the list scrolls */
listenToScroll?(offset: number): void;
}
export interface ChatProps {
client: Client.StreamChat;
// Available built in themes:
// 'messaging light'
// | 'messaging dark'
// | 'team light'
// | 'team dark'
// | 'commerce light'
// | 'commerce dark'
// | 'gaming light'
// | 'gaming dark'
// | 'livestream light'
// | 'livestream dark'
theme?: string;
i18nInstance?: Streami18n;
initialNavOpen?: boolean;
}
export interface ChannelProps
extends ChatContextValue,
TranslationContextValue {
/** The loading indicator to use */
LoadingIndicator?: React.ElementType<LoadingIndicatorProps>;
LoadingErrorIndicator?: React.ElementType<LoadingErrorIndicatorProps>;
Message?: React.ElementType<MessageUIComponentProps>;
Attachment?: React.ElementType<AttachmentUIComponentProps>;
Avatar?: React.ElementType<Avatar>;
mutes?: Client.Mute[];
multipleUploads?: boolean;
acceptedFiles?: string[];
maxNumberOfFiles?: number;
/** Function to be called when a @mention is clicked. Function has access to the DOM event and the target user object */
onMentionsClick?(e: React.MouseEvent, user: Client.UserResponse): void;
/** Function to be called when hovering over a @mention. Function has access to the DOM event and the target user object */
onMentionsHover?(e: React.MouseEvent, user: Client.UserResponse): void;
/** Override send message request (Advanced usage only) */
doSendMessageRequest?(
channelId: string,
message: Client.Message,
): Promise<Client.MessageResponse> | void;
/** Override update(edit) message request (Advanced usage only) */
doUpdateMessageRequest?(
channelId: string,
updatedMessage: Client.Message,
): Promise<Client.MessageResponse> | void;
}
export interface ChannelListProps extends ChatContextValue {
Avatar?: React.ElementType<AvatarProps>;
List?: React.ElementType<ChannelListUIComponentProps>;
EmptyStateIndicator?: React.ElementType<EmptyStateIndicatorProps>;
/** The Preview to use, defaults to ChannelPreviewLastMessage */
Preview?: React.ElementType<ChannelPreviewUIComponentProps>;
/** The loading indicator to use */
LoadingIndicator?: React.ElementType<LoadingIndicatorProps>;
LoadingErrorIndicator?: React.ElementType<LoadingErrorIndicatorProps>;
Paginator?: React.ElementType<PaginatorProps>;
lockChannelOrder?: boolean;
onMessageNew?(
thisArg: React.Component<ChannelListProps>,
e: Client.Event<Client.MessageNewEvent>,
): any;
/** Function that overrides default behaviour when users gets added to a channel */
onAddedToChannel?(
thisArg: React.Component<ChannelListProps>,
e: Client.Event<Client.NotificationAddedToChannelEvent>,
): any;
/** Function that overrides default behaviour when users gets removed from a channel */
onRemovedFromChannel?(
thisArg: React.Component<ChannelListProps>,
e: Client.Event<Client.NotificationRemovedFromChannelEvent>,
): any;
onChannelUpdated?(
thisArg: React.Component<ChannelListProps>,
e: Client.Event<Client.ChannelUpdatedEvent>,
): any;
onChannelDeleted?(
thisArg: React.Component<ChannelListProps>,
e: Client.Event<Client.ChannelDeletedEvent>,
): void;
onChannelTruncated?(
thisArg: React.Component<ChannelListProps>,
e: Client.Event<Client.ChannelTruncatedEvent>,
): void;
setActiveChannelOnMount?: boolean;
/** Object containing query filters */
filters: object;
/** Object containing query options */
options?: object;
/** Object containing sort parameters */
sort?: object;
showSidebar?: boolean;
}
export interface ChannelListUIComponentProps extends ChatContextValue {
/** If channel list ran into error */
error?: boolean;
/** If channel list is in loading state */
loading?: boolean;
showSidebar?: boolean;
/**
* Loading indicator UI Component. It will be displayed if `loading` prop is true.
*
* Defaults to and accepts same props as:
* [LoadingChannels](https://github.com/GetStream/stream-chat-react/blob/master/src/components/LoadingChannels.js)
*
*/
LoadingIndicator?: React.ElementType<LoadingChannelsProps>;
/**
* Error indicator UI Component. It will be displayed if `error` prop is true
*
* Defaults to and accepts same props as:
* [ChatDown](https://github.com/GetStream/stream-chat-react/blob/master/src/components/ChatDown.js)
*
*/
LoadingErrorIndicator?: React.ElementType<ChatDownProps>;
}
export interface ChannelPreviewProps {
/** The Avatar to use, defaults to our Avatar */
Avatar?: React.ElementType<AvatarProps>;
/** **Available from [chat context](https://getstream.github.io/stream-chat-react/#chat)** */
channel: Client.Channel;
/** Current selected channel object */
activeChannel?: Client.Channel;
/**
* Available built-in options (also accepts the same props as):
*
* 1. [ChannelPreviewCompact](https://getstream.github.io/stream-chat-react/#ChannelPreviewCompact) (default)
* 2. [ChannelPreviewLastMessage](https://getstream.github.io/stream-chat-react/#ChannelPreviewLastMessage)
* 3. [ChannelPreviewMessanger](https://getstream.github.io/stream-chat-react/#ChannelPreviewMessanger)
*
* The Preview to use, defaults to ChannelPreviewLastMessage
* */
Preview?: React.ElementType<ChannelPreviewUIComponentProps>;
key: string;
/** Setter for selected channel */
setActiveChannel(
channel: Client.Channel,
watchers?: SeamlessImmutable.Immutable<{ [user_id: string]: Client.User }>,
e?: React.BaseSyntheticEvent,
): void;
// Following props is just to make sure preview component gets updated after connection is recovered.
// It is not actually used anywhere internally
connectionRecoveredCount?: number;
channelUpdateCount?: number;
}
export interface ChannelPreviewUIComponentProps extends ChannelPreviewProps {
/** Title of channel to display */
displayTitle?: string;
/** Image of channel to display */
displayImage?: string;
/** Latest message's text. */
latestMessage?: string;
/** Length of latest message to truncate at */
latestMessageLength?: number;
active?: boolean;
/** Following props are coming from state of ChannelPreview */
unread?: number;
lastMessage?: Client.MessageResponse;
lastRead?: Date;
/** The Avatar to use, defaults to our Avatar */
Avatar?: React.ElementType<AvatarProps>;
}
export interface PaginatorProps {
/** callback to load the next page */
loadNextPage(): void;
hasNextPage?: boolean;
/** indicates if there there's currently any refreshing taking place */
refreshing?: boolean;
}
export interface LoadMorePaginatorProps extends PaginatorProps {
/** display the items in opposite order */
reverse: boolean;
LoadMoreButton: React.ElementType;
}
export interface InfiniteScrollPaginatorProps extends PaginatorProps {
/** display the items in opposite order */
reverse?: boolean;
/** Offset from when to start the loadNextPage call */
threshold?: number;
/** The loading indicator to use */
LoadingIndicator?: React.ElementType<LoadingIndicatorProps>;
}
export interface LoadingIndicatorProps {
/** The size of the loading icon */
size?: number;
/** Set the color of the LoadingIndicator */
color?: string;
}
export interface LoadingErrorIndicatorProps extends TranslationContextValue {
error: boolean | object;
}
export interface AvatarProps {
/** image url */
image?: string | null;
/** name of the picture, used for title tag fallback */
name?: string;
/** shape of the avatar, circle, rounded or square */
shape?: 'circle' | 'rounded' | 'square';
/** size in pixels */
size?: number;
user?: object;
/** onClick handler */
onClick?(e: React.MouseEvent): void;
/** onMouseOver handler */
onMouseOver?(e: React.MouseEvent): void;
}
export interface DateSeparatorProps extends TranslationContextValue {
/** The date to format */
date: Date;
/** Set the position of the date in the separator */
position?: 'left' | 'center' | 'right';
/** Override the default formatting of the date. This is a function that has access to the original date object. Returns a string or Node */
formatDate?(date: Date): string;
}
export interface EmptyStateIndicatorProps extends TranslationContextValue {
/** List Type */
listType: string;
}
export interface SendButtonProps {
/** Function that gets triggered on click */
sendMessage(e: React.MouseEvent<HTMLButtonElement, MouseEvent>): void;
}
export interface MessageListProps
extends ChannelContextValue,
TranslationContextValue {
/** Typing indicator component to render */
TypingIndicator?: React.ElementType<TypingIndicatorProps>;
/** Component to render at the top of the MessageList */
HeaderComponent?: React.ElementType;
/** Component to render at the top of the MessageList */
EmptyStateIndicator?: React.ElementType<EmptyStateIndicatorProps>;
LoadingIndicator?: React.ElementType<LoadingIndicatorProps>;
/** Date separator component to render */
dateSeparator?: React.ElementType<DateSeparatorProps>;
/** Turn off grouping of messages by user */
noGroupByUser?: boolean;
/** Weather its a thread of no. Default - false */
threadList?: boolean;
/** render HTML instead of markdown. Posting HTML is only allowed server-side */
unsafeHTML?: boolean;
messageLimit?: number;
messageActions?: Array<string>;
mutes?: Client.Mute[];
getFlagMessageSuccessNotification?(message: MessageResponse): string;
getFlagMessageErrorNotification?(message: MessageResponse): string;
getMuteUserSuccessNotification?(message: MessageResponse): string;
getMuteUserErrorNotification?(message: MessageResponse): string;
getBanUserSuccessNotification?(message: MessageResponse): string;
getBanUserErrorNotification?(message: MessageResponse): string;
additionalMessageInputProps?: object;
listenToScroll?(offset: number): void;
}
export interface ChannelHeaderProps {
/** Set title manually */
title?: string;
/** Show a little indicator that the channel is live right now */
live?: boolean;
}
export interface MessageInputProps {
/** Set focus to the text input if this is enabled */
focus?: boolean;
/** Disable input */
disabled?: boolean;
/** enable/disable firing the typing event */
publishTypingEvent?: boolean;
/** Grow the textarea while you're typing */
grow?: boolean;
/** Max number of rows the textarea is allowed to grow */
maxRows?: number;
/** The parent message object when replying on a thread */
parent?: Client.MessageResponse | null;
/** The component handling how the input is rendered */
Input?: React.ElementType<MessageInputProps>;
/** Change the SendButton component */
SendButton?: React.ElementType<SendButtonProps>;
/** Override image upload request */
doImageUploadRequest?(
file: object,
channel: Client.Channel,
): Promise<Client.FileUploadAPIResponse>;
/** Override file upload request */
doFileUploadRequest?(
file: File,
channel: Client.Channel,
): Promise<Client.FileUploadAPIResponse>;
/** Completely override the submit handler (advanced usage only) */
overrideSubmitHandler?(
message: object,
channelCid: string,
): Promise<any> | void;
/**
* Any additional attrubutes that you may want to add for underlying HTML textarea element.
* e.g.
* <MessageInput
* additionalTextareaProps={{
* maxLength: 10,
* }}
* />
*/
additionalTextareaProps?: object;
/** Message object. If defined, the message passed will be edited, instead of a new message being created */
message?: Client.MessageResponse;
/** Callback to clear editing state in parent component */
clearEditingState?: () => void;
/** If true, file uploads are disabled. Default: false */
noFiles?: boolean;
/** Custom error handler, called when file/image uploads fail. */
errorHandler?: (e: Error, type: string, file: object) => Promise<any> | void;
}
export type ImageUpload = {
id: string;
file: File;
state: 'finished' | 'failed' | 'uploading';
previewUri?: string;
url?: string;
};
export type FileUpload = {
id: string;
url: string;
state: 'finished' | 'failed' | 'uploading';
file: File;
};
export interface MessageInputState {
text: string;
attachments: Client.Attachment[];
imageOrder: string[];
imageUploads: SeamlessImmutable.ImmutableObject<{
[id: string]: ImageUpload;
}>;
fileOrder: string[];
fileUploads: SeamlessImmutable.ImmutableObject<{ [id: string]: FileUpload }>;
emojiPickerIsOpen: boolean;
// ids of users mentioned in message
mentioned_users: Client.UserResponse[];
numberOfUploads: number;
}
export interface MessageInputUploadsProps extends MessageInputState {
uploadNewFiles?(files: FileList): void;
removeImage?(id: string): void;
uploadImage?(id: string): void;
removeFile?(id: string): void;
uploadFile?(id: string): void;
}
export interface MessageInputEmojiPickerProps extends MessageInputState {
onSelectEmoji(emoji: object): void;
emojiPickerRef: React.RefObject<HTMLDivElement>;
small?: boolean;
}
export interface AttachmentUIComponentProps {
/** The attachment to render */
attachment: Client.Attachment;
/**
The handler function to call when an action is selected on an attachment.
Examples include canceling a \/giphy command or shuffling the results.
*/
actionHandler?(
name: string,
value: string,
event: React.BaseSyntheticEvent,
): void;
}
// MessageProps are all props shared between the Message component and the Message UI components (e.g. MessageSimple)
export interface MessageProps extends TranslationContextValue {
addNotification?(notificationText: string, type: string): any;
/** The message object */
message?: Client.MessageResponse;
/** The client connection object for connecting to Stream */
client?: Client.StreamChat;
/** A list of users that have read this message **/
readBy?: Array<Client.UserResponse>;
/** groupStyles, a list of styles to apply to this message. ie. top, bottom, single etc */
groupStyles?: Array<string>;
/** Editing, if the message is currently being edited */
editing?: boolean;
/** The message rendering component, the Message component delegates its rendering logic to this component */
Message?: React.ElementType<MessageUIComponentProps>;
/** Message Deleted rendering component. Optional; if left undefined, the default of the Message rendering component is used */
MessageDeleted?: React.ElementType<MessageDeletedProps>;
/** Allows you to overwrite the attachment component */
Attachment?: React.ElementType<AttachmentUIComponentProps>;
/** Allows you to overwrite the avatar component */
Avatar?: React.ElementType<AvatarProps>;
/** render HTML instead of markdown. Posting HTML is only allowed server-side */
unsafeHTML?: boolean;
lastReceivedId?: string | null;
messageListRect?: DOMRect;
updateMessage?(
updatedMessage: Client.MessageResponse,
extraState?: object,
): void;
additionalMessageInputProps?: object;
clearEditingState?(e?: React.MouseEvent): void;
getFlagMessageSuccessNotification?(message: MessageResponse): string;
getFlagMessageErrorNotification?(message: MessageResponse): string;
getMuteUserSuccessNotification?(message: MessageResponse): string;
getMuteUserErrorNotification?(message: MessageResponse): string;
getBanUserSuccessNotification?(message: MessageResponse): string;
getBanUserErrorNotification?(message: MessageResponse): string;
setEditingState?(message: Client.MessageResponse): any;
}
export type MessageComponentState = {
loading: boolean;
};
// MessageComponentProps defines the props for the Message component
export interface MessageComponentProps
extends MessageProps,
TranslationContextValue {
/** The current channel this message is displayed in */
channel?: Client.Channel;
/** Function to be called when a @mention is clicked. Function has access to the DOM event and the target user object */
onMentionsClick?(
e: React.MouseEvent,
mentioned_users: Client.UserResponse[],
): void;
/** Function to be called when hovering over a @mention. Function has access to the DOM event and the target user object */
onMentionsHover?(
e: React.MouseEvent,
mentioned_users: Client.UserResponse[],
): void;
/** Function to be called when clicking the user that posted the message. Function has access to the DOM event and the target user object */
onUserClick?(e: React.MouseEvent, user: Client.User): void;
/** Function to be called when hovering the user that posted the message. Function has access to the DOM event and the target user object */
onUserHover?(e: React.MouseEvent, user: Client.User): void;
messageActions?: Array<string>;
members?: SeamlessImmutable.Immutable<{ [user_id: string]: Client.Member }>;
retrySendMessage?(message: Client.Message): void;
removeMessage?(updatedMessage: Client.MessageResponse): void;
mutes?: Client.Mute[];
openThread?(
message: Client.MessageResponse,
event: React.SyntheticEvent,
): void;
}
// MessageUIComponentProps defines the props for the Message UI components (e.g. MessageSimple)
export interface MessageUIComponentProps
extends MessageProps,
TranslationContextValue {
actionsEnabled?: boolean;
handleReaction?(reactionType: string, event?: React.BaseSyntheticEvent): void;
handleEdit?(event?: React.BaseSyntheticEvent): void;
handleDelete?(event?: React.BaseSyntheticEvent): void;
handleFlag?(event?: React.BaseSyntheticEvent): void;
handleMute?(event?: React.BaseSyntheticEvent): void;
handleBan?(event?: React.BaseSyntheticEvent, options?: object): void;
handleAction?(
name: string,
value: string,
event: React.BaseSyntheticEvent,
): void;
handleRetry?(message: Client.Message): void;
isMyMessage?(message: Client.MessageResponse): boolean;
isUserMuted?(): boolean;
handleOpenThread?(event: React.BaseSyntheticEvent): void;
mutes?: Client.Mute[];
onMentionsClickMessage?(event: React.MouseEvent): void;
onMentionsHoverMessage?(event: React.MouseEvent): void;
onUserClick?(e: React.MouseEvent): void;
onUserHover?(e: React.MouseEvent): void;
getMessageActions(): Array<string>;
channelConfig?: Client.ChannelConfigWithInfo;
threadList?: boolean;
additionalMessageInputProps?: object;
initialMessage?: boolean;
}
export interface MessageDeletedProps extends TranslationContextValue {
/** The message object */
message: Client.MessageResponse;
isMyMessage?(message: Client.MessageResponse): boolean;
}
export interface ThreadProps
extends ChannelContextValue,
TranslationContextValue {
/** Display the thread on 100% width of it's container. Useful for mobile style view */
fullWidth?: boolean;
/** Make input focus on mounting thread */
autoFocus?: boolean;
additionalParentMessageProps?: object;
additionalMessageListProps?: object;
additionalMessageInputProps?: object;
MessageInput?: React.ElementType<MessageInputProps>;
}
export interface TypingIndicatorProps {
typing: object;
client: Client.StreamChat;
}
export interface ReactionSelectorProps {
/**
* Array of latest reactions.
* Reaction object has following structure:
*
* ```json
* {
* "type": "love",
* "user_id": "demo_user_id",
* "user": {
* ...userObject
* },
* "created_at": "datetime";
* }
* ```
* */
latest_reactions?: Client.ReactionResponse[];
/**
* {
* 'like': 9,
* 'love': 6,
* 'haha': 2
* }
*/
reaction_counts?: {
[reaction_type: string]: number;
};
/** Enable the avatar display */
detailedView?: boolean;
/** Provide a list of reaction options [{name: 'angry', emoji: 'angry'}] */
reactionOptions?: MinimalEmojiInterface[];
reverse?: boolean;
handleReaction?(reactionType: string, event?: React.BaseSyntheticEvent): void;
}
export interface EnojiSetDef {
spriteUrl: string;
size: number;
sheetColumns: number;
sheetRows: number;
sheetSize: number;
}
export interface ReactionsListProps {
/**
* Array of latest reactions.
* Reaction object has following structure:
*
* ```json
* {
* "type": "love",
* "user_id": "demo_user_id",
* "user": {
* ...userObject
* },
* "created_at": "datetime";
* }
* ```
* */
reactions?: Client.ReactionResponse[];
/**
* {
* 'like': 9,
* 'love': 6,
* 'haha': 2
* }
*/
reaction_counts?: {
[reaction_type: string]: number;
};
/** Provide a list of reaction options [{name: 'angry', emoji: 'angry'}] */
reactionOptions?: MinimalEmojiInterface[];
onClick?(): void;
reverse?: boolean;
emojiSetDef?: EnojiSetDef;
}
export interface WindowProps {
/** show or hide the window when a thread is active */
hideOnThread?: boolean;
thread?: Client.MessageResponse | boolean;
}
export interface AttachmentActionsProps {
id: string;
text: string;
actions: Client.Action[];
actionHandler?(
name: string,
value: string,
event: React.BaseSyntheticEvent,
): void;
}
export interface AudioProps {
og: Client.Attachment;
}
export interface CardProps extends TranslationContextValue {
title?: string;
title_link?: string;
og_scrape_url?: string;
image_url?: string;
thumb_url?: string;
text?: string;
type?: string;
}
export interface ChatAutoCompleteProps {
rows?: number;
grow?: boolean;
maxRows?: number;
disabled?: boolean;
value?: string;
handleSubmit?(event: React.FormEvent): void;
onChange?(event: React.ChangeEventHandler): void;
placeholder?: string;
LoadingIndicator?: React.ElementType<LoadingIndicatorProps>;
minChar?: number;
onSelectItem?(item: any): any;
commands?: Client.CommandResponse[];
onFocus?: React.FocusEventHandler;
onPaste?: React.ClipboardEventHandler;
additionalTextareaProps?: object;
innerRef: React.MutableRefObject<HTMLTextAreaElement | undefined>;
trigger?(): object;
}
export interface ChatDownProps extends TranslationContextValue {
image?: string;
type: string;
text?: string;
}
export interface CommandItemProps {
entity: {
name?: string | null;
args?: string | null;
description?: string | null;
};
}
export interface EditMessageFormProps
extends MessageInputProps,
TranslationContextValue {}
export interface EmoticonItemProps {
entity: {
name: string;
native: string;
};
}
export interface UserItemProps {
entity: {
name?: string | null;
id?: string | null;
image?: string | null;
};
}
export interface EventComponentProps {
message: Client.MessageResponse;
}
export interface GalleryProps {
images: Client.Attachment[];
}
export interface ImageProps {
image_url?: string;
thumb_url?: string;
fallback?: string;
}
export interface ModalWrapperProps {
images: { src: string; source: string }[];
toggleModal: (selectedIndex?: number) => void;
index?: number;
modalIsOpen: boolean;
}
export interface InfiniteScrollProps {
loadMore(): any;
hasMore?: boolean;
initialLoad?: boolean;
isReverse?: boolean;
pageStart?: number;
isLoading?: boolean;
useCapture?: boolean;
useWindow?: boolean;
element?: React.ElementType;
loader?: React.ReactNode;
threshold?: number;
children?: any;
listenToScroll?: (offset: number, reverseOffset: number) => void;
}
export interface ModalImageProps {
data: { src: string };
}
export interface ReverseInfiniteScrollProps {
loadMore(): any;
hasMore?: boolean;
initialLoad?: boolean;
isReverse?: boolean;
pageStart?: number;
isLoading?: boolean;
useCapture?: boolean;
useWindow?: boolean;
element?: React.ElementType;
loader?: React.ReactNode;
threshold?: number;
className?: string;
/** The function is called when the list scrolls */
listenToScroll?(
standardOffset: string | number,
reverseOffset: string | number,
): any;
listenToScroll?(standardOffset: number, reverseOffset: number): void;
[elementAttribute: string]: any; // any other prop is applied as attribute to element
}
export interface LoadMoreButtonProps {
onClick: React.MouseEventHandler;
refreshing: boolean;
}
export interface LoadingChannelsProps {}
export interface MessageActionsBoxProps {
/** If the message actions box should be open or not */
open?: boolean;
/** If message belongs to current user. */
mine?: boolean;
isUserMuted?(): boolean;
/** DOMRect object for parent MessageList component */
messageListRect?: DOMRect;
handleEdit?(event?: React.BaseSyntheticEvent): void;
handleDelete?(event?: React.BaseSyntheticEvent): void;
handleFlag?(event?: React.BaseSyntheticEvent): void;
handleMute?(event?: React.BaseSyntheticEvent): void;
getMessageActions(): Array<string>;
}
export interface MessageNotificationProps {
showNotification: boolean;
onClick: React.MouseEventHandler;
}
export interface MessageRepliesCountButtonProps
extends TranslationContextValue {
labelSingle?: string;
labelPlural?: string;
reply_count?: number;
onClick?: React.MouseEventHandler;
}
export interface ModalProps {
onClose?(): void;
open: boolean;
}
export interface SafeAnchorProps {}
export interface SimpleReactionsListProps {
reactions?: Client.ReactionResponse[];
/**
* {
* 'like': 9,
* 'love': 6,
* 'haha': 2
* }
*/
reaction_counts?: {
[reaction_type: string]: number;
};
/** Provide a list of reaction options [{name: 'angry', emoji: 'angry'}] */
reactionOptions?: MinimalEmojiInterface[];
handleReaction?(reactionType: string): void;
}
export interface TooltipProps {}
export const AttachmentActions: React.FC<AttachmentActionsProps>;
export class Audio extends React.PureComponent<AudioProps, any> {}
export const Card: React.FC<CardProps>;
export class ChatAutoComplete extends React.PureComponent<
ChatAutoCompleteProps,
any
> {}
export const ChatDown: React.FC<ChatDownProps>;
export const CommandItem: React.FC<CommandItemProps>;
export const UserItem: React.FC<UserItemProps>;
export const DateSeparator: React.FC<DateSeparatorProps>;
export class EditMessageForm extends React.PureComponent<
EditMessageFormProps,
any
> {}
export const EmoticonItem: React.FC<EmoticonItemProps>;
export const EmptyStateIndicator: React.FC<EmptyStateIndicatorProps>;
export const Gallery: React.FC<GalleryProps>;
export const Image: React.FC<ImageProps>;
export const ImageModal: React.FC<ModalWrapperProps>;
export const EventComponent: React.FC<EventComponentProps>;
export class InfiniteScroll extends React.PureComponent<
InfiniteScrollProps,
any
> {}
export const LoadMoreButton: React.FC<LoadMoreButtonProps>;
export const LoadingChannels: React.FC<LoadingChannelsProps>;
export const LoadingErrorIndicator: React.FC<LoadingErrorIndicatorProps>;
export class MessageActionsBox extends React.PureComponent<
MessageActionsBoxProps,
any
> {}
export const MessageNotification: React.FC<MessageNotificationProps>;
export const MessageRepliesCountButton: React.FC<MessageRepliesCountButtonProps>;
export class Modal extends React.PureComponent<ModalProps, any> {}
export const ModalImage: React.FC<ModalImageProps>;
export class ReverseInfiniteScroll extends React.PureComponent<
InfiniteScrollProps,
any
> {}
export class SafeAnchor extends React.PureComponent<SafeAnchorProps, any> {}
export const SendButton: React.FC<SendButtonProps>;
export class SimpleReactionsList extends React.PureComponent<
SimpleReactionsListProps,
any
> {}
export const Tooltip: React.FC<TooltipProps>;
export const Chat: React.FC<ChatProps>;
export class Channel extends React.PureComponent<ChannelProps, any> {}
export class Avatar extends React.PureComponent<AvatarProps, any> {}
export class Message extends React.PureComponent<MessageComponentProps, any> {}
export class MessageList extends React.PureComponent<MessageListProps, any> {}
export const ChannelHeader: React.FC<ChannelHeaderProps>;
export class MessageInput extends React.PureComponent<MessageInputProps, any> {}
export class MessageInputLarge extends React.PureComponent<
MessageInputProps,
any
> {}
export class MessageInputFlat extends React.PureComponent<
MessageInputProps,
any
> {}
export class MessageInputSmall extends React.PureComponent<
MessageInputProps,
any
> {}
export class Attachment extends React.PureComponent<
AttachmentUIComponentProps
> {}
export class ChannelList extends React.PureComponent<ChannelListProps> {}
export class ChannelListMessenger extends React.PureComponent<
ChannelListUIComponentProps,
any
> {}
export class ChannelListTeam extends React.PureComponent<
ChannelListUIComponentProps,
any
> {}
export const ChannelPreview: React.FC<ChannelPreviewProps>;
export const ChannelPreviewCompact: React.FC<ChannelPreviewUIComponentProps>;
export const ChannelPreviewMessenger: React.FC<ChannelPreviewUIComponentProps>;
export const ChannelPreviewCountOnly: React.FC<ChannelPreviewUIComponentProps>;
export const ChannelPreviewLastMessage: React.FC<ChannelPreviewUIComponentProps>;
export const ChannelSearch: React.FC<any>;
export const LoadMorePaginator: React.FC<LoadMorePaginatorProps>;
export const InfiniteScrollPaginator: React.FC<InfiniteScrollPaginatorProps>;
export const LoadingIndicator: React.FC<LoadingIndicatorProps>;
export interface MessageCommerceProps extends MessageUIComponentProps {}
export type MessageCommerceState = {
isFocused: boolean;
showDetailedReactions: boolean;
};
export class MessageCommerce extends React.PureComponent<
MessageCommerceProps,
MessageCommerceState
> {}
export interface MessageLivestreamProps extends MessageUIComponentProps {}
export interface MessageLivestreamActionProps {
initialMessage?: boolean;
message?: Client.MessageResponse;
tDateTimeParser?(datetime: string | number): Dayjs.Dayjs;
channelConfig?: Client.ChannelConfig | Client.ChannelConfigWithInfo;
threadList?: boolean;
handleOpenThread?(event: React.BaseSyntheticEvent): void;
onReactionListClick?: () => void;
getMessageActions(): Array<string>;
messageWrapperRef?: React.RefObject<HTMLElement>;
setEditingState?(message: Client.MessageResponse): any;
}
export const MessageLivestream: React.FC<MessageLivestreamProps>;
export type MessageTeamState = {
actionsBoxOpen: boolean;
reactionSelectorOpen: boolean;
};
export interface MessageTeamProps extends MessageUIComponentProps {}
export interface MessageTeamAttachmentsProps {
Attachment?: React.ElementType<AttachmentUIComponentProps>;
message?: Client.MessageResponse;
handleAction?(
name: string,
value: string,
event: React.BaseSyntheticEvent,
): void;
}
export interface MessageTeamStatusProps {
Avatar?: React.ElementType<AvatarProps>;
t?: i18next.TFunction;
threadList?: boolean;
lastReceivedId?: string | null;
message?: Client.MessageResponse;
readBy?: Array<Client.UserResponse>;
}
export class MessageTeam extends React.PureComponent<
MessageUIComponentProps,
MessageTeamState
> {}
export interface MessageSimpleProps extends MessageUIComponentProps {}
export interface MessageTextProps extends MessageSimpleProps {
customOptionProps?: Partial<MessageOptionsProps>;
customInnerClass?: string;
customWrapperClass?: string;
onReactionListClick?: () => void;
theme?: string;
showDetailedReactions?: boolean;
messageWrapperRef?: React.RefObject<HTMLElement>;
}
export interface MessageActionsProps {
addNotification?(notificationText: string, type: string): any;
handleEdit?(event?: React.BaseSyntheticEvent): void;
handleDelete?(event?: React.BaseSyntheticEvent): void;
handleFlag?(event?: React.BaseSyntheticEvent): void;
handleMute?(event?: React.BaseSyntheticEvent): void;
mutes?: Client.Mute[];
getMessageActions(): Array<string>;
getFlagMessageSuccessNotification?(message: MessageResponse): string;
getFlagMessageErrorNotification?(message: MessageResponse): string;
getMuteUserSuccessNotification?(message: MessageResponse): string;
getMuteUserErrorNotification?(message: MessageResponse): string;
getBanUserSuccessNotification?(message: MessageResponse): string;
getBanUserErrorNotification?(message: MessageResponse): string;
setEditingState?(message: Client.MessageResponse): any;
messageListRect?: DOMRect;
message?: Client.MessageResponse;
messageWrapperRef?: React.RefObject<HTMLElement>;
inline?: boolean;
customWrapperClass?: string;
}
export interface MessageActionsWrapperProps {
customWrapperClass?: string;
inline?: boolean;
setActionsBoxOpen: (actionsBoxOpen: boolean) => void;
}
export interface MessageOptionsProps {
getMessageActions(): Array<string>;
handleOpenThread?(event: React.BaseSyntheticEvent): void;
initialMessage?: boolean;
message?: Client.MessageResponse;
messageWrapperRef?: React.RefObject<HTMLElement>;
onReactionListClick?: () => void;
threadList?: boolean;
displayLeft?: boolean;
displayReplies?: boolean;
displayActions?: boolean;
theme?: string;
}
export const MessageSimple: React.FC<MessageSimpleProps>;
export class MessageDeleted extends React.PureComponent<
MessageDeletedProps,
any
> {}
export class Thread extends React.PureComponent<ThreadProps, any> {}
export const TypingIndicator: React.FC<TypingIndicatorProps>;
export class ReactionSelector extends React.PureComponent<
ReactionSelectorProps,
any
> {}
export class ReactionsList extends React.PureComponent<
ReactionsListProps,
any
> {}
export const Window: React.FC<WindowProps>;
/** Utils */
export const emojiSetDef: emojiSetDefInterface;
export interface emojiSetDefInterface {
emoticons: [];
short_names: [];
custom: boolean;
}
export const commonEmoji: commonEmojiInterface;
export interface commonEmojiInterface {
emoticons: [];
short_names: [];
custom: boolean;
}
export const defaultMinimalEmojis: MinimalEmojiInterface[];
export interface MinimalEmojiInterface
extends commonEmojiInterface,
emojiSetDefInterface {
id: string;
name: string;
colons: string;
sheet_x: number;
sheet_y: number;
}
export function renderText(
message:
| SeamlessImmutable.Immutable<Client.MessageResponse>
| Client.MessageResponse,
): ReactMarkdown;
export function smartRender(
ElementOrComponentOrLiteral: ElementOrComponentOrLiteral,
props?: {},
fallback?: ElementOrComponentOrLiteral,
): React.Component<{}, {}>;
export type ElementOrComponentOrLiteral =
| string
| boolean
| number
| React.ElementType
| null
| undefined;
/**
* {
* edit: 'edit',
* delete: 'delete',
* flag: 'flag',
* mute: 'mute',
* }
*/
export const MESSAGE_ACTIONS: {
[key: string]: string;
};
/** Context */
export const ChatContext: React.Context<ChatContextValue>;
/**
* const CustomMessage = withChatContext<MessageUIComponentProps & ChatContextValue>(
* class CustomMessageComponent extends React.Component<MessageUIComponentProps & ChatContextValue> {
* render() {
* return (
* <div>Custom Message : {this.props.message.text}</div>
* )
* }
* }
* )
*/
export function withChatContext<T>(
OriginalComponent: React.ElementType<T>,
): React.ElementType<T>;
export const ChannelContext: React.Context<ChannelContextValue>;
/**
* const CustomMessage = withChannelContext<MessageUIComponentProps & ChannelContextValue>(
* class CustomMessageComponent extends React.Component<MessageUIComponentProps & ChannelContextValue> {
* render() {
* return (
* <div>Custom Message : {this.props.message.text}</div>
* )
* }
* }
* )
*/
export function withChannelContext<T>(
OriginalComponent: React.ElementType<T>,
): React.ElementType<T>;
declare function withTranslationContext<T>(
OriginalComponent: React.ElementType<T>,
): React.ElementType<T>;
export interface TranslationContext
extends React.Context<TranslationContextValue> {}
export interface TranslationContextValue {
t?: i18next.TFunction;
tDateTimeParser?(datetime: string | number): Dayjs.Dayjs;
}
export interface Streami18nOptions {
language: string;
disableDateTimeTranslations?: boolean;
translationsForLanguage?: object;
debug?: boolean;
logger?(msg: string): any;
dayjsLocaleConfigForLanguage?: object;
DateTimeParser?(): object;
}
export interface Streami18nTranslators {
t: i18next.TFunction;
tDateTimeParser?(datetime?: string | number): object;
}
export class Streami18n {
constructor(options?: Streami18nOptions);
init(): Promise<Streami18nTranslators>;
validateCurrentLanguage(): void;
geti18Instance(): i18next.i18n;
getAvailableLanguages(): Array<string>;
getTranslations(): Array<string>;
getTranslators(): Promise<Streami18nTranslators>;
registerTranslation(
key: string,
translation: object,
customDayjsLocale?: Partial<ILocale>,
): void;
addOrUpdateLocale(key: string, config: Partial<ILocale>): void;
setLanguage(language: string): Promise<void>;
localeExists(language: string): boolean;
registerSetLanguageCallback(callback: (t: i18next.TFunction) => void): void;
}
export const enTranslations: object;
export const nlTranslations: object;
export const ruTranslations: object;
export const trTranslations: object;
export const frTranslations: object;
export const hiTranslations: object;
export const itTranslations: object;
export function useMessageInput(
props: MessageInputProps,
): {
textareaRef: {
current: HTMLTextAreaElement | undefined;
};
emojiPickerRef: {
current: HTMLDivElement | null;
};
uploadNewFiles: (files: FileList) => void;
removeImage: (id: any) => void;
uploadImage: (id: any) => Promise<void>;
removeFile: (id: any) => void;
uploadFile: (id: any) => void;
onSelectEmoji: (emoji: any) => void;
getUsers: () => (
| SeamlessImmutable.ImmutableObject<Client.UserResponse>
| undefined
)[];
getCommands: () => Client.CommandResponse[] | undefined;
handleSubmit: (event: React.FormEvent | React.MouseEvent) => void;
handleChange: (event: any) => void;
onPaste: (e: any) => void;
onSelectItem: (item: Client.UserResponse) => void;
openEmojiPicker: () => void;
text: string;
attachments: Client.Attachment[];
imageOrder: string[];
imageUploads: SeamlessImmutable.ImmutableObject<ImageUpload>;
fileOrder: string[];
fileUploads: SeamlessImmutable.ImmutableObject<FileUpload>;
emojiPickerIsOpen: boolean;
mentioned_users: Client.UserResponse[];
numberOfUploads: number;
};