@seamly/web-ui 20.7.0 → 20.8.0-beta.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 (226) hide show
  1. package/build/dist/lib/hooks.js +1 -1
  2. package/build/dist/lib/hooks.min.js +1 -1
  3. package/build/dist/lib/index.debug.js +945 -790
  4. package/build/dist/lib/index.debug.min.js +1 -1
  5. package/build/dist/lib/index.debug.min.js.LICENSE.txt +187 -131
  6. package/build/dist/lib/index.js +24800 -19606
  7. package/build/dist/lib/index.min.js +1 -1
  8. package/build/dist/lib/index.min.js.LICENSE.txt +38 -4
  9. package/build/dist/lib/standalone.js +32920 -26742
  10. package/build/dist/lib/standalone.min.js +1 -1
  11. package/build/dist/lib/standalone.min.js.LICENSE.txt +39 -0
  12. package/build/dist/lib/storage.js +2 -2
  13. package/build/dist/lib/storage.min.js +1 -1
  14. package/build/dist/lib/style-guide.js +8780 -7907
  15. package/build/dist/lib/style-guide.min.js +2 -1
  16. package/build/dist/lib/style-guide.min.js.LICENSE.txt +38 -0
  17. package/build/dist/lib/styles.css +1 -1
  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 +96 -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 +113 -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} +40 -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 +642 -0
  56. package/src/javascripts/domains/store/store.types.ts +146 -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.ts +114 -0
  62. package/src/javascripts/domains/translations/middleware.js +29 -27
  63. package/src/javascripts/domains/translations/selectors.ts +12 -0
  64. package/src/javascripts/domains/translations/slice.ts +120 -0
  65. package/src/javascripts/domains/translations/translations.types.ts +19 -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 +1448 -0
  82. package/src/javascripts/style-guide/components/app.js +6 -6
  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 +67 -7
  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 +11 -7
  91. package/src/javascripts/ui/components/conversation/event/card-message.js +2 -2
  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 +2 -2
  95. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +3 -3
  96. package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +19 -15
  97. package/src/javascripts/ui/components/conversation/event/cta.js +2 -2
  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 +44 -5
  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 +6 -8
  104. package/src/javascripts/ui/components/conversation/event/participant.js +2 -2
  105. package/src/javascripts/ui/components/conversation/event/splash.js +4 -4
  106. package/src/javascripts/ui/components/conversation/event/text.js +2 -2
  107. package/src/javascripts/ui/components/conversation/event/translation.js +3 -3
  108. package/src/javascripts/ui/components/conversation/event/upload.js +3 -3
  109. package/src/javascripts/ui/components/conversation/event/video.js +2 -2
  110. package/src/javascripts/ui/components/conversation/message-container.js +4 -26
  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 +98 -92
  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 +9 -7
  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 +14 -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 +14 -10
  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 +20 -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/src/stylesheets/5-components/_message-carousel.scss +10 -8
  173. package/webpack/config.common.js +16 -0
  174. package/webpack/config.dev.js +1 -0
  175. package/webpack/config.package.js +26 -5
  176. package/webpack/defaults.js +7 -2
  177. package/webpack/parts/babel-loader-browser-plugins.js +1 -0
  178. package/webpack/parts/dev-server.js +4 -3
  179. package/CHANGELOG.md +0 -791
  180. package/src/javascripts/domains/app/actions.js +0 -112
  181. package/src/javascripts/domains/app/index.js +0 -7
  182. package/src/javascripts/domains/app/reducer.js +0 -16
  183. package/src/javascripts/domains/app/selectors.js +0 -8
  184. package/src/javascripts/domains/app/utils.js +0 -4
  185. package/src/javascripts/domains/config/actions.js +0 -7
  186. package/src/javascripts/domains/config/hooks.js +0 -23
  187. package/src/javascripts/domains/config/index.js +0 -7
  188. package/src/javascripts/domains/config/reducer.js +0 -79
  189. package/src/javascripts/domains/config/selectors.js +0 -23
  190. package/src/javascripts/domains/config/utils.js +0 -4
  191. package/src/javascripts/domains/forms/actions.js +0 -21
  192. package/src/javascripts/domains/forms/context.js +0 -6
  193. package/src/javascripts/domains/forms/index.js +0 -8
  194. package/src/javascripts/domains/forms/reducer.js +0 -84
  195. package/src/javascripts/domains/forms/utils.js +0 -20
  196. package/src/javascripts/domains/i18n/actions.js +0 -20
  197. package/src/javascripts/domains/i18n/index.js +0 -7
  198. package/src/javascripts/domains/i18n/selectors.js +0 -15
  199. package/src/javascripts/domains/i18n/utils.js +0 -4
  200. package/src/javascripts/domains/interrupt/actions.js +0 -4
  201. package/src/javascripts/domains/interrupt/index.js +0 -9
  202. package/src/javascripts/domains/interrupt/reducer.js +0 -22
  203. package/src/javascripts/domains/interrupt/selectors.js +0 -6
  204. package/src/javascripts/domains/interrupt/utils.js +0 -4
  205. package/src/javascripts/domains/options/index.js +0 -1
  206. package/src/javascripts/domains/redux/context.js +0 -6
  207. package/src/javascripts/domains/redux/create-redux-store.js +0 -21
  208. package/src/javascripts/domains/redux/hooks.js +0 -80
  209. package/src/javascripts/domains/redux/index.js +0 -19
  210. package/src/javascripts/domains/redux/provider.js +0 -5
  211. package/src/javascripts/domains/redux/utils.js +0 -12
  212. package/src/javascripts/domains/store/index.js +0 -46
  213. package/src/javascripts/domains/store/state-reducer.js +0 -56
  214. package/src/javascripts/domains/translations/actions.js +0 -11
  215. package/src/javascripts/domains/translations/hooks.js +0 -103
  216. package/src/javascripts/domains/translations/index.js +0 -10
  217. package/src/javascripts/domains/translations/reducer.js +0 -69
  218. package/src/javascripts/domains/translations/selectors.js +0 -16
  219. package/src/javascripts/domains/translations/utils.js +0 -4
  220. package/src/javascripts/domains/visibility/index.js +0 -8
  221. package/src/javascripts/domains/visibility/reducer.js +0 -24
  222. package/src/javascripts/index.js +0 -153
  223. package/src/javascripts/lib/redux-helpers/index.js +0 -99
  224. package/src/javascripts/style-guide.js +0 -5
  225. package/src/javascripts/ui/hooks/use-seamly-dispatch.js +0 -3
  226. package/src/javascripts/ui/utils/seamly-utils.js +0 -832
