@defra/flood-webchat 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react'
2
2
  import { PanelHeader } from '../panel/panel-header.jsx'
3
3
 
4
- import { useApp } from '../../store/app/useApp.js'
4
+ import { useApp } from '../../store/useApp.js'
5
5
 
6
6
  export function Settings ({ onCancel }) {
7
7
  const { settings, setSettings } = useApp()
@@ -7,18 +7,16 @@ export function Unavailable () {
7
7
  <PanelHeader />
8
8
 
9
9
  <div className='wc-body'>
10
- <div className='wc-content'>
11
- <h3 id='wc-subtitle' className='govuk-heading-m'>Webchat is currently not available</h3>
12
- <p className='govuk-body-s'>Try again later, or call Floodline:</p>
13
- <p className='govuk-body-s'>
14
- <strong>Floodline helpline</strong>
15
- <br />Telephone: 0345 988 1188
16
- <br />Textphone: 0345 602 6340
17
- <br />Open 24 hours a day, 7 days a week
18
- <br /><a className='govuk-link' href='https://gov.uk/call-charges'>Find out more about call charges</a>
19
- </p>
20
- <p className='govuk-body-s'>We're running webchat as a trial, it will not always be available.</p>
21
- </div>
10
+ <h3 id='wc-subtitle' className='govuk-heading-m'>Webchat is currently not available</h3>
11
+ <p className='govuk-body-s'>Try again later, or call Floodline:</p>
12
+ <p className='govuk-body-s'>
13
+ <strong>Floodline helpline</strong>
14
+ <br />Telephone: 0345 988 1188
15
+ <br />Textphone: 0345 602 6340
16
+ <br />Open 24 hours a day, 7 days a week
17
+ <br /><a className='govuk-link' href='https://gov.uk/call-charges'>Find out more about call charges</a>
18
+ </p>
19
+ <p className='govuk-body-s'>We're running webchat as a trial, it will not always be available.</p>
22
20
  </div>
23
21
  </>
24
22
  )
@@ -1,6 +1,6 @@
1
1
  import React from 'react'
2
2
  import { createPortal } from 'react-dom'
3
- import { useApp } from '../store/app/useApp'
3
+ import { useApp } from '../store/useApp'
4
4
 
5
5
  export const SkipLink = () => {
6
6
  const { threadId, setInstigatorId } = useApp()
@@ -32,7 +32,7 @@ export const getFocusableElements = () => {
32
32
  return Array.from(elements).filter(e => !e.closest('[hidden]') && !e.closest('[aria-hidden="true"]'))
33
33
  }
34
34
 
35
- const useFocusedElements = (screen, isChatOpen) => {
35
+ const useFocusedElements = screen => {
36
36
  const [panelElements, setPanelElements] = useState([])
37
37
 
38
38
  const onKeyDown = useCallback(e => {
@@ -63,20 +63,18 @@ const useFocusedElements = (screen, isChatOpen) => {
63
63
  }, [screen])
64
64
 
65
65
  useEffect(() => {
66
- if (isChatOpen) {
67
- setAriaHidden(true)
66
+ setAriaHidden(true)
68
67
 
69
- const panelElement = document.querySelector('#wc-panel')
70
- panelElement.focus()
68
+ const panelElement = document.querySelector('#wc-panel')
69
+ panelElement.focus()
71
70
 
72
- document.addEventListener('keydown', onKeyDown)
73
- }
71
+ document.addEventListener('keydown', onKeyDown)
74
72
 
75
73
  return () => {
76
74
  setAriaHidden()
77
75
  document.removeEventListener('keydown', onKeyDown)
78
76
  }
79
- }, [panelElements, isChatOpen])
77
+ }, [panelElements])
80
78
  }
81
79
 
82
80
  export { useFocusedElements }
@@ -3,44 +3,31 @@ import { createRoot } from 'react-dom/client'
3
3
  import { ChatSdk } from '@nice-devone/nice-cxone-chat-web-sdk'
4
4
  import { Availability } from './components/availability/availability.jsx'
5
5
  import { checkAvailability } from './lib/check-availability'
6
- import { AppProvider } from './store/app/AppProvider.jsx'
6
+ import { AppProvider } from './store/AppProvider.jsx'
7
7
  import { CUSTOMER_ID_STORAGE_KEY } from './store/constants.js'
8
8
  import { messageNotification } from './lib/message-notification.js'
9
- import { SkipLink } from './components/skip-link.jsx'
10
- import { Panel } from './components/panel/panel.jsx'
11
9
 
12
10
  export async function init (container, options) {
13
- const root = createRoot(container)
14
-
15
- const initSdk = () => {
16
- return new ChatSdk({
17
- brandId: options.brandId,
18
- channelId: options.channelId,
19
- customerId: window.localStorage.getItem(CUSTOMER_ID_STORAGE_KEY) || '',
20
- environment: options.environment,
21
- onError: error => {
22
- console.log('ChatSdk onError', error)
23
- }
24
- })
25
- }
11
+ const sdk = new ChatSdk({
12
+ brandId: options.brandId,
13
+ channelId: options.channelId,
14
+ customerId: window.localStorage.getItem(CUSTOMER_ID_STORAGE_KEY) || '',
15
+ environment: options.environment
16
+ })
26
17
 
18
+ const root = createRoot(container)
27
19
  let availability
28
20
  let playSound
29
-
30
21
  try {
31
22
  const result = await checkAvailability(options.availabilityEndpoint)
32
-
33
23
  playSound = await messageNotification(options.audioUrl)
34
24
  availability = result.availability
35
25
  } catch (e) {
36
26
  availability = 'UNAVAILABLE'
37
27
  }
38
-
39
28
  root.render(
40
- <AppProvider availability={availability}>
29
+ <AppProvider sdk={sdk} availability={availability} playSound={playSound}>
41
30
  <Availability />
42
- <SkipLink />
43
- <Panel initSdk={initSdk} playSound={playSound} />
44
31
  </AppProvider>
45
32
  )
46
33
  }
@@ -1,14 +1,84 @@
1
1
  import React, { createContext, useEffect, useReducer, useMemo } from 'react'
2
- // import { ChatEvent } from '@nice-devone/nice-cxone-chat-web-sdk'
2
+ import { ChatEvent } from '@nice-devone/nice-cxone-chat-web-sdk'
3
3
 
4
4
  import { initialState, reducer } from './reducer.js'
5
- import { CUSTOMER_ID_STORAGE_KEY, THREAD_ID_STORAGE_KEY, SETTINGS_STORAGE_KEY, MESSAGES_UNSEEN_COUNT } from '../constants.js'
5
+ import { CUSTOMER_ID_STORAGE_KEY, THREAD_ID_STORAGE_KEY, SETTINGS_STORAGE_KEY, MESSAGES_UNSEEN_COUNT } from './constants.js'
6
6
 
7
7
  export const AppContext = createContext(initialState)
8
8
 
9
- export const AppProvider = ({ availability, children }) => {
9
+ export const AppProvider = ({ sdk, availability, playSound, children }) => {
10
10
  const [state, dispatch] = useReducer(reducer, initialState)
11
11
 
12
+ /**
13
+ * SDK event handlers
14
+ */
15
+ const onLiveChatRecovered = e => {
16
+ dispatch({ type: 'SET_AGENT', payload: e.detail.data.inboxAssignee })
17
+ dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.contact.status })
18
+ dispatch({ type: 'SET_UNSEEN_COUNT', payload: e.detail.data.contact.customerStatistics.unseenMessagesCount })
19
+ }
20
+
21
+ const onAssignedAgentChanged = e => {
22
+ dispatch({ type: 'SET_AGENT', payload: e.detail.data.inboxAssignee })
23
+ dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.case.status })
24
+ }
25
+
26
+ const onAgentTypingStarted = () => {
27
+ dispatch({ type: 'SET_AGENT_TYPING', payload: true })
28
+ }
29
+
30
+ const onAgentTypingEnded = () => {
31
+ dispatch({ type: 'SET_AGENT_TYPING', payload: false })
32
+ dispatch({ type: 'SET_LIVE_REGION_TEXT' })
33
+ }
34
+
35
+ const onMessageCreated = e => {
36
+ dispatch({ type: 'SET_MESSAGE', payload: e.detail.data.message })
37
+ dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.case.status })
38
+ dispatch({ type: 'SET_UNSEEN_COUNT', payload: e.detail.data.case.customerStatistics.unseenMessagesCount })
39
+
40
+ const isAudioOn = JSON.parse(window.localStorage.getItem(SETTINGS_STORAGE_KEY)).audio
41
+
42
+ if (isAudioOn && e.detail.data.message.direction === 'outbound' && playSound) {
43
+ playSound()
44
+ }
45
+ }
46
+
47
+ const onContactStatusChanged = e => {
48
+ dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.case.status })
49
+ }
50
+
51
+ const onMatchMedia = e => {
52
+ dispatch({ type: 'TOGGLE_IS_MOBILE', payload: e.matches })
53
+ }
54
+
55
+ const onKeydown = () => {
56
+ dispatch({ type: 'TOGGLE_IS_KEYBOARD', payload: true })
57
+ }
58
+
59
+ const onPointerdown = () => {
60
+ dispatch({ type: 'TOGGLE_IS_KEYBOARD', payload: false })
61
+ }
62
+
63
+ useEffect(() => {
64
+ sdk.onChatEvent(ChatEvent.LIVECHAT_RECOVERED, onLiveChatRecovered)
65
+ sdk.onChatEvent(ChatEvent.MESSAGE_CREATED, onMessageCreated)
66
+ sdk.onChatEvent(ChatEvent.AGENT_TYPING_STARTED, onAgentTypingStarted)
67
+ sdk.onChatEvent(ChatEvent.AGENT_TYPING_ENDED, onAgentTypingEnded)
68
+ sdk.onChatEvent(ChatEvent.ASSIGNED_AGENT_CHANGED, onAssignedAgentChanged)
69
+ sdk.onChatEvent(ChatEvent.CONTACT_STATUS_CHANGED, onContactStatusChanged)
70
+ // We need to know if it is a mobile and if it is a keyboard interaction
71
+ window.matchMedia('(max-width: 640px)').addEventListener('change', onMatchMedia)
72
+ window.addEventListener('keydown', onKeydown)
73
+ window.addEventListener('pointerdown', onPointerdown)
74
+ // Tidying up
75
+ return () => {
76
+ window.removeEventListener('change', onMatchMedia)
77
+ window.removeEventListener('keydown', onKeydown)
78
+ window.removeEventListener('pointerdown', onPointerdown)
79
+ }
80
+ }, [sdk])
81
+
12
82
  /**
13
83
  * Initialize customerId, threadId and whether the webchat should be open
14
84
  */
