Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

botonic-react: Webchat component with typescript #2947

Open
wants to merge 4 commits into
base: botonic-react/webchat-app-typescript
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/botonic-react/src/components/index-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ export interface BlobProps {
imageStyle?: any
}

export interface CustomMessageType {
(props: any): JSX.Element
customTypeName: string
deserialize(msg: any): JSX.Element
}

export interface ThemeProps extends StyleProp {
coverComponent?: CoverComponentOptions
mobileBreakpoint?: number
Expand All @@ -115,13 +121,13 @@ export interface ThemeProps extends StyleProp {
StyleProp &
CustomProp
// TODO: Review if this is needed hear, or only in message.customTypes? use the same type in both places
customMessageTypes?: React.ComponentType[]
customMessageTypes?: CustomMessageType[]
message?: {
bot?: BlobProps & ImageProp & StyleProp
agent?: ImageProp
user?: BlobProps & StyleProp
// TODO: Review type used in cutomTypes should be a component exported by default with customMessage function
customTypes?: React.ComponentType[]
customTypes?: CustomMessageType[]
} & StyleProp & {
timestamps?: {
withImage?: boolean
Expand Down
11 changes: 4 additions & 7 deletions packages/botonic-react/src/contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,20 @@ export interface CloseWebviewOptions {

export const WebviewRequestContext = createContext<{
closeWebview: (options?: CloseWebviewOptions) => Promise<void>
getString: (stringId: string) => string
getString?: (stringId: string) => string
params: Record<string, any>
session: CoreSession
session: Partial<CoreSession>
}>({
closeWebview: async () => undefined,
getString: () => '',
getString: undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for?

params: {} as Record<string, any>,
session: {} as CoreSession,
session: {} as Partial<CoreSession>,
})

export const WebchatContext = createContext<WebchatContextProps>({
addMessage: () => {
return
},
closeWebview: async () => {
return
},
getThemeProperty: () => {
return
}, // used to retrieve a specific property of the theme defined by the developer in his 'webchat/index.js'
Expand Down
112 changes: 91 additions & 21 deletions packages/botonic-react/src/index-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Plugin as CorePlugin,
Route as CoreRoute,
Routes as CoreRoutes,
ServerConfig,
Session as CoreSession,
SessionUser as CoreSessionUser,
} from '@botonic/core'
Expand All @@ -20,6 +21,8 @@ import {
WebchatSettingsProps,
Webview,
} from './components/index-types'
import { CloseWebviewOptions } from './contexts'
import { UseWebchat } from './webchat/hooks/use-webchat'
import { WebchatState } from './webchat/index-types'
import { WebchatApp } from './webchat-app'

Expand Down Expand Up @@ -51,32 +54,91 @@ export interface RequestContextInterface extends ActionRequest {
setLocale: (locale: string) => string
}

export interface CustomMessageType {
customTypeName: string
export interface WebchatRef {
addBotResponse: ({
response,
session,
lastRoutePath,
}: AddBotResponseArgs) => void
setTyping: (typing: boolean) => void
addUserMessage: (message: any) => Promise<void>
updateUser: (userToUpdate: any) => void
openWebchat: () => void
closeWebchat: () => void
toggleWebchat: () => void
openCoverComponent: () => void
closeCoverComponent: () => void
toggleCoverComponent: () => void
renderCustomComponent: (customComponent: any) => void
unmountCustomComponent: () => void
isOnline: () => boolean
setOnline: (online: boolean) => void
getMessages: () => { id: string; ack: number; unsentInput: CoreInput }[] // TODO: define MessagesJSON
Iru89 marked this conversation as resolved.
Show resolved Hide resolved
clearMessages: () => void
getLastMessageUpdate: () => string | undefined
updateMessageInfo: (msgId: string, messageInfo: any) => void
updateWebchatSettings: (settings: WebchatSettingsProps) => void
closeWebview: (options?: CloseWebviewOptions) => Promise<void>
}

interface AddBotResponseArgs {
response: any
session?: any
lastRoutePath?: any
}

export interface WebchatArgs {
blockInputs?: BlockInputOption[]
theme?: ThemeProps
persistentMenu?: PersistentMenuTheme
coverComponent?: CoverComponentOptions
defaultDelay?: number
defaultTyping?: number
enableAnimations?: boolean
enableAttachments?: boolean
blockInputs?: BlockInputOption[]
enableEmojiPicker?: boolean
enableAttachments?: boolean
enableUserInput?: boolean
shadowDOM?: boolean | (() => boolean)
enableAnimations?: boolean
hostId?: string
getString?: (stringId: string, session: CoreSession) => string
onClose?: (app: WebchatApp, args: any) => void
shadowDOM?: boolean | (() => boolean)
defaultDelay?: number
defaultTyping?: number
storage?: Storage | null
storageKey?: string
onInit?: (app: WebchatApp, args: any) => void
onMessage?: (app: WebchatApp, message: WebchatMessage) => void
onOpen?: (app: WebchatApp, args: any) => void
onConnectionChange?: (app: WebchatApp, isOnline: boolean) => void
onClose?: (app: WebchatApp, args: any) => void
onMessage?: (app: WebchatApp, message: WebchatMessage) => void
onTrackEvent?: TrackEventFunction
onConnectionChange?: (app: WebchatApp, isOnline: boolean) => void
appId?: string
visibility?: boolean | (() => boolean) | 'dynamic'
server?: ServerConfig
}

export interface WebchatProps {
webchatHooks?: UseWebchat
initialSession?: any
initialDevSettings?: any
onStateChange: (args: OnStateChangeArgs) => void

shadowDOM?: any
theme?: ThemeProps
persistentMenu?: PersistentMenuTheme
coverComponent?: any
blockInputs?: any
enableEmojiPicker?: boolean
enableAttachments?: boolean
enableUserInput?: boolean
enableAnimations?: boolean
storage?: Storage | null
storageKey?: any
theme?: ThemeProps
storageKey?: string | (() => string)
defaultDelay?: number
defaultTyping?: number
onInit?: (args?: any) => void
onOpen?: (args?: any) => void
onClose?: (args?: any) => void
onUserInput(args: OnUserInputArgs): Promise<void> // TODO: Review this function and params types
onTrackEvent?: TrackEventFunction
host?: any
server?: ServerConfig
}

export type EventArgs = { [key: string]: any }
Expand Down Expand Up @@ -123,7 +185,7 @@ export interface OnUserInputArgs {
input: CoreInput
lastRoutePath?: string
session?: CoreSession
user: CoreSessionUser
user?: CoreSessionUser
}

export interface OnStateChangeArgs {
Expand All @@ -137,18 +199,26 @@ export interface MessageInfo {
type: 'update_webchat_settings' | 'sender_action'
}

export interface Event {
action?: 'update_message_info'
export type Event = ConnectionChangeEvent | UpdateMessageInfoEvent

interface ConnectionChangeEvent {
action: 'connectionChange'
online: boolean
isError?: boolean
message?: MessageInfo
}

interface UpdateMessageInfoEvent {
action: 'update_message_info'
message: MessageInfo
isError?: boolean
}

// ClientInput: type for sendInput and updateLatestInput function without message_id and bot_interaction_id because backend set this values
export type ClientInput = Omit<CoreInput, 'message_id' | 'bot_interaction_id'>

export interface WebchatContextProps {
addMessage: (message: WebchatMessage) => void
closeWebview: () => Promise<void>
getThemeProperty: (property: string, defaultValue?: any) => any
openWebview: (webviewComponent: Webview, params?: any) => void
resetUnreadMessages: () => void
Expand All @@ -159,7 +229,7 @@ export interface WebchatContextProps {
sendText: (text: string, payload?: string) => Promise<void>
setIsInputFocused: (isInputFocused: boolean) => void
setLastMessageVisible: (isLastMessageVisible: boolean) => void
theme: ThemeProps
theme: ThemeProps // TODO: Review if theme is needed and used from WebchatContext
toggleWebchat: (toggle: boolean) => void
toggleEmojiPicker: (toggle: boolean) => void
togglePersistentMenu: (toggle: boolean) => void
Expand All @@ -169,9 +239,9 @@ export interface WebchatContextProps {
updateReplies: (replies: boolean) => void
updateUser: (user: Partial<CoreSessionUser>) => void
updateWebchatDevSettings: (settings: WebchatSettingsProps) => void
trackEvent?: TrackEventFunction
webchatState: WebchatState
trackEvent: TrackEventFunction
webchatRef: React.MutableRefObject<HTMLDivElement | null>
webchatRef: React.MutableRefObject<HTMLDivElement | null> // Rename this to webchatContainerRef
Iru89 marked this conversation as resolved.
Show resolved Hide resolved
chatAreaRef: React.MutableRefObject<HTMLDivElement | null>
inputPanelRef: React.MutableRefObject<HTMLDivElement | null>
headerRef: React.MutableRefObject<HTMLDivElement | null>
Expand Down
2 changes: 1 addition & 1 deletion packages/botonic-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ export { msgsToBotonic, msgToBotonic } from './msg-to-botonic'
export { NodeApp } from './node-app'
export * from './util'
export * from './webchat'
export { WebchatApp, WebchatAppProps } from './webchat-app'
export { WebchatApp } from './webchat-app'
export { WebviewApp } from './webview-app'
6 changes: 1 addition & 5 deletions packages/botonic-react/src/msg-to-botonic.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
* @param customMessageTypes {{customTypeName}[]?}
* @return {React.ReactNode}
*/
export function msgToBotonic(msg, customMessageTypes) {
export function msgToBotonic(msg, customMessageTypes = []) {
delete msg.display
if (isCustom(msg)) {
try {
Expand Down Expand Up @@ -99,10 +99,6 @@ export function msgToBotonic(msg, customMessageTypes) {
return null
}

function rndStr() {
return Math.random().toString()
}

/**
* @param msgs {object|object[]}
* @param customMessageTypes {{customTypeName}[]?}
Expand Down
Loading
Loading