@seamly/web-ui 20.7.0 → 20.8.0-alpha.1

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 (222) hide show
  1. package/CHANGELOG.md +212 -16
  2. package/build/dist/lib/hooks.js +1 -1
  3. package/build/dist/lib/hooks.min.js +1 -1
  4. package/build/dist/lib/index.debug.js +939 -784
  5. package/build/dist/lib/index.debug.min.js +1 -1
  6. package/build/dist/lib/index.debug.min.js.LICENSE.txt +186 -130
  7. package/build/dist/lib/index.js +24806 -19703
  8. package/build/dist/lib/index.min.js +1 -1
  9. package/build/dist/lib/index.min.js.LICENSE.txt +38 -4
  10. package/build/dist/lib/standalone.js +32726 -26838
  11. package/build/dist/lib/standalone.min.js +1 -1
  12. package/build/dist/lib/standalone.min.js.LICENSE.txt +39 -0
  13. package/build/dist/lib/storage.js +2 -2
  14. package/build/dist/lib/storage.min.js +1 -1
  15. package/build/dist/lib/style-guide.js +8649 -7863
  16. package/build/dist/lib/style-guide.min.js +2 -1
  17. package/build/dist/lib/style-guide.min.js.LICENSE.txt +38 -0
  18. package/build/dist/lib/utils.js +1 -2
  19. package/build/dist/lib/utils.min.js +1 -1
  20. package/package.json +19 -9
  21. package/src/icons/avatar_agent-32.svg +7 -0
  22. package/src/icons/avatar_bot-32.svg +6 -1
  23. package/src/javascripts/api/index.js +1 -1
  24. package/src/javascripts/{config.js → config.ts} +3 -1
  25. package/src/javascripts/config.types.ts +95 -0
  26. package/src/javascripts/domains/app/actions.ts +83 -0
  27. package/src/javascripts/domains/app/app.types.ts +3 -0
  28. package/src/javascripts/domains/app/hooks.js +3 -5
  29. package/src/javascripts/domains/app/selectors.ts +6 -0
  30. package/src/javascripts/domains/app/slice.ts +30 -0
  31. package/src/javascripts/domains/config/actions.ts +45 -0
  32. package/src/javascripts/domains/config/hooks.ts +19 -0
  33. package/src/javascripts/domains/config/selectors.ts +24 -0
  34. package/src/javascripts/domains/config/slice.ts +111 -0
  35. package/src/javascripts/domains/errors/index.js +13 -9
  36. package/src/javascripts/domains/forms/context.ts +14 -0
  37. package/src/javascripts/domains/forms/forms.types.ts +24 -0
  38. package/src/javascripts/domains/forms/{hooks.js → hooks.ts} +23 -26
  39. package/src/javascripts/domains/forms/{provider.js → provider.tsx} +20 -14
  40. package/src/javascripts/domains/forms/{selectors.js → selectors.ts} +7 -8
  41. package/src/javascripts/domains/forms/slice.ts +84 -0
  42. package/src/javascripts/domains/forms/utils.ts +15 -0
  43. package/src/javascripts/domains/i18n/actions.ts +24 -0
  44. package/src/javascripts/domains/i18n/{hooks.js → hooks.ts} +2 -2
  45. package/src/javascripts/domains/i18n/i18n.types.ts +6 -0
  46. package/src/javascripts/domains/i18n/selectors.ts +16 -0
  47. package/src/javascripts/domains/i18n/{reducer.js → slice.ts} +43 -37
  48. package/src/javascripts/domains/interrupt/{hooks.js → hooks.ts} +2 -2
  49. package/src/javascripts/domains/interrupt/{middleware.js → middleware.ts} +11 -8
  50. package/src/javascripts/domains/interrupt/selectors.ts +6 -0
  51. package/src/javascripts/domains/interrupt/slice.ts +40 -0
  52. package/src/javascripts/domains/options/middleware.js +9 -6
  53. package/src/javascripts/domains/redux/redux.types.ts +11 -0
  54. package/src/javascripts/domains/store/index.ts +53 -0
  55. package/src/javascripts/domains/store/slice.ts +639 -0
  56. package/src/javascripts/domains/store/store.types.ts +135 -0
  57. package/src/javascripts/domains/translations/components/chat-status.js +2 -2
  58. package/src/javascripts/domains/translations/components/options-button.js +1 -1
  59. package/src/javascripts/domains/translations/components/options-dialog/form.js +5 -5
  60. package/src/javascripts/domains/translations/components/options-dialog/index.js +2 -2
  61. package/src/javascripts/domains/translations/{hooks.js → hooks.ts} +28 -23
  62. package/src/javascripts/domains/translations/middleware.js +29 -27
  63. package/src/javascripts/domains/translations/selectors.js +4 -9
  64. package/src/javascripts/domains/translations/slice.ts +67 -0
  65. package/src/javascripts/domains/translations/translations.types.ts +12 -0
  66. package/src/javascripts/domains/visibility/{actions.js → actions.ts} +25 -19
  67. package/src/javascripts/domains/visibility/{hooks.js → hooks.ts} +13 -10
  68. package/src/javascripts/domains/visibility/{selectors.js → selectors.ts} +3 -6
  69. package/src/javascripts/domains/visibility/slice.ts +38 -0
  70. package/src/javascripts/domains/visibility/utils.js +0 -9
  71. package/src/javascripts/domains/visibility/visibility.types.ts +6 -0
  72. package/src/javascripts/index.ts +92 -0
  73. package/src/javascripts/lib/engine/index.js +15 -11
  74. package/src/javascripts/lib/external-api/initialize-api.js +1 -1
  75. package/src/javascripts/lib/id.js +5 -8
  76. package/src/javascripts/lib/mutex.js +3 -1
  77. package/src/javascripts/lib/store/providers/cookie-storage.js +1 -1
  78. package/src/javascripts/lib/store/providers/session-storage.js +1 -1
  79. package/src/javascripts/package/hooks.js +2 -2
  80. package/src/javascripts/package/utils.js +0 -1
  81. package/src/javascripts/schema.ts +1455 -0
  82. package/src/javascripts/style-guide/components/app.js +4 -4
  83. package/src/javascripts/style-guide/components/static-core.js +87 -65
  84. package/src/javascripts/style-guide/components/view.js +4 -4
  85. package/src/javascripts/style-guide/state-helpers/index.js +5 -5
  86. package/src/javascripts/style-guide/states.js +6 -4
  87. package/src/javascripts/style-guide.ts +5 -0
  88. package/src/javascripts/ui/components/app-options/index.js +2 -4
  89. package/src/javascripts/ui/components/conversation/component-filter.js +1 -1
  90. package/src/javascripts/ui/components/conversation/conversation.js +5 -5
  91. package/src/javascripts/ui/components/conversation/event/card-message.js +1 -1
  92. package/src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js +1 -1
  93. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +1 -1
  94. package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +1 -1
  95. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +2 -2
  96. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +11 -14
  97. package/src/javascripts/ui/components/conversation/event/cta.js +1 -1
  98. package/src/javascripts/ui/components/conversation/event/divider/variants/default.js +1 -1
  99. package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +5 -2
  100. package/src/javascripts/ui/components/conversation/event/event-participant.js +2 -2
  101. package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +2 -2
  102. package/src/javascripts/ui/components/conversation/event/image-lightbox.js +1 -1
  103. package/src/javascripts/ui/components/conversation/event/image.js +5 -7
  104. package/src/javascripts/ui/components/conversation/event/participant.js +1 -1
  105. package/src/javascripts/ui/components/conversation/event/splash.js +3 -3
  106. package/src/javascripts/ui/components/conversation/event/text.js +1 -1
  107. package/src/javascripts/ui/components/conversation/event/translation.js +2 -2
  108. package/src/javascripts/ui/components/conversation/event/upload.js +2 -2
  109. package/src/javascripts/ui/components/conversation/event/video.js +1 -1
  110. package/src/javascripts/ui/components/conversation/message-container.js +4 -4
  111. package/src/javascripts/ui/components/core/seamly-api-context.js +1 -1
  112. package/src/javascripts/ui/components/core/seamly-core.js +15 -14
  113. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +96 -91
  114. package/src/javascripts/ui/components/core/seamly-file-upload.js +20 -24
  115. package/src/javascripts/ui/components/core/seamly-initializer.js +1 -1
  116. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +5 -4
  117. package/src/javascripts/ui/components/core/seamly-new-notifications.js +2 -2
  118. package/src/javascripts/ui/components/core/seamly-read-state.js +10 -17
  119. package/src/javascripts/ui/components/entry/deprecated-toggle-button.js +3 -3
  120. package/src/javascripts/ui/components/entry/entry-container.js +4 -6
  121. package/src/javascripts/ui/components/entry/text-entry/hooks.js +3 -3
  122. package/src/javascripts/ui/components/entry/text-entry/index.js +3 -2
  123. package/src/javascripts/ui/components/entry/text-entry/text-entry-form.js +6 -10
  124. package/src/javascripts/ui/components/entry/upload/file-upload-form.js +2 -2
  125. package/src/javascripts/ui/components/entry/upload/index.js +10 -9
  126. package/src/javascripts/ui/components/entry/upload-toggle.js +2 -2
  127. package/src/javascripts/ui/components/faq/faq.js +6 -6
  128. package/src/javascripts/ui/components/form-controls/file-input.js +1 -1
  129. package/src/javascripts/ui/components/form-controls/form.js +1 -1
  130. package/src/javascripts/ui/components/form-controls/input.js +1 -1
  131. package/src/javascripts/ui/components/form-controls/select.js +1 -1
  132. package/src/javascripts/ui/components/layout/agent-info.js +4 -4
  133. package/src/javascripts/ui/components/layout/chat-frame.js +3 -3
  134. package/src/javascripts/ui/components/layout/chat.js +11 -12
  135. package/src/javascripts/ui/components/layout/deprecated-app-frame.js +10 -9
  136. package/src/javascripts/ui/components/layout/header.js +1 -1
  137. package/src/javascripts/ui/components/layout/interrupt.js +23 -24
  138. package/src/javascripts/ui/components/layout/pre-chat-messages.js +11 -11
  139. package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
  140. package/src/javascripts/ui/components/options/options-button.js +12 -10
  141. package/src/javascripts/ui/components/options/transcript/index.js +2 -2
  142. package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
  143. package/src/javascripts/ui/components/suggestions/index.js +9 -8
  144. package/src/javascripts/ui/components/view/deprecated-view.js +19 -16
  145. package/src/javascripts/ui/components/view/index.js +12 -12
  146. package/src/javascripts/ui/components/view/inline-view.js +2 -2
  147. package/src/javascripts/ui/components/view/window-view/collapse-button.js +3 -3
  148. package/src/javascripts/ui/components/view/window-view/index.js +13 -13
  149. package/src/javascripts/ui/components/view/window-view/window-open-button.js +13 -13
  150. package/src/javascripts/ui/components/warnings/idle-detach-warning.js +1 -1
  151. package/src/javascripts/ui/components/warnings/resume-conversation-prompt.js +1 -1
  152. package/src/javascripts/ui/components/widgets/lightbox.js +2 -2
  153. package/src/javascripts/ui/components/widgets/upload-progress.js +1 -1
  154. package/src/javascripts/ui/hooks/component-helper-hooks.js +1 -1
  155. package/src/javascripts/ui/hooks/file-upload-hooks.js +4 -6
  156. package/src/javascripts/ui/hooks/focus-helper-hooks.js +14 -12
  157. package/src/javascripts/ui/hooks/live-region-hooks.js +2 -0
  158. package/src/javascripts/ui/hooks/seamly-api-hooks.js +8 -3
  159. package/src/javascripts/ui/hooks/seamly-entry-hooks.js +28 -25
  160. package/src/javascripts/ui/hooks/seamly-hooks.js +25 -25
  161. package/src/javascripts/ui/hooks/seamly-option-hooks.js +17 -19
  162. package/src/javascripts/ui/hooks/seamly-state-hooks.js +14 -13
  163. package/src/javascripts/ui/hooks/use-seamly-chat.js +15 -25
  164. package/src/javascripts/ui/hooks/use-seamly-commands.js +46 -46
  165. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +22 -24
  166. package/src/javascripts/ui/hooks/use-seamly-resume-conversation-prompt.js +8 -9
  167. package/src/javascripts/ui/hooks/use-single-file-upload.js +4 -6
  168. package/src/javascripts/ui/hooks/utility-hooks.js +4 -4
  169. package/src/javascripts/ui/utils/form-utils.js +0 -145
  170. package/src/javascripts/ui/utils/general-utils.js +3 -4
  171. package/src/javascripts/ui/utils/seamly-utils.ts +73 -0
  172. package/webpack/config.common.js +16 -0
  173. package/webpack/config.dev.js +1 -0
  174. package/webpack/config.package.js +26 -5
  175. package/webpack/defaults.js +7 -2
  176. package/webpack/parts/babel-loader-browser-plugins.js +1 -0
  177. package/webpack/parts/dev-server.js +4 -3
  178. package/src/javascripts/domains/app/actions.js +0 -112
  179. package/src/javascripts/domains/app/index.js +0 -7
  180. package/src/javascripts/domains/app/reducer.js +0 -16
  181. package/src/javascripts/domains/app/selectors.js +0 -8
  182. package/src/javascripts/domains/app/utils.js +0 -4
  183. package/src/javascripts/domains/config/actions.js +0 -7
  184. package/src/javascripts/domains/config/hooks.js +0 -23
  185. package/src/javascripts/domains/config/index.js +0 -7
  186. package/src/javascripts/domains/config/reducer.js +0 -79
  187. package/src/javascripts/domains/config/selectors.js +0 -23
  188. package/src/javascripts/domains/config/utils.js +0 -4
  189. package/src/javascripts/domains/forms/actions.js +0 -21
  190. package/src/javascripts/domains/forms/context.js +0 -6
  191. package/src/javascripts/domains/forms/index.js +0 -8
  192. package/src/javascripts/domains/forms/reducer.js +0 -84
  193. package/src/javascripts/domains/forms/utils.js +0 -20
  194. package/src/javascripts/domains/i18n/actions.js +0 -20
  195. package/src/javascripts/domains/i18n/index.js +0 -7
  196. package/src/javascripts/domains/i18n/selectors.js +0 -15
  197. package/src/javascripts/domains/i18n/utils.js +0 -4
  198. package/src/javascripts/domains/interrupt/actions.js +0 -4
  199. package/src/javascripts/domains/interrupt/index.js +0 -9
  200. package/src/javascripts/domains/interrupt/reducer.js +0 -22
  201. package/src/javascripts/domains/interrupt/selectors.js +0 -6
  202. package/src/javascripts/domains/interrupt/utils.js +0 -4
  203. package/src/javascripts/domains/options/index.js +0 -1
  204. package/src/javascripts/domains/redux/context.js +0 -6
  205. package/src/javascripts/domains/redux/create-redux-store.js +0 -21
  206. package/src/javascripts/domains/redux/hooks.js +0 -80
  207. package/src/javascripts/domains/redux/index.js +0 -19
  208. package/src/javascripts/domains/redux/provider.js +0 -5
  209. package/src/javascripts/domains/redux/utils.js +0 -12
  210. package/src/javascripts/domains/store/index.js +0 -46
  211. package/src/javascripts/domains/store/state-reducer.js +0 -56
  212. package/src/javascripts/domains/translations/actions.js +0 -11
  213. package/src/javascripts/domains/translations/index.js +0 -10
  214. package/src/javascripts/domains/translations/reducer.js +0 -69
  215. package/src/javascripts/domains/translations/utils.js +0 -4
  216. package/src/javascripts/domains/visibility/index.js +0 -8
  217. package/src/javascripts/domains/visibility/reducer.js +0 -24
  218. package/src/javascripts/index.js +0 -153
  219. package/src/javascripts/lib/redux-helpers/index.js +0 -99
  220. package/src/javascripts/style-guide.js +0 -5
  221. package/src/javascripts/ui/hooks/use-seamly-dispatch.js +0 -3
  222. package/src/javascripts/ui/utils/seamly-utils.js +0 -832
