Permalink
Browse files

Improve typings to allow for generic messages (#1025)

* allow generic message types

* refactor generic message types to extends interface + improve custom render function props

* Use RN StyleProp for style props

* Preseve backwards compatibility

* add defaultProps and onPressActionButton typings

* fix user typing
  • Loading branch information...
hammadj authored and sibelius committed Dec 4, 2018
1 parent e0fb667 commit 679e338d302d5b88eb5d926e9e286cbe728eb2e8
Showing with 76 additions and 76 deletions.
  1. +76 −76 index.d.ts
@@ -1,5 +1,9 @@
import * as React from 'react';
import { ViewStyle, TextStyle, TextProperties, TextInputProperties, ImageStyle, ListViewProperties, ImageProperties } from 'react-native';
import * as RN from 'react-native';

type ViewStyle = RN.StyleProp<RN.ViewStyle>;
type TextStyle = RN.StyleProp<RN.TextStyle>;
type ImageStyle = RN.StyleProp<RN.ImageStyle>;

export interface LeftRightStyle<T> {
left: T;
@@ -12,27 +16,16 @@ export interface User {
avatar?: string;
}

export interface IChatMessage {
export interface IMessage {
_id: any;
text: string;
createdAt: Date;
user: {
_id: any;
name: string;
avatar: string;
};
user: User;
image?: string;
system?: false;
system?: boolean;
}

export interface ISystemMessage {
_id: any;
text: string;
createdAt: Date;
system: true;
}

export type IMessage = IChatMessage | ISystemMessage;
export type IChatMessage = IMessage

interface ActionsProps {
// todo: onSend is not used
@@ -43,18 +36,19 @@ interface ActionsProps {
wrapperStyle?: ViewStyle;
containerStyle?: ViewStyle;
iconTextStyle?: ViewStyle;
onPressActionButton(): void;
}

export class Actions extends React.Component<ActionsProps> { }

interface AvatarProps {
interface AvatarProps<TMessage extends IMessage = IMessage> {
renderAvatarOnTop: boolean;
position: "left" | "right";
currentMessage: IChatMessage;
previousMessage: IMessage;
nextMessage: IMessage;
currentMessage: TMessage;
previousMessage: TMessage;
nextMessage: TMessage;
onPressAvatar(): void;
renderAvatar(props: AvatarProps): JSX.Element;
renderAvatar(props: AvatarProps<TMessage>): JSX.Element;
containerStyle: {
left: any;
right: any;
@@ -64,34 +58,34 @@ interface AvatarProps {
right: any;
};
// TODO: remove in next major release
isSameDay(currentMessage: IMessage, message: IMessage): boolean;
isSameUser(currentMessage: IMessage, message: IMessage): boolean;
isSameDay(currentMessage: TMessage, message: TMessage): boolean;
isSameUser(currentMessage: TMessage, message: TMessage): boolean;
}

export class Avatar extends React.Component<AvatarProps> { }

interface BubbleProps {
interface BubbleProps<TMessage extends IMessage = IMessage> {
user: User;
touchableProps?: object;
onLongPress?(): void;
renderMessageImage?(messageImageProps: MessageImageProps): React.ReactNode;
onLongPress?(context?: any, message?: any): void;
renderMessageImage?(messageImageProps: RenderMessageImageProps): React.ReactNode;
renderMessageText?(messageTextProps: MessageTextProps): React.ReactNode;
renderCustomView?(bubbleProps: BubbleProps): React.ReactNode;
renderTime?(timeProps: TimeProps): React.ReactNode;
renderTicks?(currentMessage: IMessage): React.ReactNode;
renderTicks?(currentMessage: TMessage): React.ReactNode;
position?: "left" | "right";
currentMessage?: IMessage;
nextMessage?: IMessage;
previousMessage?: IMessage;
currentMessage?: TMessage;
nextMessage?: TMessage;
previousMessage?: TMessage;
containerStyle?: LeftRightStyle<ViewStyle>;
wrapperStyle: LeftRightStyle<ViewStyle>;
bottomContainerStyle: LeftRightStyle<ViewStyle>;
tickStyle: TextStyle;
containerToNextStyle: LeftRightStyle<ViewStyle>;
containerToPreviousStyle: LeftRightStyle<ViewStyle>;
// TODO: remove in next major release
isSameDay?(currentMessage: IMessage, nextMessage: IMessage): boolean;
isSameUser?(currentMessage: IMessage, nextMessage: IMessage): boolean;
isSameDay?(currentMessage: TMessage, nextMessage: TMessage): boolean;
isSameUser?(currentMessage: TMessage, nextMessage: TMessage): boolean;
}

export class Bubble extends React.Component<BubbleProps> { }
@@ -101,26 +95,26 @@ interface ComposerProps {
text?: string;
placeholder?: string;
placeholderTextColor?: string;
textInputProps?: Partial<TextInputProperties>;
textInputProps?: Partial<RN.TextInputProps>;
onTextChanged?(text: string): void;
onInputSizeChanged?(contentSize: number): void;
multiline?: boolean;
textInputStyle?: TextInputProperties["style"];
textInputStyle?: RN.TextInputProps["style"];
textInputAutoFocus?: boolean;
keyboardAppearance: TextInputProperties["keyboardAppearance"];
keyboardAppearance: RN.TextInputProps["keyboardAppearance"];
}

export class Composer extends React.Component<ComposerProps> { }

interface DayProps {
currentMessage?: IMessage;
previousMessage?: IMessage;
interface DayProps<TMessage extends IMessage = IMessage> {
currentMessage?: TMessage;
previousMessage?: TMessage;
containerStyle?: ViewStyle;
wrapperStyle?: ViewStyle;
textStyle?: TextStyle;
// TODO: remove in next major release
isSameDay?(currentMessage: IMessage, nextMessage: IMessage): boolean;
isSameUser?(currentMessage: IMessage, nextMessage: IMessage): boolean;
isSameDay?(currentMessage: TMessage, nextMessage: TMessage): boolean;
isSameUser?(currentMessage: TMessage, nextMessage: TMessage): boolean;
dateFormat?: string;
}

@@ -135,19 +129,19 @@ interface GiftedAvatarProps {

export class GiftedAvatar extends React.Component<GiftedAvatarProps> { }

export interface GiftedChatProps {
export interface GiftedChatProps<TMessage extends IMessage = IMessage> {
/* Messages to display */
messages?: IMessage[];
messages?: TMessage[];
/* Input text; default is undefined, but if specified, it will override GiftedChat's internal state */
text?: string;
/* Placeholder when text is empty; default is 'Type a message...' */
placeholder?: string;
/* Generate an id for new messages. Defaults to UUID v4, generated by uuid */
messageIdGenerator?(message: IMessage): string;
messageIdGenerator?(message: TMessage): string;
/* User sending the messages: { _id, name, avatar } */
user?: User;
/* Callback when sending a message */
onSend?(messages: IMessage[]): void;
onSend?(messages: TMessage[]): void;
/* Locale to localize the dates */
locale?: string;
/* Format to use for rendering times; default is 'LT' */
@@ -185,11 +179,11 @@ export interface GiftedChatProps {
/* Reverses display order of messages; default is true */
inverted?: boolean;
/*Custom message container */
renderMessage?(message: IMessage): React.ReactNode;
renderMessage?(message: MessageProps): React.ReactNode;
/* Custom message text */
renderMessageText?(messageText: MessageTextProps): React.ReactNode;
/* Custom message image */
renderMessageImage?(props: MessageImageProps): React.ReactNode;
renderMessageImage?(props: RenderMessageImageProps): React.ReactNode;
/* Extra props to be passed to the <Image> component created by the default renderMessageImage */
imageProps?: MessageProps;
/*Extra props to be passed to the MessageImage's Lightbox */
@@ -241,16 +235,17 @@ export interface GiftedChatProps {
}

export class GiftedChat extends React.Component<GiftedChatProps> {
static append(
currentMessages: IMessage[],
messages: IMessage[],
static defaultProps: GiftedChatProps;
static append<TMessage extends IMessage = IMessage>(
currentMessages: TMessage[],
messages: TMessage[],
inverted?: boolean
): IMessage[];
static prepend(
currentMessages: IMessage[],
messages: IMessage[],
): TMessage[];
static prepend<TMessage extends IMessage = IMessage>(
currentMessages: TMessage[],
messages: TMessage[],
inverted?: boolean
): IMessage[];
): TMessage[];
}

interface InputToolbarProps {
@@ -277,33 +272,33 @@ interface LoadEarlierProps {

export class LoadEarlier extends React.Component<LoadEarlierProps> { }

interface MessageProps {
interface MessageProps<TMessage extends IMessage = IMessage> {
// TODO: this is not used
renderAvatar(props: AvatarProps): React.ReactNode;
showUserAvatar?: boolean;
renderBubble(props: BubbleProps): React.ReactNode;
renderDay(props: DayProps): React.ReactNode;
renderSystemMessage(props: SystemMessageProps): React.ReactNode;
position?: "left" | "right";
currentMessage?: IMessage;
nextMessage?: IMessage;
previousMessage?: IMessage;
currentMessage?: TMessage;
nextMessage?: TMessage;
previousMessage?: TMessage;
user?: User;
inverted?: boolean;
containerStyle: LeftRightStyle<ViewStyle>;
}

export class Message extends React.Component<MessageProps> { }

interface MessageContainerProps {
messages?: IMessage[];
interface MessageContainerProps<TMessage extends IMessage = IMessage> {
messages?: TMessage[];
user?: User;
renderFooter?(props: MessageContainerProps): React.ReactNode;
renderMessage?(props: MessageProps): React.ReactNode;
renderLoadEarlier?(props: LoadEarlierProps): React.ReactNode;
// todo: not used
onLoadEarlier?(): void;
listViewProps: Partial<ListViewProperties>;
listViewProps: Partial<RN.ListViewProps>;
inverted?: boolean;
loadEarlier?: boolean;
// todo: should be InvertibleScrollView props
@@ -312,30 +307,36 @@ interface MessageContainerProps {

export class MessageContainer extends React.Component<MessageContainerProps> { }

interface MessageImageProps {
currentMessage?: IMessage;
interface MessageImageProps<TMessage extends IMessage = IMessage> {
currentMessage?: TMessage;
containerStyle?: ViewStyle;
imageStyle?: ImageStyle;
imageProps?: Partial<ImageProperties>;
imageProps?: Partial<RN.ImageProps>;
// todo: should be LightBox properties
lightboxProps?: object;
}

export class MessageImage extends React.Component<MessageImageProps> { }

interface MessageTextProps {
export type RenderMessageImageProps<TMessage extends IMessage = IMessage> =
MessageImageProps<TMessage> & Exclude<BubbleProps<TMessage>, 'wrapperStyle' | 'containerStyle'>

interface MessageTextProps<TMessage extends IMessage = IMessage> {
position: "left" | "right";
currentMessage?: IMessage;
currentMessage?: TMessage;
containerStyle?: LeftRightStyle<ViewStyle>;
textStyle?: LeftRightStyle<TextStyle>;
linkStyle?: LeftRightStyle<TextStyle>;
parsePatterns?(linkStyle: TextStyle): any;
textProps?: TextProperties;
textProps?: RN.TextProps;
customTextStyle?: TextStyle;
}

export class MessageText extends React.Component<MessageTextProps> { }

export type RenderMessageTextProps<TMessage extends IMessage = IMessage> =
MessageTextProps<TMessage> & Exclude<BubbleProps<TMessage>, 'wrapperStyle' | 'containerStyle'>

interface SendProps {
text?: string;
onSend?({ text }: { text: string }, b: boolean): void;
@@ -347,30 +348,29 @@ interface SendProps {

export class Send extends React.Component<SendProps> { }

interface SystemMessageProps {
currentMessage?: IMessage;
interface SystemMessageProps<TMessage extends IMessage = IMessage> {
currentMessage?: TMessage;
containerStyle?: ViewStyle;
wrapperStyle?: ViewStyle;
textStyle?: TextStyle;
}

export class SystemMessage extends React.Component<SystemMessageProps> { }

interface TimeProps {
interface TimeProps<TMessage extends IMessage = IMessage> {
position?: "left" | "right";
currentMessage?: IMessage;
currentMessage?: TMessage;
containerStyle?: LeftRightStyle<ViewStyle>;
textStyle?: LeftRightStyle<TextStyle>;
timeFormat?: string;
}

export class Time extends React.Component<TimeProps> { }

export type utils = {
isSameUser(currentMessage?: IMessage, message?: IMessage): boolean;
isSameDay(currentMessage?: IMessage, message?: IMessage): boolean;
isSameTime(currentMessage?: IMessage, message?: IMessage): boolean;
export type utils<TMessage extends IMessage = IMessage> = {
isSameUser(currentMessage?: TMessage, message?: TMessage): boolean;
isSameDay(currentMessage?: TMessage, message?: TMessage): boolean;
isSameTime(currentMessage?: TMessage, message?: TMessage): boolean;
};

export const utils: utils;

0 comments on commit 679e338

Please sign in to comment.