@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
@@ -2,12 +2,13 @@ import { createRef } from 'preact'
2
2
  import { useState, useRef, useEffect, useMemo } from 'preact/hooks'
3
3
  import { className } from 'lib/css'
4
4
  import { useSeamlyOptions, useOptionButton } from 'ui/hooks/seamly-hooks'
5
- import { useI18n } from 'domains/i18n'
5
+ import { useI18n } from 'domains/i18n/hooks'
6
6
  import Icon from 'ui/components/layout/icon'
7
7
  import InOutTransition, {
8
8
  transitionStartStates,
9
9
  } from 'ui/components/widgets/in-out-transition'
10
10
  import { getKey, keyNames, focusElement } from 'ui/utils/general-utils'
11
+ import { timeout } from 'ui/hooks/focus-helper-hooks'
11
12
  import Options from './options'
12
13
 
13
14
  const OptionsButton = () => {
@@ -41,15 +42,15 @@ const OptionsButton = () => {
41
42
 
42
43
  useEffect(() => {
43
44
  if (menuIsOpen && !prevMenuIsOpen.current) {
44
- requestAnimationFrame(() => {
45
- requestAnimationFrame(() => {
46
- const firstActiveOptionIndex = menuOptions.findIndex(
47
- (option) => option.available,
48
- )
49
- const focusIndex =
50
- firstActiveOptionIndex === -1 ? 0 : firstActiveOptionIndex
51
- focusElement(menuItemButtons.current[focusIndex])
52
- })
45
+ requestAnimationFrame(async () => {
46
+ await timeout(60) // Wait for next frame tick
47
+ const firstActiveOptionIndex = menuOptions.findIndex(
48
+ (option) => option.available,
49
+ )
50
+
51
+ const focusIndex =
52
+ firstActiveOptionIndex === -1 ? 0 : firstActiveOptionIndex
53
+ focusElement(menuItemButtons.current[focusIndex])
53
54
  })
54
55
  }
55
56
  prevMenuIsOpen.current = menuIsOpen
@@ -155,11 +156,14 @@ const OptionsButton = () => {
155
156
  if (!optionsLength) {
156
157
  return null
157
158
  }
159
+
158
160
  return (
159
161
  <div
160
162
  className={className('options__container')}
161
163
  onKeyDown={onMainKeyDownHandler}
164
+ // eslint-disable-next-line react/no-unknown-property
162
165
  onfocusout={onFocusOutHandler}
166
+ // eslint-disable-next-line react/no-unknown-property
163
167
  onfocusin={onFocusInHandler}
164
168
  >
165
169
  <InOutTransition
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useMemo, useState } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import OptionsFrame from 'ui/components/options/options-frame'
4
4
  import { className } from 'lib/css'
5
5
  import {
@@ -9,7 +9,7 @@ import {
9
9
  useSeamlyOptions,
10
10
  } from 'ui/hooks/seamly-hooks'
11
11
  import { actionTypes } from 'ui/utils/seamly-utils'
12
- import { FormProvider } from 'domains/forms'
12
+ import FormProvider from 'domains/forms/provider'
13
13
  import { getValidator } from 'ui/utils/form-utils'
14
14
  import { isEmailString, isNotEmptyString } from 'ui/utils/validations'
15
15
  import TranscriptForm from './transcript-form'
@@ -1,5 +1,5 @@
1
1
  import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import Form from 'ui/components/form-controls/form'
4
4
  import Input from 'ui/components/form-controls/input'
5
5
 
@@ -1,8 +1,10 @@
1
- import { useUserHasResponded } from 'domains/app'
2
- import { useI18n } from 'domains/i18n'
3
- import { useInterrupt } from 'domains/interrupt'
4
- import { useTranslatedEventData } from 'domains/translations'
5
- import { useVisibility, visibilityStates } from 'domains/visibility'
1
+ import { useUserHasResponded } from 'domains/app/hooks'
2
+ import { useConfig } from 'domains/config/hooks'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
+ import { useInterrupt } from 'domains/interrupt/hooks'
5
+ import { useTranslatedEventData } from 'domains/translations/hooks'
6
+ import { visibilityStates } from 'domains/visibility/constants'
7
+ import { useVisibility } from 'domains/visibility/hooks'
6
8
  import { className } from 'lib/css'
7
9
  import { useCallback, useEffect, useMemo, useRef } from 'preact/hooks'
8
10
  import SuggestionsList from 'ui/components/suggestions/suggestions-list'
@@ -28,6 +30,7 @@ const Suggestions = ({ isAside = false }) => {
28
30
  const { t } = useI18n()
29
31
  const { sendAction, addMessageBubble } = useSeamlyCommands()
30
32
  const { isOpen, setVisibility } = useVisibility()
33
+ const { showSuggestions } = useConfig()
31
34
  // a11y hooks
32
35
  const sectionId = useGeneratedId()
33
36
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()
@@ -38,9 +41,9 @@ const Suggestions = ({ isAside = false }) => {
38
41
  const { hasCountdown, endCountdown } = useSeamlyIdleDetachCountdown()
39
42
  const { hasPrompt, continueChat } = useSeamlyResumeConversationPrompt()
40
43
  // data hooks
41
- const hasResponded = useUserHasResponded()
44
+ const userHasResponded = useUserHasResponded()
42
45
  const payload = useSeamlyServiceData('suggestion')
43
- const [eventBody] = useTranslatedEventData({ payload })
46
+ const { body: eventBody } = useTranslatedEventData({ payload })
44
47
  const suggestions = useMemo(
45
48
  () => (payload && !hasInterrupt ? eventBody : []),
46
49
  [payload, hasInterrupt, eventBody],
@@ -52,10 +55,11 @@ const Suggestions = ({ isAside = false }) => {
52
55
  const previousRenderedSuggestions = useRef([])
53
56
  const hasSuggestions = !!suggestions.length
54
57
  const hideSuggestions = isInline
55
- ? (hasResponded || isOpen) && !isAside
56
- : hasResponded
58
+ ? (userHasResponded || isOpen) && !isAside
59
+ : userHasResponded
57
60
  const prevHideSuggestions = useRef(hideSuggestions)
58
- const showSuggestionsContainer = hasSuggestions && !hideSuggestions
61
+ const showSuggestionsContainer =
62
+ hasSuggestions && !hideSuggestions && showSuggestions
59
63
  const renderedSuggestions = hasSuggestions
60
64
  ? suggestions
61
65
  : previousRenderedSuggestions.current
@@ -1,4 +1,4 @@
1
- import { useVisibility, useShowInlineView } from 'domains/visibility'
1
+ import { useVisibility, useShowInlineView } from 'domains/visibility/hooks'
2
2
  import DeprecatedAppFrame from '../layout/deprecated-app-frame'
3
3
  import ChatFrame from '../layout/chat-frame'
4
4
  import AgentInfo from '../layout/agent-info'
@@ -9,27 +9,30 @@ import Interrupt from '../layout/interrupt'
9
9
  import { useSeamlyChat } from '../../hooks/seamly-hooks'
10
10
  import DeprecatedToggleButton from '../entry/deprecated-toggle-button'
11
11
 
12
+ const ShowInlineView = ({ children }) => {
13
+ const { showInlineView, containerRef } = useShowInlineView()
14
+
15
+ return <div ref={containerRef}>{showInlineView && children}</div>
16
+ }
17
+
12
18
  const DeprecatedView = () => {
13
19
  const { isVisible } = useVisibility()
14
20
  const { openChat, closeChat } = useSeamlyChat()
15
- const { showInlineView, containerRef } = useShowInlineView()
16
21
 
17
22
  return (
18
23
  isVisible && (
19
- <div ref={containerRef}>
20
- {showInlineView && (
21
- <DeprecatedAppFrame>
22
- <DeprecatedToggleButton onOpenChat={openChat} />
23
- <Header onCloseChat={closeChat}>
24
- <AgentInfo />
25
- </Header>
26
- <ChatFrame interruptComponent={Interrupt}>
27
- <Conversation />
28
- <EntryContainer />
29
- </ChatFrame>
30
- </DeprecatedAppFrame>
31
- )}
32
- </div>
24
+ <ShowInlineView>
25
+ <DeprecatedAppFrame>
26
+ <DeprecatedToggleButton onOpenChat={openChat} />
27
+ <Header onCloseChat={closeChat}>
28
+ <AgentInfo />
29
+ </Header>
30
+ <ChatFrame interruptComponent={Interrupt}>
31
+ <Conversation />
32
+ <EntryContainer />
33
+ </ChatFrame>
34
+ </DeprecatedAppFrame>
35
+ </ShowInlineView>
33
36
  )
34
37
  )
35
38
  }
@@ -1,14 +1,14 @@
1
+ import { useUserHasResponded } from 'domains/app/hooks'
1
2
  import { useCallback, useMemo } from 'preact/hooks'
2
- import { useConfig } from '../../../domains/config'
3
- import AppView from './app-view'
4
- import InlineView from './inline-view'
5
- import WindowView from './window-view'
6
- import { useVisibility } from '../../../domains/visibility'
7
- import { className } from '../../../lib/css'
8
- import { useSeamlyAppContainerClassNames } from '../../hooks/component-helper-hooks'
9
- import { useUserHasResponded } from '../../../domains/app'
10
- import { useI18n } from '../../../domains/i18n'
11
- import { useSeamlyContainerElement } from '../../hooks/focus-helper-hooks'
3
+ import { useVisibility } from 'domains/visibility/hooks'
4
+ import { useSeamlyContainerElement } from 'ui/hooks/focus-helper-hooks'
5
+ import { useConfig } from 'domains/config/hooks'
6
+ import { useSeamlyAppContainerClassNames } from 'ui/hooks/component-helper-hooks'
7
+ import { useI18n } from 'domains/i18n/hooks'
8
+ import AppView from 'ui/components/view/app-view'
9
+ import InlineView from 'ui/components/view/inline-view'
10
+ import WindowView from 'ui/components/view/window-view'
11
+ import { className } from 'lib/css'
12
12
 
13
13
  const ViewComponentsMap = {
14
14
  app: AppView,
@@ -21,7 +21,7 @@ const View = ({ children }) => {
21
21
  const { namespace, layoutMode, zIndex } = useConfig()
22
22
  const { isOpen, isVisible } = useVisibility()
23
23
  const appContainerClassNames = useSeamlyAppContainerClassNames()
24
- const userResponded = useUserHasResponded()
24
+ const userHasResponded = useUserHasResponded()
25
25
  const { locale } = useI18n()
26
26
  const ViewComponent = ViewComponentsMap[layoutMode]
27
27
 
@@ -60,7 +60,7 @@ const View = ({ children }) => {
60
60
  classNames.push('app--collapsed')
61
61
  }
62
62
 
63
- if (userResponded) {
63
+ if (userHasResponded) {
64
64
  classNames.push('app--user-responded')
65
65
  }
66
66
 
@@ -1,6 +1,6 @@
1
1
  import { className } from 'lib/css'
2
- import { useVisibility, useShowInlineView } from 'domains/visibility'
3
- import { useInterrupt } from 'domains/interrupt'
2
+ import { useVisibility, useShowInlineView } from 'domains/visibility/hooks'
3
+ import { useInterrupt } from 'domains/interrupt/hooks'
4
4
  import Chat from '../layout/chat'
5
5
  import Interrupt from '../layout/interrupt'
6
6
  import Conversation from '../conversation/conversation'
@@ -1,7 +1,7 @@
1
+ import { useI18n } from 'domains/i18n/hooks'
2
+ import { className } from 'lib/css'
3
+ import Icon from 'ui/components/layout/icon'
1
4
  import { useCallback } from 'preact/hooks'
2
- import { className } from '../../../../lib/css'
3
- import Icon from '../../layout/icon'
4
- import { useI18n } from '../../../../domains/i18n'
5
5
 
6
6
  const CollapseButton = ({ onClick }) => {
7
7
  const { t } = useI18n()
@@ -1,26 +1,26 @@
1
+ import { useUserHasResponded } from 'domains/app/hooks'
1
2
  import { useMemo } from 'preact/hooks'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
+ import { useVisibility } from 'domains/visibility/hooks'
5
+ import { className } from 'lib/css'
2
6
  import { useSeamlyChat } from '../../../hooks/seamly-hooks'
3
- import { useVisibility } from '../../../../domains/visibility'
7
+ import Conversation from '../../conversation/conversation'
8
+ import Text from '../../conversation/event/text'
9
+ import EntryContainer from '../../entry/entry-container'
4
10
  import Chat from '../../layout/chat'
5
11
  import ChatFrame from '../../layout/chat-frame'
6
12
  import Interrupt from '../../layout/interrupt'
7
- import Conversation from '../../conversation/conversation'
8
- import EntryContainer from '../../entry/entry-container'
9
- import WindowOpenButton from './window-open-button'
10
- import CollapseButton from './collapse-button'
13
+ import PreChatMessages from '../../layout/pre-chat-messages'
11
14
  import InOutTransition, {
12
15
  transitionStartStates,
13
16
  } from '../../widgets/in-out-transition'
14
- import PreChatMessages from '../../layout/pre-chat-messages'
15
- import { useUserHasResponded } from '../../../../domains/app'
16
- import { className } from '../../../../lib/css'
17
- import Text from '../../conversation/event/text'
18
- import { useI18n } from '../../../../domains/i18n'
17
+ import CollapseButton from './collapse-button'
18
+ import WindowOpenButton from './window-open-button'
19
19
 
20
20
  const WindowView = () => {
21
21
  const { openChat, closeChat } = useSeamlyChat()
22
22
  const { isOpen } = useVisibility()
23
- const hasResponded = useUserHasResponded()
23
+ const userHasResponded = useUserHasResponded()
24
24
  const { t } = useI18n()
25
25
  const continueChatText = t('window.chat.continue')
26
26
  const continueChatEvent = useMemo(
@@ -37,7 +37,7 @@ const WindowView = () => {
37
37
  <>
38
38
  <WindowOpenButton onClick={openChat} />
39
39
  <InOutTransition
40
- isActive={!isOpen && !hasResponded}
40
+ isActive={!isOpen && !userHasResponded}
41
41
  transitionStartState={transitionStartStates.rendered}
42
42
  >
43
43
  <div
@@ -50,7 +50,7 @@ const WindowView = () => {
50
50
  </div>
51
51
  </InOutTransition>
52
52
  <InOutTransition
53
- isActive={!isOpen && hasResponded}
53
+ isActive={!isOpen && userHasResponded}
54
54
  transitionStartState={transitionStartStates.notRendered}
55
55
  >
56
56
  <div
@@ -1,19 +1,19 @@
1
+ import { useStartChatIcon } from 'domains/config/hooks'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
+ import { useInterrupt } from 'domains/interrupt/hooks'
4
+ import { useVisibility } from 'domains/visibility/hooks'
5
+ import { className } from 'lib/css'
6
+ import Icon from 'ui/components/layout/icon'
1
7
  import { useCallback } from 'preact/hooks'
2
- import { className } from '../../../../lib/css'
8
+ import InOutTransition, {
9
+ transitionStartStates,
10
+ } from 'ui/components/widgets/in-out-transition'
11
+ import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
12
+ import { useSeamlyHasConversation } from 'ui/hooks/seamly-api-hooks'
3
13
  import {
4
14
  useSeamlyCurrentAgent,
5
15
  useSeamlyUnreadCount,
6
- useSkiplinkTargetFocusing,
7
- } from '../../../hooks/seamly-hooks'
8
- import { useI18n } from '../../../../domains/i18n'
9
- import { useStartChatIcon } from '../../../../domains/config'
10
- import { useVisibility } from '../../../../domains/visibility'
11
- import Icon from '../../layout/icon'
12
- import { useInterrupt } from '../../../../domains/interrupt'
13
- import InOutTransition, {
14
- transitionStartStates,
15
- } from '../../widgets/in-out-transition'
16
- import { useSeamlyHasConversation } from '../../../hooks/seamly-api-hooks'
16
+ } from 'ui/hooks/seamly-state-hooks'
17
17
 
18
18
  const ButtonIcon = () => {
19
19
  const startChatIcon = useStartChatIcon()
@@ -35,7 +35,7 @@ const ButtonIcon = () => {
35
35
  const WindowOpenButton = ({ onClick }) => {
36
36
  const hasConversation = useSeamlyHasConversation()
37
37
  const { t } = useI18n()
38
- const ariaLabel = hasConversation
38
+ const ariaLabel = hasConversation()
39
39
  ? t('window.openButton.srContinue')
40
40
  : t('window.openButton.srStart')
41
41
  const focusSkiplinkTarget = useSkiplinkTargetFocusing()
@@ -1,5 +1,5 @@
1
1
  import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import useSeamlyIdleDetachCountdown from 'ui/hooks/use-seamly-idle-detach-countdown'
4
4
  import { useSkiplinkTargetFocusing } from 'ui/hooks/focus-helper-hooks'
5
5
  import useSeamlyActivityEventHandler from 'ui/hooks/use-seamly-activity-event-handler'
@@ -1,5 +1,5 @@
1
1
  import { className } from 'lib/css'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import useSeamlyResumeConversationPrompt from 'ui/hooks/use-seamly-resume-conversation-prompt'
4
4
  import useSeamlyActivityEventHandler from 'ui/hooks/use-seamly-activity-event-handler'
5
5
  import { useSeamlyCurrentAgent } from 'ui/hooks/seamly-state-hooks'
@@ -1,12 +1,12 @@
1
1
  import { useRef } from 'preact/hooks'
2
- import { useI18n } from 'domains/i18n'
2
+ import { useI18n } from 'domains/i18n/hooks'
3
3
  import {
4
4
  useSeamlyActivityEventHandler,
5
5
  useSeamlyAppContainerClassNames,
6
6
  } from 'ui/hooks/seamly-hooks'
7
7
  import { className } from 'lib/css'
8
8
  import Icon from 'ui/components/layout/icon'
9
- import { useConfig } from 'domains/config'
9
+ import { useConfig } from 'domains/config/hooks'
10
10
  import Modal from './modal'
11
11
 
12
12
  const Lightbox = ({ url, description, onClose: onCloseHandler }) => {
@@ -1,6 +1,6 @@
1
1
  import { className } from 'lib/css'
2
2
  import { useFileUploads } from 'ui/hooks/seamly-hooks'
3
- import { useI18n } from 'domains/i18n'
3
+ import { useI18n } from 'domains/i18n/hooks'
4
4
  import Error from 'ui/components/form-controls/error'
5
5
 
6
6
  const UploadProgress = () => {
@@ -1,4 +1,4 @@
1
- import { useConfig } from 'domains/config'
1
+ import { useConfig } from 'domains/config/hooks'
2
2
 
3
3
  export const useSeamlyAppContainerClassNames = () => {
4
4
  return useConfig().appContainerClassNames
@@ -1,10 +1,8 @@
1
+ import { clearAllUploads } from 'domains/store/slice'
1
2
  import { useCallback, useContext } from 'preact/hooks'
3
+ import { useDispatch } from 'react-redux'
2
4
  import SeamlyFileUploadContext from 'ui/components/core/seamly-file-upload-context'
3
- import { seamlyActions } from 'ui/utils/seamly-utils'
4
5
  import { useSeamlyStateContext } from './seamly-state-hooks'
5
- import useSeamlyDispatchContext from './use-seamly-dispatch'
6
-
7
- const { CLEAR_ALL_UPLOADS } = seamlyActions
8
6
 
9
7
  const useSeamlyFileUploadContext = () => useContext(SeamlyFileUploadContext)
10
8
 
@@ -47,7 +45,7 @@ export const useFileUploadMeta = () => {
47
45
 
48
46
  export const useFileUploads = () => {
49
47
  const { currentUploads } = useSeamlyStateContext()
50
- const dispatch = useSeamlyDispatchContext()
48
+ const dispatch = useDispatch()
51
49
  const upload = useSeamlyFileUploadContext()
52
50
 
53
51
  const uploadFile = useCallback(
@@ -58,7 +56,7 @@ export const useFileUploads = () => {
58
56
  )
59
57
 
60
58
  const clearUploads = useCallback(() => {
61
- dispatch({ type: CLEAR_ALL_UPLOADS })
59
+ dispatch(clearAllUploads())
62
60
  }, [dispatch])
63
61
 
64
62
  return {
@@ -1,36 +1,38 @@
1
+ import { setSeamlyContainerElement } from 'domains/store/slice'
1
2
  import { useCallback, useRef } from 'preact/hooks'
3
+ import { useDispatch } from 'react-redux'
2
4
  import {
3
5
  focusElement,
4
6
  runIfElementContainsOrHasFocus,
5
7
  } from 'ui/utils/general-utils'
6
- import { seamlyActions } from 'ui/utils/seamly-utils'
7
8
  import { useSeamlyStateContext, useSkiplink } from './seamly-state-hooks'
8
- import useSeamlyDispatchContext from './use-seamly-dispatch'
9
9
 
10
- const { SET_SEAMLY_CONTAINER_ELEMENT } = seamlyActions
10
+ export const timeout = (ms = 0) =>
11
+ new Promise((resolve) => {
12
+ setTimeout(resolve, ms)
13
+ })
11
14
 
12
15
  const focusWithRaf = (el) => {
13
- requestAnimationFrame(() => {
14
- requestAnimationFrame(() => {
15
- const focusEl = typeof el === 'string' ? document.getElementById(el) : el
16
- focusElement(focusEl)
17
- })
16
+ requestAnimationFrame(async () => {
17
+ await timeout(180) // wait for next 3 ticks
18
+ const focusEl = typeof el === 'string' ? document.getElementById(el) : el
19
+ focusElement(focusEl)
18
20
  })
19
21
  }
20
22
 
21
23
  export const useSeamlyContainerElement = () => {
22
24
  const { seamlyContainerElement } = useSeamlyStateContext()
23
25
 
24
- const dispatch = useSeamlyDispatchContext()
26
+ const dispatch = useDispatch()
25
27
 
26
- const setSeamlyContainerElement = useCallback(
28
+ const dispatchSeamlyContainerElement = useCallback(
27
29
  (element) => {
28
- dispatch({ type: SET_SEAMLY_CONTAINER_ELEMENT, element })
30
+ dispatch(setSeamlyContainerElement(element))
29
31
  },
30
32
  [dispatch],
31
33
  )
32
34
 
33
- return [seamlyContainerElement, setSeamlyContainerElement]
35
+ return [seamlyContainerElement, dispatchSeamlyContainerElement]
34
36
  }
35
37
 
36
38
  export const useElementFocusingById = (elementId) =>
@@ -9,6 +9,7 @@ export const useLiveRegion = () => {
9
9
  const sendMessage = useSeamlyLiveRegionContext()
10
10
  const sendPolite = useCallback(
11
11
  (messageText) => {
12
+ if (!messageText) return
12
13
  sendMessage({
13
14
  ariaLive: ariaLiveLevels.polite,
14
15
  messageText,
@@ -18,6 +19,7 @@ export const useLiveRegion = () => {
18
19
  )
19
20
  const sendAssertive = useCallback(
20
21
  (messageText) => {
22
+ if (!messageText) return
21
23
  sendMessage({
22
24
  ariaLive: ariaLiveLevels.assertive,
23
25
  messageText,
@@ -1,4 +1,4 @@
1
- import { useContext } from 'preact/hooks'
1
+ import { useCallback, useContext } from 'preact/hooks'
2
2
  import { SeamlyApiContext } from 'ui/components/core/seamly-api-context'
3
3
 
4
4
  export const useSeamlyApiContext = () => useContext(SeamlyApiContext)
@@ -19,6 +19,11 @@ export const useSeamlyConversationUrl = () => {
19
19
  }
20
20
 
21
21
  export const useSeamlyHasConversation = () => {
22
- const url = useSeamlyConversationUrl()
23
- return !!url
22
+ const api = useSeamlyApiContext()
23
+
24
+ const hasConversation = useCallback(() => {
25
+ return api.hasConversation()
26
+ }, [api])
27
+
28
+ return hasConversation
24
29
  }
@@ -1,16 +1,14 @@
1
- import { useRef, useCallback, useEffect } from 'preact/hooks'
2
- import { seamlyActions, actionTypes } from 'ui/utils/seamly-utils'
3
1
  import { typingTimeout } from 'config'
4
- import { useSeamlyStateContext } from './seamly-state-hooks'
5
- import useSeamlyDispatchContext from './use-seamly-dispatch'
6
- import { useSeamlyOptions } from './seamly-option-hooks'
7
- import useSeamlyCommands from './use-seamly-commands'
8
-
9
- const {
10
- SET_BLOCK_AUTO_ENTRY_SWITCH,
11
- SET_ACTIVE_ENTRY_TYPE,
12
- SET_USER_ENTRY_TYPE,
13
- } = seamlyActions
2
+ import {
3
+ setBlockAutoEntrySwitch,
4
+ setActiveEntryType,
5
+ setUserEntryType,
6
+ } from 'domains/store/slice'
7
+ import { useSeamlyCommands, useSeamlyOptions } from 'ui/hooks/seamly-hooks'
8
+ import { useRef, useEffect, useCallback } from 'preact/hooks'
9
+ import { useSeamlyStateContext } from 'ui/hooks/seamly-state-hooks'
10
+ import { useDispatch } from 'react-redux'
11
+ import { actionTypes } from 'ui/utils/seamly-utils'
14
12
 
15
13
  export const useSeamlyTyping = () => {
16
14
  const { sendAction } = useSeamlyCommands()
@@ -82,47 +80,52 @@ export const useSeamlyEntry = () => {
82
80
  options: entryOptions,
83
81
  optionsOverride: entryOptionsOverride,
84
82
  } = useSeamlyStateContext().entryMeta
85
- const dispatch = useSeamlyDispatchContext()
83
+ const dispatch = useDispatch()
86
84
 
87
85
  const activeEntry = userSelected || active || defaultEntry
88
86
  const activeEntryOptions =
89
87
  entryOptionsOverride[activeEntry] || entryOptions[activeEntry] || {}
90
88
 
91
- const setBlockAutoEntrySwitch = useCallback(
89
+ const dispatchBlockAutoEntrySwitch = useCallback(
92
90
  (value) => {
93
- dispatch({ type: SET_BLOCK_AUTO_ENTRY_SWITCH, value })
91
+ dispatch(setBlockAutoEntrySwitch(value))
94
92
  },
95
93
  [dispatch],
96
94
  )
97
95
 
98
- const setActiveEntryType = useCallback(
96
+ const dispatchActiveEntryType = useCallback(
99
97
  (entryType) => {
100
- dispatch({ type: SET_ACTIVE_ENTRY_TYPE, entryType })
98
+ dispatch(setActiveEntryType(entryType))
101
99
  },
102
100
  [dispatch],
103
101
  )
104
102
 
105
- const setUserEntryType = useCallback(
103
+ const dispatchUserEntryType = useCallback(
106
104
  (entryType) => {
107
- dispatch({ type: SET_USER_ENTRY_TYPE, entryType })
105
+ dispatch(setUserEntryType(entryType))
108
106
  },
109
107
  [dispatch],
110
108
  )
111
109
 
112
110
  const cancelEntrySelection = useCallback(() => {
113
111
  if (userSelected) {
114
- setUserEntryType(null)
112
+ dispatchUserEntryType(null)
115
113
  } else {
116
- setActiveEntryType(defaultEntry)
114
+ dispatchActiveEntryType(defaultEntry)
117
115
  }
118
- }, [userSelected, defaultEntry, setUserEntryType, setActiveEntryType])
116
+ }, [
117
+ userSelected,
118
+ defaultEntry,
119
+ dispatchUserEntryType,
120
+ dispatchActiveEntryType,
121
+ ])
119
122
 
120
123
  return {
121
124
  activeEntry,
122
125
  activeEntryOptions,
123
- setActiveEntryType,
124
- setUserEntryType,
126
+ setActiveEntryType: dispatchActiveEntryType,
127
+ setUserEntryType: dispatchUserEntryType,
125
128
  cancelEntrySelection,
126
- setBlockAutoEntrySwitch,
129
+ setBlockAutoEntrySwitch: dispatchBlockAutoEntrySwitch,
127
130
  }
128
131
  }