@@ -1,27 +1,28 @@
1
- import { useErrorBoundary } from 'preact/hooks'
2
- import { StoreProvider } from 'domains/redux'
3
1
  import { catchError } from 'domains/errors'
4
- import SeamlyInstanceFunctionsLoader from './seamly-instance-functions-loader'
5
- import SeamlyReadState from './seamly-read-state'
6
- import SeamlyNewNotifications from './seamly-new-notifications'
7
- import SeamlyLiveRegion from './seamly-live-region'
8
- import SeamlyIdleDetachCounter from './seamly-idle-detach-counter'
2
+ import { useErrorBoundary } from 'preact/hooks'
3
+ import { Provider } from 'react-redux'
4
+ import ComponentFilter from '../conversation/component-filter'
9
5
  import SeamlyActivityMonitor from './seamly-activity-monitor'
10
- import SeamlyInitializer from './seamly-initializer'
6
+ import { SeamlyApiContext, SeamlyEventBusContext } from './seamly-api-context'
11
7
  import SeamlyEventSubscriber from './seamly-event-subscriber'
12
8
  import SeamlyFileUpload from './seamly-file-upload'
13
- import { SeamlyEventBusContext, SeamlyApiContext } from './seamly-api-context'
14
- import ComponentFilter from '../conversation/component-filter'
9
+ import SeamlyIdleDetachCounter from './seamly-idle-detach-counter'
10
+ import SeamlyInitializer from './seamly-initializer'
11
+ import SeamlyInstanceFunctionsLoader from './seamly-instance-functions-loader'
12
+ import SeamlyLiveRegion from './seamly-live-region'
13
+ import SeamlyNewNotifications from './seamly-new-notifications'
14
+ import SeamlyReadState from './seamly-read-state'
15
15
 
