@seamly/web-ui 19.0.0-beta.2 → 19.1.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/index.debug.js +152 -64
- package/build/dist/lib/index.debug.min.js +1 -1
- package/build/dist/lib/index.debug.min.js.LICENSE.txt +40 -8
- package/build/dist/lib/index.js +595 -462
- package/build/dist/lib/index.min.js +1 -1
- package/build/dist/lib/standalone.js +716 -490
- package/build/dist/lib/standalone.min.js +1 -1
- package/build/dist/lib/storage.js +8 -1
- package/build/dist/lib/storage.min.js +1 -1
- package/build/dist/lib/style-guide.js +1920 -1814
- package/build/dist/lib/style-guide.min.js +1 -1
- package/package.json +1 -1
- package/src/javascripts/api/errors/seamly-base-error.js +10 -0
- package/src/javascripts/api/errors/seamly-configuration-error.js +4 -6
- package/src/javascripts/api/errors/seamly-general-error.js +4 -6
- package/src/javascripts/api/errors/seamly-offline-error.js +4 -6
- package/src/javascripts/api/errors/seamly-session-expired-error.js +4 -6
- package/src/javascripts/api/errors/seamly-unauthorized-error.js +4 -6
- package/src/javascripts/api/errors/seamly-unavailable-error.js +17 -0
- package/src/javascripts/api/index.js +10 -11
- package/src/javascripts/domains/app/actions.js +33 -24
- package/src/javascripts/domains/app/index.js +2 -1
- package/src/javascripts/domains/config/reducer.js +1 -0
- package/src/javascripts/domains/config/selectors.js +1 -1
- package/src/javascripts/domains/errors/index.js +32 -0
- package/src/javascripts/domains/i18n/actions.js +9 -24
- package/src/javascripts/domains/i18n/reducer.js +15 -3
- package/src/javascripts/domains/i18n/utils.js +2 -7
- package/src/javascripts/domains/interrupt/middleware.js +12 -9
- package/src/javascripts/domains/interrupt/reducer.js +10 -9
- package/src/javascripts/domains/store/index.js +7 -2
- package/src/javascripts/domains/store/state-reducer.js +10 -6
- package/src/javascripts/domains/visibility/actions.js +73 -0
- package/src/javascripts/domains/visibility/constants.js +8 -0
- package/src/javascripts/domains/visibility/hooks.js +24 -0
- package/src/javascripts/domains/visibility/index.js +8 -0
- package/src/javascripts/domains/visibility/reducer.js +19 -0
- package/src/javascripts/domains/visibility/selectors.js +9 -0
- package/src/javascripts/domains/visibility/utils.js +42 -0
- package/src/javascripts/index.js +3 -12
- package/src/javascripts/lib/engine/index.js +1 -0
- package/src/javascripts/lib/redux-helpers/index.js +45 -13
- package/src/javascripts/lib/store/providers/session-storage.js +6 -1
- package/src/javascripts/style-guide/components/app.js +1 -1
- package/src/javascripts/style-guide/components/static-core.js +6 -1
- package/src/javascripts/style-guide/states.js +48 -21
- package/src/javascripts/ui/components/conversation/conversation.js +2 -2
- package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +1 -8
- package/src/javascripts/ui/components/conversation/event/text.js +19 -13
- package/src/javascripts/ui/components/core/seamly-core.js +3 -0
- package/src/javascripts/ui/components/core/seamly-event-subscriber.js +3 -3
- package/src/javascripts/ui/components/core/seamly-initializer.js +2 -6
- package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +2 -3
- package/src/javascripts/ui/components/core/seamly-new-notifications.js +2 -2
- package/src/javascripts/ui/components/core/seamly-read-state.js +2 -2
- package/src/javascripts/ui/components/entry/toggle-button.js +2 -2
- package/src/javascripts/ui/components/layout/agent-info.js +2 -2
- package/src/javascripts/ui/components/layout/app-frame.js +2 -3
- package/src/javascripts/ui/components/layout/chat-frame.js +2 -2
- package/src/javascripts/ui/components/layout/modal-wrapper.js +3 -6
- package/src/javascripts/ui/components/layout/view.js +3 -6
- package/src/javascripts/ui/hooks/seamly-hooks.js +0 -2
- package/src/javascripts/ui/hooks/use-seamly-chat.js +3 -5
- package/src/javascripts/ui/hooks/use-seamly-commands.js +7 -29
- package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +2 -2
- package/src/javascripts/ui/utils/general-utils.js +0 -9
- package/src/javascripts/ui/utils/seamly-utils.js +0 -66
- package/src/javascripts/ui/hooks/use-seamly-stored-visibility.js +0 -31
- package/src/javascripts/ui/hooks/use-seamly-visibility.js +0 -98
package/src/javascripts/index.js
CHANGED
|
@@ -12,7 +12,7 @@ export { default as AgentInfo } from './ui/components/layout/agent-info'
|
|
|
12
12
|
export { default as AppFrame } from './ui/components/layout/app-frame'
|
|
13
13
|
|
|
14
14
|
// Used by: Client
|
|
15
|
-
export { calculateVisibility } from './
|
|
15
|
+
export { calculateVisibility } from './domains/visibility'
|
|
16
16
|
|
|
17
17
|
// Used by: Client
|
|
18
18
|
export { default as ChatFrame } from './ui/components/layout/chat-frame'
|
|
@@ -114,7 +114,7 @@ export { useSeamlyMessageContainerClassNames } from './ui/hooks/seamly-hooks'
|
|
|
114
114
|
export { useSeamlyOptions } from './ui/hooks/seamly-hooks'
|
|
115
115
|
|
|
116
116
|
// Used by: Client
|
|
117
|
-
export { useSeamlyVisibility } from './
|
|
117
|
+
export { useVisibility as useSeamlyVisibility } from './domains/visibility'
|
|
118
118
|
|
|
119
119
|
// Used by: Client
|
|
120
120
|
export {
|
|
@@ -135,7 +135,7 @@ export { default as View } from './ui/components/layout/view'
|
|
|
135
135
|
|
|
136
136
|
// Used by: Client
|
|
137
137
|
// Used by: StyleGuide
|
|
138
|
-
export { visibilityStates } from './
|
|
138
|
+
export { visibilityStates } from './domains/visibility'
|
|
139
139
|
|
|
140
140
|
// Used by: StyleGuide
|
|
141
141
|
export { API } from './api'
|
|
@@ -143,14 +143,5 @@ export { API } from './api'
|
|
|
143
143
|
// Used by: StyleGuide
|
|
144
144
|
export { default as SeamlyGeneralError } from './api/errors/seamly-general-error'
|
|
145
145
|
|
|
146
|
-
// Used by: StyleGuide
|
|
147
|
-
export { default as SeamlyConfigurationError } from './api/errors/seamly-configuration-error'
|
|
148
|
-
|
|
149
|
-
// Used by: StyleGuide
|
|
150
|
-
export { default as SeamlySessionExpiredError } from './api/errors/seamly-session-expired-error'
|
|
151
|
-
|
|
152
146
|
// Used by: StyleGuide
|
|
153
147
|
export { default as SeamlyOfflineError } from './api/errors/seamly-offline-error'
|
|
154
|
-
|
|
155
|
-
// Used by: StyleGuide
|
|
156
|
-
export { default as SeamlyUnauthorizedError } from './api/errors/seamly-unauthorized-error'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { randomId } from '../id'
|
|
2
|
+
|
|
1
3
|
export const SLICE_DELIMITER = '/'
|
|
2
4
|
export const DOMAIN_DELIMITER = '//'
|
|
3
5
|
|
|
@@ -10,7 +12,8 @@ export function createAction(
|
|
|
10
12
|
identityReducer = (payload) => ({ payload }),
|
|
11
13
|
) {
|
|
12
14
|
const action = (...params) => ({ type, ...identityReducer(...params) })
|
|
13
|
-
action.toString = () => type
|
|
15
|
+
action.toString = () => String(type)
|
|
16
|
+
action.match = (obj) => obj?.type === String(type)
|
|
14
17
|
return action
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -32,22 +35,51 @@ export function createActions(baseType, ...args) {
|
|
|
32
35
|
return handlers.map((handler) => create(...handler))
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
export function createThunk(type,
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
export function createThunk(type, payloadCreator) {
|
|
39
|
+
const [pending, fulfilled, rejected] = createActions(type, {
|
|
40
|
+
pending: (arg, requestId) => ({
|
|
41
|
+
meta: { arg, requestId, status: 'pending' },
|
|
42
|
+
}),
|
|
43
|
+
fulfilled: (arg, payload, requestId) => ({
|
|
44
|
+
payload,
|
|
45
|
+
meta: { arg, requestId, status: 'fulfilled' },
|
|
46
|
+
}),
|
|
47
|
+
rejected: (arg, error, requestId) => ({
|
|
48
|
+
error,
|
|
49
|
+
meta: { arg, requestId, status: 'rejected', error: String(error) },
|
|
50
|
+
}),
|
|
51
|
+
})
|
|
52
|
+
const thunkCreator = (arg) => (dispatch, getState, extra) => {
|
|
53
|
+
const requestId = randomId()
|
|
54
|
+
const promise = (async () => {
|
|
55
|
+
let finalAction
|
|
56
|
+
try {
|
|
57
|
+
dispatch(pending(arg, requestId))
|
|
58
|
+
const prms = payloadCreator(arg, { dispatch, getState, extra })
|
|
59
|
+
const result = await prms
|
|
60
|
+
finalAction = fulfilled(arg, result, requestId)
|
|
61
|
+
} catch (error) {
|
|
62
|
+
finalAction = rejected(arg, error, requestId)
|
|
63
|
+
}
|
|
64
|
+
dispatch(finalAction)
|
|
65
|
+
return finalAction
|
|
66
|
+
})()
|
|
67
|
+
return Object.assign(promise, {
|
|
68
|
+
type,
|
|
69
|
+
arg,
|
|
70
|
+
requestId,
|
|
71
|
+
})
|
|
40
72
|
}
|
|
41
|
-
|
|
42
|
-
|
|
73
|
+
return Object.assign(thunkCreator, {
|
|
74
|
+
type,
|
|
75
|
+
pending,
|
|
76
|
+
fulfilled,
|
|
77
|
+
rejected,
|
|
78
|
+
})
|
|
43
79
|
}
|
|
44
80
|
|
|
45
81
|
export function createReducer(domain, handlers = {}, defaultState) {
|
|
46
|
-
const reducer = (state, action) => {
|
|
47
|
-
if (state === undefined) {
|
|
48
|
-
// eslint-disable-next-line no-param-reassign
|
|
49
|
-
state = defaultState
|
|
50
|
-
}
|
|
82
|
+
const reducer = (state = defaultState, action) => {
|
|
51
83
|
const typeReducer = handlers?.[action?.type]
|
|
52
84
|
return typeReducer ? typeReducer(state, action) : state
|
|
53
85
|
}
|
|
@@ -3,7 +3,12 @@ export default function store(key) {
|
|
|
3
3
|
|
|
4
4
|
return {
|
|
5
5
|
get() {
|
|
6
|
-
|
|
6
|
+
const candidates = [KEY, KEY.split('.').slice(0, -1).join('.')]
|
|
7
|
+
let val
|
|
8
|
+
do {
|
|
9
|
+
val = sessionStorage.getItem(candidates[0])
|
|
10
|
+
} while (candidates.shift() && !val)
|
|
11
|
+
return JSON.parse(val)
|
|
7
12
|
},
|
|
8
13
|
|
|
9
14
|
set(value) {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
StoreProvider,
|
|
7
7
|
createReduxStore,
|
|
8
8
|
} from '@seamly/web-ui'
|
|
9
|
+
|
|
9
10
|
import stateReducer from '../../domains/store/state-reducer'
|
|
10
11
|
import { Reducer as formReducer } from '../../domains/forms'
|
|
11
12
|
import { Reducer as translationsReducer } from '../../domains/translations'
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
Reducer as configReducer,
|
|
20
21
|
Actions as ConfigActions,
|
|
21
22
|
} from '../../domains/config'
|
|
23
|
+
import { Reducer as visibilityReducer } from '../../domains/visibility'
|
|
22
24
|
|
|
23
25
|
const bareApi = {
|
|
24
26
|
send: () => {},
|
|
@@ -37,6 +39,7 @@ const SeamlyTestCore = ({ state, translations, children }) => {
|
|
|
37
39
|
translations: translationsSlice,
|
|
38
40
|
interrupt: interruptSlice,
|
|
39
41
|
config: configSlice,
|
|
42
|
+
visibility: visibilitySlice,
|
|
40
43
|
...restState
|
|
41
44
|
} = state || {}
|
|
42
45
|
const newStore = createReduxStore({
|
|
@@ -48,15 +51,17 @@ const SeamlyTestCore = ({ state, translations, children }) => {
|
|
|
48
51
|
[String(translationsReducer)]: translationsReducer,
|
|
49
52
|
[String(i18nReducer)]: i18nReducer,
|
|
50
53
|
[String(interruptReducer)]: interruptReducer,
|
|
54
|
+
[String(visibilityReducer)]: visibilityReducer,
|
|
51
55
|
},
|
|
52
56
|
initialState: {
|
|
53
57
|
state: restState,
|
|
54
58
|
[String(translationsReducer)]: translationsSlice,
|
|
55
59
|
[String(interruptReducer)]: interruptSlice,
|
|
60
|
+
[String(visibilityReducer)]: visibilitySlice,
|
|
56
61
|
},
|
|
57
62
|
})
|
|
58
63
|
newStore.dispatch(ConfigActions.initialize(configSlice || {}))
|
|
59
|
-
newStore.dispatch(I18nActions.
|
|
64
|
+
newStore.dispatch(I18nActions.setLocale.fulfilled('en-GB', translations))
|
|
60
65
|
return newStore
|
|
61
66
|
}, [state, translations])
|
|
62
67
|
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
randomId,
|
|
4
4
|
SeamlyOfflineError,
|
|
5
5
|
SeamlyGeneralError,
|
|
6
|
-
SeamlyConfigurationError,
|
|
7
6
|
} from '@seamly/web-ui'
|
|
8
7
|
import { addTranslationData } from './state-helpers'
|
|
9
8
|
|
|
@@ -21,7 +20,9 @@ const baseState = {
|
|
|
21
20
|
isLoading: false,
|
|
22
21
|
idleDetachCountdown: { hasCountdown: false, isActive: false },
|
|
23
22
|
resumeConversationPrompt: false,
|
|
24
|
-
|
|
23
|
+
visibility: {
|
|
24
|
+
visibility: visibilityStates.open,
|
|
25
|
+
},
|
|
25
26
|
serviceInfo: {
|
|
26
27
|
activeServiceSessionId: '',
|
|
27
28
|
},
|
|
@@ -953,13 +954,37 @@ const standardState = {
|
|
|
953
954
|
headingText: 'System messages',
|
|
954
955
|
description: '',
|
|
955
956
|
...baseState,
|
|
957
|
+
config: {
|
|
958
|
+
overrideMessages: {
|
|
959
|
+
timeIndicator: {
|
|
960
|
+
enabled: true,
|
|
961
|
+
threshold: 3600000,
|
|
962
|
+
},
|
|
963
|
+
},
|
|
964
|
+
},
|
|
956
965
|
participantInfo,
|
|
957
966
|
events: [
|
|
967
|
+
{
|
|
968
|
+
type: 'message',
|
|
969
|
+
payload: {
|
|
970
|
+
...shortTextMessage.payload,
|
|
971
|
+
occurredAt: (Date.now() - 86400000 * 5) * 1000,
|
|
972
|
+
id: randomId(),
|
|
973
|
+
body: {
|
|
974
|
+
text: 'Long ago when a dialog started',
|
|
975
|
+
type: 'text',
|
|
976
|
+
variables: {},
|
|
977
|
+
},
|
|
978
|
+
},
|
|
979
|
+
},
|
|
958
980
|
participantMessage,
|
|
959
981
|
participantMessageDefaultIcon,
|
|
960
982
|
newTopicDivider,
|
|
961
|
-
infoMessage,
|
|
962
983
|
transcriptInfoMessage,
|
|
984
|
+
...[newTranslationDividerStart, newTranslationDividerStop].map(
|
|
985
|
+
addTranslationData,
|
|
986
|
+
),
|
|
987
|
+
infoMessage,
|
|
963
988
|
],
|
|
964
989
|
},
|
|
965
990
|
choicePromptMessages: {
|
|
@@ -1142,34 +1167,24 @@ const standardState = {
|
|
|
1142
1167
|
},
|
|
1143
1168
|
],
|
|
1144
1169
|
},
|
|
1145
|
-
|
|
1146
|
-
// Important: This cannot pick up the language files so the text is hard set here.
|
|
1147
|
-
category: categoryKeys.errors,
|
|
1148
|
-
headingText: 'Disconnected interrupt',
|
|
1149
|
-
description: '',
|
|
1150
|
-
...baseState,
|
|
1151
|
-
interrupt: {
|
|
1152
|
-
error: new SeamlyOfflineError(),
|
|
1153
|
-
},
|
|
1154
|
-
},
|
|
1155
|
-
generalErrorInterrupt: {
|
|
1170
|
+
errorWithAction: {
|
|
1156
1171
|
// Important: This cannot pick up the language files so the text is hard set here.
|
|
1157
1172
|
category: categoryKeys.errors,
|
|
1158
|
-
headingText: '
|
|
1173
|
+
headingText: 'Error with a user action',
|
|
1159
1174
|
description: '',
|
|
1160
1175
|
...baseState,
|
|
1161
1176
|
interrupt: {
|
|
1162
1177
|
error: new SeamlyGeneralError(),
|
|
1163
1178
|
},
|
|
1164
1179
|
},
|
|
1165
|
-
|
|
1180
|
+
errorWithoutAction: {
|
|
1166
1181
|
// Important: This cannot pick up the language files so the text is hard set here.
|
|
1167
1182
|
category: categoryKeys.errors,
|
|
1168
|
-
headingText: '
|
|
1183
|
+
headingText: 'Error without a user action',
|
|
1169
1184
|
description: '',
|
|
1170
1185
|
...baseState,
|
|
1171
1186
|
interrupt: {
|
|
1172
|
-
error: new
|
|
1187
|
+
error: new SeamlyOfflineError(),
|
|
1173
1188
|
},
|
|
1174
1189
|
},
|
|
1175
1190
|
privacyDisclaimer: {
|
|
@@ -1694,6 +1709,7 @@ const standardState = {
|
|
|
1694
1709
|
activeServiceSessionId: '3942159e-9878-469e-9120-f44fd6be0f35',
|
|
1695
1710
|
},
|
|
1696
1711
|
events: [
|
|
1712
|
+
newTranslationDividerStart,
|
|
1697
1713
|
infoMessage,
|
|
1698
1714
|
shortTextMessage,
|
|
1699
1715
|
{
|
|
@@ -1722,6 +1738,8 @@ const standardState = {
|
|
|
1722
1738
|
textMesageWithBullets,
|
|
1723
1739
|
choicePromptMessage,
|
|
1724
1740
|
ctaMessage,
|
|
1741
|
+
newTranslationDividerStop,
|
|
1742
|
+
newTranslationDividerStart,
|
|
1725
1743
|
].map(addTranslationData),
|
|
1726
1744
|
translations: {
|
|
1727
1745
|
...translationsSlice,
|
|
@@ -1786,7 +1804,10 @@ export const getStateObj = (layoutModes, customComponentEventBodies) => ({
|
|
|
1786
1804
|
window: {
|
|
1787
1805
|
...baseState,
|
|
1788
1806
|
config: { ...baseState.config, layoutMode: 'window' },
|
|
1789
|
-
|
|
1807
|
+
visibility: {
|
|
1808
|
+
...baseState.visibility,
|
|
1809
|
+
visibility: visibilityStates.minimized,
|
|
1810
|
+
},
|
|
1790
1811
|
},
|
|
1791
1812
|
},
|
|
1792
1813
|
minimizedStarted: {
|
|
@@ -1796,7 +1817,10 @@ export const getStateObj = (layoutModes, customComponentEventBodies) => ({
|
|
|
1796
1817
|
window: {
|
|
1797
1818
|
...baseState,
|
|
1798
1819
|
config: { ...baseState.config, layoutMode: 'window' },
|
|
1799
|
-
|
|
1820
|
+
visibility: {
|
|
1821
|
+
...baseState.visibility,
|
|
1822
|
+
visibility: visibilityStates.minimized,
|
|
1823
|
+
},
|
|
1800
1824
|
participantInfo,
|
|
1801
1825
|
headerTitles,
|
|
1802
1826
|
},
|
|
@@ -1808,7 +1832,10 @@ export const getStateObj = (layoutModes, customComponentEventBodies) => ({
|
|
|
1808
1832
|
window: {
|
|
1809
1833
|
...baseState,
|
|
1810
1834
|
config: { ...baseState.config, layoutMode: 'window' },
|
|
1811
|
-
|
|
1835
|
+
visibility: {
|
|
1836
|
+
...baseState.visibility,
|
|
1837
|
+
visibility: visibilityStates.minimized,
|
|
1838
|
+
},
|
|
1812
1839
|
participantInfo,
|
|
1813
1840
|
headerTitles,
|
|
1814
1841
|
unreadEvents: 12,
|
|
@@ -3,7 +3,6 @@ import { className } from '../../../lib/css'
|
|
|
3
3
|
import { useI18n } from '../../../domains/i18n'
|
|
4
4
|
import {
|
|
5
5
|
useSeamlyIsLoading,
|
|
6
|
-
useSeamlyVisibility,
|
|
7
6
|
useSkiplink,
|
|
8
7
|
useSkiplinkTargetFocusing,
|
|
9
8
|
} from '../../hooks/seamly-hooks'
|
|
@@ -12,13 +11,14 @@ import Event from './event/event'
|
|
|
12
11
|
import Loader from './loader'
|
|
13
12
|
import ComponentFilter from './component-filter'
|
|
14
13
|
import PrivacyDisclaimer from '../layout/privacy-disclaimer'
|
|
14
|
+
import { useVisibility } from '../../../domains/visibility'
|
|
15
15
|
|
|
16
16
|
const Conversation = () => {
|
|
17
17
|
const { t } = useI18n()
|
|
18
18
|
const appBodyContainer = useRef(null)
|
|
19
19
|
const events = useEvents()
|
|
20
20
|
const isLoading = useSeamlyIsLoading()
|
|
21
|
-
const { isOpen } =
|
|
21
|
+
const { isOpen } = useVisibility()
|
|
22
22
|
const skiplinkTargetId = useSkiplink()
|
|
23
23
|
const focusSkiplinkTarget = useSkiplinkTargetFocusing()
|
|
24
24
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useMemo } from 'preact/hooks'
|
|
2
1
|
import Mustache from 'mustache'
|
|
3
2
|
|
|
4
3
|
Mustache.escape = function (escapeText) {
|
|
@@ -11,7 +10,7 @@ const parseLinkVariable = (variable) => {
|
|
|
11
10
|
}>${variable.name}</a>`
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
export function
|
|
13
|
+
export function parseRichText(text, variables = {}) {
|
|
15
14
|
const view = {}
|
|
16
15
|
Object.entries(variables).forEach(([key, variable]) => {
|
|
17
16
|
switch (variable.type) {
|
|
@@ -34,9 +33,3 @@ export function parseRichtText(text, variables = {}) {
|
|
|
34
33
|
|
|
35
34
|
return output
|
|
36
35
|
}
|
|
37
|
-
|
|
38
|
-
const useTextRendering = ({ text, variables = {} }) => {
|
|
39
|
-
return useMemo(() => parseRichtText(text, variables), [text, variables])
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export default useTextRendering
|
|
@@ -1,29 +1,35 @@
|
|
|
1
|
+
import { useMemo } from 'preact/hooks'
|
|
1
2
|
import parseBody from '../../../../lib/parse-body'
|
|
2
3
|
import useEventLinkClickHandler from './hooks/use-event-link-click-handler'
|
|
3
|
-
import
|
|
4
|
+
import { parseRichText } from './hooks/use-text-rendering'
|
|
4
5
|
import MessageContainer from '../message-container'
|
|
5
6
|
import { useTranslatedEventData } from '../../../../domains/translations'
|
|
6
7
|
|
|
7
8
|
const Text = ({ event, ...props }) => {
|
|
8
|
-
const { payload } = event
|
|
9
|
-
|
|
10
9
|
const [body] = useTranslatedEventData(event)
|
|
11
|
-
const eventClick = useEventLinkClickHandler(payload.id)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const eventClick = useEventLinkClickHandler(event.payload.id)
|
|
11
|
+
|
|
12
|
+
const containerProps = useMemo(() => {
|
|
13
|
+
if (!event.payload.fromClient) {
|
|
14
|
+
return {
|
|
15
|
+
bodyProps: {
|
|
16
|
+
dangerouslySetInnerHTML: {
|
|
17
|
+
__html: parseRichText(parseBody(body.text), body.variables),
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
children: <p>{body.text}</p>,
|
|
24
|
+
}
|
|
25
|
+
}, [body, event])
|
|
16
26
|
return (
|
|
17
27
|
<MessageContainer
|
|
18
28
|
type="text"
|
|
19
29
|
event={event}
|
|
20
30
|
onClick={eventClick}
|
|
21
31
|
{...props}
|
|
22
|
-
|
|
23
|
-
dangerouslySetInnerHTML: {
|
|
24
|
-
__html: eventBody,
|
|
25
|
-
},
|
|
26
|
-
}}
|
|
32
|
+
{...containerProps}
|
|
27
33
|
/>
|
|
28
34
|
)
|
|
29
35
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useErrorBoundary } from 'preact/hooks'
|
|
1
2
|
import SeamlyInstanceFunctionsLoader from './seamly-instance-functions-loader'
|
|
2
3
|
import SeamlyReadState from './seamly-read-state'
|
|
3
4
|
import SeamlyNewNotifications from './seamly-new-notifications'
|
|
@@ -9,8 +10,10 @@ import SeamlyEventSubscriber from './seamly-event-subscriber'
|
|
|
9
10
|
import SeamlyFileUpload from './seamly-file-upload'
|
|
10
11
|
import { SeamlyEventBusContext, SeamlyApiContext } from './seamly-api-context'
|
|
11
12
|
import { StoreProvider } from '../../../domains/redux'
|
|
13
|
+
import { catchError } from '../../../domains/errors'
|
|
12
14
|
|
|
13
15
|
const SeamlyCore = ({ store, children, config, eventBus, api }) => {
|
|
16
|
+
useErrorBoundary((error) => store.dispatch(catchError(error)))
|
|
14
17
|
return (
|
|
15
18
|
<StoreProvider store={store}>
|
|
16
19
|
<SeamlyEventBusContext.Provider value={eventBus}>
|
|
@@ -179,15 +179,15 @@ const SeamlyEventSubscriber = ({ eventBus }) => {
|
|
|
179
179
|
switch (payload.type) {
|
|
180
180
|
case 'find_conversation_erred':
|
|
181
181
|
dispatch(
|
|
182
|
-
InterruptActions.set(new SeamlySessionExpiredError()),
|
|
182
|
+
InterruptActions.set(new SeamlySessionExpiredError(event)),
|
|
183
183
|
)
|
|
184
184
|
break
|
|
185
185
|
case 'seamly_offline':
|
|
186
|
-
dispatch(InterruptActions.set(new SeamlyOfflineError()))
|
|
186
|
+
dispatch(InterruptActions.set(new SeamlyOfflineError(event)))
|
|
187
187
|
dispatch({ type: CLEAR_EVENTS })
|
|
188
188
|
break
|
|
189
189
|
default:
|
|
190
|
-
dispatch(InterruptActions.set(new SeamlyGeneralError()))
|
|
190
|
+
dispatch(InterruptActions.set(new SeamlyGeneralError(event)))
|
|
191
191
|
break
|
|
192
192
|
}
|
|
193
193
|
break
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'preact/hooks'
|
|
2
|
-
import {
|
|
3
|
-
import { useSeamlyOptions, useSeamlyVisibility } from '../../hooks/seamly-hooks'
|
|
2
|
+
import { useSeamlyOptions } from '../../hooks/seamly-hooks'
|
|
4
3
|
import { useConfig } from '../../../domains/config'
|
|
5
4
|
|
|
6
5
|
const SeamlyInitializer = () => {
|
|
7
6
|
const { initUserSelectedOptions } = useSeamlyOptions()
|
|
8
7
|
const seamlyInitialized = useRef(false)
|
|
9
|
-
const { setVisibility } = useSeamlyVisibility()
|
|
10
8
|
const config = useConfig()
|
|
11
9
|
|
|
12
10
|
useEffect(() => {
|
|
13
11
|
if (config.api && !seamlyInitialized.current) {
|
|
14
12
|
seamlyInitialized.current = true
|
|
15
13
|
initUserSelectedOptions()
|
|
16
|
-
|
|
17
|
-
setVisibility(visibilityStates.initialize)
|
|
18
14
|
}
|
|
19
|
-
}, [initUserSelectedOptions, config
|
|
15
|
+
}, [initUserSelectedOptions, config])
|
|
20
16
|
|
|
21
17
|
return null
|
|
22
18
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { useContext, useEffect, useRef } from 'preact/hooks'
|
|
2
2
|
import {
|
|
3
3
|
useSeamlyCommands,
|
|
4
|
-
useSeamlyVisibility,
|
|
5
4
|
useSeamlyUnreadCount,
|
|
6
5
|
useSeamlyLayoutMode,
|
|
7
6
|
useSeamlyConversationUrl,
|
|
8
7
|
useSeamlyActivityEventHandler,
|
|
9
8
|
useSeamlyApiContext,
|
|
10
9
|
} from '../../hooks/seamly-hooks'
|
|
11
|
-
import { visibilityStates } from '../../utils/seamly-utils'
|
|
12
10
|
import { SeamlyEventBusContext } from './seamly-api-context'
|
|
13
11
|
import { useTranslations } from '../../../domains/translations'
|
|
14
12
|
import { useInterrupt } from '../../../domains/interrupt'
|
|
15
13
|
import { useConfig } from '../../../domains/config'
|
|
14
|
+
import { visibilityStates, useVisibility } from '../../../domains/visibility'
|
|
16
15
|
|
|
17
16
|
function useSeamlyInstanceFunction(functionName, fn, deps = []) {
|
|
18
17
|
const eventBus = useContext(SeamlyEventBusContext)
|
|
@@ -34,7 +33,7 @@ function useSeamlyInstanceFunction(functionName, fn, deps = []) {
|
|
|
34
33
|
const SeamlyInstanceFunctionsLoader = () => {
|
|
35
34
|
const config = useConfig()
|
|
36
35
|
const { sendMessage, sendContext, sendAction } = useSeamlyCommands()
|
|
37
|
-
const { setVisibility, visible } =
|
|
36
|
+
const { setVisibility, visible } = useVisibility()
|
|
38
37
|
const currentVisibility = useRef(visible)
|
|
39
38
|
const eventBus = useContext(SeamlyEventBusContext)
|
|
40
39
|
const api = useSeamlyApiContext()
|
|
@@ -3,11 +3,11 @@ import { useI18n } from '../../../domains/i18n'
|
|
|
3
3
|
import {
|
|
4
4
|
useEvents,
|
|
5
5
|
useLiveRegion,
|
|
6
|
-
useSeamlyVisibility,
|
|
7
6
|
useSeamlyIsHistoryLoaded,
|
|
8
7
|
} from '../../hooks/seamly-hooks'
|
|
9
8
|
import { newMessageScreenReaderWait } from '../../../config'
|
|
10
9
|
import { debounce } from '../../utils/general-utils'
|
|
10
|
+
import { useVisibility } from '../../../domains/visibility'
|
|
11
11
|
|
|
12
12
|
const SeamlyNewNotifications = () => {
|
|
13
13
|
const { t } = useI18n()
|
|
@@ -16,7 +16,7 @@ const SeamlyNewNotifications = () => {
|
|
|
16
16
|
const previousServerEventCount = useRef(0)
|
|
17
17
|
const isHistoryLoaded = useSeamlyIsHistoryLoaded()
|
|
18
18
|
const { sendPolite } = useLiveRegion()
|
|
19
|
-
const { isOpen } =
|
|
19
|
+
const { isOpen } = useVisibility()
|
|
20
20
|
const prevIsOpen = useRef(null)
|
|
21
21
|
const debounceFunc = useRef(null)
|
|
22
22
|
|
|
@@ -2,7 +2,6 @@ import { useEffect, useRef, useMemo } from 'preact/hooks'
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
useEvents,
|
|
5
|
-
useSeamlyVisibility,
|
|
6
5
|
useSeamlyCommands,
|
|
7
6
|
useLiveRegion,
|
|
8
7
|
useSeamlyUnreadCount,
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
} from '../../utils/seamly-utils'
|
|
18
17
|
import { debounce } from '../../utils/general-utils'
|
|
19
18
|
import { unreadScreenReaderWait } from '../../../config'
|
|
19
|
+
import { useVisibility } from '../../../domains/visibility'
|
|
20
20
|
|
|
21
21
|
const { SET_EVENTS_READ } = seamlyActions
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ const SeamlyReadState = () => {
|
|
|
24
24
|
const { t } = useI18n()
|
|
25
25
|
const events = useEvents()
|
|
26
26
|
const dispatch = useSeamlyDispatchContext()
|
|
27
|
-
const { isOpen, isVisible } =
|
|
27
|
+
const { isOpen, isVisible } = useVisibility()
|
|
28
28
|
const { sendAction } = useSeamlyCommands()
|
|
29
29
|
const unreadCount = useSeamlyUnreadCount()
|
|
30
30
|
const { sendPolite } = useLiveRegion()
|
|
@@ -2,7 +2,6 @@ import { useLayoutEffect, useRef } from 'preact/hooks'
|
|
|
2
2
|
import { useI18n } from '../../../domains/i18n'
|
|
3
3
|
import { className } from '../../../lib/css'
|
|
4
4
|
import {
|
|
5
|
-
useSeamlyVisibility,
|
|
6
5
|
useSkiplinkTargetFocusing,
|
|
7
6
|
useFocusIfSeamlyContainedFocus,
|
|
8
7
|
useSeamlyCurrentAgent,
|
|
@@ -11,11 +10,12 @@ import {
|
|
|
11
10
|
useSeamlyStateContext,
|
|
12
11
|
} from '../../hooks/seamly-hooks'
|
|
13
12
|
import { useInterrupt } from '../../../domains/interrupt'
|
|
13
|
+
import { useVisibility } from '../../../domains/visibility'
|
|
14
14
|
|
|
15
15
|
const ToggleButton = ({ onOpenChat }) => {
|
|
16
16
|
const { t } = useI18n()
|
|
17
17
|
const titleId = useGeneratedId()
|
|
18
|
-
const { isOpen } =
|
|
18
|
+
const { isOpen } = useVisibility()
|
|
19
19
|
const prevIsOpen = useRef(null)
|
|
20
20
|
const buttonRef = useRef(null)
|
|
21
21
|
const lastEventRef = useRef()
|
|
@@ -2,19 +2,19 @@ import Icon from './icon'
|
|
|
2
2
|
import {
|
|
3
3
|
useSeamlyHeaderData,
|
|
4
4
|
useSeamlyUnreadCount,
|
|
5
|
-
useSeamlyVisibility,
|
|
6
5
|
useSeamlyCurrentAgent,
|
|
7
6
|
} from '../../hooks/seamly-hooks'
|
|
8
7
|
import { className } from '../../../lib/css'
|
|
9
8
|
import { useI18n } from '../../../domains/i18n'
|
|
10
9
|
import { useInterrupt } from '../../../domains/interrupt'
|
|
11
10
|
import { useConfig } from '../../../domains/config'
|
|
11
|
+
import { useVisibility } from '../../../domains/visibility'
|
|
12
12
|
|
|
13
13
|
const AgentInfo = () => {
|
|
14
14
|
const { t } = useI18n()
|
|
15
15
|
const { title, subTitle } = useSeamlyHeaderData()
|
|
16
16
|
const unreadMessageCount = useSeamlyUnreadCount()
|
|
17
|
-
const { isOpen } =
|
|
17
|
+
const { isOpen } = useVisibility()
|
|
18
18
|
const currentAgent = useSeamlyCurrentAgent()
|
|
19
19
|
const { hasInterrupt } = useInterrupt()
|
|
20
20
|
const { defaults } = useConfig()
|
|
@@ -2,19 +2,18 @@ import { useCallback, useMemo } from 'preact/hooks'
|
|
|
2
2
|
import { className } from '../../../lib/css'
|
|
3
3
|
import {
|
|
4
4
|
useSeamlyAppContainerClassNames,
|
|
5
|
-
useSeamlyVisibility,
|
|
6
5
|
useSeamlyLayoutMode,
|
|
7
6
|
useSeamlyContainerElement,
|
|
8
7
|
} from '../../hooks/seamly-hooks'
|
|
9
8
|
import Faq from '../faq/faq'
|
|
10
|
-
import { visibilityStates } from '../../utils/seamly-utils'
|
|
11
9
|
import { useConfig } from '../../../domains/config'
|
|
12
10
|
import { useUserHasResponded } from '../../../domains/app'
|
|
13
11
|
import { useI18n } from '../../../domains/i18n'
|
|
12
|
+
import { useVisibility, visibilityStates } from '../../../domains/visibility'
|
|
14
13
|
|
|
15
14
|
const AppFrame = ({ children }) => {
|
|
16
15
|
const [, setSeamlyContainerElement] = useSeamlyContainerElement()
|
|
17
|
-
const { isOpen, isVisible, setVisibility } =
|
|
16
|
+
const { isOpen, isVisible, setVisibility } = useVisibility()
|
|
18
17
|
const { zIndex, showFaq } = useConfig()
|
|
19
18
|
const { isModal, isInline } = useSeamlyLayoutMode()
|
|
20
19
|
const appContainerClassNames = useSeamlyAppContainerClassNames()
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { className } from '../../../lib/css'
|
|
2
|
-
import { useSeamlyVisibility } from '../../hooks/seamly-hooks'
|
|
3
2
|
import CobrowsingActiveFrame from '../warnings/cobrowsing-active-frame'
|
|
4
3
|
import AppOptions from '../app-options'
|
|
5
4
|
import { ChatStatus as TranslationsChatStatus } from '../../../domains/translations'
|
|
6
5
|
import { useInterrupt } from '../../../domains/interrupt'
|
|
6
|
+
import { useVisibility } from '../../../domains/visibility'
|
|
7
7
|
|
|
8
8
|
function ChatFrame({ children, interruptComponent: InterruptComponent }) {
|
|
9
9
|
const { hasInterrupt, meta } = useInterrupt()
|
|
10
|
-
const { isOpen } =
|
|
10
|
+
const { isOpen } = useVisibility()
|
|
11
11
|
|
|
12
12
|
const getContent = () => {
|
|
13
13
|
if (hasInterrupt) {
|