@@ -44,38 +114,9 @@ export const AppProvider = ({ availability, children }) => {
44
114
  }
45
115
  }, [])
46
116
 
47
- const onMatchMedia = e => {
48
- dispatch({ type: 'TOGGLE_IS_MOBILE', payload: e.matches })
49
- }
50
-
51
- const onKeydown = () => {
52
- dispatch({ type: 'TOGGLE_IS_KEYBOARD', payload: true })
53
- }
54
-
55
- const onPointerdown = () => {
56
- dispatch({ type: 'TOGGLE_IS_KEYBOARD', payload: false })
57
- }
58
-
59
- useEffect(() => {
60
- // We need to know if it is a mobile and if it is a keyboard interaction
61
- window.matchMedia('(max-width: 640px)').addEventListener('change', onMatchMedia)
62
- window.addEventListener('keydown', onKeydown)
63
- window.addEventListener('pointerdown', onPointerdown)
64
-
65
- return () => {
66
- window.removeEventListener('change', onMatchMedia)
67
- window.removeEventListener('keydown', onKeydown)
68
- window.removeEventListener('pointerdown', onPointerdown)
69
- }
70
- }, [])
71
-
72
117
  /**
73
118
  * State update functions
74
119
  */
75
- const setSdk = payload => {
76
- dispatch({ type: 'SET_SDK', payload })
77
- }
78
-
79
120
  const setChatVisibility = payload => {
80
121
  dispatch({ type: 'SET_CHAT_VISIBILITY', payload })
81
122
  }
