UNPKG

@botonic/react

Version:

Build Chatbots using React

224 lines (200 loc) 6.01 kB
import { SENDERS } from '../../index-types' import { WebchatAction } from './actions' import { WebchatState } from './types' export const messagesReducer = ( state: WebchatState, action: { type: WebchatAction; payload?: any } ): WebchatState => { switch (action.type) { case WebchatAction.ADD_MESSAGE: return addMessageReducer(state, action) case WebchatAction.ADD_MESSAGE_COMPONENT: return addMessageComponent(state, action) case WebchatAction.UPDATE_MESSAGE: return updateMessageReducer(state, action) case WebchatAction.UPDATE_CUSTOM_MESSAGE_PROPS: return updateCustomMessagePropsReducer(state, action) case WebchatAction.UPDATE_REPLIES: return { ...state, replies: action.payload } case WebchatAction.REMOVE_REPLIES: return { ...state, replies: undefined } case WebchatAction.CLEAR_MESSAGES: return { ...state, messagesJSON: [], messagesComponents: [], numUnreadMessages: 0, } case WebchatAction.UPDATE_LAST_MESSAGE_DATE: return { ...state, lastMessageUpdate: action.payload, } case WebchatAction.RESET_UNREAD_MESSAGES: return resetUnreadMessages(state) case WebchatAction.SET_LAST_MESSAGE_VISIBLE: return { ...state, isLastMessageVisible: action.payload, } default: throw new Error() } } function addMessageComponent( state: WebchatState, action: { type: WebchatAction; payload?: any } ) { const messageComponent = action.payload const isUnreadMessage = messageComponent.props?.isUnread && messageComponent.props?.sentBy !== SENDERS.user && messageComponent.props?.sentBy !== SENDERS.system const numUnreadMessages = isUnreadMessage ? state.numUnreadMessages + 1 : state.numUnreadMessages return { ...state, messagesComponents: [...(state.messagesComponents || []), messageComponent], numUnreadMessages, } } function resetUnreadMessages(state: WebchatState) { const messagesComponents = state.messagesComponents.map(messageComponent => { if (messageComponent.props.isUnread) { messageComponent = { ...messageComponent, props: { ...messageComponent.props, isUnread: false }, } } return messageComponent }) const messagesJSON = state.messagesJSON.map(messageJSON => { if (messageJSON.isUnread) { messageJSON.isUnread = false } return messageJSON }) return { ...state, messagesComponents, messagesJSON, numUnreadMessages: 0, } } function updateMessageReducer( state: WebchatState, action: { type: WebchatAction; payload?: any } ) { const messageId = action.payload.id const msgIndex = state.messagesJSON.map(m => m.id).indexOf(messageId) if (msgIndex > -1) { const msgComponent = state.messagesComponents[msgIndex] let updatedMsgComponent = {} if (msgComponent) { updatedMsgComponent = { ...msgComponent, ...{ props: { ...msgComponent.props, ack: action.payload.ack }, }, } } const updatedMessagesComponents = msgComponent ? getUpdatedMessagesComponents(state, msgIndex, updatedMsgComponent) : state.messagesComponents const messageJSON = state.messagesJSON.find(m => m.id === messageId) const updatedMessagesJSON = messageJSON ? getUpdatedMessagesJSON(state, msgIndex, action.payload) : state.messagesJSON const numUnreadMessages = updatedMessagesComponents.filter( messageComponent => messageComponent.props?.isUnread && messageComponent.props?.sentBy !== SENDERS.user && messageComponent.props?.sentBy !== SENDERS.system ).length return { ...state, messagesJSON: updatedMessagesJSON, messagesComponents: updatedMessagesComponents, numUnreadMessages, } } return state } function addMessageReducer( state: WebchatState, action: { type: WebchatAction; payload?: any } ) { if ( state.messagesJSON && state.messagesJSON.find(m => m.id === action.payload.id) ) return state return { ...state, messagesJSON: [...(state.messagesJSON || []), action.payload], } } function updateCustomMessagePropsReducer( state: WebchatState, action: { type: WebchatAction; payload?: any } ) { const { messageId, props } = action.payload if (!messageId) { return state } // Similar to updateMessageReducer but only for custom messages when update props const msgIndex = state.messagesJSON.map(m => m.id).indexOf(messageId) if (msgIndex > -1) { const msgComponent = state.messagesComponents[msgIndex] if (msgComponent) { msgComponent.props = { ...msgComponent.props, ack: action.payload.ack, ...props, } } const updatedMessagesComponents = msgComponent ? getUpdatedMessagesComponents(state, msgIndex, msgComponent) : state.messagesComponents const messageJSON = state.messagesJSON.find(m => m.id === messageId) if (messageJSON) { messageJSON.data = { ...messageJSON.data, ...props, } } const updatedMessagesJSON = messageJSON ? getUpdatedMessagesJSON(state, msgIndex, messageJSON) : state.messagesJSON return { ...state, messagesJSON: updatedMessagesJSON, messagesComponents: updatedMessagesComponents, } } return state } // Helper functions to update messagesComponents and messagesJSON function getUpdatedMessagesComponents( state: WebchatState, msgIndex: number, updatedMessageComponent: any ) { return [ ...state.messagesComponents.slice(0, msgIndex), { ...updatedMessageComponent }, ...state.messagesComponents.slice(msgIndex + 1), ] } function getUpdatedMessagesJSON( state: WebchatState, msgIndex: number, messageJSON: any ) { return [ ...state.messagesJSON.slice(0, msgIndex), { ...messageJSON }, ...state.messagesJSON.slice(msgIndex + 1), ] }