@seamly/web-ui 18.1.1 → 18.3.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 (165) hide show
  1. package/build/dist/lib/index.debug.js +286 -99
  2. package/build/dist/lib/index.debug.min.js +1 -1
  3. package/build/dist/lib/index.debug.min.js.LICENSE.txt +84 -16
  4. package/build/dist/lib/index.js +4104 -3887
  5. package/build/dist/lib/index.min.js +1 -1
  6. package/build/dist/lib/standalone.js +4351 -4084
  7. package/build/dist/lib/standalone.min.js +1 -1
  8. package/build/dist/lib/style-guide.js +746 -641
  9. package/build/dist/lib/style-guide.min.js +1 -1
  10. package/build/dist/lib/styles.css +1 -1
  11. package/build/dist/lib/utils.js +0 -1
  12. package/build/dist/lib/utils.min.js +1 -1
  13. package/build/dist/translations/de-informal.js +0 -1
  14. package/build/dist/translations/de-informal.min.js +1 -1
  15. package/build/dist/translations/en.js +0 -1
  16. package/build/dist/translations/en.min.js +1 -1
  17. package/build/dist/translations/es-informal.js +0 -1
  18. package/build/dist/translations/es-informal.min.js +1 -1
  19. package/build/dist/translations/nl-formal.js +0 -1
  20. package/build/dist/translations/nl-formal.min.js +1 -1
  21. package/build/dist/translations/nl-informal.js +0 -1
  22. package/build/dist/translations/nl-informal.min.js +1 -1
  23. package/package.json +4 -2
  24. package/src/javascripts/api/index.js +9 -9
  25. package/src/javascripts/api/producer.js +8 -8
  26. package/src/javascripts/config.js +9 -11
  27. package/src/javascripts/domains/app/actions.js +25 -0
  28. package/src/javascripts/domains/app/index.js +3 -0
  29. package/src/javascripts/domains/config/actions.js +6 -0
  30. package/src/javascripts/domains/config/hooks.js +6 -0
  31. package/src/javascripts/domains/config/index.js +8 -0
  32. package/src/javascripts/domains/config/middleware.js +26 -0
  33. package/src/javascripts/domains/config/reducer.js +74 -0
  34. package/src/javascripts/domains/config/selectors.js +23 -0
  35. package/src/javascripts/domains/forms/actions.js +1 -1
  36. package/src/javascripts/domains/forms/hooks.js +10 -14
  37. package/src/javascripts/domains/forms/provider.js +4 -6
  38. package/src/javascripts/domains/forms/selectors.js +3 -3
  39. package/src/javascripts/domains/i18n/index.js +9 -5
  40. package/src/javascripts/domains/interrupt/actions.js +6 -0
  41. package/src/javascripts/domains/interrupt/hooks.js +29 -0
  42. package/src/javascripts/domains/interrupt/index.js +9 -0
  43. package/src/javascripts/domains/interrupt/middleware.js +30 -0
  44. package/src/javascripts/domains/interrupt/reducer.js +22 -0
  45. package/src/javascripts/domains/interrupt/selectors.js +5 -0
  46. package/src/javascripts/domains/options/index.js +1 -0
  47. package/src/javascripts/domains/options/middleware.js +35 -0
  48. package/src/javascripts/domains/redux/create-redux-store.js +14 -6
  49. package/src/javascripts/domains/redux/hooks.js +2 -2
  50. package/src/javascripts/domains/redux/index.js +2 -1
  51. package/src/javascripts/domains/redux/provider.js +5 -0
  52. package/src/javascripts/domains/store/index.js +38 -0
  53. package/src/javascripts/{ui → domains}/store/state-reducer.js +4 -7
  54. package/src/javascripts/domains/translations/actions.js +3 -3
  55. package/src/javascripts/domains/translations/components/chat-status.js +6 -12
  56. package/src/javascripts/domains/translations/components/options-button.js +3 -3
  57. package/src/javascripts/domains/translations/components/options-dialog/form.js +2 -2
  58. package/src/javascripts/domains/translations/components/options-dialog/index.js +2 -5
  59. package/src/javascripts/domains/translations/hooks.js +1 -1
  60. package/src/javascripts/domains/translations/reducer.js +2 -2
  61. package/src/javascripts/domains/translations/selectors.js +2 -2
  62. package/src/javascripts/index.js +17 -5
  63. package/src/javascripts/lib/css.js +5 -5
  64. package/src/javascripts/lib/engine/index.js +38 -11
  65. package/src/javascripts/lib/external-api/index.js +6 -6
  66. package/src/javascripts/lib/i18n.js +2 -2
  67. package/src/javascripts/lib/parse-body.js +1 -1
  68. package/src/javascripts/lib/redux-helpers/index.js +18 -4
  69. package/src/javascripts/lib/split-url-params.js +2 -2
  70. package/src/javascripts/lib/store/providers/app-storage.js +1 -1
  71. package/src/javascripts/lib/store/providers/cookie-storage.js +1 -1
  72. package/src/javascripts/package/utils.js +0 -1
  73. package/src/javascripts/style-guide/components/app.js +5 -12
  74. package/src/javascripts/style-guide/components/links.js +6 -6
  75. package/src/javascripts/style-guide/components/static-core.js +23 -7
  76. package/src/javascripts/style-guide/state-helpers/index.js +1 -1
  77. package/src/javascripts/style-guide/states.js +27 -67
  78. package/src/javascripts/style-guide/style-guide-engine.js +1 -1
  79. package/src/javascripts/ui/components/chat-app.js +2 -2
  80. package/src/javascripts/ui/components/conversation/component-filter.js +2 -2
  81. package/src/javascripts/ui/components/conversation/conversation.js +2 -2
  82. package/src/javascripts/ui/components/conversation/event/card-component.js +29 -4
  83. package/src/javascripts/ui/components/conversation/event/carousel-component/components/pagination.js +2 -2
  84. package/src/javascripts/ui/components/conversation/event/carousel-component/index.js +4 -3
  85. package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +2 -1
  86. package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +2 -2
  87. package/src/javascripts/ui/components/conversation/event/choice-prompt.js +11 -6
  88. package/src/javascripts/ui/components/conversation/event/cta.js +1 -6
  89. package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +1 -1
  90. package/src/javascripts/ui/components/conversation/event/event-participant.js +3 -5
  91. package/src/javascripts/ui/components/conversation/event/hooks/use-event-link-click-handler.js +2 -2
  92. package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +3 -3
  93. package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +3 -3
  94. package/src/javascripts/ui/components/conversation/event/participant.js +2 -2
  95. package/src/javascripts/ui/components/conversation/event/upload.js +12 -27
  96. package/src/javascripts/ui/components/conversation/message-container.js +4 -6
  97. package/src/javascripts/ui/components/core/seamly-activity-monitor.js +4 -5
  98. package/src/javascripts/ui/components/core/seamly-core.js +6 -7
  99. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +16 -17
  100. package/src/javascripts/ui/components/core/seamly-file-upload.js +5 -6
  101. package/src/javascripts/ui/components/core/seamly-idle-detach-counter.js +2 -6
  102. package/src/javascripts/ui/components/core/seamly-initializer.js +7 -60
  103. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +10 -10
  104. package/src/javascripts/ui/components/core/seamly-live-region.js +1 -1
  105. package/src/javascripts/ui/components/core/seamly-new-notifications.js +1 -1
  106. package/src/javascripts/ui/components/core/seamly-read-state.js +2 -2
  107. package/src/javascripts/ui/components/entry/entry-container.js +7 -10
  108. package/src/javascripts/ui/components/entry/toggle-button.js +24 -10
  109. package/src/javascripts/ui/components/entry/upload/index.js +4 -11
  110. package/src/javascripts/ui/components/faq/faq.js +4 -4
  111. package/src/javascripts/ui/components/form-controls/error.js +22 -0
  112. package/src/javascripts/ui/components/form-controls/file-input.js +3 -9
  113. package/src/javascripts/ui/components/form-controls/select.js +1 -1
  114. package/src/javascripts/ui/components/form-controls/wrapper.js +2 -9
  115. package/src/javascripts/ui/components/layout/agent-info.js +4 -4
  116. package/src/javascripts/ui/components/layout/app-frame.js +5 -5
  117. package/src/javascripts/ui/components/layout/chat-frame.js +3 -5
  118. package/src/javascripts/ui/components/layout/header.js +4 -18
  119. package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
  120. package/src/javascripts/ui/components/options/cobrowsing.js +3 -7
  121. package/src/javascripts/ui/components/options/options-button.js +9 -13
  122. package/src/javascripts/ui/components/options/options-frame.js +1 -1
  123. package/src/javascripts/ui/components/options/transcript/index.js +2 -2
  124. package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
  125. package/src/javascripts/ui/components/warnings/cobrowsing-active-frame.js +3 -6
  126. package/src/javascripts/ui/components/warnings/idle-detach-warning.js +2 -6
  127. package/src/javascripts/ui/components/widgets/in-out-transition.js +2 -2
  128. package/src/javascripts/ui/components/widgets/lightbox.js +4 -4
  129. package/src/javascripts/ui/components/widgets/modal.js +3 -3
  130. package/src/javascripts/ui/components/widgets/upload-progress.js +2 -13
  131. package/src/javascripts/ui/hooks/component-helper-hooks.js +4 -15
  132. package/src/javascripts/ui/hooks/file-upload-hooks.js +3 -3
  133. package/src/javascripts/ui/hooks/focus-helper-hooks.js +4 -4
  134. package/src/javascripts/ui/hooks/live-region-hooks.js +2 -2
  135. package/src/javascripts/ui/hooks/seamly-entry-hooks.js +7 -6
  136. package/src/javascripts/ui/hooks/seamly-hooks.js +3 -9
  137. package/src/javascripts/ui/hooks/seamly-option-hooks.js +4 -4
  138. package/src/javascripts/ui/hooks/seamly-state-hooks.js +8 -16
  139. package/src/javascripts/ui/hooks/use-event-component-mapping.js +1 -1
  140. package/src/javascripts/ui/hooks/use-seamly-chat.js +1 -0
  141. package/src/javascripts/ui/hooks/use-seamly-commands.js +27 -49
  142. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +3 -3
  143. package/src/javascripts/ui/hooks/use-seamly-stored-visibility.js +3 -3
  144. package/src/javascripts/ui/hooks/use-seamly-visibility.js +3 -3
  145. package/src/javascripts/ui/hooks/utility-hooks.js +2 -2
  146. package/src/javascripts/ui/utils/form-utils.js +3 -3
  147. package/src/javascripts/ui/utils/general-utils.js +17 -11
  148. package/src/javascripts/ui/utils/seamly-utils.js +15 -83
  149. package/src/javascripts/ui/utils/validations.js +10 -7
  150. package/src/stylesheets/5-components/_card.scss +0 -1
  151. package/src/stylesheets/5-components/_choice-prompt.scss +5 -0
  152. package/src/stylesheets/5-components/_message.scss +10 -0
  153. package/src/stylesheets/5-components/_options.scss +3 -2
  154. package/translations/de-informal.js +0 -2
  155. package/translations/en.js +0 -2
  156. package/translations/es-informal.js +0 -2
  157. package/translations/nl-formal.js +0 -2
  158. package/translations/nl-informal.js +0 -2
  159. package/webpack/config.common.js +3 -3
  160. package/webpack/config.package.js +4 -4
  161. package/webpack/config.site.js +8 -6
  162. package/CHANGELOG.md +0 -551
  163. package/src/javascripts/ui/components/core/seamly-api.js +0 -44
  164. package/src/javascripts/ui/hooks/use-seamly-interrupt.js +0 -62
  165. package/src/javascripts/ui/store/index.js +0 -37
