@defra/flood-webchat 1.0.10 → 1.0.12

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.
Files changed (29) hide show
  1. package/dist/client.js +1 -1
  2. package/dist/server.js +1 -1
  3. package/package.json +12 -12
  4. package/src/client/components/availability/availability.jsx +13 -23
  5. package/src/client/components/chat/chat.jsx +26 -36
  6. package/src/client/components/live-region.jsx +2 -4
  7. package/src/client/components/panel/panel-header.jsx +4 -4
  8. package/src/client/components/panel/panel.jsx +39 -34
  9. package/src/client/components/panel/panel.scss +1 -1
  10. package/src/client/components/screens/end-chat.jsx +3 -6
  11. package/src/client/components/screens/request-chat.jsx +9 -13
  12. package/src/client/components/screens/settings.jsx +1 -1
  13. package/src/client/components/screens/unavailable.jsx +10 -12
  14. package/src/client/components/skip-link.jsx +1 -1
  15. package/src/client/hooks/useFocusedElements.js +6 -8
  16. package/src/client/index.jsx +9 -22
  17. package/src/client/lib/history.js +0 -4
  18. package/src/client/store/{app/AppProvider.jsx → AppProvider.jsx} +86 -35
  19. package/src/client/store/{app/actions-map.js → actions-map.js} +48 -15
  20. package/src/client/store/constants.js +0 -1
  21. package/src/client/store/{app/reducer.js → reducer.js} +4 -1
  22. package/src/client/store/useChatSdk.js +37 -0
  23. package/src/server/lib/client.js +2 -2
  24. package/src/server/lib/utils.js +1 -7
  25. package/src/client/store/sdk/SdkProvider.jsx +0 -141
  26. package/src/client/store/sdk/actions-map.js +0 -45
  27. package/src/client/store/sdk/reducer.js +0 -21
  28. package/src/client/store/sdk/useSdk.js +0 -5
  29. /package/src/client/store/{app/useApp.js → useApp.js} +0 -0
@@ -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,6 +1,6 @@
1
1
  const querystring = require('querystring')
2
2
  const axios = require('axios')
3
- const jwtdecode = require('jwt-decode')
3
+ const { jwtDecode } = require('jwt-decode')
4
4
  const { isWithinHours } = require('./utils.js')
5
5
 
6
6
  const contentType = 'application/x-www-form-urlencoded'
@@ -25,7 +25,7 @@ const authenticate = async ({ authenticationUri, authorisation, accessKey, acces
25
25
  return {
26
26
  token: auth.data.access_token,
27
27
  tokenType: auth.data.token_type,
28
- tenantId: jwtdecode(auth.data.id_token)?.tenantId
28
+ tenantId: jwtDecode(auth.data.id_token)?.tenantId
29
29
  }
30
30
  }
31
31
 
@@ -18,12 +18,6 @@ const isWithinHours = (days, date) => {
18
18
  return now.diff(todaysDateTimeOpen).milliseconds >= 0 && now.diff(todaysDateTimeClose).milliseconds <= 0
19
19
  }
20
20
 
21
- const stripPageTitle = title => {
22
- const prefixPattern = /^\(\d+ new messages?\) - /
23
- return title.replace(prefixPattern, '')
24
- }
25
-
26
21
  module.exports = {
27
- isWithinHours,
28
- stripPageTitle
22
+ isWithinHours
29
23
  }
@@ -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