16
- const SeamlyCore = ({ store, children, config, eventBus, api }) => {
16
+ const SeamlyCore = ({ store, children, eventBus, api }) => {
17
17
  useErrorBoundary((error) => store.dispatch(catchError(error)))
18
+
18
19
  return (
19
- <StoreProvider store={store}>
20
+ <Provider store={store}>
20
21
  <SeamlyEventBusContext.Provider value={eventBus}>
21
22
  <SeamlyApiContext.Provider value={api}>
22
23
  <SeamlyLiveRegion>
23
24
  <ComponentFilter>
24
- <SeamlyInitializer config={config} />
25
+ <SeamlyInitializer />
25
26
  <SeamlyEventSubscriber eventBus={eventBus} />
26
27
  <SeamlyReadState />
27
28
  <SeamlyNewNotifications />
@@ -34,7 +35,7 @@ const SeamlyCore = ({ store, children, config, eventBus, api }) => {
34
35
  </SeamlyLiveRegion>
35
36
  </SeamlyApiContext.Provider>
36
37
  </SeamlyEventBusContext.Provider>
37
- </StoreProvider>
38
+ </Provider>
38
39
  )
39
40
  }
40
41
 
@@ -1,44 +1,39 @@
1
+ import SeamlyGeneralError from 'api/errors/seamly-general-error'
2
+ import SeamlyOfflineError from 'api/errors/seamly-offline-error'
3
+ import SeamlySessionExpiredError from 'api/errors/seamly-session-expired-error'
4
+ import { setHasResponded } from 'domains/app/slice'
5
+ import { clearInterrupt, setInterrupt } from 'domains/interrupt/slice'
6
+ import {
7
+ ackEvent,
8
+ addEvent,
9
+ clearEvents,
10
+ initResumeConversationPrompt,
11
+ setActiveService,
12
+ setFeatureEnabledState,
13
+ setHeaderSubTitle,
14
+ setHistory,
15
+ setIsLoading,
16
+ setParticipant,
17
+ setServiceDataItem,
18
+ setServiceEntryMetadata,
19
+ } from 'domains/store/slice'
1
20
  import { useEffect, useRef } from 'preact/hooks'
2
- import { seamlyActions, featureKeys } from 'ui/utils/seamly-utils'
3
- import { useI18n } from 'domains/i18n'
21
+ import { useDispatch } from 'react-redux'
4
22
  import {
5
- useSeamlyOptions,
6
23
  useEvents,
7
24
  useSeamlyApiContext,
8
- useSeamlyDispatchContext,
9
- useSeamlyIdleDetachCountdown,
10
25
  useSeamlyCommands,
26
+ useSeamlyIdleDetachCountdown,
11
27
  } from 'ui/hooks/seamly-hooks'
12
- import SeamlyGeneralError from 'api/errors/seamly-general-error'
13
- import SeamlySessionExpiredError from 'api/errors/seamly-session-expired-error'
14
- import SeamlyOfflineError from 'api/errors/seamly-offline-error'
15
- import * as InterruptActions from 'domains/interrupt/actions'
16
- import * as AppActions from 'domains/app/actions'
17
-
18
- const {
19
- ADD_EVENT,
20
- ACK_EVENT,
21
- SET_IS_LOADING,
22
- SET_PARTICIPANT,
23
- SET_HEADER_SUB_TITLE,
24
- SET_ACTIVE_SERVICE,
25
- INIT_RESUME_CONVERSATION_PROMPT,
26
- CLEAR_EVENTS,
27
- SET_SERVICE_DATA_ITEM,
28
- SET_FEATURE_ENABLED_STATE,
29
- SET_SERVICE_ENTRY_METADATA,
30
- SET_HISTORY,
31
- } = seamlyActions
28
+ import { featureKeys } from 'ui/utils/seamly-utils'
32
29
 
33
30
  const EMITTABLE_MESSAGE_TYPES = ['text', 'choice_prompt', 'image', 'video']
34
31
 
35
32
  const SeamlyEventSubscriber = ({ eventBus }) => {
36
- const { t } = useI18n()
37
33
  const api = useSeamlyApiContext()
38
- const dispatch = useSeamlyDispatchContext()
34
+ const dispatch = useDispatch()
39
35
  const events = useEvents()
40
36
  const prevEmittedEventId = useRef(null)
41
- const { setUserSelectedOption } = useSeamlyOptions()
42
37
  const { initCountdown, endCountdown } = useSeamlyIdleDetachCountdown()
43
38
  const { emitEvent } = useSeamlyCommands()
44
39
 
@@ -54,33 +49,28 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
54
49
  const { fromClient, participant } = payload
55
50
 
56
51
  if (!fromClient && participant.name) {
57
- dispatch({
58
- type: SET_HEADER_SUB_TITLE,
59
- title: participant.name,
60
- })
52
+ dispatch(setHeaderSubTitle(participant.name))
61
53
  }
62
54
 
63
- dispatch({
64
- type: SET_PARTICIPANT,
65
- participant,
66
- fromClient,
67
- })
55
+ dispatch(
56
+ setParticipant({
57
+ participant,
58
+ fromClient,
59
+ }),
60
+ )
68
61
 
69
62
  if (participant.introduction) {
70
- dispatch({ type: ADD_EVENT, event })
63
+ dispatch(addEvent(event))
71
64
  }
72
65
  }
73
66
 
74
- api.stream().subscribe({
67
+ const subscription = api.stream().subscribe({
75
68
  next: (event) => {
76
69
  const { type, payload } = event
77
70
  switch (type) {
78
71
  case 'ui':
79
72
  if (payload.state && payload.state.hasOwnProperty('loading')) {
80
- dispatch({
81
- type: SET_IS_LOADING,
82
- isLoading: payload.state.loading,
83
- })
73
+ dispatch(setIsLoading(payload.state.loading))
84
74
  }
85
75
  switch (payload.type) {
86
76
  case 'idle_detach_countdown':
@@ -90,10 +80,10 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
90
80
  endCountdown(undefined, true)
91
81
  break
92
82
  case 'resume_conversation_prompt':
93
- dispatch({ type: INIT_RESUME_CONVERSATION_PROMPT })
83
+ dispatch(initResumeConversationPrompt())
94
84
  break
95
85
  case 'user_first_response':
96
- dispatch(AppActions.setHasResponded(true))
86
+ dispatch(setHasResponded(true))
97
87
  eventBus.emit('system.userFirstResponse', payload.body)
98
88
  break
99
89
  }
@@ -112,13 +102,10 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
112
102
  case 'carousel':
113
103
  case 'card':
114
104
  if (payload.service && payload.service.serviceSessionId) {
115
- dispatch({
116
- type: SET_ACTIVE_SERVICE,
117
- activeServiceSessionId: payload.service.serviceSessionId,
118
- })
105
+ dispatch(setActiveService(payload.service.serviceSessionId))
119
106
  }
120
107
 
121
- dispatch({ type: ADD_EVENT, event })
108
+ dispatch(addEvent(event))
122
109
  break
123
110
  }
124
111
  break
@@ -127,35 +114,26 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
127
114
  break
128
115
  case 'service_data':
129
116
  if (payload.persist) {
130
- dispatch({
131
- type: SET_SERVICE_DATA_ITEM,
132
- payload,
133
- })
117
+ dispatch(setServiceDataItem(payload))
134
118
  }
135
119
  break
136
120
  case 'ack':
137
- dispatch({ type: ACK_EVENT, event })
121
+ dispatch(ackEvent(event.payload))
138
122
  break
139
123
  case 'system':
140
124
  if (payload.type === 'service_changed') {
141
125
  const { serviceSettings, ...eventPayload } = payload
142
126
  const { uploads, entry } = serviceSettings
143
127
 
144
- dispatch({
145
- type: SET_FEATURE_ENABLED_STATE,
146
- key: featureKeys.uploads,
147
- enabled: !!(uploads && uploads.enabled),
148
- })
149
-
150
- dispatch({
151
- type: SET_SERVICE_ENTRY_METADATA,
152
- entryMeta: entry,
153
- })
128
+ dispatch(
129
+ setFeatureEnabledState({
130
+ key: featureKeys.uploads,
131
+ enabled: !!(uploads && uploads.enabled),
132
+ }),
133
+ )
154
134
 
155
- dispatch({
156
- type: SET_ACTIVE_SERVICE,
157
- activeServiceSessionId: payload.serviceSessionId,
158
- })
135
+ dispatch(setServiceEntryMetadata(entry))
136
+ dispatch(setActiveService(payload.serviceSessionId))
159
137
 
160
138
  emitEvent('system.serviceChanged', eventPayload)
161
139
  }
@@ -166,27 +144,54 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
166
144
  payload.type === 'text' ||
167
145
  payload.type === 'translation'
168
146
  ) {
169
- dispatch({ type: ADD_EVENT, event })
147
+ dispatch(addEvent(event))
170
148
  }
171
149
  break
172
150
  case 'error':
173
151
  switch (payload.type) {
174
152
  case 'find_conversation_erred':
153
+ const seamlySessionExpiredError =
154
+ new SeamlySessionExpiredError(event)
175
155
  dispatch(
176
- InterruptActions.set(new SeamlySessionExpiredError(event)),
156
+ setInterrupt({
157
+ name: seamlySessionExpiredError.name,
158
+ action: seamlySessionExpiredError.action,
159
+ message: seamlySessionExpiredError.message,
160
+ originalEvent: seamlySessionExpiredError.originalEvent,
161
+ originalError: seamlySessionExpiredError.originalError,
162
+ }),
177
163
  )
178
164
  break
179
165
  case 'seamly_offline':
180
- dispatch(InterruptActions.set(new SeamlyOfflineError(event)))
181
- dispatch({ type: CLEAR_EVENTS })
166
+ const seamlyOfflineError = new SeamlyOfflineError(event)
167
+ dispatch(
168
+ setInterrupt({
169
+ name: seamlyOfflineError.name,
170
+ message: seamlyOfflineError.message,
171
+ langKey: seamlyOfflineError.langKey,
172
+ originalEvent: seamlyOfflineError.originalEvent,
173
+ originalError: seamlyOfflineError.originalError,
174
+ }),
175
+ )
176
+ dispatch(clearEvents())
182
177
  break
183
178
  default:
184
- dispatch(InterruptActions.set(new SeamlyGeneralError(event)))
179
+ const seamlyGeneralError = new SeamlyGeneralError(event)
180
+ dispatch(
181
+ setInterrupt({
182
+ name: seamlyGeneralError.name,
183
+ message: seamlyGeneralError.message,
184
+ langKey: seamlyGeneralError.langKey,
185
+ originalEvent: seamlyGeneralError.originalEvent,
186
+ originalError: seamlyGeneralError.originalError,
187
+ action: seamlyGeneralError.action,
188
+ }),
189
+ )
185
190
  break
186
191
  }
187
192
  break
188
193
  case 'socket_opened':
189
- dispatch(InterruptActions.clear())
194
+ dispatch(clearInterrupt())
190
195
  break
191
196
  }
192
197
  },
@@ -210,17 +215,12 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
210
215
  prevEmittedEventId.current = payload.id
211
216
  },
212
217
  })
218
+ return () => {
219
+ subscription.unsubscribe()
220
+ }
213
221
  }
