@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.
- package/build/dist/lib/hooks.js +1 -1
- package/build/dist/lib/hooks.min.js +1 -1
- package/build/dist/lib/index.debug.js +945 -790
- package/build/dist/lib/index.debug.min.js +1 -1
- package/build/dist/lib/index.debug.min.js.LICENSE.txt +187 -131
- package/build/dist/lib/index.js +24800 -19606
- package/build/dist/lib/index.min.js +1 -1
- package/build/dist/lib/index.min.js.LICENSE.txt +38 -4
- package/build/dist/lib/standalone.js +32920 -26742
- package/build/dist/lib/standalone.min.js +1 -1
- package/build/dist/lib/standalone.min.js.LICENSE.txt +39 -0
- package/build/dist/lib/storage.js +2 -2
- package/build/dist/lib/storage.min.js +1 -1
- package/build/dist/lib/style-guide.js +8780 -7907
- package/build/dist/lib/style-guide.min.js +2 -1
- package/build/dist/lib/style-guide.min.js.LICENSE.txt +38 -0
- package/build/dist/lib/styles.css +1 -1
- package/build/dist/lib/utils.js +1 -2
- package/build/dist/lib/utils.min.js +1 -1
- package/package.json +19 -9
- package/src/icons/avatar_agent-32.svg +7 -0
- package/src/icons/avatar_bot-32.svg +6 -1
- package/src/javascripts/api/index.js +1 -1
- package/src/javascripts/{config.js → config.ts} +3 -1
- package/src/javascripts/config.types.ts +96 -0
- package/src/javascripts/domains/app/actions.ts +83 -0
- package/src/javascripts/domains/app/app.types.ts +3 -0
- package/src/javascripts/domains/app/hooks.js +3 -5
- package/src/javascripts/domains/app/selectors.ts +6 -0
- package/src/javascripts/domains/app/slice.ts +30 -0
- package/src/javascripts/domains/config/actions.ts +45 -0
- package/src/javascripts/domains/config/hooks.ts +19 -0
- package/src/javascripts/domains/config/selectors.ts +24 -0
- package/src/javascripts/domains/config/slice.ts +113 -0
- package/src/javascripts/domains/errors/index.js +13 -9
- package/src/javascripts/domains/forms/context.ts +14 -0
- package/src/javascripts/domains/forms/forms.types.ts +24 -0
- package/src/javascripts/domains/forms/{hooks.js → hooks.ts} +23 -26
- package/src/javascripts/domains/forms/{provider.js → provider.tsx} +20 -14
- package/src/javascripts/domains/forms/{selectors.js → selectors.ts} +7 -8
- package/src/javascripts/domains/forms/slice.ts +84 -0
- package/src/javascripts/domains/forms/utils.ts +15 -0
- package/src/javascripts/domains/i18n/actions.ts +24 -0
- package/src/javascripts/domains/i18n/{hooks.js → hooks.ts} +2 -2
- package/src/javascripts/domains/i18n/i18n.types.ts +6 -0
- package/src/javascripts/domains/i18n/selectors.ts +16 -0
- package/src/javascripts/domains/i18n/{reducer.js → slice.ts} +40 -37
- package/src/javascripts/domains/interrupt/{hooks.js → hooks.ts} +2 -2
- package/src/javascripts/domains/interrupt/{middleware.js → middleware.ts} +11 -8
- package/src/javascripts/domains/interrupt/selectors.ts +6 -0
- package/src/javascripts/domains/interrupt/slice.ts +40 -0
- package/src/javascripts/domains/options/middleware.js +9 -6
- package/src/javascripts/domains/redux/redux.types.ts +11 -0
- package/src/javascripts/domains/store/index.ts +53 -0
- package/src/javascripts/domains/store/slice.ts +642 -0
- package/src/javascripts/domains/store/store.types.ts +146 -0
- package/src/javascripts/domains/translations/components/chat-status.js +2 -2
- package/src/javascripts/domains/translations/components/options-button.js +1 -1
- package/src/javascripts/domains/translations/components/options-dialog/form.js +5 -5
- package/src/javascripts/domains/translations/components/options-dialog/index.js +2 -2
- package/src/javascripts/domains/translations/hooks.ts +114 -0
- package/src/javascripts/domains/translations/middleware.js +29 -27
- package/src/javascripts/domains/translations/selectors.ts +12 -0
- package/src/javascripts/domains/translations/slice.ts +120 -0
- package/src/javascripts/domains/translations/translations.types.ts +19 -0
- package/src/javascripts/domains/visibility/{actions.js → actions.ts} +25 -19
- package/src/javascripts/domains/visibility/{hooks.js → hooks.ts} +13 -10
- package/src/javascripts/domains/visibility/{selectors.js → selectors.ts} +3 -6
- package/src/javascripts/domains/visibility/slice.ts +38 -0
- package/src/javascripts/domains/visibility/utils.js +0 -9
- package/src/javascripts/domains/visibility/visibility.types.ts +6 -0
- package/src/javascripts/index.ts +92 -0
- package/src/javascripts/lib/engine/index.js +15 -11
- package/src/javascripts/lib/external-api/initialize-api.js +1 -1
- package/src/javascripts/lib/id.js +5 -8
- package/src/javascripts/lib/mutex.js +3 -1
- package/src/javascripts/lib/store/providers/cookie-storage.js +1 -1
- package/src/javascripts/lib/store/providers/session-storage.js +1 -1
- package/src/javascripts/package/hooks.js +2 -2
- package/src/javascripts/package/utils.js +0 -1
- package/src/javascripts/schema.ts +1448 -0
- package/src/javascripts/style-guide/components/app.js +6 -6
- package/src/javascripts/style-guide/components/static-core.js +87 -65
- package/src/javascripts/style-guide/components/view.js +4 -4
- package/src/javascripts/style-guide/state-helpers/index.js +5 -5
- package/src/javascripts/style-guide/states.js +67 -7
- package/src/javascripts/style-guide.ts +5 -0
- package/src/javascripts/ui/components/app-options/index.js +2 -4
- package/src/javascripts/ui/components/conversation/component-filter.js +1 -1
- package/src/javascripts/ui/components/conversation/conversation.js +11 -7
- package/src/javascripts/ui/components/conversation/event/card-message.js +2 -2
- package/src/javascripts/ui/components/conversation/event/carousel-component/components/controls.js +1 -1
- package/src/javascripts/ui/components/conversation/event/carousel-message/components/slide.js +1 -1
- package/src/javascripts/ui/components/conversation/event/carousel-message/index.js +2 -2
- package/src/javascripts/ui/components/conversation/event/choice-prompt.js +3 -3
- package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +19 -15
- package/src/javascripts/ui/components/conversation/event/cta.js +2 -2
- package/src/javascripts/ui/components/conversation/event/divider/variants/default.js +1 -1
- package/src/javascripts/ui/components/conversation/event/divider/variants/new-translation.js +44 -5
- package/src/javascripts/ui/components/conversation/event/event-participant.js +2 -2
- package/src/javascripts/ui/components/conversation/event/hooks/use-formatted-date.js +2 -2
- package/src/javascripts/ui/components/conversation/event/image-lightbox.js +1 -1
- package/src/javascripts/ui/components/conversation/event/image.js +6 -8
- package/src/javascripts/ui/components/conversation/event/participant.js +2 -2
- package/src/javascripts/ui/components/conversation/event/splash.js +4 -4
- package/src/javascripts/ui/components/conversation/event/text.js +2 -2
- package/src/javascripts/ui/components/conversation/event/translation.js +3 -3
- package/src/javascripts/ui/components/conversation/event/upload.js +3 -3
- package/src/javascripts/ui/components/conversation/event/video.js +2 -2
- package/src/javascripts/ui/components/conversation/message-container.js +4 -26
- package/src/javascripts/ui/components/core/seamly-api-context.js +1 -1
- package/src/javascripts/ui/components/core/seamly-core.js +15 -14
- package/src/javascripts/ui/components/core/seamly-event-subscriber.js +98 -92
- package/src/javascripts/ui/components/core/seamly-file-upload.js +20 -24
- package/src/javascripts/ui/components/core/seamly-initializer.js +1 -1
- package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +5 -4
- package/src/javascripts/ui/components/core/seamly-new-notifications.js +2 -2
- package/src/javascripts/ui/components/core/seamly-read-state.js +10 -17
- package/src/javascripts/ui/components/entry/deprecated-toggle-button.js +3 -3
- package/src/javascripts/ui/components/entry/entry-container.js +4 -6
- package/src/javascripts/ui/components/entry/text-entry/hooks.js +3 -3
- package/src/javascripts/ui/components/entry/text-entry/index.js +3 -2
- package/src/javascripts/ui/components/entry/text-entry/text-entry-form.js +6 -10
- package/src/javascripts/ui/components/entry/upload/file-upload-form.js +2 -2
- package/src/javascripts/ui/components/entry/upload/index.js +10 -9
- package/src/javascripts/ui/components/entry/upload-toggle.js +2 -2
- package/src/javascripts/ui/components/faq/faq.js +9 -7
- package/src/javascripts/ui/components/form-controls/file-input.js +1 -1
- package/src/javascripts/ui/components/form-controls/form.js +1 -1
- package/src/javascripts/ui/components/form-controls/input.js +1 -1
- package/src/javascripts/ui/components/form-controls/select.js +1 -1
- package/src/javascripts/ui/components/layout/agent-info.js +4 -4
- package/src/javascripts/ui/components/layout/chat-frame.js +3 -3
- package/src/javascripts/ui/components/layout/chat.js +11 -12
- package/src/javascripts/ui/components/layout/deprecated-app-frame.js +10 -9
- package/src/javascripts/ui/components/layout/header.js +1 -1
- package/src/javascripts/ui/components/layout/interrupt.js +23 -24
- package/src/javascripts/ui/components/layout/pre-chat-messages.js +11 -11
- package/src/javascripts/ui/components/layout/privacy-disclaimer.js +2 -2
- package/src/javascripts/ui/components/options/options-button.js +14 -10
- package/src/javascripts/ui/components/options/transcript/index.js +2 -2
- package/src/javascripts/ui/components/options/transcript/transcript-form.js +1 -1
- package/src/javascripts/ui/components/suggestions/index.js +14 -10
- package/src/javascripts/ui/components/view/deprecated-view.js +19 -16
- package/src/javascripts/ui/components/view/index.js +12 -12
- package/src/javascripts/ui/components/view/inline-view.js +2 -2
- package/src/javascripts/ui/components/view/window-view/collapse-button.js +3 -3
- package/src/javascripts/ui/components/view/window-view/index.js +13 -13
- package/src/javascripts/ui/components/view/window-view/window-open-button.js +13 -13
- package/src/javascripts/ui/components/warnings/idle-detach-warning.js +1 -1
- package/src/javascripts/ui/components/warnings/resume-conversation-prompt.js +1 -1
- package/src/javascripts/ui/components/widgets/lightbox.js +2 -2
- package/src/javascripts/ui/components/widgets/upload-progress.js +1 -1
- package/src/javascripts/ui/hooks/component-helper-hooks.js +1 -1
- package/src/javascripts/ui/hooks/file-upload-hooks.js +4 -6
- package/src/javascripts/ui/hooks/focus-helper-hooks.js +14 -12
- package/src/javascripts/ui/hooks/live-region-hooks.js +2 -0
- package/src/javascripts/ui/hooks/seamly-api-hooks.js +8 -3
- package/src/javascripts/ui/hooks/seamly-entry-hooks.js +28 -25
- package/src/javascripts/ui/hooks/seamly-hooks.js +25 -25
- package/src/javascripts/ui/hooks/seamly-option-hooks.js +17 -19
- package/src/javascripts/ui/hooks/seamly-state-hooks.js +20 -13
- package/src/javascripts/ui/hooks/use-seamly-chat.js +15 -25
- package/src/javascripts/ui/hooks/use-seamly-commands.js +46 -46
- package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +22 -24
- package/src/javascripts/ui/hooks/use-seamly-resume-conversation-prompt.js +8 -9
- package/src/javascripts/ui/hooks/use-single-file-upload.js +4 -6
- package/src/javascripts/ui/hooks/utility-hooks.js +4 -4
- package/src/javascripts/ui/utils/form-utils.js +0 -145
- package/src/javascripts/ui/utils/general-utils.js +3 -4
- package/src/javascripts/ui/utils/seamly-utils.ts +73 -0
- package/src/stylesheets/5-components/_message-carousel.scss +10 -8
- package/webpack/config.common.js +16 -0
- package/webpack/config.dev.js +1 -0
- package/webpack/config.package.js +26 -5
- package/webpack/defaults.js +7 -2
- package/webpack/parts/babel-loader-browser-plugins.js +1 -0
- package/webpack/parts/dev-server.js +4 -3
- package/CHANGELOG.md +0 -791
- package/src/javascripts/domains/app/actions.js +0 -112
- package/src/javascripts/domains/app/index.js +0 -7
- package/src/javascripts/domains/app/reducer.js +0 -16
- package/src/javascripts/domains/app/selectors.js +0 -8
- package/src/javascripts/domains/app/utils.js +0 -4
- package/src/javascripts/domains/config/actions.js +0 -7
- package/src/javascripts/domains/config/hooks.js +0 -23
- package/src/javascripts/domains/config/index.js +0 -7
- package/src/javascripts/domains/config/reducer.js +0 -79
- package/src/javascripts/domains/config/selectors.js +0 -23
- package/src/javascripts/domains/config/utils.js +0 -4
- package/src/javascripts/domains/forms/actions.js +0 -21
- package/src/javascripts/domains/forms/context.js +0 -6
- package/src/javascripts/domains/forms/index.js +0 -8
- package/src/javascripts/domains/forms/reducer.js +0 -84
- package/src/javascripts/domains/forms/utils.js +0 -20
- package/src/javascripts/domains/i18n/actions.js +0 -20
- package/src/javascripts/domains/i18n/index.js +0 -7
- package/src/javascripts/domains/i18n/selectors.js +0 -15
- package/src/javascripts/domains/i18n/utils.js +0 -4
- package/src/javascripts/domains/interrupt/actions.js +0 -4
- package/src/javascripts/domains/interrupt/index.js +0 -9
- package/src/javascripts/domains/interrupt/reducer.js +0 -22
- package/src/javascripts/domains/interrupt/selectors.js +0 -6
- package/src/javascripts/domains/interrupt/utils.js +0 -4
- package/src/javascripts/domains/options/index.js +0 -1
- package/src/javascripts/domains/redux/context.js +0 -6
- package/src/javascripts/domains/redux/create-redux-store.js +0 -21
- package/src/javascripts/domains/redux/hooks.js +0 -80
- package/src/javascripts/domains/redux/index.js +0 -19
- package/src/javascripts/domains/redux/provider.js +0 -5
- package/src/javascripts/domains/redux/utils.js +0 -12
- package/src/javascripts/domains/store/index.js +0 -46
- package/src/javascripts/domains/store/state-reducer.js +0 -56
- package/src/javascripts/domains/translations/actions.js +0 -11
- package/src/javascripts/domains/translations/hooks.js +0 -103
- package/src/javascripts/domains/translations/index.js +0 -10
- package/src/javascripts/domains/translations/reducer.js +0 -69
- package/src/javascripts/domains/translations/selectors.js +0 -16
- package/src/javascripts/domains/translations/utils.js +0 -4
- package/src/javascripts/domains/visibility/index.js +0 -8
- package/src/javascripts/domains/visibility/reducer.js +0 -24
- package/src/javascripts/index.js +0 -153
- package/src/javascripts/lib/redux-helpers/index.js +0 -99
- package/src/javascripts/style-guide.js +0 -5
- package/src/javascripts/ui/hooks/use-seamly-dispatch.js +0 -3
- package/src/javascripts/ui/utils/seamly-utils.js +0 -832
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useEffect } from 'preact/hooks'
|
|
2
|
+
import { useDispatch } from 'react-redux'
|
|
2
3
|
|
|
3
4
|
// Import extracted hooks here for use inside this file
|
|
4
5
|
import { useSeamlyApiContext } from './seamly-api-hooks'
|
|
@@ -6,10 +7,27 @@ import { useSeamlyApiContext } from './seamly-api-hooks'
|
|
|
6
7
|
// although this is a redundant, it prevents a bazillion code changes for now.
|
|
7
8
|
// TODO: Remove exports and import them from the correct files
|
|
8
9
|
export {
|
|
9
|
-
|
|
10
|
+
useElementFocusingById,
|
|
11
|
+
useFocusIfSeamlyContainedFocus,
|
|
12
|
+
useSeamlyContainerElement,
|
|
13
|
+
useSkiplinkTargetFocusing,
|
|
14
|
+
} from 'ui/hooks/focus-helper-hooks'
|
|
15
|
+
export {
|
|
16
|
+
useSeamlyAppContainerClassNames,
|
|
17
|
+
useSeamlyMessageContainerClassNames,
|
|
18
|
+
} from './component-helper-hooks'
|
|
19
|
+
export { useFileUploadMeta, useFileUploads } from './file-upload-hooks'
|
|
20
|
+
export { useLiveRegion, useSeamlyLiveRegionContext } from './live-region-hooks'
|
|
21
|
+
export {
|
|
22
|
+
useSeamlyApiContext,
|
|
23
|
+
useSeamlyConversationUrl,
|
|
24
|
+
} from './seamly-api-hooks'
|
|
25
|
+
export { useOptionButton, useSeamlyOptions } from './seamly-option-hooks'
|
|
26
|
+
export {
|
|
10
27
|
useEntryTextLimit,
|
|
11
|
-
useSeamlyCurrentAgent,
|
|
12
28
|
useEvents,
|
|
29
|
+
useLastMessageEventId,
|
|
30
|
+
useSeamlyCurrentAgent,
|
|
13
31
|
useSeamlyHeaderData,
|
|
14
32
|
useSeamlyIsHistoryLoaded,
|
|
15
33
|
useSeamlyIsLoading,
|
|
@@ -21,35 +39,17 @@ export {
|
|
|
21
39
|
useSeamlyUnreadCount,
|
|
22
40
|
useSkiplink,
|
|
23
41
|
} from './seamly-state-hooks'
|
|
24
|
-
export {
|
|
25
|
-
useSeamlyApiContext,
|
|
26
|
-
useSeamlyConversationUrl,
|
|
27
|
-
} from './seamly-api-hooks'
|
|
28
|
-
export { default as useSeamlyDispatchContext } from './use-seamly-dispatch'
|
|
29
|
-
export {
|
|
30
|
-
useSeamlyAppContainerClassNames,
|
|
31
|
-
useSeamlyMessageContainerClassNames,
|
|
32
|
-
} from './component-helper-hooks'
|
|
33
|
-
export { useSeamlyOptions, useOptionButton } from './seamly-option-hooks'
|
|
34
|
-
export { useFileUploadMeta, useFileUploads } from './file-upload-hooks'
|
|
35
|
-
export { default as useSeamlyCommands } from './use-seamly-commands'
|
|
36
|
-
export { useLiveRegion, useSeamlyLiveRegionContext } from './live-region-hooks'
|
|
37
42
|
export { default as useSeamlyActivityEventHandler } from './use-seamly-activity-event-handler'
|
|
38
|
-
export {
|
|
43
|
+
export { default as useSeamlyChat } from './use-seamly-chat'
|
|
44
|
+
export { default as useSeamlyCommands } from './use-seamly-commands'
|
|
45
|
+
export { default as useSeamlyIdleDetachCountdown } from './use-seamly-idle-detach-countdown'
|
|
46
|
+
export { default as useSeamlyResumeConversationPrompt } from './use-seamly-resume-conversation-prompt'
|
|
39
47
|
export {
|
|
40
48
|
useForceUpdate,
|
|
41
49
|
useGeneratedId,
|
|
42
50
|
useStableCallback,
|
|
43
51
|
} from './utility-hooks'
|
|
44
|
-
export {
|
|
45
|
-
useElementFocusingById,
|
|
46
|
-
useSkiplinkTargetFocusing,
|
|
47
|
-
useFocusIfSeamlyContainedFocus,
|
|
48
|
-
useSeamlyContainerElement,
|
|
49
|
-
} from './focus-helper-hooks'
|
|
50
|
-
export { default as useSeamlyChat } from './use-seamly-chat'
|
|
51
|
-
export { default as useSeamlyIdleDetachCountdown } from './use-seamly-idle-detach-countdown'
|
|
52
|
-
export { default as useSeamlyResumeConversationPrompt } from './use-seamly-resume-conversation-prompt'
|
|
52
|
+
export { useDispatch as useSeamlyDispatchContext }
|
|
53
53
|
|
|
54
54
|
// This hook isn't used within the core
|
|
55
55
|
// But it is used in implementations
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
+
import { useI18n } from 'domains/i18n/hooks'
|
|
2
|
+
import {
|
|
3
|
+
hideOption as dispatchHideOption,
|
|
4
|
+
setUserSelectedOption as dispatchUserSelectedOption,
|
|
5
|
+
setUserSelectedOptions as dispatchUserSelectedOptions,
|
|
6
|
+
showOption as dispatchShowOption,
|
|
7
|
+
} from 'domains/store/slice'
|
|
1
8
|
import { useCallback } from 'preact/hooks'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import { useSeamlyObjectStore } from './seamly-api-hooks'
|
|
7
|
-
import { useElementFocusingById } from './focus-helper-hooks'
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
SET_USER_SELECTED_OPTION,
|
|
11
|
-
SET_USER_SELECTED_OPTIONS,
|
|
12
|
-
SHOW_OPTION,
|
|
13
|
-
HIDE_OPTION,
|
|
14
|
-
} = seamlyActions
|
|
9
|
+
import { useDispatch } from 'react-redux'
|
|
10
|
+
import { useElementFocusingById } from 'ui/hooks/focus-helper-hooks'
|
|
11
|
+
import { useSeamlyObjectStore } from 'ui/hooks/seamly-api-hooks'
|
|
12
|
+
import { useSeamlyStateContext } from 'ui/hooks/seamly-state-hooks'
|
|
15
13
|
|
|
16
14
|
export const useSeamlyOptions = () => {
|
|
17
15
|
const { t } = useI18n()
|
|
@@ -35,17 +33,17 @@ export const useSeamlyOptions = () => {
|
|
|
35
33
|
|
|
36
34
|
const allowOptionSelection = cobrowsing || sendTranscript
|
|
37
35
|
|
|
38
|
-
const dispatch =
|
|
36
|
+
const dispatch = useDispatch()
|
|
39
37
|
const { get, set } = useSeamlyObjectStore()
|
|
40
38
|
|
|
41
39
|
const initUserSelectedOptions = useCallback(() => {
|
|
42
40
|
const storedOptions = get('options') || {}
|
|
43
|
-
dispatch(
|
|
41
|
+
dispatch(dispatchUserSelectedOptions(storedOptions))
|
|
44
42
|
}, [get, dispatch])
|
|
45
43
|
|
|
46
44
|
const setUserSelectedOptions = useCallback(
|
|
47
45
|
(optionValues) => {
|
|
48
|
-
dispatch(
|
|
46
|
+
dispatch(dispatchUserSelectedOptions(optionValues))
|
|
49
47
|
set('options', optionValues)
|
|
50
48
|
},
|
|
51
49
|
[set, dispatch],
|
|
@@ -58,17 +56,17 @@ export const useSeamlyOptions = () => {
|
|
|
58
56
|
...storedOptions,
|
|
59
57
|
[option]: value,
|
|
60
58
|
})
|
|
61
|
-
dispatch({
|
|
59
|
+
dispatch(dispatchUserSelectedOption({ option, value }))
|
|
62
60
|
},
|
|
63
61
|
[dispatch, get, set],
|
|
64
62
|
)
|
|
65
63
|
|
|
66
64
|
const showOption = (optionName) => {
|
|
67
|
-
dispatch(
|
|
65
|
+
dispatch(dispatchShowOption(optionName))
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
const hideOption = () => {
|
|
71
|
-
dispatch(
|
|
69
|
+
dispatch(dispatchHideOption())
|
|
72
70
|
}
|
|
73
71
|
|
|
74
72
|
return {
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { createSelector } from 'reselect'
|
|
2
|
-
import { useSelector } from 'domains/redux'
|
|
3
|
-
import { microsecondsToMilliseconds } from 'ui/utils/general-utils'
|
|
4
1
|
import * as ConfigSelectors from 'domains/config/selectors'
|
|
5
|
-
import
|
|
2
|
+
import { microsecondsToMilliseconds } from 'ui/utils/general-utils'
|
|
3
|
+
import { createSelector } from '@reduxjs/toolkit'
|
|
4
|
+
import { selectUserHasResponded } from 'domains/app/selectors'
|
|
6
5
|
import { useConfig } from 'domains/config/hooks'
|
|
6
|
+
import { useSelector } from 'react-redux'
|
|
7
7
|
|
|
8
|
-
export const selectState = (state) => state
|
|
8
|
+
export const selectState = ({ state }) => state
|
|
9
9
|
export const useSeamlyStateContext = () => useSelector(selectState)
|
|
10
10
|
|
|
11
11
|
export const selectEventsWithSuggestion = createSelector(
|
|
12
12
|
selectState,
|
|
13
13
|
ConfigSelectors.selectConfig,
|
|
14
|
-
|
|
15
|
-
({ events, serviceData }, config,
|
|
14
|
+
selectUserHasResponded,
|
|
15
|
+
({ events, serviceData }, config, hasUserResponded) => {
|
|
16
16
|
if (
|
|
17
|
-
|
|
17
|
+
hasUserResponded ||
|
|
18
18
|
config.layoutMode === 'inline' ||
|
|
19
|
-
!serviceData
|
|
20
|
-
!serviceData
|
|
19
|
+
!serviceData?.suggestion ||
|
|
20
|
+
!serviceData?.suggestion?.body.length
|
|
21
21
|
) {
|
|
22
22
|
return events
|
|
23
23
|
}
|
|
@@ -63,7 +63,13 @@ export const selectEvents = createSelector(
|
|
|
63
63
|
return mappedEvents
|
|
64
64
|
},
|
|
65
65
|
)
|
|
66
|
-
export const useEvents = () => useSelector(selectEvents
|
|
66
|
+
export const useEvents = () => useSelector(selectEvents)
|
|
67
|
+
|
|
68
|
+
export const selectEventIds = createSelector(selectEvents, (events) => {
|
|
69
|
+
return events.map((event) => event.payload.id)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
export const useEventsIds = () => useSelector(selectEventIds)
|
|
67
73
|
|
|
68
74
|
export const useSeamlyIsLoading = () => useSeamlyStateContext().isLoading
|
|
69
75
|
|
|
@@ -96,8 +102,9 @@ export const useSeamlyCurrentAgent = () => {
|
|
|
96
102
|
return currentAgent ? participants[currentAgent] : null
|
|
97
103
|
}
|
|
98
104
|
|
|
99
|
-
export const useSeamlyServiceData = (key) =>
|
|
100
|
-
useSeamlyStateContext().serviceData[key]
|
|
105
|
+
export const useSeamlyServiceData = (key) => {
|
|
106
|
+
return useSeamlyStateContext().serviceData[key]
|
|
107
|
+
}
|
|
101
108
|
|
|
102
109
|
export const useEntryTextLimit = () => {
|
|
103
110
|
const {
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
+
import { useI18n } from 'domains/i18n/hooks'
|
|
2
|
+
import { setIsLoading } from 'domains/store/slice'
|
|
3
|
+
import { visibilityStates } from 'domains/visibility/constants'
|
|
4
|
+
import { useVisibility } from 'domains/visibility/hooks'
|
|
1
5
|
import { useCallback, useEffect, useRef } from 'preact/hooks'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
+
import { useDispatch, useSelector } from 'react-redux'
|
|
7
|
+
import { selectShowInlineView } from '../../domains/visibility/selectors'
|
|
8
|
+
import { useLiveRegion } from './live-region-hooks'
|
|
9
|
+
import { useSeamlyHasConversation } from './seamly-api-hooks'
|
|
6
10
|
import { useEvents, useSeamlyLayoutMode } from './seamly-state-hooks'
|
|
7
11
|
import useSeamlyCommands from './use-seamly-commands'
|
|
8
|
-
import { useSeamlyHasConversation } from './seamly-api-hooks'
|
|
9
|
-
import { useLiveRegion } from './live-region-hooks'
|
|
10
|
-
import { useSelector } from '../../domains/redux/hooks'
|
|
11
|
-
import { selectShowInlineView } from '../../domains/visibility/selectors'
|
|
12
|
-
|
|
13
|
-
const { SET_IS_LOADING } = seamlyActions
|
|
14
12
|
|
|
15
13
|
const useSeamlyChat = () => {
|
|
16
14
|
const { t } = useI18n()
|
|
17
15
|
const { isInline, isWindow } = useSeamlyLayoutMode()
|
|
18
16
|
const { isOpen, isVisible, setVisibility } = useVisibility()
|
|
19
17
|
const showInlineView = useSelector(selectShowInlineView)
|
|
20
|
-
const dispatch =
|
|
18
|
+
const dispatch = useDispatch()
|
|
21
19
|
const events = useEvents()
|
|
22
20
|
const spinnerTimeout = useRef(null)
|
|
23
21
|
const { start, connect, apiConfigReady, apiConnected } = useSeamlyCommands()
|
|
@@ -60,20 +58,14 @@ const useSeamlyChat = () => {
|
|
|
60
58
|
// This delays the start of the loading inidicator we set when we initialise
|
|
61
59
|
// the application. This is done to only avoid BSOD on initial load if DCX is slow.
|
|
62
60
|
spinnerTimeout.current = setTimeout(() => {
|
|
63
|
-
dispatch(
|
|
64
|
-
type: SET_IS_LOADING,
|
|
65
|
-
isLoading: true,
|
|
66
|
-
})
|
|
61
|
+
dispatch(setIsLoading(true))
|
|
67
62
|
}, 500)
|
|
68
63
|
}, [dispatch])
|
|
69
64
|
|
|
70
65
|
useEffect(() => {
|
|
71
66
|
if (hasEvents) {
|
|
72
67
|
clearTimeout(spinnerTimeout.current)
|
|
73
|
-
dispatch(
|
|
74
|
-
type: SET_IS_LOADING,
|
|
75
|
-
isLoading: false,
|
|
76
|
-
})
|
|
68
|
+
dispatch(setIsLoading(false))
|
|
77
69
|
}
|
|
78
70
|
}, [hasEvents, dispatch])
|
|
79
71
|
|
|
@@ -106,21 +98,19 @@ const useSeamlyChat = () => {
|
|
|
106
98
|
if (
|
|
107
99
|
!apiConfigReady ||
|
|
108
100
|
startCalled.current ||
|
|
109
|
-
(isWindow && !isOpen && !hasConversation) ||
|
|
101
|
+
(isWindow && !isOpen && !hasConversation()) ||
|
|
110
102
|
(isInline && !showInlineView)
|
|
111
103
|
) {
|
|
112
104
|
return
|
|
113
105
|
}
|
|
114
106
|
|
|
115
|
-
if (hasConversation && isOpen) {
|
|
107
|
+
if (hasConversation() && isOpen) {
|
|
116
108
|
// We deactivate the extra startup loading spinner when a conversation is available
|
|
117
109
|
// We also stop setting the loading indicator in the first place to avoid a flash.
|
|
118
110
|
clearTimeout(spinnerTimeout.current)
|
|
119
|
-
dispatch(
|
|
120
|
-
type: SET_IS_LOADING,
|
|
121
|
-
isLoading: false,
|
|
122
|
-
})
|
|
111
|
+
dispatch(setIsLoading(false))
|
|
123
112
|
}
|
|
113
|
+
|
|
124
114
|
connectAndStart()
|
|
125
115
|
}, [
|
|
126
116
|
apiConfigReady,
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { useCallback, useContext } from 'preact/hooks'
|
|
2
|
-
import { SeamlyEventBusContext } from 'ui/components/core/seamly-api-context'
|
|
3
|
-
import { randomId } from 'lib/id'
|
|
4
1
|
import { userParticipantId } from 'config'
|
|
5
|
-
import { actionTypes, seamlyActions } from 'ui/utils/seamly-utils'
|
|
6
|
-
import { Actions as InterruptActions } from 'domains/interrupt'
|
|
7
|
-
import { useConfig } from 'domains/config'
|
|
8
|
-
import * as AppActions from 'domains/app/actions'
|
|
9
2
|
import { useUserHasResponded } from 'domains/app/hooks'
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
3
|
+
import * as AppActions from 'domains/app/actions'
|
|
4
|
+
import { setHasResponded } from 'domains/app/slice'
|
|
5
|
+
import { useConfig } from 'domains/config/hooks'
|
|
6
|
+
import { setInterrupt } from 'domains/interrupt/slice'
|
|
7
|
+
import { addEvent, setInitialState } from 'domains/store/slice'
|
|
8
|
+
import { visibilityStates } from 'domains/visibility/constants'
|
|
9
|
+
import { useVisibility } from 'domains/visibility/hooks'
|
|
10
|
+
|
|
11
|
+
import { randomId } from 'lib/id'
|
|
12
|
+
import { useCallback, useContext } from 'preact/hooks'
|
|
13
|
+
import { useDispatch } from 'react-redux'
|
|
14
|
+
import { SeamlyEventBusContext } from 'ui/components/core/seamly-api-context'
|
|
15
|
+
import { actionTypes } from 'ui/utils/seamly-utils'
|
|
14
16
|
import {
|
|
15
17
|
useSeamlyApiContext,
|
|
16
18
|
useSeamlyHasConversation,
|
|
17
19
|
} from './seamly-api-hooks'
|
|
18
|
-
|
|
19
|
-
const { ADD_EVENT, SET_INITIAL_STATE } = seamlyActions
|
|
20
|
+
import { useSeamlyUnreadCount } from './seamly-state-hooks'
|
|
20
21
|
|
|
21
22
|
const useSeamlyCommands = () => {
|
|
22
23
|
const api = useSeamlyApiContext()
|
|
23
24
|
const appConfig = useConfig()
|
|
24
|
-
const dispatch =
|
|
25
|
+
const dispatch = useDispatch()
|
|
25
26
|
const eventBus = useContext(SeamlyEventBusContext)
|
|
26
|
-
|
|
27
|
-
const hasResponded = useUserHasResponded()
|
|
27
|
+
const userHasResponded = useUserHasResponded()
|
|
28
28
|
const hasConversation = useSeamlyHasConversation()
|
|
29
29
|
const { visible: visibility, setVisibility } = useVisibility()
|
|
30
30
|
const unreadMessageCount = useSeamlyUnreadCount()
|
|
@@ -36,34 +36,34 @@ const useSeamlyCommands = () => {
|
|
|
36
36
|
[eventBus],
|
|
37
37
|
)
|
|
38
38
|
|
|
39
|
-
const start =
|
|
39
|
+
const start = useCallback(() => {
|
|
40
40
|
api.sendContext(appConfig.context || {})
|
|
41
41
|
emitEvent('ui.beforeStart', {
|
|
42
42
|
visibility,
|
|
43
|
-
hasConversation,
|
|
44
|
-
hasResponded,
|
|
43
|
+
hasConversation: hasConversation(),
|
|
44
|
+
hasResponded: userHasResponded,
|
|
45
45
|
unreadMessageCount,
|
|
46
46
|
})
|
|
47
47
|
|
|
48
48
|
api.send('start')
|
|
49
49
|
emitEvent('ui.start', {
|
|
50
50
|
visibility,
|
|
51
|
-
hasConversation,
|
|
52
|
-
hasResponded,
|
|
51
|
+
hasConversation: hasConversation(),
|
|
52
|
+
hasResponded: userHasResponded,
|
|
53
53
|
unreadMessageCount,
|
|
54
54
|
})
|
|
55
55
|
}, [
|
|
56
56
|
api,
|
|
57
|
-
appConfig,
|
|
57
|
+
appConfig.context,
|
|
58
58
|
emitEvent,
|
|
59
|
-
hasResponded,
|
|
60
59
|
hasConversation,
|
|
61
|
-
|
|
60
|
+
userHasResponded,
|
|
62
61
|
unreadMessageCount,
|
|
62
|
+
visibility,
|
|
63
63
|
])
|
|
64
64
|
|
|
65
65
|
const reset = useCallback(async () => {
|
|
66
|
-
dispatch(AppActions.
|
|
66
|
+
dispatch(AppActions.resetApp())
|
|
67
67
|
}, [dispatch])
|
|
68
68
|
|
|
69
69
|
const getMessageBase = useCallback(
|
|
@@ -106,35 +106,30 @@ const useSeamlyCommands = () => {
|
|
|
106
106
|
|
|
107
107
|
api.send('message', message)
|
|
108
108
|
emitEvent('message', message)
|
|
109
|
-
dispatch(
|
|
110
|
-
|
|
111
|
-
event: {
|
|
109
|
+
dispatch(
|
|
110
|
+
addEvent({
|
|
112
111
|
type: 'message',
|
|
113
112
|
payload: {
|
|
114
113
|
...message,
|
|
115
114
|
optimisticallyInjected: true,
|
|
116
115
|
},
|
|
117
|
-
},
|
|
118
|
-
|
|
116
|
+
}),
|
|
117
|
+
)
|
|
119
118
|
},
|
|
120
119
|
[api, dispatch, emitEvent, getTextMessageBase],
|
|
121
120
|
)
|
|
122
121
|
|
|
123
122
|
const addMessageBubble = useCallback(
|
|
124
123
|
(text) => {
|
|
125
|
-
dispatch({
|
|
126
|
-
type: ADD_EVENT,
|
|
127
|
-
event: { type: 'message', payload: getTextMessageBase(text) },
|
|
128
|
-
})
|
|
124
|
+
dispatch(addEvent({ type: 'message', payload: getTextMessageBase(text) }))
|
|
129
125
|
},
|
|
130
126
|
[dispatch, getTextMessageBase],
|
|
131
127
|
)
|
|
132
128
|
|
|
133
129
|
const addUploadBubble = useCallback(
|
|
134
130
|
(id, transactionId, occurredAt, contentType, filename, filesize, url) => {
|
|
135
|
-
dispatch(
|
|
136
|
-
|
|
137
|
-
event: {
|
|
131
|
+
dispatch(
|
|
132
|
+
addEvent({
|
|
138
133
|
type: 'message',
|
|
139
134
|
payload: {
|
|
140
135
|
type: 'upload',
|
|
@@ -146,8 +141,8 @@ const useSeamlyCommands = () => {
|
|
|
146
141
|
meta: {},
|
|
147
142
|
body: { contentType, filename, filesize, url },
|
|
148
143
|
},
|
|
149
|
-
},
|
|
150
|
-
|
|
144
|
+
}),
|
|
145
|
+
)
|
|
151
146
|
},
|
|
152
147
|
[dispatch],
|
|
153
148
|
)
|
|
@@ -163,10 +158,7 @@ const useSeamlyCommands = () => {
|
|
|
163
158
|
type: 'divider',
|
|
164
159
|
}
|
|
165
160
|
|
|
166
|
-
dispatch({
|
|
167
|
-
type: ADD_EVENT,
|
|
168
|
-
event: { type: 'info', payload },
|
|
169
|
-
})
|
|
161
|
+
dispatch(addEvent({ type: 'info', payload }))
|
|
170
162
|
},
|
|
171
163
|
[dispatch],
|
|
172
164
|
)
|
|
@@ -203,15 +195,23 @@ const useSeamlyCommands = () => {
|
|
|
203
195
|
.connect()
|
|
204
196
|
.then((initialState) => {
|
|
205
197
|
if (initialState) {
|
|
206
|
-
dispatch(
|
|
198
|
+
dispatch(setInitialState(initialState))
|
|
207
199
|
if (initialState.userResponded) {
|
|
208
|
-
dispatch(
|
|
200
|
+
dispatch(setHasResponded(initialState.userResponded))
|
|
209
201
|
setVisibility(visibilityStates.open)
|
|
210
202
|
}
|
|
211
203
|
}
|
|
212
204
|
})
|
|
213
205
|
.catch((error) => {
|
|
214
|
-
dispatch(
|
|
206
|
+
dispatch(
|
|
207
|
+
setInterrupt({
|
|
208
|
+
name: error.name,
|
|
209
|
+
message: error.message,
|
|
210
|
+
langKey: error.langKey,
|
|
211
|
+
originalEvent: error.originalEvent,
|
|
212
|
+
originalError: error.originalError,
|
|
213
|
+
}),
|
|
214
|
+
)
|
|
215
215
|
})
|
|
216
216
|
}, [api, dispatch, setVisibility])
|
|
217
217
|
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
+
import { screenReaderDebounceDelaySeconds } from 'config'
|
|
2
|
+
import { useI18n } from 'domains/i18n/hooks'
|
|
3
|
+
import { useVisibility } from 'domains/visibility/hooks'
|
|
4
|
+
import {
|
|
5
|
+
clearIdleDetachCountdown,
|
|
6
|
+
decrementIdleDetachCountdownCounter,
|
|
7
|
+
initIdleDetachCountdown,
|
|
8
|
+
stopIdleDetachCountdownCounter,
|
|
9
|
+
} from 'domains/store/slice'
|
|
1
10
|
import { useCallback, useRef } from 'preact/hooks'
|
|
2
|
-
import {
|
|
11
|
+
import { useDispatch } from 'react-redux'
|
|
3
12
|
import {
|
|
4
13
|
getTimeFromSeconds,
|
|
5
14
|
millisecondsToSeconds,
|
|
6
15
|
} from 'ui/utils/general-utils'
|
|
7
|
-
import { actionTypes
|
|
8
|
-
import { screenReaderDebounceDelaySeconds } from 'config'
|
|
9
|
-
import { useVisibility } from 'domains/visibility'
|
|
16
|
+
import { actionTypes } from 'ui/utils/seamly-utils'
|
|
10
17
|
import { useLiveRegion } from './live-region-hooks'
|
|
11
|
-
import useSeamlyCommands from './use-seamly-commands'
|
|
12
18
|
import { useSeamlyStateContext } from './seamly-state-hooks'
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
const {
|
|
16
|
-
CLEAR_IDLE_DETACH_COUNTDOWN,
|
|
17
|
-
INIT_IDLE_DETACH_COUNTDOWN,
|
|
18
|
-
DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER,
|
|
19
|
-
STOP_IDLE_DETACH_COUNTDOWN_COUNTER,
|
|
20
|
-
} = seamlyActions
|
|
19
|
+
import useSeamlyCommands from './use-seamly-commands'
|
|
21
20
|
|
|
22
21
|
const useSeamlyIdleDetachCountdown = () => {
|
|
23
|
-
const dispatch =
|
|
22
|
+
const dispatch = useDispatch()
|
|
24
23
|
|
|
25
24
|
const { idleDetachCountdown } = useSeamlyStateContext()
|
|
26
25
|
|
|
@@ -65,11 +64,12 @@ const useSeamlyIdleDetachCountdown = () => {
|
|
|
65
64
|
const delaySeconds = millisecondsToSeconds(milliseconds)
|
|
66
65
|
const delayTime = getTimeFromSeconds(delaySeconds)
|
|
67
66
|
|
|
68
|
-
dispatch(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
dispatch(
|
|
68
|
+
initIdleDetachCountdown({
|
|
69
|
+
delaySeconds,
|
|
70
|
+
delayTime,
|
|
71
|
+
}),
|
|
72
|
+
)
|
|
73
73
|
emitEvent('idleTimer.start')
|
|
74
74
|
sendAssertiveIfOpen(
|
|
75
75
|
`${t('idleDetachWarning.countdownTitle')} ${t(
|
|
@@ -98,7 +98,7 @@ const useSeamlyIdleDetachCountdown = () => {
|
|
|
98
98
|
emitEvent('idleTimer.stop')
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
dispatch(
|
|
101
|
+
dispatch(clearIdleDetachCountdown())
|
|
102
102
|
},
|
|
103
103
|
[dispatch, sendAction, emitEvent, sendAssertiveIfOpen, t],
|
|
104
104
|
)
|
|
@@ -120,9 +120,7 @@ const useSeamlyIdleDetachCountdown = () => {
|
|
|
120
120
|
)
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
dispatch(
|
|
124
|
-
type: DECREMENT_IDLE_DETACH_COUNTDOWN_COUNTER,
|
|
125
|
-
})
|
|
123
|
+
dispatch(decrementIdleDetachCountdownCounter())
|
|
126
124
|
}, [dispatch, sendAssertiveIfOpen, t])
|
|
127
125
|
|
|
128
126
|
const stopCountdown = useCallback(() => {
|
|
@@ -131,7 +129,7 @@ const useSeamlyIdleDetachCountdown = () => {
|
|
|
131
129
|
return
|
|
132
130
|
}
|
|
133
131
|
|
|
134
|
-
dispatch(
|
|
132
|
+
dispatch(stopIdleDetachCountdownCounter())
|
|
135
133
|
|
|
136
134
|
if (remaining) {
|
|
137
135
|
emitEvent('idleTimer.stop')
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { useI18n } from 'domains/i18n'
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import { useI18n } from 'domains/i18n/hooks'
|
|
2
|
+
import { clearResumeConversationPrompt } from 'domains/store/slice'
|
|
3
|
+
import { useDispatch } from 'react-redux'
|
|
4
|
+
import { actionTypes, dismissTypes } from 'ui/utils/seamly-utils'
|
|
5
|
+
import { useLiveRegion } from './live-region-hooks'
|
|
4
6
|
import { useSeamlyStateContext } from './seamly-state-hooks'
|
|
5
7
|
import useSeamlyCommands from './use-seamly-commands'
|
|
6
|
-
import { useLiveRegion } from './live-region-hooks'
|
|
7
|
-
|
|
8
|
-
const { CLEAR_RESUME_CONVERSATION_PROMPT } = seamlyActions
|
|
9
8
|
|
|
10
9
|
const useSeamlyResumeConversationPrompt = () => {
|
|
11
|
-
const dispatch =
|
|
10
|
+
const dispatch = useDispatch()
|
|
12
11
|
const hasPrompt = useSeamlyStateContext().resumeConversationPrompt
|
|
13
12
|
const { sendAction } = useSeamlyCommands()
|
|
14
13
|
const { t } = useI18n()
|
|
@@ -19,13 +18,13 @@ const useSeamlyResumeConversationPrompt = () => {
|
|
|
19
18
|
type: actionTypes.dismiss,
|
|
20
19
|
body: { type: dismissTypes.resumeConversationPrompt },
|
|
21
20
|
})
|
|
22
|
-
dispatch(
|
|
21
|
+
dispatch(clearResumeConversationPrompt())
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
const restartChat = () => {
|
|
26
25
|
sendAssertive(t('resumeConversationPrompt.srNotifyRestartText'))
|
|
27
26
|
sendAction({ type: actionTypes.detachService })
|
|
28
|
-
dispatch(
|
|
27
|
+
dispatch(clearResumeConversationPrompt())
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
return { continueChat, hasPrompt, restartChat }
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getControlValueByName } from 'domains/forms/selectors'
|
|
2
|
+
import { useSelector } from 'react-redux'
|
|
3
3
|
import { useFileUploads } from './seamly-hooks'
|
|
4
4
|
|
|
5
5
|
const useSingleFileUpload = (formId, name) => {
|
|
6
|
-
const fileList =
|
|
7
|
-
|
|
8
|
-
{ formId, name },
|
|
9
|
-
[formId, name],
|
|
6
|
+
const fileList = useSelector((store) =>
|
|
7
|
+
getControlValueByName(store, { formId, name }),
|
|
10
8
|
)
|
|
11
9
|
// This hook acts as a helper as the data model is built to handle multiple
|
|
12
10
|
// file uploads but currently Seamly only supports single file uploads.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
+
import { randomId } from 'lib/id'
|
|
1
2
|
import {
|
|
2
3
|
useCallback,
|
|
4
|
+
useMemo,
|
|
3
5
|
useReducer,
|
|
4
6
|
useRef,
|
|
5
7
|
useState,
|
|
6
|
-
useMemo,
|
|
7
8
|
} from 'preact/hooks'
|
|
8
|
-
import { randomId } from 'lib/id'
|
|
9
9
|
|
|
10
10
|
export const useForceUpdate = () => {
|
|
11
11
|
// This is an escape hatch mentioned in the React docs:
|
|
12
12
|
// https://reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
|
|
13
13
|
/* eslint-disable-next-line no-unused-vars */
|
|
14
|
-
const [
|
|
14
|
+
const [_, forceUpdate] = useReducer((x) => x + 1, 0)
|
|
15
15
|
|
|
16
16
|
return useCallback(() => {
|
|
17
17
|
setTimeout(() => {
|
|
@@ -26,7 +26,7 @@ export const useGeneratedId = () => {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export const useStableCallback = (callback) => {
|
|
29
|
-
const callbackRef = useRef()
|
|
29
|
+
const callbackRef = useRef(null)
|
|
30
30
|
callbackRef.current = callback
|
|
31
31
|
const isFunction = typeof callback === 'function'
|
|
32
32
|
return useMemo(() => {
|