@@ -1,18 +1,44 @@
1
- import { useI18n } from 'domains/i18n'
1
+ import { useI18n } from 'domains/i18n/hooks'
2
2
  import EventDivider from 'ui/components/conversation/event-divider'
3
3
  import { className } from 'lib/css'
4
- import { useTranslations, useLocaleNativeName } from 'domains/translations'
4
+ import {
5
+ useTranslations,
6
+ useLocaleNativeName,
7
+ } from 'domains/translations/hooks'
8
+ import { useDispatch, useSelector } from 'react-redux'
9
+ import {
10
+ enableEventsTranslation,
11
+ disableEventsTranslation,
12
+ } from 'domains/translations/slice'
13
+ import { useCallback } from 'preact/hooks'
14
+ import { useEvents } from 'ui/hooks/seamly-hooks'
5
15
 
6
16
  const NewTranslationDivider = ({ event }) => {
7
17
  const { t } = useI18n()
8
- const { translationEnabled, translationLocale, text } = event.payload.body
18
+ const events = useEvents()
19
+ const {
20
+ body: { translationEnabled, translationLocale, text },
21
+ id,
22
+ } = event.payload
9
23
  const { enableTranslations } = useTranslations()
10
24
  const localeNativeName = useLocaleNativeName(translationLocale)
25
+ const translatedEventGroups = useSelector(
26
+ (state) => state.translations.translatedEventGroups,
27
+ )
28
+
29
+ const dispatch = useDispatch()
30
+ const toggleTranslations = useCallback(() => {
31
+ if (!translatedEventGroups[id]) {
32
+ dispatch(disableEventsTranslation({ events, id }))
33
+ return
34
+ }
35
+
36
+ dispatch(enableEventsTranslation({ events, id }))
37
+ }, [dispatch, events, id, translatedEventGroups])
11
38
 
12
39
  const handleRestartButtonclick = () => {
13
40
  enableTranslations(translationLocale)
14
41
  }
15
-
16
42
  return (
17
43
  <EventDivider iconName="newTranslation" dividerType="newtranslation">
18
44
  <p className={className('divider__title')}>
@@ -24,10 +50,23 @@ const NewTranslationDivider = ({ event }) => {
24
50
  )}
25
51
  </p>
26
52
  {translationEnabled ? (
27
- <p>{text}</p>
53
+ <>
54
+ <p>{text}</p>
55
+ <button
56
+ className={className('button', 'button--secondary')}
57
+ onClick={toggleTranslations}
58
+ >
59
+ {t(
60
+ !translatedEventGroups[id]
61
+ ? 'translations.toggle.hideTranslationsButtonText'
62
+ : 'translations.toggle.showTranslationsButtonText',
63
+ )}
64
+ </button>
65
+ </>
28
66
  ) : (
29
67
  <button
30
68
  className={className('button', 'button--secondary')}
69
+ data-testid="restartTranslationButton"
31
70
  onClick={handleRestartButtonclick}
32
71
  >
33
72
  {t('translations.divider.restartButtonText')}
@@ -1,7 +1,7 @@
1
1
  import { useSeamlyParticipant } from 'ui/hooks/seamly-hooks'
2
2
  import { className } from 'lib/css'
3
- import { useConfig } from 'domains/config'
4
- import { useI18n } from 'domains/i18n'
3
+ import { useConfig } from 'domains/config/hooks'
4
+ import { useI18n } from 'domains/i18n/hooks'
5
5
 
6
6
  const EventParticipant = ({ eventPayload }) => {
7
7
  const { t } = useI18n()
@@ -1,6 +1,6 @@
1
- import { useI18n } from 'domains/i18n'
1
+ import { useI18n } from 'domains/i18n/hooks'
2
2
  import { getRelativeDate } from 'ui/utils/general-utils'
3
- import { useConfig } from 'domains/config'
3
+ import { useConfig } from 'domains/config/hooks'
4
4
 
5
5
  const dateFormatOptions = { month: 'long', day: 'numeric', year: 'numeric' }
6
6
  const timeFormatOptions = { hour: 'numeric', minute: 'numeric' }
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'preact/hooks'
2
2
  import Lightbox from 'ui/components/widgets/lightbox'
3
- import { useI18n } from 'domains/i18n'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
4
  import { className } from 'lib/css'
5
5
  import Icon from 'ui/components/layout/icon'
6
6
 
@@ -1,20 +1,18 @@
1
+ import { setLoadedImageEventIds } from 'domains/store/slice'
2
+ import { useTranslatedEventData } from 'domains/translations/hooks'
1
3
  import { useState } from 'preact/hooks'
4
+ import { useDispatch } from 'react-redux'
2
5
  import MessageContainer from 'ui/components/conversation/message-container'
3
- import { useTranslatedEventData } from 'domains/translations'
4
- import { useStoreDispatch } from 'domains/redux'
5
6
  import ImageLightbox from './image-lightbox'
6
- import { seamlyActions } from '../../../utils/seamly-utils'
7
-
8
- const { SET_LOADED_IMAGE_EVENT_IDS } = seamlyActions
9
7
 
10
8
  const Image = ({ event, descriptorId, ...props }) => {
11
- const [body] = useTranslatedEventData(event)
9
+ const { body } = useTranslatedEventData(event)
12
10
  const { description, url, isZoomable } = body
13
11
  const [showLighbox, setShowLightbox] = useState(false)
14
- const dispatch = useStoreDispatch()
12
+ const dispatch = useDispatch()
15
13
 
16
14
  const handleOnLoad = () => {
17
- dispatch({ type: SET_LOADED_IMAGE_EVENT_IDS, eventId: event.payload.id })
15
+ dispatch(setLoadedImageEventIds(event.payload.id))
18
16
  setShowLightbox(true)
19
17
  }
20
18
 
@@ -1,9 +1,9 @@
1
1
  import EventDivider from 'ui/components/conversation/event-divider'
2
- import { useTranslatedEventData } from 'domains/translations'
2
+ import { useTranslatedEventData } from 'domains/translations/hooks'
3
3
 
4
4
  const Participant = ({ event }) => {
5
5
  const { participant } = event.payload
6
- const [introduction] = useTranslatedEventData(event)
6
+ const { body: introduction } = useTranslatedEventData(event)
7
7
 
8
8
  if (!introduction) {
9
9
  return null
@@ -1,10 +1,10 @@
1
- import useEventLinkClickHandler from './hooks/use-event-link-click-handler'
2
- import MessageContainer from '../message-container'
3
- import { useTranslatedEventData } from '../../../../domains/translations'
1
+ import { useTranslatedEventData } from 'domains/translations/hooks'
2
+ import useEventLinkClickHandler from 'ui/components/conversation/event/hooks/use-event-link-click-handler'
3
+ import MessageContainer from 'ui/components/conversation/message-container'
4
4
 
5
5
  const Splash = ({ event, ...props }) => {
6
6
  const { payload } = event
7
- const [body] = useTranslatedEventData(event)
7
+ const { body } = useTranslatedEventData(event)
8
8
  const eventClick = useEventLinkClickHandler(payload.id)
9
9
 
10
10
  return (
@@ -1,10 +1,10 @@
1
1
  import { useMemo } from 'preact/hooks'
2
2
  import MessageContainer from 'ui/components/conversation/message-container'
3
- import { useTranslatedEventData } from 'domains/translations'
3
+ import { useTranslatedEventData } from 'domains/translations/hooks'
4
4
  import useEventLinkClickHandler from './hooks/use-event-link-click-handler'
5
5
 
6
6
  const Text = ({ event, ...props }) => {
7
- const [body] = useTranslatedEventData(event)
7
+ const { body } = useTranslatedEventData(event)
8
8
  const eventClick = useEventLinkClickHandler(event.payload.id)
9
9
 
10
10
  const containerProps = useMemo(() => {
@@ -1,10 +1,10 @@
1
- import { useI18n } from 'domains/i18n'
1
+ import { useI18n } from 'domains/i18n/hooks'
2
2
  import MessageContainer from 'ui/components/conversation/message-container'
3
- import { useTranslatedEventData } from 'domains/translations'
3
+ import { useTranslatedEventData } from 'domains/translations/hooks'
4
4
 
5
5
  const Translation = ({ event, ...props }) => {
6
6
  const { t } = useI18n()
7
- const [body] = useTranslatedEventData(event)
7
+ const { body } = useTranslatedEventData(event)
8
8
  return (
9
9
  <MessageContainer type="text" event={event} {...props}>
10
10
  {t(body.key.join('.'), body.variables)}
@@ -1,9 +1,9 @@
1
1
  import { useMemo } from 'preact/hooks'
2
2
  import { className } from 'lib/css'
3
3
  import Icon from 'ui/components/layout/icon'
4
- import { useI18n } from 'domains/i18n'
4
+ import { useI18n } from 'domains/i18n/hooks'
5
5
  import MessageContainer from 'ui/components/conversation/message-container'
6
- import { useTranslatedEventData } from 'domains/translations'
6
+ import { useTranslatedEventData } from 'domains/translations/hooks'
7
7
 
8
8
  const UploadContent = ({ children, url, target }) =>
9
9
  url ? (
@@ -21,7 +21,7 @@ const UploadContent = ({ children, url, target }) =>
21
21
 
22
22
  const Upload = ({ event, ...props }) => {
23
23
  const { t } = useI18n()
24
- const [body] = useTranslatedEventData(event)
24
+ const { body } = useTranslatedEventData(event)
25
25
  const { fromClient } = event.payload
26
26
  const { filename, url } = body
27
27
 
@@ -1,10 +1,10 @@
1
1
  import { className } from 'lib/css'
2
2
  import { useSeamlyMessageContainerClassNames } from 'ui/hooks/seamly-hooks'
3
- import { useTranslatedEventData } from 'domains/translations'
3
+ import { useTranslatedEventData } from 'domains/translations/hooks'
4
4
  import MessageContainer from 'ui/components/conversation/message-container'
5
5
 
6
6
  const Video = ({ event, descriptorId, ...props }) => {
7
- const [body] = useTranslatedEventData(event)
7
+ const { body } = useTranslatedEventData(event)
8
8
  const { description, url } = body
9
9
  const classNames = useSeamlyMessageContainerClassNames(event)
10
10
 
@@ -1,12 +1,10 @@
1
1
  import { className } from 'lib/css'
2
2
  import { useSeamlyMessageContainerClassNames } from 'ui/hooks/component-helper-hooks'
3
- import { useTranslatedEventData } from 'domains/translations'
4
- import { useI18n } from 'domains/i18n'
3
+ import { useTranslatedEventData } from 'domains/translations/hooks'
5
4
  import EventParticipant from './event/event-participant'
6
5
 
7
6
  function MessageContainer({
8
7
  showParticipant = true,
9
- showTranslationToggle = true,
10
8
  event,
11
9
  type,
12
10
  modifiers,
@@ -16,13 +14,11 @@ function MessageContainer({
16
14
  ...props
17
15
  }) {
18
16
  const classNames = useSeamlyMessageContainerClassNames(event)
19
- const { t } = useI18n()
20
17
 
21
- const [, { hasTranslation, isTranslated, toggleTranslation, locale }] =
22
- useTranslatedEventData(event)
18
+ const { hasTranslation, isTranslated, locale } = useTranslatedEventData(event)
23
19
 
24
20
  if (type) {
25
- classNames.push('message--type-' + type)
21
+ classNames.push(`message--type-${type}`)
26
22
  }
27
23
  if (modifiers) {
28
24
  if (typeof modifiers === 'string') {
@@ -30,7 +26,7 @@ function MessageContainer({
30
26
  modifiers = modifiers.split(' ').filter((v) => v.length)
31
27
  }
32
28
  modifiers.forEach((modifier) => {
33
- classNames.push('message--' + modifier)
29
+ classNames.push(`message--${modifier}`)
34
30
  })
35
31
  }
36
32
  if (isTranslated) {
@@ -60,24 +56,6 @@ function MessageContainer({
60
56
  {info}
61
57
  </div>
62
58
  )}
63
- {showTranslationToggle && hasTranslation && (
64
- <div className={className('message__translation-info')}>
65
- <button
66
- className={className(
67
- 'message__translation-toggle',
68
- 'button',
69
- 'button--secondary',
70
- )}
71
- onClick={toggleTranslation}
72
- >
73
- {t(
74
- isTranslated
75
- ? 'translations.toggle.hideButtonText'
76
- : 'translations.toggle.showButtonText',
77
- )}
78
- </button>
79
- </div>
80
- )}
81
59
  </div>
82
60
  </>
83
61
  )
@@ -2,4 +2,4 @@ import { createContext } from 'preact'
2
2
 
3
3
  export const SeamlyApiContext = createContext(null)
4
4
 
5
- export const SeamlyEventBusContext = createContext('')
5
+ export const SeamlyEventBusContext = createContext(null)
@@ -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,27 @@ 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
- const { uploads, entry } = serviceSettings
143
-
144
- dispatch({
145
- type: SET_FEATURE_ENABLED_STATE,
146
- key: featureKeys.uploads,
147
- enabled: !!(uploads && uploads.enabled),
148
- })
126
+ const { entry } = serviceSettings
127
+ const { upload } = entry.options
149
128
 
150
- dispatch({
151
- type: SET_SERVICE_ENTRY_METADATA,
152
- entryMeta: entry,
153
- })
129
+ dispatch(
130
+ setFeatureEnabledState({
131
+ key: featureKeys.uploads,
132
+ enabled: !!(upload && upload.enabled),
133
+ }),
134
+ )
154
135
 
155
- dispatch({
156
- type: SET_ACTIVE_SERVICE,
157
- activeServiceSessionId: payload.serviceSessionId,
158
- })
136
+ dispatch(setServiceEntryMetadata(entry))
137
+ dispatch(setActiveService(payload.serviceSessionId))
159
138
 
160
139
  emitEvent('system.serviceChanged', eventPayload)
161
140
  }
@@ -166,27 +145,54 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
166
145
  payload.type === 'text' ||
167
146
  payload.type === 'translation'
168
147
  ) {
169
- dispatch({ type: ADD_EVENT, event })
148
+ dispatch(addEvent(event))
170
149
  }
171
150
  break
172
151
  case 'error':
173
152
  switch (payload.type) {
174
153
  case 'find_conversation_erred':
154
+ const seamlySessionExpiredError =
155
+ new SeamlySessionExpiredError(event)
175
156
  dispatch(
176
- InterruptActions.set(new SeamlySessionExpiredError(event)),
157
+ setInterrupt({
158
+ name: seamlySessionExpiredError.name,
159
+ action: seamlySessionExpiredError.action,
160
+ message: seamlySessionExpiredError.message,
161
+ originalEvent: seamlySessionExpiredError.originalEvent,
162
+ originalError: seamlySessionExpiredError.originalError,
163
+ }),
177
164
  )
178
165
  break
179
166
  case 'seamly_offline':
180
- dispatch(InterruptActions.set(new SeamlyOfflineError(event)))
181
- dispatch({ type: CLEAR_EVENTS })
167
+ const seamlyOfflineError = new SeamlyOfflineError(event)
168
+ dispatch(
169
+ setInterrupt({
170
+ name: seamlyOfflineError.name,
171
+ message: seamlyOfflineError.message,
172
+ langKey: seamlyOfflineError.langKey,
173
+ originalEvent: seamlyOfflineError.originalEvent,
174
+ originalError: seamlyOfflineError.originalError,
175
+ }),
176
+ )
177
+ dispatch(clearEvents())
182
178
  break
183
179
  default:
184
- dispatch(InterruptActions.set(new SeamlyGeneralError(event)))
180
+ const seamlyGeneralError = new SeamlyGeneralError(event)
181
+ dispatch(
182
+ setInterrupt({
183
+ name: seamlyGeneralError.name,
184
+ message: seamlyGeneralError.message,
185
+ langKey: seamlyGeneralError.langKey,
186
+ originalEvent: seamlyGeneralError.originalEvent,
187
+ originalError: seamlyGeneralError.originalError,
188
+ action: seamlyGeneralError.action,
189
+ }),
190
+ )
185
191
  break
186
192
  }
187
193
  break
188
194
  case 'socket_opened':
189
- dispatch(InterruptActions.clear())
195
+ dispatch(clearInterrupt())
190
196
  break
191
197
  }
192
198
  },
@@ -210,17 +216,12 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
210
216
  prevEmittedEventId.current = payload.id
211
217
  },
212
218
  })
219
+ return () => {
220
+ subscription.unsubscribe()
221
+ }
213
222
  }
214
- }, [
215
- dispatch,
216
- api,
217
- eventBus,
218
- t,
219
- setUserSelectedOption,
220
- initCountdown,
221
- endCountdown,
222
- emitEvent,
223
- ])
223
+ return () => undefined
224
+ }, [dispatch, api, eventBus, initCountdown, endCountdown, emitEvent])
224
225
 
225
226
  useEffect(() => {
226
227
  const subscribe = () => {
@@ -245,13 +246,18 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
245
246
  return
246
247
  }
247
248
 
248
- dispatch({
249
- type: SET_HISTORY,
250
- history,
251
- })
249
+ dispatch(setHistory(history))
252
250
  })
253
251
  .catch((error) => {
254
- dispatch(InterruptActions.set(error))
252
+ dispatch(
253
+ setInterrupt({
254
+ name: error.name,
255
+ message: error.message,
256
+ langKey: error.langKey,
257
+ originalEvent: error.originalEvent,
258
+ originalError: error.originalError,
259
+ }),
260
+ )
255
261
  })
256
262
  },
257
263
  })
@@ -264,7 +270,7 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
264
270
  }
265
271
  }
266
272
 
267
- return () => {}
273
+ return () => undefined
268
274
  }, [api, events, dispatch])
269
275
 
270
276
  return null