214
- }, [
215
- dispatch,
216
- api,
217
- eventBus,
218
- t,
219
- setUserSelectedOption,
220
- initCountdown,
221
- endCountdown,
222
- emitEvent,
223
- ])
222
+ return () => undefined
223
+ }, [dispatch, api, eventBus, initCountdown, endCountdown, emitEvent])
224
224
 
225
225
  useEffect(() => {
226
226
  const subscribe = () => {
@@ -245,13 +245,18 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
245
245
  return
246
246
  }
247
247
 
248
- dispatch({
249
- type: SET_HISTORY,
250
- history,
251
- })
248
+ dispatch(setHistory(history))
252
249
  })
253
250
  .catch((error) => {
254
- dispatch(InterruptActions.set(error))
251
+ dispatch(
252
+ setInterrupt({
253
+ name: error.name,
254
+ message: error.message,
255
+ langKey: error.langKey,
256
+ originalEvent: error.originalEvent,
257
+ originalError: error.originalError,
258
+ }),
259
+ )
255
260
  })
256
261
  },
257
262
  })
@@ -264,7 +269,7 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
264
269
  }
265
270
  }
266
271
 
267
- return () => {}
272
+ return () => undefined
268
273
  }, [api, events, dispatch])
269
274
 
270
275
  return null