@@ -92,6 +133,10 @@ export const AppProvider = ({ availability, children }) => {
92
133
  dispatch({ type: 'SET_THREAD', payload: thread })
93
134
  }
94
135
 
136
+ const setMessages = messages => {
137
+ dispatch({ type: 'SET_MESSAGES', payload: messages })
138
+ }
139
+
95
140
  const setSettings = data => {
96
141
  dispatch({ type: 'SET_SETTINGS', payload: data })
97
142
  }
@@ -113,15 +158,22 @@ export const AppProvider = ({ availability, children }) => {
113
158
  */
114
159
  const store = useMemo(() => ({
115
160
  ...state,
116
- setSdk,
161
+ sdk,
117
162
  setSettings,
118
163
  setCustomerId,
119
164
  setThreadId,
120
165
  setThread,
166
+ setMessages,
121
167
  setUnseenCount,
122
168
  setChatVisibility,
123
169
  setInstigatorId,
124
- setLiveRegionText
170
+ setLiveRegionText,
171
+ onLiveChatRecovered,
172
+ onAssignedAgentChanged,
173
+ onAgentTypingStarted,
174
+ onAgentTypingEnded,
175
+ onMessageCreated,
176
+ onContactStatusChanged
125
177
  }))
126
178
 
127
179
  return (
@@ -1,11 +1,5 @@
1
- import { CUSTOMER_ID_STORAGE_KEY, THREAD_ID_STORAGE_KEY, SETTINGS_STORAGE_KEY, MESSAGES_UNSEEN_COUNT } from '../constants'
2
-
3
- const setSdk = (state, payload) => {
4
- return {
5
- ...state,
6
- sdk: payload
7
- }
8
- }
1
+ import { transformMessages, transformMessage } from '../lib/transform-messages'
2
+ import { CUSTOMER_ID_STORAGE_KEY, THREAD_ID_STORAGE_KEY, SETTINGS_STORAGE_KEY, MESSAGES_UNSEEN_COUNT } from './constants'
9
3
 
10
4
  const setSettings = (state, payload) => {
11
5
  if (payload) {
@@ -46,6 +40,20 @@ const setThreadId = (state, payload) => {
46
40
  }
47
41
  }
48
42
 
43
+ const setChatVisibility = (state, payload) => {
44
+ return {
45
+ ...state,
46
+ isChatOpen: payload
47
+ }
48
+ }
49
+
50
+ const setAvailability = (state, payload) => {
51
+ return {
52
+ ...state,
53
+ availability: payload
54
+ }
55
+ }
56
+
49
57
  const setThread = (state, payload) => {
50
58
  return {
51
59
  ...state,
@@ -53,17 +61,39 @@ const setThread = (state, payload) => {
53
61
  }
54
62
  }
55
63
 
56
- const setChatVisibility = (state, payload) => {
64
+ const setMessages = (state, payload) => {
57
65
  return {
58
66
  ...state,
59
- isChatOpen: payload
67
+ messages: transformMessages(payload).reverse()
60
68
  }
61
69
  }
62
70
 
63
- const setAvailability = (state, payload) => {
71
+ const setMessage = (state, payload) => {
64
72
  return {
65
73
  ...state,
66
- availability: payload
74
+ message: transformMessage(payload),
75
+ messages: [...state.messages, transformMessage(payload)]
76
+ }
77
+ }
78
+
79
+ const setAgent = (state, payload) => {
80
+ return {
81
+ ...state,
82
+ agent: payload
83
+ }
84
+ }
85
+
86
+ const setAgentIsTyping = (state, payload) => {
87
+ return {
88
+ ...state,
89
+ isAgentTyping: payload
90
+ }
91
+ }
92
+
93
+ const setAgentStatus = (state, payload) => {
94
+ return {
95
+ ...state,
96
+ agentStatus: payload
67
97
  }
68
98
  }
69
99
 
@@ -104,13 +134,17 @@ const toggleIsKeyboard = (state, payload) => {
104
134
  }
105
135
 
106
136
  export const actionsMap = {
107
- SET_SDK: setSdk,
108
- SET_THREAD: setThread,
109
137
  SET_CHAT_VISIBILITY: setChatVisibility,
110
138
  SET_AVAILABILITY: setAvailability,
111
139
  SET_SETTINGS: setSettings,
112
140
  SET_CUSTOMER_ID: setCustomerId,
113
141
  SET_THREAD_ID: setThreadId,
142
+ SET_THREAD: setThread,
143
+ SET_MESSAGE: setMessage,
144
+ SET_MESSAGES: setMessages,
145
+ SET_AGENT: setAgent,
146
+ SET_AGENT_TYPING: setAgentIsTyping,
147
+ SET_AGENT_STATUS: setAgentStatus,
114
148
  SET_UNSEEN_COUNT: setUnseenCount,
115
149
  SET_INSTIGATOR_ID: setInstigatorId,
116
150
  SET_LIVE_REGION_TEXT: setLiveRegionText,
@@ -1,13 +1,16 @@
1
1
  import { actionsMap } from './actions-map'
2
2
 
3
3
  export const initialState = {
4
- sdk: null,
5
4
  availability: null,
6
5
  customerId: null,
7
6
  threadId: null,
8
7
  thread: null,
8
+ messages: [],
9
9
  unseenCount: 0,
10
10
  instigatorId: null,
11
+ agent: null,
12
+ agentStatus: null,
13
+ isAgentTyping: false,
11
14
  isChatOpen: false,
12
15
  isMobile: window.matchMedia('(max-width: 640px)').matches,
13
16
  isKeyboard: false,
@@ -0,0 +1,37 @@
1
+ export const useChatSdk = sdk => {
2
+ const connect = async () => sdk.authorize()
3
+
4
+ const fetchCustomerId = async () => {
5
+ const response = await connect()
6
+ return response?.consumerIdentity.idOnExternalPlatform
7
+ }
8
+
9
+ const fetchThread = async threadId => {
10
+ await connect()
11
+ return sdk.getThread(threadId)
12
+ }
13
+
14
+ const fetchMessages = async (thread, threadId) => {
15
+ await connect()
16
+
17
+ const recovered = await thread.recover(threadId)
18
+
19
+ const allMessages = []
20
+ let fetchedMessages = recovered.messages
21
+
22
+ while (fetchedMessages.length) {
23
+ fetchedMessages.map(msg => allMessages.push(msg))
24
+
25
+ try {
26
+ const response = await thread.loadMoreMessages()
27
+ fetchedMessages = response.data.messages
28
+ } catch (err) {
29
+ fetchedMessages = []
30
+ }
31
+ }
32
+
33
+ return allMessages
34
+ }
35
+
36
+ return { connect, fetchCustomerId, fetchThread, fetchMessages }
37
+ }
@@ -1,141 +0,0 @@
1
- import React, { createContext, useEffect, useReducer, useMemo } from 'react'
2
- import { ChatEvent } from '@nice-devone/nice-cxone-chat-web-sdk'
3
-
4
- import { initialState, reducer } from './reducer.js'
5
- import { SETTINGS_STORAGE_KEY } from '../constants.js'
6
- import { useApp } from '../app/useApp.js'
7
-
8
- export const SdkContext = createContext(initialState)
9
-
10
- export const SdkProvider = ({ sdk, playSound, onRecoverError, children }) => {
11
- const [state, dispatch] = useReducer(reducer, initialState)
12
- const { thread, threadId, setThread, setThreadId, setUnseenCount } = useApp()
13
-
14
- /**
15
- * SDK event handlers
16
- */
17
- const onLiveChatRecovered = e => {
18
- dispatch({ type: 'SET_AGENT', payload: e.detail.data.inboxAssignee })
19
- dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.contact.status })
20
- setUnseenCount(e.detail.data.contact.customerStatistics.unseenMessagesCount)
21
- }
22
-
23
- const onAssignedAgentChanged = e => {
24
- dispatch({ type: 'SET_AGENT', payload: e.detail.data.inboxAssignee })
25
- dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.case.status })
26
- }
27
-
28
- const onAgentTypingStarted = () => {
29
- dispatch({ type: 'SET_AGENT_TYPING', payload: true })
30
- }
31
-
32
- const onAgentTypingEnded = () => {
33
- dispatch({ type: 'SET_AGENT_TYPING', payload: false })
34
- dispatch({ type: 'SET_LIVE_REGION_TEXT' })
35
- }
36
-
37
- const onMessageCreated = e => {
38
- dispatch({ type: 'SET_MESSAGE', payload: e.detail.data.message })
39
- dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.case.status })
40
-
41
- setUnseenCount(e.detail.data.case.customerStatistics.unseenMessagesCount)
42
-
43
- const isAudioOn = JSON.parse(window.localStorage.getItem(SETTINGS_STORAGE_KEY)).audio
44
-
45
- if (isAudioOn && e.detail.data.message.direction === 'outbound' && playSound) {
46
- playSound()
47
- }
48
- }
49
-
50
- const onContactStatusChanged = e => {
51
- dispatch({ type: 'SET_AGENT_STATUS', payload: e.detail.data.case.status })
52
- }
53
-
54
- useEffect(() => {
55
- if (sdk) {
56
- sdk.onChatEvent(ChatEvent.LIVECHAT_RECOVERED, onLiveChatRecovered)
57
- sdk.onChatEvent(ChatEvent.MESSAGE_CREATED, onMessageCreated)
58
- sdk.onChatEvent(ChatEvent.AGENT_TYPING_STARTED, onAgentTypingStarted)
59
- sdk.onChatEvent(ChatEvent.AGENT_TYPING_ENDED, onAgentTypingEnded)
60
- sdk.onChatEvent(ChatEvent.ASSIGNED_AGENT_CHANGED, onAssignedAgentChanged)
61
- sdk.onChatEvent(ChatEvent.CONTACT_STATUS_CHANGED, onContactStatusChanged)
62
- }
63
- }, [sdk])
64
-
65
- const fetchMessages = async threadItem => {
66
- const recovered = await threadItem.recover()
67
-
68
- const allMessages = []
69
-
70
- let fetchedMessages = recovered.messages
71
-
72
- while (fetchedMessages.length) {
73
- fetchedMessages.map(msg => allMessages.push(msg))
74
-
75
- try {
76
- const response = await threadItem.loadMoreMessages()
77
- fetchedMessages = response.data.messages
78
- } catch (err) {
79
- fetchedMessages = []
80
- }
81
- }
82
-
83
- return allMessages
84
- }
85
-
86
- /**
87
- * Recovers the thread if there is a threadId but no thread loaded in to state
88
- */
89
- useEffect(() => {
90
- const recover = async () => {
91
- try {
92
- await sdk.authorize()
93
-
94
- const fetchedThread = await sdk.getThread(threadId)
95
- const fetchedMessages = await fetchMessages(fetchedThread)
96
-
97
- setThread(fetchedThread)
98
- setMessages(fetchedMessages)
99
- } catch (err) {
100
- console.log('[Chat Error] fetchThread', err)
101
- setThreadId()
102
- setThread()
103
- onRecoverError()
104
- }
105
- }
106
-
107
- if (sdk && threadId && !thread) {
108
- console.log('recovering chat...')
109
- recover()
110
- }
111
- }, [sdk, thread, threadId])
112
-
113
- /**
114
- * State update functions
115
- */
116
- const setMessages = messages => {
117
- dispatch({ type: 'SET_MESSAGES', payload: messages })
118
- }
119
-
120
- /**
121
- * Application-wide state and state functions
122
- */
123
- const store = useMemo(() => ({
124
- ...state,
125
- sdk,
126
- fetchMessages,
127
- setMessages,
128
- onLiveChatRecovered,
129
- onAssignedAgentChanged,
130
- onAgentTypingStarted,
131
- onAgentTypingEnded,
132
- onMessageCreated,
133
- onContactStatusChanged
134
- }))
135
-
136
- return (
137
- <SdkContext.Provider value={store}>
138
- {children}
139
- </SdkContext.Provider>
140
- )
141
- }
@@ -1,45 +0,0 @@
1
- import { transformMessages, transformMessage } from '../../lib/transform-messages'
2
-
3
- const setMessages = (state, payload) => {
4
- return {
5
- ...state,
6
- messages: transformMessages(payload).reverse()
7
- }
8
- }
9
-
10
- const setMessage = (state, payload) => {
11
- return {
12
- ...state,
13
- message: transformMessage(payload),
14
- messages: [...state.messages, transformMessage(payload)]
15
- }
16
- }
17
-
18
- const setAgent = (state, payload) => {
19
- return {
20
- ...state,
21
- agent: payload
22
- }
23
- }
24
-
25
- const setAgentIsTyping = (state, payload) => {
26
- return {
27
- ...state,
28
- isAgentTyping: payload
29
- }
30
- }
31
-
32
- const setAgentStatus = (state, payload) => {
33
- return {
34
- ...state,
35
- agentStatus: payload
36
- }
37
- }
38
-
39
- export const actionsMap = {
40
- SET_MESSAGE: setMessage,
41
- SET_MESSAGES: setMessages,
42
- SET_AGENT: setAgent,
43
- SET_AGENT_TYPING: setAgentIsTyping,
44
- SET_AGENT_STATUS: setAgentStatus
45
- }
@@ -1,21 +0,0 @@
1
- import { actionsMap } from './actions-map'
2
-
3
- export const initialState = {
4
- messages: [],
5
- agent: null,
6
- agentStatus: null,
7
- isAgentTyping: false
8
- }
9
-
10
- export const reducer = (state, action) => {
11
- const { type, payload } = action
12
-
13
- const fn = actionsMap[type]
14
-
15
- if (fn) {
16
- const actionFunction = fn.bind(this, state, payload)
17
- return actionFunction()
18
- }
19
-
20
- return state
21
- }
@@ -1,5 +0,0 @@
1
- import { useContext } from 'react'
2
-
3
- import { SdkContext } from './SdkProvider.jsx'
4
-
5
- export const useSdk = () => useContext(SdkContext)
File without changes