{"version":3,"sources":["webpack:///./webpack-entry/chat.tsx","webpack:///./apps/chat/reducer.ts","webpack:///./apps/chat/index.tsx"],"names":["pin","Cookies","get","$ats","KEY","USER_COOKIE","document","querySelector","dataset","theme","chatSystem","chatHubUrl","chatApiKey","chatBotName","isOurApp","isDev","Modal","setAppElement","ReactDOM","render","apiKey","url","botName","hideOpener","proactive","getElementById","createPlaceholderMessages","senderUserId","sessionId","texts","now","Date","toISOString","map","text","i","id","created","updated","deleted","delivered","seen","payload","type","data","message","chatWidgetReducer","state","action","me","oldList","newList","oldIds","remainingPlaceholders","placeholders","session","allUsers","sessionMessages","newMessages","messages","msg","filter","includes","length","onNewMessages","newTexts","computeMyNewMessages","console","warn","firstAid","ChatWidget","hub","onClose","onRestart","soundRef","useRef","smallSoundRef","useEffect","current","Audio","useReducer","makeInitialState","output","dispatch","subscribeMe","newMe","subscribe","Kind","SESSION","sesUpdate","subSessionMessages","allUserIds","Array","from","Set","sort","fetch","entityName","USER","then","user","join","useMemo","sendMessage","sendTextMessage","see","msgs","forEach","seeMessage","setTyping","isTyping","update","clientTyping","useChatWidgetReducer","play","open","onSend","onSeen","onType","users","ChatWelcome","unavailable","ChatError","errorMessage","hubberReducer","initialMessage","connectionError","agentsAvailable","windowReady","stop","chatting","Sessioner","forceSession","keptSessionId","onSessionChange","rest","useState","setSession","started","setStarted","getOrCreateSession","existingSession","sendModifyTripMessage","prompt","getSession","a","fetchSessionById","keptSession","newSession","Hubber","aid","uuidv4","set","unstartedRef","builder","useCallback","Hub","signalR","withUrl","configureLogging","Information","withAutomaticReconnect","build","initialHubberState","useSessionStorageJsonHook","keptSessionStore","setKeptSessionId","clearKeptSessionId","ensureStarted","handleConnectionError","connErr","closeChat","connect","connectModifyTrip","connectWithMessage","window","startProactiveChat","ReactNativeWebView","postMessage","JSON","stringify","startModifyChat","startChatWithMessage","Promise","all","fetchMe","isAnyAgentAvailable","openButtonOrNothing","onClick","hubReady","themeName"],"mappings":"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","file":"chat.bundle.js","sourcesContent":["import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport Modal from 'react-modal';\r\nimport Cookies from 'js-cookie';\r\nimport 'core-js/stable';\r\nimport 'regenerator-runtime/runtime';\r\n\r\nimport ChatWidget from '../apps/chat';\r\n// Set a type for the global $ats (at least the parts we use)\r\ndeclare const $ats: {\r\n KEY: { USER_COOKIE: string };\r\n};\r\n// Get the user PIN from the local cookie. Right now we are using the old $ats\r\n// code since it still works, but this should be converted to a React aware\r\n// library\r\n\r\nconst pin = Cookies.get($ats.KEY.USER_COOKIE);\r\nconst { theme, chatSystem, chatHubUrl, chatApiKey, chatBotName, isDev, isOurApp } =\r\n document.querySelector('body').dataset;\r\n\r\nModal.setAppElement('#chatContainer');\r\nReactDOM.render(\r\n ,\r\n document.getElementById('chatContainer'),\r\n);\r\n","import React, { useReducer, useEffect, useMemo, useCallback } from 'react';\r\nimport { Session, User, Message, Payload, ID, IDMap, Hub, Kind } from '@amtrav/chat-stream';\r\n\r\ninterface ChatWidgetState {\r\n session: Session;\r\n me?: User;\r\n allUsers: IDMap;\r\n sessionMessages: Message[];\r\n placeholders: string[];\r\n}\r\n\r\ninterface ChatWidgetActions {\r\n sendMessage: (text: string) => Promise;\r\n setTyping: (isTyping: boolean) => void;\r\n see: (msgs: Message[]) => void;\r\n}\r\n\r\ninterface SetHub {\r\n type: 'setHub';\r\n payload: Hub;\r\n}\r\n\r\ninterface SetSession {\r\n type: 'setSession';\r\n payload: Session;\r\n}\r\n\r\ninterface ClearSession {\r\n type: 'clearSession';\r\n}\r\n\r\ninterface UpdateSessionMessages {\r\n type: 'updateSessionMessages';\r\n payload: {\r\n messages: Message[];\r\n onNewMessages?: (msgs: Message[]) => void;\r\n };\r\n}\r\n\r\ninterface AddPlaceholderText {\r\n type: 'addPlaceholderText';\r\n payload: string;\r\n}\r\n\r\ninterface UpdateUser {\r\n type: 'updateUser';\r\n payload: User;\r\n}\r\n\r\ninterface UpdateMe {\r\n type: 'updateMe';\r\n payload: User;\r\n}\r\n\r\ninterface UpdateSession {\r\n type: 'updateSession';\r\n payload: Session;\r\n}\r\n\r\ntype ChatWidgetReducerActions =\r\n | SetHub\r\n | SetSession\r\n | ClearSession\r\n | UpdateSessionMessages\r\n | AddPlaceholderText\r\n | UpdateUser\r\n | UpdateMe\r\n | UpdateSession;\r\n\r\nfunction computeNewMessages(me: User, oldList: Message[], newList: Message[]) {\r\n const oldIds = oldList.map((msg) => msg.id);\r\n return newList.filter((msg) => !oldIds.includes(msg.id)).filter((msg) => msg.senderUserId !== me.id);\r\n}\r\n\r\nfunction computeMyNewMessages(me: User, oldList: Message[], newList: Message[]) {\r\n const oldIds = oldList.map((msg) => msg.id);\r\n return newList.filter((msg) => !oldIds.includes(msg.id)).filter((msg) => msg.senderUserId === me.id);\r\n}\r\n\r\nfunction createPlaceholderMessages(senderUserId: ID, sessionId: ID, texts: string[]): Message[] {\r\n const now = new Date().toISOString();\r\n return texts.map((text, i) => ({\r\n id: `Placeholder::${i}`,\r\n created: now,\r\n updated: now,\r\n deleted: false,\r\n sessionId,\r\n senderUserId,\r\n delivered: false,\r\n seen: false,\r\n payload: { type: 'text', data: { message: text } },\r\n }));\r\n}\r\n\r\nexport const chatWidgetReducer = (state: ChatWidgetState, action: ChatWidgetReducerActions): ChatWidgetState => {\r\n let remainingPlaceholders: string[] = state.placeholders;\r\n switch (action.type) {\r\n case 'setHub': {\r\n return {\r\n ...state,\r\n };\r\n }\r\n case 'setSession':\r\n return {\r\n ...state,\r\n session: action.payload,\r\n };\r\n case 'clearSession':\r\n return {\r\n ...state,\r\n session: null,\r\n };\r\n case 'updateSession':\r\n return {\r\n ...state,\r\n session: action.payload,\r\n };\r\n case 'updateMe':\r\n return {\r\n ...state,\r\n me: action.payload,\r\n };\r\n case 'updateUser':\r\n return {\r\n ...state,\r\n allUsers: {\r\n ...state.allUsers,\r\n [action.payload.id]: action.payload,\r\n },\r\n };\r\n case 'updateSessionMessages':\r\n if (state.session && state.sessionMessages) {\r\n const newMessages = computeNewMessages(state.me, state.sessionMessages, action.payload.messages);\r\n if (newMessages.length > 0 && action.payload.onNewMessages) {\r\n action.payload.onNewMessages(newMessages);\r\n }\r\n const myNewMessages = computeMyNewMessages(state.me, state.sessionMessages, action.payload.messages);\r\n const newTexts = myNewMessages\r\n .map((msg) => {\r\n const { payload } = msg;\r\n switch (payload.type) {\r\n case 'text':\r\n return payload.data.message;\r\n default:\r\n return null;\r\n }\r\n })\r\n .filter((text) => text);\r\n remainingPlaceholders = state.placeholders.filter((text) => !newTexts.includes(text));\r\n }\r\n return {\r\n ...state,\r\n placeholders: remainingPlaceholders,\r\n sessionMessages: [\r\n ...action.payload.messages,\r\n ...createPlaceholderMessages(state.me?.id, state.session?.id, remainingPlaceholders),\r\n ],\r\n };\r\n case 'addPlaceholderText':\r\n return {\r\n ...state,\r\n placeholders: [...state.placeholders, action.payload],\r\n sessionMessages: [\r\n ...state.sessionMessages,\r\n ...createPlaceholderMessages(state.me?.id, state.session?.id, [...state.placeholders, action.payload]),\r\n ],\r\n };\r\n default:\r\n console.warn('Unknown action sent to chat reducer: ', action);\r\n return state;\r\n }\r\n};\r\n\r\nconst makeInitialState = (session: Session, me: User): ChatWidgetState => {\r\n return {\r\n allUsers: {},\r\n sessionMessages: [],\r\n placeholders: [],\r\n session,\r\n me,\r\n };\r\n};\r\n\r\nexport const useChatWidgetReducer = (\r\n hub: Hub,\r\n session: Session,\r\n me: User,\r\n onNewMessages?: (msgs: Message[]) => void,\r\n): [ChatWidgetState, ChatWidgetActions] => {\r\n // We use a callback as the reducer because we need to avoid creating a new reducer on each hook call,\r\n // but we do need it to track the current hub.\r\n const [output, dispatch] = useReducer(chatWidgetReducer, makeInitialState(session, me));\r\n\r\n useEffect(() => {\r\n return hub.subscribeMe((newMe) => dispatch({ type: 'updateMe', payload: newMe }));\r\n }, [hub]);\r\n\r\n useEffect(() => {\r\n return hub.subscribe(Kind.SESSION, session.id, (sesUpdate) =>\r\n dispatch({ type: 'updateSession', payload: sesUpdate }),\r\n );\r\n }, [hub, session.id]);\r\n\r\n useEffect(() => {\r\n return hub.subSessionMessages(session.id, (messages) => {\r\n dispatch({ type: 'updateSessionMessages', payload: { messages, onNewMessages } });\r\n });\r\n }, [hub, session.id]);\r\n\r\n const allUserIds = Array.from(new Set(output.sessionMessages.map((msg) => msg.senderUserId))).sort();\r\n useEffect(() => {\r\n if (hub) {\r\n allUserIds.map((id) =>\r\n hub\r\n .fetch({ entityName: Kind.USER, filter: `id = ${id}` })\r\n .then((user) => dispatch({ type: 'updateUser', payload: user[0] as User })),\r\n );\r\n }\r\n }, [hub, allUserIds.join('::')]);\r\n\r\n const actions = useMemo(() => {\r\n return {\r\n sendMessage: (text: string) => {\r\n dispatch({ type: 'addPlaceholderText', payload: text });\r\n return hub.sendTextMessage(session.id, text);\r\n },\r\n see: (msgs: Message[]) => {\r\n msgs\r\n .filter((msg) => !msg.seen)\r\n .map((msg) => msg.id)\r\n .forEach(hub.seeMessage);\r\n },\r\n setTyping: (isTyping: boolean) => hub.update(Kind.SESSION, { id: session.id, clientTyping: isTyping }),\r\n };\r\n }, [hub]);\r\n\r\n return [output, actions];\r\n};\r\n","import React, { useEffect, useState, FunctionComponent, useCallback, useRef, useReducer } from 'react';\r\nimport * as signalR from '@microsoft/signalr';\r\nimport Cookies from 'js-cookie';\r\nimport { v4 as uuidv4 } from 'uuid';\r\nimport { ThemeSystemProvider } from '@amtrav/theme-system';\r\nimport { DynamicThemeProvider } from '@amtrav/themes';\r\nimport { Hub, Connection, Session, Message, Payload, User } from '@amtrav/chat-stream';\r\nimport { WebChatLauncher, OpenButton } from '@amtrav/web-chat';\r\n\r\nimport { useLocalStorageJsonHook, useSessionStorageJsonHook } from '@amtrav/external-storage-helpers';\r\nimport { useChatWidgetReducer } from './reducer';\r\n\r\nconst AID_KEY = 'WEBCHATAIDKEY';\r\nconst firstAid = Cookies.get(AID_KEY);\r\n\r\ninterface HubberProps {\r\n pin?: string;\r\n apiKey: string;\r\n url: string;\r\n botName?: string;\r\n theme?: string;\r\n hideOpener?: boolean;\r\n proactive?: boolean;\r\n forceSession?: boolean;\r\n isOurApp?: boolean;\r\n}\r\n\r\ninterface ChatWidgetProps {\r\n botName?: string;\r\n hub: Hub;\r\n me: User;\r\n session: Session;\r\n onClose: () => void;\r\n onRestart: () => void;\r\n}\r\n\r\nconst ChatWidget: FunctionComponent = ({ botName, hub, me, session, onClose, onRestart }) => {\r\n const soundRef = useRef();\r\n const smallSoundRef = useRef();\r\n useEffect(() => {\r\n soundRef.current = new Audio('//cdn.amtrav.com/agent-console/whistle.mp3');\r\n smallSoundRef.current = new Audio('//cdn.amtrav.com/agent-console/new-chat-msg.mp3');\r\n }, []);\r\n\r\n const [state, { see, sendMessage, setTyping }] = useChatWidgetReducer(hub, session, me, () => {\r\n if (smallSoundRef.current) {\r\n smallSoundRef.current.play();\r\n }\r\n });\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\ninterface ChatWelcomeProps {\r\n botName?: string;\r\n me: User;\r\n onSend: (msg: string) => Promise;\r\n onClose: () => void;\r\n unavailable: boolean;\r\n}\r\n\r\nconst ChatWelcome: FunctionComponent = ({ botName, me, unavailable, onSend, onClose }) => {\r\n return (\r\n {}}\r\n onType={() => {}}\r\n user={me}\r\n users={{}}\r\n botName={botName}\r\n onClose={onClose}\r\n />\r\n );\r\n};\r\n\r\ninterface ChatErrorProps {\r\n errorMessage: string;\r\n onClose: () => void;\r\n}\r\n\r\nconst ChatError: FunctionComponent = ({ errorMessage, onClose }) => {\r\n return (\r\n {}}\r\n onSeen={() => {}}\r\n onType={() => {}}\r\n user={{}}\r\n users={{}}\r\n botName=\"\"\r\n onClose={onClose}\r\n />\r\n );\r\n};\r\n\r\ninterface HubberState {\r\n builder: () => Hub;\r\n connectionError?: string;\r\n initialMessage?: Payload;\r\n hub: Hub;\r\n me?: User;\r\n agentsAvailable: boolean;\r\n chatting: boolean;\r\n windowReady: boolean;\r\n}\r\n\r\nconst initialHubberState = (builder: () => Hub): HubberState => ({\r\n builder,\r\n initialMessage: null,\r\n hub: null,\r\n chatting: false,\r\n agentsAvailable: false,\r\n windowReady: false,\r\n});\r\n\r\ninterface InitHubberAction {\r\n type: 'initHubber';\r\n payload: Hub;\r\n}\r\n\r\ninterface InitHubberWithMessageAction {\r\n type: 'initHubberWithMessage';\r\n payload: {\r\n hub: Hub;\r\n message: Payload;\r\n };\r\n}\r\n\r\ninterface InitErrorAction {\r\n type: 'initError';\r\n payload: string;\r\n}\r\n\r\ninterface SetInitialState {\r\n type: 'setInitialState';\r\n payload: {\r\n me: User;\r\n agentsAvailable: boolean;\r\n };\r\n}\r\n\r\ninterface ClearHub {\r\n type: 'clearHub';\r\n}\r\n\r\ntype HubberAction = InitHubberAction | InitHubberWithMessageAction | InitErrorAction | SetInitialState | ClearHub;\r\n\r\nconst hubberReducer = (state: HubberState, action: HubberAction) => {\r\n switch (action.type) {\r\n case 'initHubber': {\r\n return {\r\n ...state,\r\n hub: action.payload,\r\n };\r\n }\r\n case 'initHubberWithMessage': {\r\n return {\r\n ...state,\r\n hub: action.payload.hub,\r\n initialMessage: action.payload.message,\r\n };\r\n }\r\n case 'initError': {\r\n return {\r\n ...state,\r\n connectionError: action.payload,\r\n };\r\n }\r\n case 'setInitialState': {\r\n return {\r\n ...state,\r\n me: action.payload.me,\r\n agentsAvailable: action.payload.agentsAvailable,\r\n windowReady: true,\r\n };\r\n }\r\n case 'clearHub': {\r\n state.hub?.stop();\r\n return {\r\n ...state,\r\n hub: null,\r\n me: null,\r\n connectionError: null,\r\n initialMessage: null,\r\n chatting: false,\r\n };\r\n }\r\n default:\r\n console.warn('Unrecognized Action: ', action);\r\n return state;\r\n }\r\n};\r\n\r\ninterface SessionerProps {\r\n hub: Hub;\r\n me: User;\r\n agentsAvailable: boolean;\r\n forceSession: boolean;\r\n initialMessage: Payload;\r\n keptSessionId: string;\r\n onSessionChange: (id: string) => void;\r\n botName: string;\r\n onClose: () => void;\r\n}\r\n\r\nconst Sessioner = ({\r\n hub,\r\n initialMessage,\r\n me,\r\n forceSession,\r\n agentsAvailable,\r\n keptSessionId,\r\n onSessionChange = () => {},\r\n ...rest\r\n}: SessionerProps) => {\r\n const [session, setSession] = useState(null);\r\n const [started, setStarted] = useState(false);\r\n\r\n useEffect(() => {\r\n if (initialMessage || forceSession) {\r\n hub.getOrCreateSession().then((existingSession) => {\r\n if (initialMessage) {\r\n switch (initialMessage.type) {\r\n case 'text': {\r\n hub.sendTextMessage(existingSession.id, initialMessage.data.message);\r\n break;\r\n }\r\n case 'modify-trip': {\r\n hub.sendModifyTripMessage(existingSession.id, initialMessage.data.prompt, initialMessage.data.data);\r\n break;\r\n }\r\n default: {\r\n console.warn('Unsupported initial message type: ', initialMessage.type);\r\n }\r\n }\r\n }\r\n setSession(existingSession);\r\n onSessionChange(existingSession.id);\r\n setStarted(true);\r\n });\r\n } else {\r\n hub.getSession().then(async (existingSession) => {\r\n if (existingSession) {\r\n setSession(existingSession);\r\n onSessionChange(existingSession.id);\r\n } else if (keptSessionId) {\r\n await hub.fetchSessionById(keptSessionId).then((keptSession) => {\r\n setSession(keptSession);\r\n onSessionChange(keptSession.id);\r\n });\r\n }\r\n setStarted(true);\r\n });\r\n }\r\n }, [hub]);\r\n\r\n const onSend = async (msg: string) => {\r\n const newSession = await hub.getOrCreateSession();\r\n if (keptSessionId !== newSession.id) {\r\n onSessionChange(newSession.id);\r\n }\r\n setSession(newSession);\r\n return hub.sendTextMessage(newSession.id, msg);\r\n };\r\n return session ? (\r\n \r\n ) : (\r\n started && \r\n );\r\n};\r\n\r\ninterface KeptSessionStore {\r\n id: string;\r\n}\r\n\r\nconst Hubber = ({ url, pin, apiKey, theme, hideOpener, proactive, botName, forceSession, isOurApp }: HubberProps) => {\r\n const aid = firstAid || uuidv4();\r\n Cookies.set(AID_KEY, aid);\r\n const unstartedRef = useRef();\r\n const builder = useCallback(\r\n () =>\r\n new Hub(\r\n new signalR.HubConnectionBuilder()\r\n .withUrl(`${url}/chathub?ak=${apiKey}${pin ? `&pin=${pin}` : ''}${aid ? `&aid=${aid}` : ''}`)\r\n .configureLogging(signalR.LogLevel.Information)\r\n .withAutomaticReconnect()\r\n .build() as unknown as Connection,\r\n ),\r\n [],\r\n );\r\n const [state, dispatch] = useReducer(hubberReducer, initialHubberState(builder));\r\n const [keptSessionStore, setKeptSessionId, clearKeptSessionId] =\r\n useSessionStorageJsonHook('KeepOpenChat');\r\n const keptSessionId = keptSessionStore?.id;\r\n const ensureStarted = async () => {\r\n if (unstartedRef.current) return unstartedRef.current.started;\r\n unstartedRef.current = builder();\r\n return unstartedRef.current.started;\r\n };\r\n\r\n const handleConnectionError = (connErr) => {\r\n dispatch({\r\n type: 'initError',\r\n payload: 'We are having trouble connecting to the chat system. Please try reloading this page...',\r\n });\r\n };\r\n\r\n const closeChat = () => {\r\n clearKeptSessionId();\r\n dispatch({ type: 'clearHub' });\r\n unstartedRef.current = null;\r\n };\r\n\r\n const restartChat = () => {\r\n closeChat();\r\n window.startProactiveChat();\r\n };\r\n\r\n const connect = async () => {\r\n try {\r\n await ensureStarted();\r\n } catch (connErr) {\r\n handleConnectionError(connErr);\r\n }\r\n dispatch({ type: 'initHubber', payload: unstartedRef.current });\r\n };\r\n\r\n const connectModifyTrip = async (message, data) => {\r\n try {\r\n await ensureStarted();\r\n } catch (connErr) {\r\n handleConnectionError(connErr);\r\n }\r\n dispatch({\r\n type: 'initHubberWithMessage',\r\n payload: { hub: unstartedRef.current, message: { type: 'modify-trip', data: { prompt: message, data } } },\r\n });\r\n };\r\n\r\n const connectWithMessage = async (message) => {\r\n try {\r\n await ensureStarted();\r\n } catch (connErr) {\r\n handleConnectionError(connErr);\r\n }\r\n dispatch({\r\n type: 'initHubberWithMessage',\r\n payload: { hub: unstartedRef.current, message: { type: 'text', data: { message } } },\r\n });\r\n };\r\n\r\n if (proactive) {\r\n window.startProactiveChat = async () => {\r\n if (isOurApp) {\r\n if (window?.ReactNativeWebView?.postMessage) {\r\n window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'startChat' }));\r\n }\r\n } else {\r\n connect();\r\n }\r\n };\r\n }\r\n window.startModifyChat = async (message: string, data: any) => {\r\n if (isOurApp) {\r\n if (window?.ReactNativeWebView?.postMessage) {\r\n window.ReactNativeWebView.postMessage(\r\n JSON.stringify({ type: 'startModifyChat', payload: { prompt: message, data } }),\r\n );\r\n }\r\n } else {\r\n connectModifyTrip(message, data);\r\n }\r\n };\r\n\r\n window.startChatWithMessage = async (message: string) => {\r\n if (isOurApp) {\r\n if (window?.ReactNativeWebView?.postMessage) {\r\n window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'startChat', payload: { message } }));\r\n }\r\n } else {\r\n connectWithMessage(message);\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (state.hub) {\r\n Promise.all([state.hub.fetchMe(), state.hub.isAnyAgentAvailable()]).then(([me, agentsAvailable]) => {\r\n dispatch({ type: 'setInitialState', payload: { me, agentsAvailable } });\r\n });\r\n }\r\n }, [state.hub]);\r\n\r\n const openButtonOrNothing = hideOpener ? null : ;\r\n const hubReady = state.hub && state.me;\r\n\r\n useEffect(() => {\r\n if (keptSessionId) {\r\n connect();\r\n }\r\n }, []);\r\n return (\r\n \r\n \r\n {state.connectionError ? (\r\n \r\n ) : hubReady ? (\r\n {\r\n setKeptSessionId({ id: sessionId });\r\n }}\r\n initialMessage={state.initialMessage}\r\n botName={botName}\r\n agentsAvailable={state.agentsAvailable}\r\n onClose={closeChat}\r\n onRestart={restartChat}\r\n />\r\n ) : (\r\n openButtonOrNothing\r\n )}\r\n \r\n \r\n );\r\n};\r\n\r\nexport default Hubber;\r\n"],"sourceRoot":""}