@@ -9,7 +9,7 @@ export default function TranscriptForm({ controlName, describedById }) {
9
9
  <Form noValidate="true">
10
10
  <Input
11
11
  name={controlName}
12
- type="text"
12
+ type="email"
13
13
  className={className('transcript__input')}
14
14
  aria-describedby={describedById}
15
15
  labelClass={className('label')}
@@ -1,16 +1,13 @@
1
1
  import { useEffect, useRef } from 'preact/hooks'
2
2
  import CobrowsingActive from './cobrowsing-active'
3
- import {
4
- useLiveRegion,
5
- useSeamlyInterrupt,
6
- useSeamlyOptions,
7
- } from '../../hooks/seamly-hooks'
3
+ import { useLiveRegion, useSeamlyOptions } from '../../hooks/seamly-hooks'
8
4
  import { useI18n } from '../../../domains/i18n'
5
+ import { useInterrupt } from '../../../domains/interrupt'
9
6
 
10
7
  const CobrowsingActiveFrame = () => {
11
8
  const { t } = useI18n()
12
9
  const { userSelectedOptions } = useSeamlyOptions()
13
- const { hasInterrupt } = useSeamlyInterrupt()
10
+ const { hasInterrupt } = useInterrupt()
14
11
  const { cobrowsing } = userSelectedOptions
15
12
  const prevCobrowsing = useRef(cobrowsing)
16
13
  const { sendPolite } = useLiveRegion()
@@ -12,12 +12,8 @@ const IdleDetachWarning = () => {
12
12
  const sendActivity = useSeamlyActivityEventHandler()
13
13
  const { emitEvent } = useSeamlyCommands()
14
14
 
15
- const {
16
- isActive,
17
- remaining,
18
- timer,
19
- endCountdown,
20
- } = useSeamlyIdleDetachCountdown()
15
+ const { isActive, remaining, timer, endCountdown } =
16
+ useSeamlyIdleDetachCountdown()
21
17
 
22
18
  const continueChat = () => {
23
19
  sendActivity()
@@ -99,11 +99,11 @@ const InOutTransition = ({
99
99
 
100
100
  return (
101
101
  renderChildren &&
102
- toChildArray(children).map(child => {
102
+ toChildArray(children).map((child) => {
103
103
  const { className: childClassName = '' } = child.props
104
104
  const cleanClasses = childClassName
105
105
  .split(' ')
106
- .filter(cl => !transitionClassesArray.includes(cl))
106
+ .filter((cl) => !transitionClassesArray.includes(cl))
107
107
 
108
108
  return cloneElement(child, {
109
109
  className: [...cleanClasses, ...activeTransitionClasses].join(' '),
@@ -4,13 +4,13 @@ import { useI18n } from '../../../domains/i18n'
4
4
  import {
5
5
  useSeamlyActivityEventHandler,
6
6
  useSeamlyAppContainerClassNames,
7
- useSeamlyConfig,
8
7
  } from '../../hooks/seamly-hooks'
9
8
  import { className } from '../../../lib/css'
10
9
  import Icon from '../layout/icon'
10
+ import { useConfig } from '../../../domains/config'
11
11
 
12
12
  const Lightbox = ({ url, description, onClose: onCloseHandler }) => {
13
- const { zIndex } = useSeamlyConfig()
13
+ const { zIndex } = useConfig()
14
14
  const onActivityHandler = useSeamlyActivityEventHandler()
15
15
  const appContainerClassNames = useSeamlyAppContainerClassNames()
16
16
  const focusContainer = useRef(null)
@@ -18,7 +18,7 @@ const Lightbox = ({ url, description, onClose: onCloseHandler }) => {
18
18
 
19
19
  const classNames = ['modal', ...appContainerClassNames]
20
20
 
21
- const onFrameClickHandler = e => {
21
+ const onFrameClickHandler = (e) => {
22
22
  e.stopPropagation()
23
23
  }
24
24
 
@@ -28,7 +28,7 @@ const Lightbox = ({ url, description, onClose: onCloseHandler }) => {
28
28
 
29
29
  const style = zIndex ? { zIndex: zIndex + 1 } : undefined
30
30
 
31
- const getModalContent = onClose => (
31
+ const getModalContent = (onClose) => (
32
32
  <div
33
33
  className={className(classNames)}
34
34
  onClick={onFloatClickHandler}
@@ -42,7 +42,7 @@ const Modal = ({
42
42
 
43
43
  useEffect(() => {
44
44
  if (containerIsSet) {
45
- modalContainer.current.addEventListener('keydown', event => {
45
+ modalContainer.current.addEventListener('keydown', (event) => {
46
46
  if ((event.code && event.code === 'Escape') || event.keyCode === 27) {
47
47
  onClose()
48
48
  }
@@ -93,12 +93,12 @@ const Modal = ({
93
93
  return typeof children === 'function'
94
94
  ? children({
95
95
  onClose,
96
- modalRenderFn: els =>
96
+ modalRenderFn: (els) =>
97
97
  modalContainer.current && render(els, modalContainer.current),
98
98
  })
99
99
  : modalContainer.current &&
100
100
  render(
101
- toChildArray(children).map(child => {
101
+ toChildArray(children).map((child) => {
102
102
  child.props = { ...child.props, onClose }
103
103
  return child
104
104
  }),
@@ -1,7 +1,7 @@
1
1
  import { className } from '../../../lib/css'
2
2
  import { useFileUploads } from '../../hooks/seamly-hooks'
3
3
  import { useI18n } from '../../../domains/i18n'
4
- import Icon from '../layout/icon'
4
+ import Error from '../form-controls/error'
5
5
 
6
6
  const UploadProgress = () => {
7
7
  const { t } = useI18n()
@@ -19,18 +19,7 @@ const UploadProgress = () => {
19
19
  className={className('progress__text--percentage')}
20
20
  >{`${progress}%`}</span>
21
21
  </div>
22
- <div
23
- className={className('error')}
24
- aria-live="assertive"
25
- aria-atomic="true"
26
- >
27
- {error && (
28
- <span>
29
- <Icon name="error" size="16" />
30
- {error}
31
- </span>
32
- )}
33
- </div>
22
+ <Error error={error} />
34
23
  <progress
35
24
  className={className('progress__bar')}
36
25
  role="progressbar"
@@ -1,23 +1,12 @@
1
- import { useSeamlyConfig, useSeamlyStateContext } from './seamly-state-hooks'
1
+ import { useSeamlyStateContext } from './seamly-state-hooks'
2
2
  import { useElementFocusingById } from './focus-helper-hooks'
3
+ import { useConfig } from '../../domains/config'
3
4
 
4
5
  export const useSeamlyAppContainerClassNames = () => {
5
- const config = useSeamlyConfig()
6
- const { appContainerClassNames } = config
7
-
8
- if (!appContainerClassNames) {
9
- return []
10
- }
11
-
12
- switch (typeof config.appContainerClassNames) {
13
- case 'function':
14
- return config.appContainerClassNames(config)
15
- default:
16
- return config.appContainerClassNames
17
- }
6
+ return useConfig().appContainerClassNames
18
7
  }
19
8
 
20
- export const useSeamlyMessageContainerClassNames = event => {
9
+ export const useSeamlyMessageContainerClassNames = (event) => {
21
10
  const { fromClient } = event.payload
22
11
  const classNames = ['message']
23
12
 
@@ -52,7 +52,7 @@ export const useFileUploads = () => {
52
52
  const upload = useSeamlyFileUploadContext()
53
53
 
54
54
  const uploadFile = useCallback(
55
- file => {
55
+ (file) => {
56
56
  upload(file)
57
57
  },
58
58
  [upload],
@@ -66,7 +66,7 @@ export const useFileUploads = () => {
66
66
  uploadFile,
67
67
  clearUploads,
68
68
  currentUploads,
69
- isUploading: currentUploads.some(file => file.uploading),
70
- isComplete: currentUploads.every(file => file.complete),
69
+ isUploading: currentUploads.some((file) => file.uploading),
70
+ isComplete: currentUploads.every((file) => file.complete),
71
71
  }
72
72
  }
@@ -9,7 +9,7 @@ import { seamlyActions } from '../utils/seamly-utils'
9
9
 
10
10
  const { SET_SEAMLY_CONTAINER_ELEMENT } = seamlyActions
11
11
 
12
- const focusWithRaf = el => {
12
+ const focusWithRaf = (el) => {
13
13
  requestAnimationFrame(() => {
14
14
  requestAnimationFrame(() => {
15
15
  const focusEl = typeof el === 'string' ? document.getElementById(el) : el
@@ -24,7 +24,7 @@ export const useSeamlyContainerElement = () => {
24
24
  const dispatch = useSeamlyDispatchContext()
25
25
 
26
26
  const setSeamlyContainerElement = useCallback(
27
- element => {
27
+ (element) => {
28
28
  dispatch({ type: SET_SEAMLY_CONTAINER_ELEMENT, element })
29
29
  },
30
30
  [dispatch],
@@ -33,7 +33,7 @@ export const useSeamlyContainerElement = () => {
33
33
  return [seamlyContainerElement, setSeamlyContainerElement]
34
34
  }
35
35
 
36
- export const useElementFocusingById = elementId =>
36
+ export const useElementFocusingById = (elementId) =>
37
37
  useCallback(() => {
38
38
  focusWithRaf(elementId)
39
39
  }, [elementId])
@@ -49,7 +49,7 @@ export const useFocusIfSeamlyContainedFocus = () => {
49
49
 
50
50
  containerElementRef.current = seamlyContainerElement
51
51
 
52
- return useCallback(elementToFocus => {
52
+ return useCallback((elementToFocus) => {
53
53
  const focusFn = () => {
54
54
  focusWithRaf(elementToFocus)
55
55
  }
@@ -8,7 +8,7 @@ export const useSeamlyLiveRegionContext = () =>
8
8
  export const useLiveRegion = () => {
9
9
  const sendMessage = useSeamlyLiveRegionContext()
10
10
  const sendPolite = useCallback(
11
- messageText => {
11
+ (messageText) => {
12
12
  sendMessage({
13
13
  ariaLive: ariaLiveLevels.polite,
14
14
  messageText,
@@ -17,7 +17,7 @@ export const useLiveRegion = () => {
17
17
  [sendMessage],
18
18
  )
19
19
  const sendAssertive = useCallback(
20
- messageText => {
20
+ (messageText) => {
21
21
  sendMessage({
22
22
  ariaLive: ariaLiveLevels.assertive,
23
23
  messageText,
@@ -1,9 +1,10 @@
1
1
  import { useRef, useCallback, useEffect } from 'preact/hooks'
2
2
  import { seamlyActions, actionTypes } from '../utils/seamly-utils'
3
- import { useSeamlyStateContext, useSeamlyConfig } from './seamly-state-hooks'
3
+ import { useSeamlyStateContext } from './seamly-state-hooks'
4
4
  import useSeamlyDispatchContext from './use-seamly-dispatch'
5
5
  import { useSeamlyOptions } from './seamly-option-hooks'
6
6
  import useSeamlyCommands from './use-seamly-commands'
7
+ import { useConfig } from '../../domains/config'
7
8
 
8
9
  const {
9
10
  SET_BLOCK_AUTO_ENTRY_SWITCH,
@@ -13,7 +14,7 @@ const {
13
14
 
14
15
  export const useSeamlyTyping = () => {
15
16
  const { sendAction } = useSeamlyCommands()
16
- const { typing: typingConfig } = useSeamlyConfig()
17
+ const { typing: typingConfig } = useConfig()
17
18
  const { features } = useSeamlyOptions()
18
19
  const { typingPeekahead } = features || {}
19
20
  const typingTimeout = useRef(null)
@@ -43,7 +44,7 @@ export const useSeamlyTyping = () => {
43
44
  })
44
45
  }
45
46
 
46
- return e => {
47
+ return (e) => {
47
48
  if ((e.code && e.code === 'Enter') || e.keyCode === 13) {
48
49
  return
49
50
  }
@@ -91,21 +92,21 @@ export const useSeamlyEntry = () => {
91
92
  const activeEntryOptions = entryOptions[activeEntry] || {}
92
93
 
93
94
  const setBlockAutoEntrySwitch = useCallback(
94
- value => {
95
+ (value) => {
95
96
  dispatch({ type: SET_BLOCK_AUTO_ENTRY_SWITCH, value })
96
97
  },
97
98
  [dispatch],
98
99
  )
99
100
 
100
101
  const setActiveEntryType = useCallback(
101
- entryType => {
102
+ (entryType) => {
102
103
  dispatch({ type: SET_ACTIVE_ENTRY_TYPE, entryType })
103
104
  },
104
105
  [dispatch],
105
106
  )
106
107
 
107
108
  const setUserEntryType = useCallback(
108
- entryType => {
109
+ (entryType) => {
109
110
  dispatch({ type: SET_USER_ENTRY_TYPE, entryType })
110
111
  },
111
112
  [dispatch],
@@ -9,8 +9,6 @@ export {
9
9
  useLastMessageEventId,
10
10
  useEntryTextLimit,
11
11
  useSeamlyCurrentAgent,
12
- useSeamlyConfig,
13
- useSeamlyDisclaimerState,
14
12
  useEvents,
15
13
  useSeamlyHeaderData,
16
14
  useSeamlyIsHistoryLoaded,
@@ -35,7 +33,6 @@ export {
35
33
  useCobrowsingContainer,
36
34
  } from './component-helper-hooks'
37
35
  export { useSeamlyOptions, useOptionButton } from './seamly-option-hooks'
38
- export { default as useSeamlyInterrupt } from './use-seamly-interrupt'
39
36
  export { useFileUploadMeta, useFileUploads } from './file-upload-hooks'
40
37
  export { default as useSeamlyCommands } from './use-seamly-commands'
41
38
  export { useLiveRegion, useSeamlyLiveRegionContext } from './live-region-hooks'
@@ -68,12 +65,9 @@ export const useSeamlyEventStream = (nextFn, filterFn) => {
68
65
  useEffect(() => {
69
66
  if (api.stream) {
70
67
  if (filterFn) {
71
- api
72
- .stream()
73
- .filter(filterFn)
74
- .subscribe({
75
- next: nextFn,
76
- })
68
+ api.stream().filter(filterFn).subscribe({
69
+ next: nextFn,
70
+ })
77
71
  } else {
78
72
  api.stream().subscribe({
79
73
  next: nextFn,
@@ -24,10 +24,10 @@ export const useSeamlyOptions = () => {
24
24
  const optionsObj = { cobrowsing, sendTranscript }
25
25
 
26
26
  const menuOptions = Object.keys(optionsObj)
27
- .filter(key => {
27
+ .filter((key) => {
28
28
  return optionsObj[key]
29
29
  })
30
- .map(option => ({
30
+ .map((option) => ({
31
31
  name: option,
32
32
  title: t(`options.${option}.menuTitle`),
33
33
  available: optionsObj[option].enabled,
@@ -44,7 +44,7 @@ export const useSeamlyOptions = () => {
44
44
  }, [get, dispatch])
45
45
 
46
46
  const setUserSelectedOptions = useCallback(
47
- optionValues => {
47
+ (optionValues) => {
48
48
  dispatch({ type: SET_USER_SELECTED_OPTIONS, options: optionValues })
49
49
  set('options', optionValues)
50
50
  },
@@ -63,7 +63,7 @@ export const useSeamlyOptions = () => {
63
63
  [dispatch, get, set],
64
64
  )
65
65
 
66
- const showOption = optionName => {
66
+ const showOption = (optionName) => {
67
67
  dispatch({ type: SHOW_OPTION, optionName })
68
68
  }
69
69
 
@@ -1,19 +1,14 @@
1
1
  import { createSelector } from 'reselect'
2
2
  import { useSelector } from '../../domains/redux'
3
3
  import { microsecondsToMilliseconds } from '../utils/general-utils'
4
+ import { Selectors as ConfigSelectors, useConfig } from '../../domains/config'
4
5
 
5
- export const selectState = state => state.state
6
+ export const selectState = (state) => state.state
6
7
  export const useSeamlyStateContext = () => useSelector(selectState)
7
8
 
8
- export const selectConfig = createSelector(
9
- selectState,
10
- ({ config }) => config || {},
11
- )
12
- export const useSeamlyConfig = () => useSelector(selectConfig)
13
-
14
9
  export const selectEvents = createSelector(
15
10
  selectState,
16
- selectConfig,
11
+ ConfigSelectors.selectConfig,
17
12
  ({ events }, config) => {
18
13
  const { enabled, threshold } = config?.messages?.timeIndicator ?? {}
19
14
  if (!enabled) {
@@ -53,13 +48,13 @@ export const useSeamlyUnreadCount = () => useSeamlyStateContext().unreadEvents
53
48
 
54
49
  export const useSkiplink = () => useSeamlyStateContext().skiplinkTargetId
55
50
 
56
- export const useSeamlyParticipant = participantId =>
51
+ export const useSeamlyParticipant = (participantId) =>
57
52
  useSeamlyStateContext().participantInfo.participants[participantId]
58
53
 
59
54
  export const useSeamlyServiceInfo = () => useSeamlyStateContext().serviceInfo
60
55
 
61
- const selectLastMessageEventId = createSelector(selectEvents, events => {
62
- const filteredEvents = events.filter(event => event.type === 'message')
56
+ const selectLastMessageEventId = createSelector(selectEvents, (events) => {
57
+ const filteredEvents = events.filter((event) => event.type === 'message')
63
58
  return filteredEvents[filteredEvents.length - 1]?.payload.id
64
59
  })
65
60
  export const useLastMessageEventId = () => useSelector(selectLastMessageEventId)
@@ -67,16 +62,13 @@ export const useLastMessageEventId = () => useSelector(selectLastMessageEventId)
67
62
  export const useSeamlyIsHistoryLoaded = () =>
68
63
  useSeamlyStateContext().historyLoaded
69
64
 
70
- export const useSeamlyDisclaimerState = () =>
71
- useSeamlyStateContext().showDisclaimer
72
-
73
65
  export const useSeamlyCurrentAgent = () => {
74
66
  const { participants, currentAgent } = useSeamlyStateContext().participantInfo
75
67
 
76
68
  return currentAgent ? participants[currentAgent] : null
77
69
  }
78
70
 
79
- export const useSeamlyServiceData = key =>
71
+ export const useSeamlyServiceData = (key) =>
80
72
  useSeamlyStateContext().serviceData[key]
81
73
 
82
74
  export const useEntryTextLimit = () => {
@@ -95,7 +87,7 @@ export const useEntryTextLimit = () => {
95
87
  }
96
88
 
97
89
  export const useSeamlyLayoutMode = () => {
98
- const { layoutMode } = useSeamlyConfig()
90
+ const { layoutMode } = useConfig()
99
91
 
100
92
  return {
101
93
  isInline: layoutMode === 'inline',
@@ -2,7 +2,7 @@ import { useContext } from 'preact/hooks'
2
2
  import ComponentContext from '../components/conversation/component-context'
3
3
  import { payloadTypes } from '../utils/seamly-utils'
4
4
 
5
- const useEventComponentMapping = event => {
5
+ const useEventComponentMapping = (event) => {
6
6
  const components = useContext(ComponentContext)
7
7
 
8
8
  let SubComponent = null
@@ -88,6 +88,7 @@ const useSeamlyChat = () => {
88
88
  // they had been connected before.
89
89
  // We also keep track of whether connect was called before to avoid
90
90
  // multiple in-flight connection processes.
91
+
91
92
  if (
92
93
  (!isOpen && !hasConversation) ||
93
94
  connectCalled.current ||
@@ -10,17 +10,17 @@ import {
10
10
  } from './seamly-state-hooks'
11
11
  import useSeamlyDispatchContext from './use-seamly-dispatch'
12
12
  import { SeamlyEventBusContext } from '../components/core/seamly-api-context'
13
- import useSeamlyInterrupt from './use-seamly-interrupt'
14
13
  import { randomId } from '../../lib/id'
15
14
  import { userParticipantId } from '../../config'
16
15
  import { sanitizeText } from '../utils/general-utils'
17
16
  import { actionTypes, seamlyActions } from '../utils/seamly-utils'
18
17
  import { useStableCallback } from './utility-hooks'
18
+ import { Actions as InterruptActions } from '../../domains/interrupt'
19
+ import { useConfig } from '../../domains/config'
19
20
 
20
21
  const {
21
22
  ADD_EVENT,
22
23
  CLEAR_EVENTS,
23
- CLEAR_INTERRUPT,
24
24
  SET_IS_LOADING,
25
25
  CLEAR_PARTICIPANTS,
26
26
  SET_HEADER_SUB_TITLE,
@@ -33,18 +33,15 @@ const {
33
33
 
34
34
  const useSeamlyCommands = () => {
35
35
  const api = useSeamlyApiContext()
36
- const seamlyState = useSeamlyStateContext()
36
+ const appConfig = useConfig()
37
37
  const dispatch = useSeamlyDispatchContext()
38
38
  const eventBus = useContext(SeamlyEventBusContext)
39
- const { setInterrupt } = useSeamlyInterrupt()
40
39
 
41
40
  const hasResponded = useSeamlyHasUserResponded()
42
41
  const hasConversation = useSeamlyHasConversation()
43
42
  const { visible: visibility } = useSeamlyStateContext()
44
43
  const unreadMessageCount = useSeamlyUnreadCount()
45
44
 
46
- const { config: appConfig } = seamlyState
47
-
48
45
  const emitEvent = useCallback(
49
46
  (...args) => {
50
47
  eventBus.emit(...args)
@@ -79,7 +76,7 @@ const useSeamlyCommands = () => {
79
76
 
80
77
  const reset = useCallback(async () => {
81
78
  dispatch({ type: CLEAR_EVENTS })
82
- dispatch({ type: CLEAR_INTERRUPT })
79
+ dispatch(InterruptActions.clear())
83
80
  dispatch({
84
81
  type: SET_IS_LOADING,
85
82
  isLoading: true,
@@ -105,35 +102,25 @@ const useSeamlyCommands = () => {
105
102
  dispatch({ type: SET_FEATURES, features })
106
103
  dispatch({ type: SET_INITIAL_STATE, initialState })
107
104
  } catch (error) {
108
- setInterrupt(error)
105
+ dispatch(InterruptActions.set(error))
109
106
  }
110
- }, [api, dispatch, appConfig, setInterrupt])
107
+ }, [api, dispatch, appConfig])
111
108
 
112
109
  const getMessageBase = useCallback(
113
- type => {
114
- const { events } = seamlyState
115
-
116
- return {
117
- type,
118
- id: randomId(),
119
- transactionId: randomId(),
120
- participant: userParticipantId,
121
- fromClient: true,
122
- // We add a timestamp of 1 greater than the previous timestamp in the
123
- // events array to ensure proper sorting should a history fetch be done
124
- // prior to receipt of the related ACK.
125
- occurredAt:
126
- events.length > 0
127
- ? events[events.length - 1].payload.occurredAt + 1
128
- : Date.now(),
129
- meta: {},
130
- }
131
- },
132
- [seamlyState],
110
+ (type) => ({
111
+ type,
112
+ id: randomId(),
113
+ transactionId: randomId(),
114
+ participant: userParticipantId,
115
+ fromClient: true,
116
+ occurredAt: Date.now() * 1000,
117
+ meta: {},
118
+ }),
119
+ [],
133
120
  )
134
121
 
135
122
  const getTextMessageBase = useCallback(
136
- bodyText => {
123
+ (bodyText) => {
137
124
  const base = getMessageBase('text')
138
125
 
139
126
  return {
@@ -177,7 +164,7 @@ const useSeamlyCommands = () => {
177
164
  )
178
165
 
179
166
  const addMessageBubble = useCallback(
180
- text => {
167
+ (text) => {
181
168
  dispatch({
182
169
  type: ADD_EVENT,
183
170
  event: { type: 'message', payload: getTextMessageBase(text) },
@@ -187,16 +174,7 @@ const useSeamlyCommands = () => {
187
174
  )
188
175
 
189
176
  const addUploadBubble = useCallback(
190
- (
191
- id,
192
- transactionId,
193
- occurredAt,
194
- contentType,
195
- deleteAt,
196
- filename,
197
- filesize,
198
- url,
199
- ) => {
177
+ (id, transactionId, occurredAt, contentType, filename, filesize, url) => {
200
178
  dispatch({
201
179
  type: ADD_EVENT,
202
180
  event: {
@@ -209,7 +187,7 @@ const useSeamlyCommands = () => {
209
187
  fromClient: true,
210
188
  occurredAt,
211
189
  meta: {},
212
- body: { contentType, deleteAt, filename, filesize, url },
190
+ body: { contentType, filename, filesize, url },
213
191
  },
214
192
  },
215
193
  })
@@ -218,7 +196,7 @@ const useSeamlyCommands = () => {
218
196
  )
219
197
 
220
198
  const addDivider = useCallback(
221
- subtype => {
199
+ (subtype) => {
222
200
  const payload = {
223
201
  body: { subtype, type: 'divider' },
224
202
  fromClient: false,
@@ -253,7 +231,7 @@ const useSeamlyCommands = () => {
253
231
  )
254
232
 
255
233
  const sendAction = useCallback(
256
- body => {
234
+ (body) => {
257
235
  if (!body) {
258
236
  return
259
237
  }
@@ -269,7 +247,7 @@ const useSeamlyCommands = () => {
269
247
  )
270
248
 
271
249
  const sendContext = useCallback(
272
- context => {
250
+ (context) => {
273
251
  api.sendContext(context)
274
252
  },
275
253
  [api],
@@ -282,15 +260,15 @@ const useSeamlyCommands = () => {
282
260
 
283
261
  return api
284
262
  .connect()
285
- .then(initialState => {
263
+ .then((initialState) => {
286
264
  if (initialState) {
287
265
  dispatch({ type: SET_INITIAL_STATE, initialState })
288
266
  }
289
267
  })
290
- .catch(error => {
291
- setInterrupt(error)
268
+ .catch((error) => {
269
+ dispatch(InterruptActions.set(error))
292
270
  })
293
- }, [api, dispatch, setInterrupt])
271
+ }, [api, dispatch])
294
272
 
295
273
  return {
296
274
  connect,
@@ -41,7 +41,7 @@ const useSeamlyIdleDetachCountdown = () => {
41
41
  const { sendAssertive, sendPolite } = useLiveRegion()
42
42
 
43
43
  const sendAssertiveIfOpen = useCallback(
44
- text => {
44
+ (text) => {
45
45
  const { isOpen } = stableState.current
46
46
  if (isOpen) {
47
47
  sendAssertive(text)
@@ -51,7 +51,7 @@ const useSeamlyIdleDetachCountdown = () => {
51
51
  )
52
52
 
53
53
  const sendPoliteIfOpen = useCallback(
54
- text => {
54
+ (text) => {
55
55
  const { isOpen } = stableState.current
56
56
  if (isOpen) {
57
57
  sendPolite(text)
@@ -61,7 +61,7 @@ const useSeamlyIdleDetachCountdown = () => {
61
61
  )
62
62
 
63
63
  const initCountdown = useCallback(
64
- milliseconds => {
64
+ (milliseconds) => {
65
65
  const delaySeconds = millisecondsToSeconds(milliseconds)
66
66
  const delayTime = getTimeFromSeconds(delaySeconds)
67
67