@@ -1,23 +1,18 @@
1
- import { useI18n } from 'domains/i18n'
2
- import { randomId } from 'lib/id'
3
- import { seamlyActions } from 'ui/utils/seamly-utils'
1
+ import { useI18n } from 'domains/i18n/hooks'
4
2
  import {
5
- useSeamlyCommands,
6
- useSeamlyApiContext,
7
- useSeamlyDispatchContext,
8
- } from 'ui/hooks/seamly-hooks'
3
+ registerUpload,
4
+ setUploadComplete,
5
+ setUploadError,
6
+ setUploadProgress,
7
+ } from 'domains/store/slice'
8
+ import { randomId } from 'lib/id'
9
+ import { useDispatch } from 'react-redux'
10
+ import { useSeamlyApiContext, useSeamlyCommands } from 'ui/hooks/seamly-hooks'
9
11
  import SeamlyFileUploadContext from './seamly-file-upload-context'
10
12
 
11
- const {
12
- REGISTER_UPLOAD,
13
- SET_UPLOAD_PROGRESS,
14
- SET_UPLOAD_ERROR,
15
- SET_UPLOAD_COMPLETE,
16
- } = seamlyActions
17
-
18
13
  const SeamlyFileUpload = ({ children }) => {
19
14
  const { t } = useI18n()
20
- const dispatch = useSeamlyDispatchContext()
15
+ const dispatch = useDispatch()
21
16
  const api = useSeamlyApiContext()
22
17
  const { addUploadBubble } = useSeamlyCommands()
23
18
 
@@ -27,7 +22,7 @@ const SeamlyFileUpload = ({ children }) => {
27
22
  const uploadHandle = api.uploadFile(
28
23
  file,
29
24
  (p) => {
30
- dispatch({ type: SET_UPLOAD_PROGRESS, fileId, progress: Math.ceil(p) })
25
+ dispatch(setUploadProgress({ fileId, progress: Math.ceil(p) }))
31
26
  },
32
27
  (result) => {
33
28
  const {
@@ -36,7 +31,7 @@ const SeamlyFileUpload = ({ children }) => {
36
31
  occurredAt,
37
32
  body: { contentType, filename, filesize, url },
38
33
  } = result.body
39
- dispatch({ type: SET_UPLOAD_COMPLETE, fileId })
34
+ dispatch(setUploadComplete(fileId))
40
35
  addUploadBubble(
41
36
  id,
42
37
  transactionId,
@@ -68,16 +63,17 @@ const SeamlyFileUpload = ({ children }) => {
68
63
  errorText = t('fileUpload.errors.general')
69
64
  }
70
65
 
71
- dispatch({ type: SET_UPLOAD_ERROR, fileId, errorText })
66
+ dispatch(setUploadError({ fileId, errorText }))
72
67
  },
73
68
  )
74
69
 
75
- dispatch({
76
- type: REGISTER_UPLOAD,
77
- fileId,
78
- fileName: file.name,
79
- uploadHandle,
80
- })
70
+ dispatch(
71
+ registerUpload({
72
+ fileId,
73
+ fileName: file.name,
74
+ uploadHandle,
75
+ }),
76
+ )
81
77
  }
82
78
 
83
79
  return (
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useRef } from 'preact/hooks'
2
2
  import { useSeamlyOptions } from 'ui/hooks/seamly-hooks'
3
- import { useConfig } from 'domains/config'
3
+ import { useConfig } from 'domains/config/hooks'
4
4
 
5
5
  const SeamlyInitializer = () => {
6
6
  const { initUserSelectedOptions } = useSeamlyOptions()
@@ -8,10 +8,11 @@ import {
8
8
  useSeamlyApiContext,
9
9
  } from 'ui/hooks/seamly-hooks'
10
10
  import { actionTypes } from 'ui/utils/seamly-utils'
11
- import { useTranslations } from 'domains/translations'
12
- import { useInterrupt } from 'domains/interrupt'
13
- import { useConfig } from 'domains/config'
14
- import { visibilityStates, useVisibility } from 'domains/visibility'
11
+ import { useTranslations } from 'domains/translations/hooks'
12
+ import { useInterrupt } from 'domains/interrupt/hooks'
13
+ import { useConfig } from 'domains/config/hooks'
14
+ import { useVisibility } from 'domains/visibility/hooks'
15
+ import { visibilityStates } from 'domains/visibility/constants'
15
16
  import { SeamlyEventBusContext } from './seamly-api-context'
16
17
 
17
18
  function useSeamlyInstanceFunction(functionName, fn, deps = []) {
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useRef, useMemo } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import {
4
4
  useEvents,
5
5
  useLiveRegion,
@@ -7,7 +7,7 @@ import {
7
7
  } from 'ui/hooks/seamly-hooks'
8
8
  import { newMessageScreenReaderWait } from 'config'
9
9
  import { debounce } from 'ui/utils/general-utils'
10
- import { useVisibility } from 'domains/visibility'
10
+ import { useVisibility } from 'domains/visibility/hooks'
11
11
 
12
12
  const SeamlyNewNotifications = () => {
13
13
  const { t } = useI18n()
@@ -1,29 +1,22 @@
1
- import { useEffect, useRef, useMemo } from 'preact/hooks'
2
-
1
+ import { useEffect, useMemo, useRef } from 'preact/hooks'
2
+ import { unreadScreenReaderWait } from 'config'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
+ import { isUnreadMessage, setEventsRead } from 'domains/store/slice'
5
+ import { useVisibility } from 'domains/visibility/hooks'
3
6
  import {
4
7
  useEvents,
5
- useSeamlyCommands,
6
8
  useLiveRegion,
9
+ useSeamlyCommands,
7
10
  useSeamlyUnreadCount,
8
- useSeamlyDispatchContext,
9
11
  } from 'ui/hooks/seamly-hooks'
10
- import { useI18n } from 'domains/i18n'
11
- import {
12
- seamlyActions,
13
- readStates,
14
- actionTypes,
15
- isUnreadMessage,
16
- } from 'ui/utils/seamly-utils'
17
12
  import { debounce } from 'ui/utils/general-utils'
18
- import { unreadScreenReaderWait } from 'config'
19
- import { useVisibility } from 'domains/visibility'
20
-
21
- const { SET_EVENTS_READ } = seamlyActions
13
+ import { actionTypes, readStates } from 'ui/utils/seamly-utils'
14
+ import { useDispatch } from 'react-redux'
22
15
 
23
16
  const SeamlyReadState = () => {
24
17
  const { t } = useI18n()
25
18
  const events = useEvents()
26
- const dispatch = useSeamlyDispatchContext()
19
+ const dispatch = useDispatch()
27
20
  const { isOpen, isVisible } = useVisibility()
28
21
  const { sendAction } = useSeamlyCommands()
29
22
  const unreadCount = useSeamlyUnreadCount()
@@ -51,7 +44,7 @@ const SeamlyReadState = () => {
51
44
  .map((event) => event.payload.id)
52
45
 
53
46
  if (unread.length > 0) {
54
- dispatch({ type: SET_EVENTS_READ, ids: unread })
47
+ dispatch(setEventsRead(unread))
55
48
  sendAction({ type: actionTypes.read, events: unread })
56
49
  }
57
50
  }, [events, dispatch, isOpen, sendAction])
@@ -1,5 +1,5 @@
1
1
  import { useLayoutEffect, useRef } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import { className } from 'lib/css'
4
4
  import {
5
5
  useSkiplinkTargetFocusing,
@@ -9,8 +9,8 @@ import {
9
9
  useGeneratedId,
10
10
  useSeamlyStateContext,
11
11
  } from 'ui/hooks/seamly-hooks'
12
- import { useInterrupt } from 'domains/interrupt'
13
- import { useVisibility } from 'domains/visibility'
12
+ import { useInterrupt } from 'domains/interrupt/hooks'
13
+ import { useVisibility } from 'domains/visibility/hooks'
14
14
 
15
15
  // Deprecated Toggle Button, should be removed once it is removed from clients
16
16
  const DeprecatedToggleButton = ({ onOpenChat }) => {
@@ -4,15 +4,15 @@ import {
4
4
  useSeamlyIdleDetachCountdown,
5
5
  useSeamlyResumeConversationPrompt,
6
6
  useSkiplinkTargetFocusing,
7
- useSeamlyEntry,
8
7
  useFileUploadMeta,
9
8
  } from 'ui/hooks/seamly-hooks'
10
9
  import { entryTypes } from 'ui/utils/seamly-utils'
11
10
  import { runIfElementContainsOrHasFocus } from 'ui/utils/general-utils'
12
11
  import IdleDetachWarning from 'ui/components/warnings/idle-detach-warning'
13
12
  import ResumeConversationPrompt from 'ui/components/warnings/resume-conversation-prompt'
14
- import { useConfig } from 'domains/config'
15
- import { useVisibility } from 'domains/visibility'
13
+ import { useConfig } from 'domains/config/hooks'
14
+ import { useVisibility } from 'domains/visibility/hooks'
15
+ import { useSeamlyEntry } from 'ui/hooks/seamly-entry-hooks'
16
16
  import TextEntry from './text-entry'
17
17
  import UploadToggle from './upload-toggle'
18
18
  import Upload from './upload'
@@ -38,9 +38,7 @@ const EntryContainer = () => {
38
38
  const { accountAllowsUploads } = useFileUploadMeta()
39
39
 
40
40
  const focusFn = useCallback(() => {
41
- runIfElementContainsOrHasFocus(entryContainer.current, () => {
42
- focusSkiplinkTarget()
43
- })
41
+ runIfElementContainsOrHasFocus(entryContainer.current, focusSkiplinkTarget)
44
42
  }, [focusSkiplinkTarget])
45
43
 
46
44
  useEffect(() => {
@@ -1,10 +1,10 @@
1
+ import { maxCharacterSrDebounceDelay, maxCharacterWarningLimit } from 'config'
2
+ import { useFormControl } from 'domains/forms/hooks'
3
+ import { useI18n } from 'domains/i18n/hooks'
1
4
  import { useEffect, useMemo } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
3
5
  import { useLiveRegion } from 'ui/hooks/live-region-hooks'
4
6
  import { useEntryTextLimit } from 'ui/hooks/seamly-state-hooks'
5
7
  import { debounce } from 'ui/utils/general-utils'
6
- import { maxCharacterSrDebounceDelay, maxCharacterWarningLimit } from 'config'
7
- import { useFormControl } from 'domains/forms'
8
8
 
9
9
  export function useCharacterLimit(controlName) {
10
10
  const { t } = useI18n()
@@ -1,12 +1,13 @@
1
+ import FormProvider from 'domains/forms/provider'
2
+ import { visibilityStates } from 'domains/visibility/constants'
3
+ import { useVisibility } from 'domains/visibility/hooks'
1
4
  import { useCallback } from 'preact/hooks'
2
5
  import {
3
6
  useSeamlyCommands,
4
7
  useSkiplink,
5
8
  useSkiplinkTargetFocusing,
6
9
  } from 'ui/hooks/seamly-hooks'
7
- import { FormProvider } from 'domains/forms'
8
10
  import TextEntryForm from './text-entry-form'
9
- import { useVisibility, visibilityStates } from '../../../../domains/visibility'
10
11
 
11
12
  const controlName = 'userText'
12
13
 
@@ -1,16 +1,12 @@
1
- import { useCallback, useLayoutEffect, useMemo } from 'preact/hooks'
1
+ import { useFormControl } from 'domains/forms/hooks'
2
+ import { useI18n } from 'domains/i18n/hooks'
2
3
  import { className } from 'lib/css'
3
- import {
4
- useLiveRegion,
5
- useSeamlyCommands,
6
- useSeamlyEntry,
7
- useSeamlyTyping,
8
- } from 'ui/hooks/seamly-hooks'
9
- import Icon from 'ui/components/layout/icon'
10
- import { useFormControl } from 'domains/forms'
4
+ import { useCallback, useLayoutEffect, useMemo } from 'preact/hooks'
11
5
  import Form from 'ui/components/form-controls/form'
12
6
  import Input from 'ui/components/form-controls/input'
13
- import { useI18n } from 'domains/i18n'
7
+ import Icon from 'ui/components/layout/icon'
8
+ import { useLiveRegion, useSeamlyCommands } from 'ui/hooks/seamly-hooks'
9
+ import { useSeamlyEntry, useSeamlyTyping } from 'ui/hooks/seamly-entry-hooks'
14
10
  import { useCharacterLimit } from './hooks'
15
11
 
16
12
  export default function TextEntryForm({ controlName, skipLinkId }) {
@@ -1,8 +1,8 @@
1
1
  import { className } from 'lib/css'
2
2
  import Form from 'ui/components/form-controls/form'
3
3
  import FileInput from 'ui/components/form-controls/file-input'
4
- import { useI18n } from 'domains/i18n'
5
- import { useFormControl } from 'domains/forms'
4
+ import { useI18n } from 'domains/i18n/hooks'
5
+ import { useFormControl } from 'domains/forms/hooks'
6
6
 
7
7
  export default function FileInputForm({
8
8
  skiplinkId,