Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Iru89 committed Dec 17, 2024
1 parent e0bbdb4 commit 731daba
Show file tree
Hide file tree
Showing 26 changed files with 3,314 additions and 6,296 deletions.
8,940 changes: 2,915 additions & 6,025 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"clean": "rimraf packages/**/lib"
},
"dependencies": {
"axios": "^1.7.2"
"axios": "^1.7.2",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@babel/cli": "^7.23.9",
Expand All @@ -17,9 +19,11 @@
"@babel/runtime": "^7.23.9",
"@types/jest": "^29.5.12",
"@types/node": "^20.11.19",
"@types/react-dom": "^18.0.0",
"@types/react": "^18.0.0",
"@types/rimraf": "^3.0.0",
"@typescript-eslint/parser": "^6.21.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"babel-plugin-add-module-exports": "^1.0.4",
"cloc": "^2.7.0",
"eslint": "^8.56.0",
Expand Down
1 change: 1 addition & 0 deletions packages/botonic-core/src/models/legacy-types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention */
// TODO: This file contains all the legacy types we had in index.ts. After some refactors, we should be able to get rid of many of them.

export enum CASE_STATUS {
Expand Down
1 change: 1 addition & 0 deletions packages/botonic-plugin-flow-builder/src/action/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type FlowBuilderActionProps = {

export class FlowBuilderAction extends React.Component<FlowBuilderActionProps> {
static contextType = RequestContext
context!: React.ContextType<typeof RequestContext>

static async executeConversationStart(
request: ActionRequest
Expand Down
1 change: 1 addition & 0 deletions packages/botonic-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/styled-components": "^5.1.34",
"@types/ua-parser-js": "^0.7.39",
"@types/uuid": "^10.0.0",
"babel-plugin-add-module-exports": "^1.0.4",
"copyfiles": "^2.4.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/botonic-react/src/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const Button = (props: ButtonProps) => {
updateMessage,
} = useContext(WebchatContext)
const [hover, setHover] = useState(false)
const { theme } = webchatState
// const { theme } = webchatState
const { autoDisable, disabledStyle } = ButtonsDisabler.resolveDisabling(
webchatState.theme,
props
Expand Down Expand Up @@ -170,7 +170,7 @@ export const Button = (props: ButtonProps) => {
return (
<StyledButton
className={getClassName()}
theme={theme}
// theme={theme}
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
onClick={e => handleClick(e)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,25 @@ import { Reply } from './reply'

/**
*
* @param name as it appears at ThemeProps' message.customTypes key
* @param CustomMessageComponent
* @param defaultProps Props for the wrapper Message
* @param ErrorBoundary to recover in case it fails
* name: as it appears at ThemeProps' message.customTypes key
* CustomMessageComponent
* defaultProps: Props for the wrapper Message
* ErrorBoundary: to recover in case it fails
*/

export interface CustomMessageArgs {
name: string
component: React.ComponentType
defaultProps?: Record<string, any>
errorBoundary?: any
}

export const customMessage = ({
name,
component: CustomMessageComponent,
defaultProps = {},
errorBoundary: ErrorBoundary = createErrorBoundary(),
}) => {
errorBoundary = createErrorBoundary(),
}: CustomMessageArgs) => {
const CustomMessage = props => {
warnDeprecatedProps(defaultProps, 'customMessage:')
if (defaultProps.sentBy === SENDERS.user) {
Expand Down Expand Up @@ -57,6 +65,9 @@ export const customMessage = ({
const WrappedComponent = props => {
const { id, children, ...customMessageProps } = props
const { replies, childrenWithoutReplies } = splitChildren(props)

const ErrorBoundary = errorBoundary

return (
<CustomMessage
id={id}
Expand All @@ -80,7 +91,7 @@ export const customMessage = ({
}
WrappedComponent.customTypeName = name
// eslint-disable-next-line react/display-name
WrappedComponent.deserialize = msg => (
WrappedComponent.deserialize = (msg: any) => (
<WrappedComponent
id={msg.id}
key={msg.key}
Expand Down
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
14 changes: 7 additions & 7 deletions packages/botonic-react/src/contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ 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,
params: {} as Record<string, any>,
session: {} as CoreSession,
session: {} as Partial<CoreSession>,
})

export const WebchatContext = createContext<WebchatContextProps>({
addMessage: () => {
return
},
closeWebview: async () => {
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
126 changes: 105 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,7 +21,9 @@ import {
WebchatSettingsProps,
Webview,
} from './components/index-types'
import { WebchatState } from './webchat/index-types'
import { CloseWebviewOptions } from './contexts'
import { UseWebchat } from './webchat/hooks/use-webchat'
import { ErrorMessage, WebchatState } from './webchat/index-types'
import { WebchatApp } from './webchat-app'

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

export interface CustomMessageType {
customTypeName: string
// TODO: Remove this interface and use interface declared in src/components/index-types.ts
// // 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
// openWebviewApi: (component: any) => void
// setError: (error: ErrorMessage) => void
isOnline: () => boolean
setOnline: (online: boolean) => void
getMessages: () => { id: string; ack: number; unsentInput: CoreInput }[] // TODO: define MessagesJSON
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: ({
session,
messagesJSON,
}: {
session: Partial<CoreSession>
messagesJSON: any
}) => 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 +198,7 @@ export interface OnUserInputArgs {
input: CoreInput
lastRoutePath?: string
session?: CoreSession
user: CoreSessionUser
user?: CoreSessionUser
}

export interface OnStateChangeArgs {
Expand All @@ -137,18 +212,27 @@ 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>
// closeWebview: () => Promise<void>
getThemeProperty: (property: string, defaultValue?: any) => any
openWebview: (webviewComponent: Webview, params?: any) => void
resetUnreadMessages: () => void
Expand All @@ -159,7 +243,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 @@ -170,7 +254,7 @@ export interface WebchatContextProps {
updateUser: (user: Partial<CoreSessionUser>) => void
updateWebchatDevSettings: (settings: WebchatSettingsProps) => void
webchatState: WebchatState
trackEvent: TrackEventFunction
trackEvent?: TrackEventFunction
webchatRef: React.MutableRefObject<HTMLDivElement | null>
chatAreaRef: React.MutableRefObject<HTMLDivElement | null>
inputPanelRef: 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

0 comments on commit 731daba

Please sign in to comment.