@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.
Files changed (69) hide show
  1. package/build/dist/lib/index.debug.js +152 -64
  2. package/build/dist/lib/index.debug.min.js +1 -1
  3. package/build/dist/lib/index.debug.min.js.LICENSE.txt +40 -8
  4. package/build/dist/lib/index.js +595 -462
  5. package/build/dist/lib/index.min.js +1 -1
  6. package/build/dist/lib/standalone.js +716 -490
  7. package/build/dist/lib/standalone.min.js +1 -1
  8. package/build/dist/lib/storage.js +8 -1
  9. package/build/dist/lib/storage.min.js +1 -1
  10. package/build/dist/lib/style-guide.js +1920 -1814
  11. package/build/dist/lib/style-guide.min.js +1 -1
  12. package/package.json +1 -1
  13. package/src/javascripts/api/errors/seamly-base-error.js +10 -0
  14. package/src/javascripts/api/errors/seamly-configuration-error.js +4 -6
  15. package/src/javascripts/api/errors/seamly-general-error.js +4 -6
  16. package/src/javascripts/api/errors/seamly-offline-error.js +4 -6
  17. package/src/javascripts/api/errors/seamly-session-expired-error.js +4 -6
  18. package/src/javascripts/api/errors/seamly-unauthorized-error.js +4 -6
  19. package/src/javascripts/api/errors/seamly-unavailable-error.js +17 -0
  20. package/src/javascripts/api/index.js +10 -11
  21. package/src/javascripts/domains/app/actions.js +33 -24
  22. package/src/javascripts/domains/app/index.js +2 -1
  23. package/src/javascripts/domains/config/reducer.js +1 -0
  24. package/src/javascripts/domains/config/selectors.js +1 -1
  25. package/src/javascripts/domains/errors/index.js +32 -0
  26. package/src/javascripts/domains/i18n/actions.js +9 -24
  27. package/src/javascripts/domains/i18n/reducer.js +15 -3
  28. package/src/javascripts/domains/i18n/utils.js +2 -7
  29. package/src/javascripts/domains/interrupt/middleware.js +12 -9
  30. package/src/javascripts/domains/interrupt/reducer.js +10 -9
  31. package/src/javascripts/domains/store/index.js +7 -2
  32. package/src/javascripts/domains/store/state-reducer.js +10 -6
  33. package/src/javascripts/domains/visibility/actions.js +73 -0
  34. package/src/javascripts/domains/visibility/constants.js +8 -0
  35. package/src/javascripts/domains/visibility/hooks.js +24 -0
  36. package/src/javascripts/domains/visibility/index.js +8 -0
  37. package/src/javascripts/domains/visibility/reducer.js +19 -0
  38. package/src/javascripts/domains/visibility/selectors.js +9 -0
  39. package/src/javascripts/domains/visibility/utils.js +42 -0
  40. package/src/javascripts/index.js +3 -12
  41. package/src/javascripts/lib/engine/index.js +1 -0
  42. package/src/javascripts/lib/redux-helpers/index.js +45 -13
  43. package/src/javascripts/lib/store/providers/session-storage.js +6 -1
  44. package/src/javascripts/style-guide/components/app.js +1 -1
  45. package/src/javascripts/style-guide/components/static-core.js +6 -1
  46. package/src/javascripts/style-guide/states.js +48 -21
  47. package/src/javascripts/ui/components/conversation/conversation.js +2 -2
  48. package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +1 -8
  49. package/src/javascripts/ui/components/conversation/event/text.js +19 -13
  50. package/src/javascripts/ui/components/core/seamly-core.js +3 -0
  51. package/src/javascripts/ui/components/core/seamly-event-subscriber.js +3 -3
  52. package/src/javascripts/ui/components/core/seamly-initializer.js +2 -6
  53. package/src/javascripts/ui/components/core/seamly-instance-functions-loader.js +2 -3
  54. package/src/javascripts/ui/components/core/seamly-new-notifications.js +2 -2
  55. package/src/javascripts/ui/components/core/seamly-read-state.js +2 -2
  56. package/src/javascripts/ui/components/entry/toggle-button.js +2 -2
  57. package/src/javascripts/ui/components/layout/agent-info.js +2 -2
  58. package/src/javascripts/ui/components/layout/app-frame.js +2 -3
  59. package/src/javascripts/ui/components/layout/chat-frame.js +2 -2
  60. package/src/javascripts/ui/components/layout/modal-wrapper.js +3 -6
  61. package/src/javascripts/ui/components/layout/view.js +3 -6
  62. package/src/javascripts/ui/hooks/seamly-hooks.js +0 -2
  63. package/src/javascripts/ui/hooks/use-seamly-chat.js +3 -5
  64. package/src/javascripts/ui/hooks/use-seamly-commands.js +7 -29
  65. package/src/javascripts/ui/hooks/use-seamly-idle-detach-countdown.js +2 -2
  66. package/src/javascripts/ui/utils/general-utils.js +0 -9
  67. package/src/javascripts/ui/utils/seamly-utils.js +0 -66
  68. package/src/javascripts/ui/hooks/use-seamly-stored-visibility.js +0 -31
  69. package/src/javascripts/ui/hooks/use-seamly-visibility.js +0 -98
@@ -145,7 +145,6 @@ const general_utils_millisecondsToSeconds = milliseconds => {
145
145
  const microsecondsToMilliseconds = microseconds => {
146
146
  return Math.ceil(microseconds / 1000);
147
147
  };
148
- const general_utils_sanitizeText = text => text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/\//g, '&#x2F;');
149
148
  const general_utils_getTimeFromSeconds = seconds => {
150
149
  const minutes = Math.floor(seconds / 60);
151
150
  const secondsPartial = seconds - minutes * 60;
@@ -270,12 +269,6 @@ const entryTypes = {
270
269
  text: 'text',
271
270
  upload: 'upload'
272
271
  };
273
- const seamly_utils_visibilityStates = {
274
- hidden: 'hidden',
275
- minimized: 'minimized',
276
- open: 'open',
277
- initialize: null
278
- };
279
272
  const readStates = {
280
273
  received: 'received',
281
274
  read: 'read'
@@ -322,7 +315,6 @@ const seamly_utils_seamlyActions = {
322
315
  SET_PARTICIPANT: 'SET_PARTICIPANT',
323
316
  SET_HEADER_TITLE: 'SET_HEADER_TITLE',
324
317
  SET_HEADER_SUB_TITLE: 'SET_HEADER_SUB_TITLE',
325
- SET_VISIBILITY: 'SET_VISIBILITY',
326
318
  RESET_HISTORY_LOADED_FLAG: 'RESET_HISTORY_LOADED_FLAG',
327
319
  SET_ACTIVE_SERVICE: 'SET_ACTIVE_SERVICE',
328
320
  INIT_IDLE_DETACH_COUNTDOWN: 'INIT_IDLE_DETACH_COUNTDOWN',
@@ -350,8 +342,6 @@ const seamly_utils_seamlyActions = {
350
342
  SET_UPLOAD_ERROR: 'SET_UPLOAD_ERROR',
351
343
  CLEAR_UPLOAD: 'CLEAR_UPLOAD',
352
344
  CLEAR_ALL_UPLOADS: 'CLEAR_ALL_UPLOADS',
353
- RESET_UPLOAD_STATE: 'RESET_UPLOAD_STATE',
354
- RESET_ENTRY_STATE: 'RESET_ENTRY_STATE',
355
345
  SET_SEAMLY_CONTAINER_ELEMENT: 'SET_SEAMLY_CONTAINER_ELEMENT'
356
346
  };
357
347
  const cardTypes = {
@@ -370,7 +360,6 @@ const {
370
360
  SET_PARTICIPANT,
371
361
  SET_HEADER_TITLE,
372
362
  SET_HEADER_SUB_TITLE,
373
- SET_VISIBILITY,
374
363
  RESET_HISTORY_LOADED_FLAG,
375
364
  SET_ACTIVE_SERVICE,
376
365
  INIT_IDLE_DETACH_COUNTDOWN,
@@ -398,8 +387,6 @@ const {
398
387
  SET_UPLOAD_ERROR,
399
388
  CLEAR_UPLOAD,
400
389
  CLEAR_ALL_UPLOADS,
401
- RESET_UPLOAD_STATE,
402
- RESET_ENTRY_STATE,
403
390
  SET_SEAMLY_CONTAINER_ELEMENT
404
391
  } = seamly_utils_seamlyActions;
405
392
  const isUnreadMessage = ({
@@ -778,11 +765,6 @@ const seamlyStateReducer = (state, action) => {
778
765
  resumeConversationPrompt: false
779
766
  });
780
767
 
781
- case SET_VISIBILITY:
782
- return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
783
- visible: action.visible
784
- });
785
-
786
768
  case SET_PARTICIPANT:
787
769
  case CLEAR_PARTICIPANTS:
788
770
  return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
@@ -990,26 +972,6 @@ const seamlyStateReducer = (state, action) => {
990
972
  currentUploads: []
991
973
  });
992
974
 
993
- case RESET_UPLOAD_STATE:
994
- return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
995
- showFileUpload: false,
996
- currentUploads: []
997
- });
998
-
999
- case RESET_ENTRY_STATE:
1000
- {
1001
- return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
1002
- entryMeta: {
1003
- default: payloadTypes.text,
1004
- active: payloadTypes.text,
1005
- userSelected: null,
1006
- blockAutoEntrySwitch: false,
1007
- options: {},
1008
- optionsOverride: {}
1009
- }
1010
- });
1011
- }
1012
-
1013
975
  case SET_SEAMLY_CONTAINER_ELEMENT:
1014
976
  {
1015
977
  return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
@@ -1021,81 +983,6 @@ const seamlyStateReducer = (state, action) => {
1021
983
  return state;
1022
984
  }
1023
985
  };
1024
- const seamly_utils_calculateVisibility = ({
1025
- hasResponded,
1026
- previousVisibility,
1027
- requestedVisibility,
1028
- config
1029
- }) => {
1030
- const {
1031
- defaults,
1032
- layoutMode,
1033
- hideOnNoUserResponse
1034
- } = config;
1035
- const {
1036
- visible: defaultVisibility
1037
- } = defaults || {}; // Requesting open should override the responded check.
1038
-
1039
- if (layoutMode === 'window' && hideOnNoUserResponse && requestedVisibility !== seamly_utils_visibilityStates.open) {
1040
- return hasResponded ? requestedVisibility || previousVisibility || seamly_utils_visibilityStates.open : seamly_utils_visibilityStates.hidden;
1041
- }
1042
-
1043
- const baseVisibility = layoutMode === 'inline' ? seamly_utils_visibilityStates.open : seamly_utils_visibilityStates.minimized;
1044
- return requestedVisibility || previousVisibility || defaultVisibility || baseVisibility;
1045
- };
1046
- ;// CONCATENATED MODULE: ./src/javascripts/domains/store/state-reducer.js
1047
- // Legacy state reducer. Do not add new features here but extract/create new reducers as needed
1048
-
1049
-
1050
- const initialState = {
1051
- events: [],
1052
- initialState: {},
1053
- unreadEvents: 0,
1054
- isLoading: false,
1055
- idleDetachCountdown: {
1056
- hasCountdown: false,
1057
- isActive: false
1058
- },
1059
- resumeConversationPrompt: false,
1060
- visible: seamly_utils_visibilityStates.hidden,
1061
- serviceInfo: {
1062
- activeServiceSessionId: ''
1063
- },
1064
- participantInfo: {
1065
- participants: {},
1066
- currentAgent: ''
1067
- },
1068
- headerTitles: {
1069
- title: null,
1070
- subTitle: ''
1071
- },
1072
- historyLoaded: false,
1073
- skiplinkTargetId: id_randomId(),
1074
- optionsButtonId: id_randomId(),
1075
- cobrowsingContainerId: id_randomId(),
1076
- headerCollapseButtonId: id_randomId(),
1077
- serviceData: {},
1078
- options: {
1079
- features: {},
1080
- panelActive: false,
1081
- optionActive: '',
1082
- userSelectedOptions: {}
1083
- },
1084
- showFileUpload: false,
1085
- currentUploads: [],
1086
- entryMeta: {
1087
- default: entryTypes.text,
1088
- active: entryTypes.text,
1089
- userSelected: null,
1090
- blockAutoEntrySwitch: false,
1091
- options: {},
1092
- optionsOverride: {}
1093
- },
1094
- seamlyContainerElement: null
1095
- };
1096
- function stateReducer(state = initialState, action) {
1097
- return seamlyStateReducer(state, action);
1098
- }
1099
986
  ;// CONCATENATED MODULE: ./src/javascripts/lib/redux-helpers/index.js
1100
987
  function redux_helpers_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1101
988
 
@@ -1103,6 +990,7 @@ function redux_helpers_objectSpread(target) { for (var i = 1; i < arguments.leng
1103
990
 
1104
991
  function redux_helpers_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1105
992
 
993
+
1106
994
  const SLICE_DELIMITER = '/';
1107
995
  const DOMAIN_DELIMITER = '//';
1108
996
  function prefixType(prefix, fn, delimiter = '/') {
@@ -1115,7 +1003,9 @@ function createAction(type, identityReducer = payload => ({
1115
1003
  type
1116
1004
  }, identityReducer(...params));
1117
1005
 
1118
- action.toString = () => type.toString();
1006
+ action.toString = () => String(type);
1007
+
1008
+ action.match = obj => (obj === null || obj === void 0 ? void 0 : obj.type) === String(type);
1119
1009
 
1120
1010
  return action;
1121
1011
  }
@@ -1138,24 +1028,73 @@ function createActions(baseType, ...args) {
1138
1028
  const create = prefixType(baseType, createAction, SLICE_DELIMITER);
1139
1029
  return handlers.map(handler => create(...handler));
1140
1030
  }
1141
- function createThunk(type, thunkCreator) {
1142
- const fn = (...args) => {
1143
- const thunk = thunkCreator(...args);
1144
- thunk.type = type;
1145
- return thunk;
1146
- };
1031
+ function createThunk(type, payloadCreator) {
1032
+ const [pending, fulfilled, rejected] = createActions(type, {
1033
+ pending: (arg, requestId) => ({
1034
+ meta: {
1035
+ arg,
1036
+ requestId,
1037
+ status: 'pending'
1038
+ }
1039
+ }),
1040
+ fulfilled: (arg, payload, requestId) => ({
1041
+ payload,
1042
+ meta: {
1043
+ arg,
1044
+ requestId,
1045
+ status: 'fulfilled'
1046
+ }
1047
+ }),
1048
+ rejected: (arg, error, requestId) => ({
1049
+ error,
1050
+ meta: {
1051
+ arg,
1052
+ requestId,
1053
+ status: 'rejected',
1054
+ error: String(error)
1055
+ }
1056
+ })
1057
+ });
1058
+
1059
+ const thunkCreator = arg => (dispatch, getState, extra) => {
1060
+ const requestId = id_randomId();
1061
+
1062
+ const promise = (async () => {
1063
+ let finalAction;
1064
+
1065
+ try {
1066
+ dispatch(pending(arg, requestId));
1067
+ const prms = payloadCreator(arg, {
1068
+ dispatch,
1069
+ getState,
1070
+ extra
1071
+ });
1072
+ const result = await prms;
1073
+ finalAction = fulfilled(arg, result, requestId);
1074
+ } catch (error) {
1075
+ finalAction = rejected(arg, error, requestId);
1076
+ }
1147
1077
 
1148
- fn.toString = () => type;
1078
+ dispatch(finalAction);
1079
+ return finalAction;
1080
+ })();
1149
1081
 
1150
- return fn;
1082
+ return Object.assign(promise, {
1083
+ type,
1084
+ arg,
1085
+ requestId
1086
+ });
1087
+ };
1088
+
1089
+ return Object.assign(thunkCreator, {
1090
+ type,
1091
+ pending,
1092
+ fulfilled,
1093
+ rejected
1094
+ });
1151
1095
  }
1152
1096
  function createReducer(domain, handlers = {}, defaultState) {
1153
- const reducer = (state, action) => {
1154
- if (state === undefined) {
1155
- // eslint-disable-next-line no-param-reassign
1156
- state = defaultState;
1157
- }
1158
-
1097
+ const reducer = (state = defaultState, action) => {
1159
1098
  const typeReducer = handlers === null || handlers === void 0 ? void 0 : handlers[action === null || action === void 0 ? void 0 : action.type];
1160
1099
  return typeReducer ? typeReducer(state, action) : state;
1161
1100
  };
@@ -1173,63 +1112,22 @@ function createDomain(domain) {
1173
1112
  selectState: state => state[domain]
1174
1113
  };
1175
1114
  }
1176
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/utils.js
1115
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/utils.js
1177
1116
 
1178
1117
  const {
1179
- createActions: utils_createActions,
1118
+ createAction: utils_createAction,
1119
+ createThunk: utils_createThunk,
1180
1120
  createReducer: utils_createReducer,
1181
1121
  selectState
1182
- } = createDomain('forms');
1183
- function utils_validate(values, schema = {}) {
1184
- return Object.entries(schema).reduce((errors, [key, validations]) => {
1185
- if (validations && !Array.isArray(validations)) {
1186
- // eslint-disable-next-line no-param-reassign
1187
- validations = [validations];
1188
- }
1189
-
1190
- for (let i = 0; i < ((_validations = validations) === null || _validations === void 0 ? void 0 : _validations.length) ?? 0; i++) {
1191
- var _validations;
1192
-
1193
- if (!validations[i].fn(values[key], validations[i].compareValue)) {
1194
- errors[key] = validations[i].errorText;
1195
- break;
1196
- }
1197
- }
1198
-
1199
- return errors;
1200
- }, {});
1201
- }
1202
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/actions.js
1122
+ } = createDomain('config');
1123
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/actions.js
1203
1124
 
1204
- const [registerForm, deregisterForm] = utils_createActions('form', {
1205
- register: (formId, persistData) => ({
1206
- formId,
1207
- persistData
1208
- }),
1209
- deregister: formId => ({
1210
- formId
1211
- })
1212
- });
1213
- const [registerControl, deregisterControl, updateControlValue, updateControlTouched] = utils_createActions('control', {
1214
- register: (formId, name) => ({
1215
- formId,
1216
- name
1217
- }),
1218
- deregister: (formId, name) => ({
1219
- formId,
1220
- name
1221
- }),
1222
- updateValue: (formId, name, value) => ({
1223
- formId,
1224
- name,
1225
- value
1226
- }),
1227
- updateTouched: (formId, name, touched) => ({
1228
- formId,
1229
- name,
1230
- touched
1231
- })
1232
- });
1125
+ const initialize = utils_createAction('initialize', config => ({
1126
+ config
1127
+ }));
1128
+ const update = utils_createAction('update', config => ({
1129
+ config
1130
+ }));
1233
1131
  ;// CONCATENATED MODULE: ./node_modules/reselect/es/index.js
1234
1132
  function defaultEqualityCheck(a, b) {
1235
1133
  return a === b;
@@ -1351,45 +1249,39 @@ function createStructuredSelector(selectors) {
1351
1249
  }, {});
1352
1250
  });
1353
1251
  }
1354
- ;// CONCATENATED MODULE: ./src/javascripts/domains/redux/utils.js
1355
- const arrayContentEquals = (a, b) => {
1356
- if (a === b) {
1357
- return true;
1358
- }
1252
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/constants.js
1253
+ const StoreKey = 'visibility';
1254
+ const constants_visibilityStates = {
1255
+ hidden: 'hidden',
1256
+ minimized: 'minimized',
1257
+ open: 'open',
1258
+ initialize: null
1259
+ };
1260
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/selectors.js
1261
+ function selectors_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1359
1262
 
1360
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
1361
- return false;
1362
- }
1263
+ function selectors_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { selectors_ownKeys(Object(source), true).forEach(function (key) { selectors_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { selectors_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1363
1264
 
1364
- return a.every((value, idx) => b[idx] === value);
1365
- };
1366
- const getPropSelector = (propName, orDefault) => (_, props) => props[propName] || orDefault;
1367
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/selectors.js
1265
+ function selectors_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1368
1266
 
1369
1267
 
1370
1268
 
1371
- const getState = selectState;
1372
- const selectors_getFormById = createSelector(getState, getPropSelector('formId'), (forms, formId) => forms[formId]);
1373
- const getFormControlsByFormId = createSelector(selectors_getFormById, form => (form === null || form === void 0 ? void 0 : form.controls) || {});
1374
- const selectors_getFormValuesByFormId = createSelector(getFormControlsByFormId, controls => {
1375
- const valuesObj = {};
1376
- Object.entries(controls).forEach(([key, {
1377
- value
1378
- }]) => {
1379
- valuesObj[key] = value;
1380
- });
1381
- return valuesObj;
1382
- });
1383
- const selectors_getControlValueByName = createSelector(getFormControlsByFormId, getPropSelector('name'), (controls, name) => {
1384
- var _controls$name;
1385
1269
 
1386
- return (_controls$name = controls[name]) === null || _controls$name === void 0 ? void 0 : _controls$name.value;
1387
- });
1388
- const selectors_getControlTouchedByName = createSelector(getFormControlsByFormId, getPropSelector('name'), (controls, name) => {
1389
- var _controls$name2;
1270
+ const selectConfig = createSelector(selectState, config => {
1271
+ let newConfig = selectors_objectSpread({
1272
+ visible: (config === null || config === void 0 ? void 0 : config.layoutMode) === 'inline' ? constants_visibilityStates.open : constants_visibilityStates.minimized,
1273
+ appContainerClassNames: config.appContainerClassNames || []
1274
+ }, config);
1390
1275
 
1391
- return (_controls$name2 = controls[name]) === null || _controls$name2 === void 0 ? void 0 : _controls$name2.touched;
1276
+ if (typeof newConfig.appContainerClassNames === 'function') {
1277
+ newConfig = selectors_objectSpread(selectors_objectSpread({}, newConfig), {}, {
1278
+ appContainerClassNames: newConfig.appContainerClassNames(newConfig)
1279
+ });
1280
+ }
1281
+
1282
+ return newConfig;
1392
1283
  });
1284
+
1393
1285
  ;// CONCATENATED MODULE: ./src/javascripts/domains/redux/context.js
1394
1286
 
1395
1287
  const context_StoreContext = (0,external_preact_namespaceObject.createContext)(undefined);
@@ -1488,932 +1380,841 @@ const hooks_useSelectorWithProps = function useSelectorWithProps(selector, props
1488
1380
 
1489
1381
 
1490
1382
 
1491
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/context.js
1383
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/hooks.js
1492
1384
 
1493
- const context_FormContext = (0,external_preact_namespaceObject.createContext)({});
1494
- /* harmony default export */ const forms_context = ((/* unused pure expression or super */ null && (context_FormContext)));
1495
- const {
1496
- Provider: forms_context_Provider,
1497
- Consumer: context_Consumer
1498
- } = context_FormContext;
1499
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/hooks.js
1500
1385
 
1386
+ function hooks_useConfig() {
1387
+ return useSelector(Selectors.selectConfig);
1388
+ }
1389
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/middleware.js
1501
1390
 
1502
1391
 
1392
+ function createMiddleware() {
1393
+ return ({
1394
+ dispatch
1395
+ }) => next => action => {
1396
+ var _action$config, _action$config$defaul;
1503
1397
 
1398
+ const result = next(action);
1504
1399
 
1400
+ switch (action.type) {
1401
+ case String(Actions.initialize):
1402
+ case String(Actions.update):
1403
+ if (action !== null && action !== void 0 && (_action$config = action.config) !== null && _action$config !== void 0 && (_action$config$defaul = _action$config.defaults) !== null && _action$config$defaul !== void 0 && _action$config$defaul.agentName) {
1404
+ var _action$config2, _action$config2$defau;
1405
+
1406
+ dispatch({
1407
+ type: seamlyActions.SET_HEADER_SUB_TITLE,
1408
+ title: action === null || action === void 0 ? void 0 : (_action$config2 = action.config) === null || _action$config2 === void 0 ? void 0 : (_action$config2$defau = _action$config2.defaults) === null || _action$config2$defau === void 0 ? void 0 : _action$config2$defau.agentName
1409
+ });
1410
+ }
1505
1411
 
1506
- function hooks_useFormContext() {
1507
- return useContext(FormContext);
1508
- }
1509
- function hooks_useForm() {
1510
- const {
1511
- handleSubmit
1512
- } = hooks_useFormContext();
1513
- return {
1514
- handleSubmit
1515
- };
1516
- }
1517
- function hooks_useValidations(values, validationSchema) {
1518
- const errors = useMemo(() => validate(values, validationSchema), [values, validationSchema]);
1519
- return {
1520
- isValid: Object.keys(errors).length === 0,
1521
- errors
1522
- };
1523
- }
1524
- function hooks_useFormControl(name) {
1525
- const dispatch = useStoreDispatch();
1526
- const {
1527
- formId,
1528
- updateControlValue,
1529
- updateControlTouched,
1530
- errors
1531
- } = hooks_useFormContext();
1532
- const form = useSelectorWithProps(getFormById, {
1533
- formId
1534
- }, [formId]);
1535
- const isRegistered = !!form;
1536
- const isRegisteredRef = useRef();
1537
- isRegisteredRef.current = isRegistered;
1538
- const value = useSelectorWithProps(getControlValueByName, {
1539
- formId,
1540
- name
1541
- }, [formId, name]);
1542
- const touched = useSelectorWithProps(getControlTouchedByName, {
1543
- formId,
1544
- name
1545
- }, [formId, name]);
1546
- const error = errors === null || errors === void 0 ? void 0 : errors[name];
1547
- const isValid = !error;
1548
- useEffect(() => {
1549
- // Make sure the form is registered
1550
- // Since child useEffect runs before FormProvider useEffect
1551
- if (isRegisteredRef.current) {
1552
- dispatch(Actions.registerControl(formId, name));
1553
1412
  }
1554
- }, [isRegistered, formId, name, dispatch]);
1555
- useLayoutEffect(() => {
1556
- return () => {
1557
- dispatch(Actions.deregisterControl(formId, name));
1558
- };
1559
- }, [isRegistered, formId, name, dispatch]); // preact uses onInput instead of onChange
1560
1413
 
1561
- const onInput = useCallback(e => updateControlValue(name, e.target.value), [name, updateControlValue]);
1562
- const onBlur = useCallback(() => {
1563
- updateControlTouched(name, true);
1564
- }, [updateControlTouched, name]);
1565
- const field = useMemo(() => ({
1566
- name,
1567
- onInput,
1568
- onBlur,
1569
- value
1570
- }), [name, onInput, onBlur, value]);
1571
- const meta = useMemo(() => ({
1572
- isValid,
1573
- error,
1574
- touched
1575
- }), [isValid, error, touched]);
1576
- return [field, meta];
1414
+ return result;
1415
+ };
1577
1416
  }
1578
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/provider.js
1579
- const _excluded = (/* unused pure expression or super */ null && (["children", "formId", "persistData", "onSubmit", "validationSchema"]));
1417
+ ;// CONCATENATED MODULE: ./src/javascripts/config.js
1418
+ const CSS_NAME = 'cvco';
1419
+ const apiVersion = '2';
1420
+ const config_userParticipantId = 'seamly-client-participant'; // How long to debounce distinct changes in unread messages for before
1421
+ // broadcasting to the screen reader. This is done to avoid verbosity.
1580
1422
 
1581
- function provider_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1423
+ const unreadScreenReaderWait = 2000;
1424
+ const newMessageScreenReaderWait = 1000;
1425
+ const config_screenReaderDebounceDelaySeconds = 10;
1426
+ const activitySendDelay = 15000;
1427
+ const maxCharacterWarningLimit = 50;
1428
+ const maxCharacterSrDebounceDelay = 300;
1429
+ const config_defaultTransitionTimeMs = 300; // How long to wait before we decide the user isn't typing
1582
1430
 
1583
- function provider_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { provider_ownKeys(Object(source), true).forEach(function (key) { provider_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { provider_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1431
+ const config_typingTimeout = 2000;
1432
+ const defaultConfig = {
1433
+ namespace: 'default',
1434
+ layoutMode: 'window',
1435
+ // "window", "inline" ("sidebar"), "modal"
1436
+ messages: {
1437
+ agent: {
1438
+ showAvatar: false,
1439
+ // true, "inline"
1440
+ showName: false
1441
+ },
1442
+ user: {
1443
+ showAvatar: false,
1444
+ // true, "inline"
1445
+ showName: false
1446
+ },
1447
+ timeIndicator: {
1448
+ enabled: false,
1449
+ threshold: 3600000 // Default threshold is an hour in milliseconds
1584
1450
 
1585
- function provider_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1451
+ }
1452
+ },
1453
+ appContainerClassNames: config => [`app--layout-${config.layoutMode}`, `namespace--${config.namespace}`]
1454
+ };
1455
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/reducer.js
1456
+ const _excluded = ["messages"];
1586
1457
 
1587
1458
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
1588
1459
 
1589
1460
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
1590
1461
 
1462
+ function reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1591
1463
 
1464
+ function reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { reducer_ownKeys(Object(source), true).forEach(function (key) { reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1592
1465
 
1466
+ function reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1593
1467
 
1594
1468
 
1595
1469
 
1596
1470
 
1597
1471
 
1598
- function provider_FormProvider(_ref) {
1599
- let {
1600
- children,
1601
- formId,
1602
- persistData,
1603
- onSubmit,
1604
- validationSchema
1605
- } = _ref,
1606
- props = _objectWithoutProperties(_ref, _excluded);
1607
1472
 
1608
- const dispatch = useStoreDispatch();
1609
- const values = useSelectorWithProps(getFormValuesByFormId, {
1610
- formId
1611
- }, [formId]);
1612
- const [isSubmitted, setIsSubmitted] = useState(false);
1613
- const [externalErrors, setExternalErrors] = useState({});
1614
- const {
1615
- isValid: validationIsValid,
1616
- errors: validationErrors
1617
- } = useValidations(values, validationSchema);
1618
- const errors = useMemo(() => provider_objectSpread(provider_objectSpread({}, validationErrors), externalErrors), [validationErrors, externalErrors]); // register
1473
+ const initialState = reducer_objectSpread(reducer_objectSpread({}, defaultConfig), {}, {
1474
+ hideOnNoUserResponse: false,
1475
+ showDisclaimer: false,
1476
+ showFaq: false,
1477
+ customComponents: {},
1478
+ defaults: {}
1479
+ });
1619
1480
 
1620
- useLayoutEffect(() => {
1621
- // register form in redux store
1622
- dispatch(Actions.registerForm(formId, persistData));
1623
- }, [formId, persistData, dispatch]); // deregister
1481
+ const configKeys = ['hideOnNoUserResponse', 'showDisclaimer', 'showFaq', 'namespace', 'customComponents', 'defaults', 'layoutMode', 'api', 'zIndex', 'context', 'appContainerClassNames', 'messages', 'visible', 'visibilityCallback', 'errorCallback'];
1624
1482
 
1625
- useEffect(() => {
1626
- return () => {
1627
- // deregister form from redux store
1628
- dispatch(Actions.deregisterForm(formId));
1629
- };
1630
- }, [formId, persistData, dispatch]);
1631
- const updateControlValue = useCallback((name, value) => {
1632
- dispatch(Actions.updateControlValue(formId, name, value));
1633
- }, [formId, dispatch]);
1634
- const updateControlTouched = useCallback((name, touched) => {
1635
- dispatch(Actions.updateControlTouched(formId, name, touched));
1636
- }, [dispatch, formId]); // Function to manually set an error
1483
+ const updateState = (state, {
1484
+ config
1485
+ }) => {
1486
+ const _pick = pick(config, configKeys),
1487
+ {
1488
+ messages
1489
+ } = _pick,
1490
+ partialConfig = _objectWithoutProperties(_pick, _excluded);
1637
1491
 
1638
- const setError = useCallback((name, error) => {
1639
- setExternalErrors(val => {
1640
- return provider_objectSpread(provider_objectSpread({}, val), {}, {
1641
- [name]: error
1642
- });
1643
- });
1644
- }, [setExternalErrors]);
1645
- const handleSubmit = useCallback(e => {
1646
- e.preventDefault();
1647
- setIsSubmitted(true);
1492
+ let newState = state;
1648
1493
 
1649
- if (validationIsValid) {
1650
- onSubmit(values, {
1651
- updateControlValue,
1652
- setError
1653
- });
1654
- }
1655
- }, [validationIsValid, onSubmit, values, updateControlValue, setError]);
1656
- const contextValue = useMemo(() => ({
1657
- formId,
1658
- values,
1659
- errors,
1660
- isValid: Object.keys(errors).length === 0,
1661
- isSubmitted,
1662
- handleSubmit,
1663
- validationSchema,
1664
- updateControlValue,
1665
- updateControlTouched
1666
- }), [formId, values, errors, isSubmitted, handleSubmit, validationSchema, updateControlValue, updateControlTouched]);
1494
+ if (Object.keys(partialConfig).length > 0) {
1495
+ newState = reducer_objectSpread(reducer_objectSpread({}, newState), partialConfig);
1496
+ }
1667
1497
 
1668
- if (!formId) {
1669
- console.error('"formId" is required.');
1670
- return null;
1498
+ if (messages) {
1499
+ newState = reducer_objectSpread(reducer_objectSpread({}, newState), {}, {
1500
+ messages: reducer_objectSpread(reducer_objectSpread({}, newState.messages), messages)
1501
+ });
1671
1502
  }
1672
1503
 
1673
- if (!onSubmit) {
1674
- console.error('"onSubmit" is required.');
1675
- return null;
1504
+ return newState;
1505
+ };
1506
+
1507
+ /* harmony default export */ const reducer = (utils_createReducer({
1508
+ [initialize]: (state, action) => {
1509
+ return updateState(state, action);
1510
+ },
1511
+ [update]: (state, action) => {
1512
+ return updateState(state, action);
1676
1513
  }
1514
+ }, initialState));
1515
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/config/index.js
1677
1516
 
1678
- return _jsx(Provider, provider_objectSpread(provider_objectSpread({}, props), {}, {
1679
- value: contextValue,
1680
- children: children
1681
- }));
1682
- }
1683
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/reducer.js
1684
- function reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1685
1517
 
1686
- function reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { reducer_ownKeys(Object(source), true).forEach(function (key) { reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1687
1518
 
1688
- function reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1689
1519
 
1690
1520
 
1691
1521
 
1692
- const reducer_initialState = {};
1693
- const initialFormState = {
1694
- controls: {}
1695
- };
1696
- const initialControlState = {
1697
- value: '',
1698
- touched: false
1699
- };
1522
+ ;// CONCATENATED MODULE: ./src/javascripts/lib/mutex.js
1523
+ function createMutex() {
1524
+ let isRunning = false;
1525
+ const tasks = [];
1700
1526
 
1701
- function updateFormControl(state, formId, name, controlState) {
1702
- var _state$formId;
1527
+ const next = async () => {
1528
+ if (!isRunning) {
1529
+ while (tasks.length) {
1530
+ const task = tasks.shift();
1531
+ isRunning = true; // eslint-disable-next-line no-await-in-loop
1703
1532
 
1704
- const currentControlState = ((_state$formId = state[formId]) === null || _state$formId === void 0 ? void 0 : _state$formId.controls[name]) || initialControlState;
1705
- return reducer_objectSpread(reducer_objectSpread({}, state), {}, {
1706
- [formId]: reducer_objectSpread(reducer_objectSpread({}, state[formId]), {}, {
1707
- controls: reducer_objectSpread(reducer_objectSpread({}, state[formId].controls), {}, {
1708
- [name]: reducer_objectSpread(reducer_objectSpread({}, currentControlState), controlState)
1709
- })
1710
- })
1711
- });
1712
- }
1533
+ await task().catch(() => {});
1534
+ isRunning = false;
1535
+ }
1536
+ }
1537
+ };
1713
1538
 
1714
- /* harmony default export */ const reducer = (utils_createReducer({
1715
- // Form handlers
1716
- [registerForm]: (state, {
1717
- formId,
1718
- persistData
1719
- }) => {
1720
- const formState = persistData ? state[formId] ?? reducer_objectSpread(reducer_objectSpread({}, initialFormState), {}, {
1721
- persistData
1722
- }) : reducer_objectSpread(reducer_objectSpread({}, initialFormState), {}, {
1723
- persistData
1724
- });
1725
- return reducer_objectSpread(reducer_objectSpread({}, state), {}, {
1726
- [formId]: formState
1727
- });
1728
- },
1729
- [deregisterForm]: (state, {
1730
- formId
1731
- }) => {
1732
- var _newState$formId;
1733
-
1734
- const newState = reducer_objectSpread({}, state);
1735
-
1736
- if (!((_newState$formId = newState[formId]) !== null && _newState$formId !== void 0 && _newState$formId.persistData)) {
1737
- delete newState[formId];
1738
- }
1739
-
1740
- return newState;
1741
- },
1742
- // Form control handlers
1743
- [registerControl]: (state, {
1744
- name,
1745
- formId
1746
- }) => {
1747
- return updateFormControl(state, formId, name);
1748
- },
1749
- [deregisterControl]: (state, {
1750
- formId,
1751
- name
1752
- }) => {
1753
- const form = state[formId];
1754
-
1755
- if (!form) {
1756
- return state;
1757
- }
1758
-
1759
- if (form.persistData) {
1760
- return state;
1761
- }
1762
-
1763
- const controls = reducer_objectSpread({}, form.controls);
1764
-
1765
- delete controls[name];
1766
- return reducer_objectSpread(reducer_objectSpread({}, state), {}, {
1767
- [formId]: reducer_objectSpread(reducer_objectSpread({}, form), {}, {
1768
- controls
1769
- })
1770
- });
1771
- },
1772
- [updateControlValue]: (state, {
1773
- formId,
1774
- name,
1775
- value
1776
- }) => {
1777
- return updateFormControl(state, formId, name, {
1778
- value
1779
- });
1780
- },
1781
- [updateControlTouched]: (state, {
1782
- formId,
1783
- name,
1784
- touched
1785
- }) => {
1786
- return updateFormControl(state, formId, name, {
1787
- touched
1539
+ const runExclusively = async task => {
1540
+ const prms = new Promise((resolve, reject) => {
1541
+ tasks.push(async () => {
1542
+ try {
1543
+ resolve(await task());
1544
+ } catch (e) {
1545
+ reject(e);
1546
+ }
1547
+ });
1788
1548
  });
1789
- }
1790
- }, reducer_initialState));
1791
- ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/index.js
1792
-
1793
-
1794
-
1795
-
1796
-
1549
+ next();
1550
+ return prms;
1551
+ };
1797
1552
 
1798
- ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/utils.js
1553
+ return {
1554
+ next,
1555
+ runExclusively
1556
+ };
1557
+ }
1558
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/utils.js
1799
1559
 
1800
1560
  const {
1801
- createActions: translations_utils_createActions,
1802
- createReducer: translations_utils_createReducer,
1561
+ createAction: i18n_utils_createAction,
1562
+ createThunk: i18n_utils_createThunk,
1563
+ createReducer: i18n_utils_createReducer,
1803
1564
  selectState: utils_selectState
1804
- } = createDomain('translations');
1805
- ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/actions.js
1806
-
1807
- const [enable, disable] = translations_utils_createActions('translate', {
1808
- enable: locale => ({
1809
- locale
1810
- }),
1811
- disable: () => ({})
1812
- });
1813
- const [enableEvent, disableEvent] = translations_utils_createActions('event', {
1814
- enable: payloadId => ({
1815
- payloadId
1816
- }),
1817
- disable: payloadId => ({
1818
- payloadId
1819
- })
1820
- });
1821
- ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/selectors.js
1822
-
1823
-
1824
-
1825
- const selectors_getState = utils_selectState;
1826
- const getOriginalPayloadIds = createSelector(selectors_getState, state => state.originalPayloadIds);
1827
- const getIsPayloadTranslated = createSelector(getOriginalPayloadIds, getPropSelector('payloadId'), (payloadIds, payloadId) => !payloadIds.includes(payloadId));
1828
- ;// CONCATENATED MODULE: ./src/javascripts/ui/components/core/seamly-api-context.js
1829
-
1830
- const seamly_api_context_SeamlyApiContext = (0,external_preact_namespaceObject.createContext)(null);
1831
- const seamly_api_context_SeamlyEventBusContext = (0,external_preact_namespaceObject.createContext)('');
1832
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/seamly-api-hooks.js
1565
+ } = createDomain('i18n');
1566
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/selectors.js
1833
1567
 
1834
1568
 
1835
- const seamly_api_hooks_useSeamlyApiContext = () => useContext(SeamlyApiContext);
1836
- const seamly_api_hooks_useSeamlyObjectStore = () => {
1837
- const api = seamly_api_hooks_useSeamlyApiContext();
1838
- return api.store || {};
1839
- };
1840
- const useSeamlyConversationUrl = () => {
1841
- const {
1842
- get
1843
- } = seamly_api_hooks_useSeamlyObjectStore();
1569
+ const selectTranslations = createSelector(utils_selectState, state => state.translations);
1570
+ const selectInitialLocale = createSelector(utils_selectState, state => state.initialLocale);
1571
+ const selectLocale = createSelector(utils_selectState, state => state.locale);
1844
1572
 
1845
- if (get) {
1846
- return get('conversationUrl');
1847
- }
1573
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/actions.js
1848
1574
 
1849
- return null;
1850
- };
1851
- const seamly_api_hooks_useSeamlyHasConversation = () => {
1852
- const url = useSeamlyConversationUrl();
1853
- return !!url;
1854
- };
1855
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/utils.js
1856
1575
 
1857
- const {
1858
- createAction: utils_createAction,
1859
- createThunk: utils_createThunk,
1860
- createReducer: config_utils_createReducer,
1861
- selectState: config_utils_selectState
1862
- } = createDomain('config');
1863
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/actions.js
1864
1576
 
1865
- const initialize = utils_createAction('initialize', config => ({
1866
- config
1867
- }));
1868
- const update = utils_createAction('update', config => ({
1869
- config
1577
+ const setInitialLocale = i18n_utils_createAction('setInitialLocale', locale => ({
1578
+ locale
1870
1579
  }));
1871
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/selectors.js
1872
- function selectors_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1873
-
1874
- function selectors_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { selectors_ownKeys(Object(source), true).forEach(function (key) { selectors_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { selectors_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1875
-
1876
- function selectors_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1580
+ const mutex = createMutex();
1581
+ const setLocale = i18n_utils_createThunk('setLocale', async (locale, {
1582
+ getState,
1583
+ extra: {
1584
+ api
1585
+ }
1586
+ }) => {
1587
+ return mutex.runExclusively(() => {
1588
+ if (locale === selectLocale(getState())) {
1589
+ return undefined;
1590
+ }
1877
1591
 
1592
+ return api.getTranslations(locale);
1593
+ });
1594
+ });
1595
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js
1596
+ function _arrayWithHoles(arr) {
1597
+ if (Array.isArray(arr)) return arr;
1598
+ }
1599
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js
1600
+ function _iterableToArrayLimit(arr, i) {
1601
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
1878
1602
 
1603
+ if (_i == null) return;
1604
+ var _arr = [];
1605
+ var _n = true;
1606
+ var _d = false;
1879
1607
 
1608
+ var _s, _e;
1880
1609
 
1881
- const selectConfig = createSelector(config_utils_selectState, config => {
1882
- let newConfig = selectors_objectSpread({
1883
- visible: (config === null || config === void 0 ? void 0 : config.layoutMode) === 'inline' ? seamly_utils_visibilityStates.open : seamly_utils_visibilityStates.minimized,
1884
- appContainerClassNames: config.appContainerClassNames || []
1885
- }, config);
1610
+ try {
1611
+ for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
1612
+ _arr.push(_s.value);
1886
1613
 
1887
- if (typeof newConfig.appContainerClassNames === 'function') {
1888
- newConfig = selectors_objectSpread(selectors_objectSpread({}, newConfig), {}, {
1889
- appContainerClassNames: newConfig.appContainerClassNames(newConfig)
1890
- });
1614
+ if (i && _arr.length === i) break;
1615
+ }
1616
+ } catch (err) {
1617
+ _d = true;
1618
+ _e = err;
1619
+ } finally {
1620
+ try {
1621
+ if (!_n && _i["return"] != null) _i["return"]();
1622
+ } finally {
1623
+ if (_d) throw _e;
1624
+ }
1891
1625
  }
1892
1626
 
1893
- return newConfig;
1894
- });
1895
-
1896
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/hooks.js
1897
-
1898
-
1899
- function hooks_useConfig() {
1900
- return useSelector(Selectors.selectConfig);
1627
+ return _arr;
1901
1628
  }
1902
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/middleware.js
1629
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js
1630
+ function _arrayLikeToArray(arr, len) {
1631
+ if (len == null || len > arr.length) len = arr.length;
1903
1632
 
1633
+ for (var i = 0, arr2 = new Array(len); i < len; i++) {
1634
+ arr2[i] = arr[i];
1635
+ }
1904
1636
 
1905
- function createMiddleware() {
1906
- return ({
1907
- dispatch
1908
- }) => next => action => {
1909
- var _action$config, _action$config$defaul;
1637
+ return arr2;
1638
+ }
1639
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js
1910
1640
 
1911
- const result = next(action);
1641
+ function _unsupportedIterableToArray(o, minLen) {
1642
+ if (!o) return;
1643
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
1644
+ var n = Object.prototype.toString.call(o).slice(8, -1);
1645
+ if (n === "Object" && o.constructor) n = o.constructor.name;
1646
+ if (n === "Map" || n === "Set") return Array.from(o);
1647
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
1648
+ }
1649
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js
1650
+ function _nonIterableRest() {
1651
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1652
+ }
1653
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/slicedToArray.js
1912
1654
 
1913
- switch (action.type) {
1914
- case String(Actions.initialize):
1915
- case String(Actions.update):
1916
- if (action !== null && action !== void 0 && (_action$config = action.config) !== null && _action$config !== void 0 && (_action$config$defaul = _action$config.defaults) !== null && _action$config$defaul !== void 0 && _action$config$defaul.agentName) {
1917
- var _action$config2, _action$config2$defau;
1918
1655
 
1919
- dispatch({
1920
- type: seamlyActions.SET_HEADER_SUB_TITLE,
1921
- title: action === null || action === void 0 ? void 0 : (_action$config2 = action.config) === null || _action$config2 === void 0 ? void 0 : (_action$config2$defau = _action$config2.defaults) === null || _action$config2$defau === void 0 ? void 0 : _action$config2$defau.agentName
1922
- });
1923
- }
1924
1656
 
1925
- }
1926
1657
 
1927
- return result;
1928
- };
1658
+ function _slicedToArray(arr, i) {
1659
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
1660
+ }
1661
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/classCallCheck.js
1662
+ function _classCallCheck(instance, Constructor) {
1663
+ if (!(instance instanceof Constructor)) {
1664
+ throw new TypeError("Cannot call a class as a function");
1665
+ }
1666
+ }
1667
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/createClass.js
1668
+ function _defineProperties(target, props) {
1669
+ for (var i = 0; i < props.length; i++) {
1670
+ var descriptor = props[i];
1671
+ descriptor.enumerable = descriptor.enumerable || false;
1672
+ descriptor.configurable = true;
1673
+ if ("value" in descriptor) descriptor.writable = true;
1674
+ Object.defineProperty(target, descriptor.key, descriptor);
1675
+ }
1929
1676
  }
1930
- ;// CONCATENATED MODULE: ./src/javascripts/config.js
1931
- const CSS_NAME = 'cvco';
1932
- const apiVersion = '2';
1933
- const config_userParticipantId = 'seamly-client-participant'; // How long to debounce distinct changes in unread messages for before
1934
- // broadcasting to the screen reader. This is done to avoid verbosity.
1935
-
1936
- const unreadScreenReaderWait = 2000;
1937
- const newMessageScreenReaderWait = 1000;
1938
- const config_screenReaderDebounceDelaySeconds = 10;
1939
- const activitySendDelay = 15000;
1940
- const maxCharacterWarningLimit = 50;
1941
- const maxCharacterSrDebounceDelay = 300;
1942
- const config_defaultTransitionTimeMs = 300; // How long to wait before we decide the user isn't typing
1943
-
1944
- const config_typingTimeout = 2000;
1945
- const defaultConfig = {
1946
- namespace: 'default',
1947
- layoutMode: 'window',
1948
- // "window", "inline" ("sidebar"), "modal"
1949
- messages: {
1950
- agent: {
1951
- showAvatar: false,
1952
- // true, "inline"
1953
- showName: false
1954
- },
1955
- user: {
1956
- showAvatar: false,
1957
- // true, "inline"
1958
- showName: false
1959
- },
1960
- timeIndicator: {
1961
- enabled: false,
1962
- threshold: 3600000 // Default threshold is an hour in milliseconds
1963
1677
 
1964
- }
1965
- },
1966
- appContainerClassNames: config => [`app--layout-${config.layoutMode}`, `namespace--${config.namespace}`]
1967
- };
1968
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/reducer.js
1969
- const reducer_excluded = ["messages"];
1678
+ function _createClass(Constructor, protoProps, staticProps) {
1679
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1680
+ if (staticProps) _defineProperties(Constructor, staticProps);
1681
+ return Constructor;
1682
+ }
1683
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/defineProperty.js
1684
+ function defineProperty_defineProperty(obj, key, value) {
1685
+ if (key in obj) {
1686
+ Object.defineProperty(obj, key, {
1687
+ value: value,
1688
+ enumerable: true,
1689
+ configurable: true,
1690
+ writable: true
1691
+ });
1692
+ } else {
1693
+ obj[key] = value;
1694
+ }
1970
1695
 
1971
- function reducer_objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = reducer_objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
1696
+ return obj;
1697
+ }
1698
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/array-utils/array-utils.es.js
1699
+ /*
1700
+ * Copyright 2017, Emanuel Rabina (http://www.ultraq.net.nz/)
1701
+ *
1702
+ * Licensed under the Apache License, Version 2.0 (the "License");
1703
+ * you may not use this file except in compliance with the License.
1704
+ * You may obtain a copy of the License at
1705
+ *
1706
+ * http://www.apache.org/licenses/LICENSE-2.0
1707
+ *
1708
+ * Unless required by applicable law or agreed to in writing, software
1709
+ * distributed under the License is distributed on an "AS IS" BASIS,
1710
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1711
+ * See the License for the specific language governing permissions and
1712
+ * limitations under the License.
1713
+ */
1972
1714
 
1973
- function reducer_objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
1715
+ /**
1716
+ * Flattens an array of arrays of infinite depth into a single-dimension array.
1717
+ *
1718
+ * > This is now natively in JavaScript as the `flat` method on an Array
1719
+ * > instance. [Check MDN for which browsers have access to this feature](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat).
1720
+ * > If you can't use `flat`, then this method will do the job 🙂
1721
+ *
1722
+ * @param {Array} array
1723
+ * @return {Array} Flattened array.
1724
+ */
1725
+ function flatten(array) {
1726
+ return array.reduce(function (accumulator, value) {
1727
+ return accumulator.concat(Array.isArray(value) ? flatten(value) : value);
1728
+ }, []);
1729
+ }
1730
+ /**
1731
+ * Creates an array of numbers from the starting value (inclusive) to the end
1732
+ * (exclusive), with an optional step (the gap between values).
1733
+ *
1734
+ * @param {Number} start
1735
+ * The value to start at, the first item in the returned array.
1736
+ * @param {Number} end
1737
+ * The value to end with, the last item in the returned array.
1738
+ * @param {Number} [step=1]
1739
+ * The increment/gap between values, defaults to 1.
1740
+ * @return {Array} An array encompassing the given range.
1741
+ */
1974
1742
 
1975
- function config_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1743
+ function range(start, end) {
1744
+ var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
1745
+ return Array.apply(0, Array(Math.ceil((end - start) / step))).map(function (empty, index) {
1746
+ return index * step + start;
1747
+ });
1748
+ }
1749
+ /**
1750
+ * Remove and return the first item from `array` that matches the predicate
1751
+ * function.
1752
+ *
1753
+ * @param {Array} array
1754
+ * @param {Function} predicate
1755
+ * Invoked with the array item.
1756
+ * @return {Object} The matching item, or `null` if no match was found.
1757
+ */
1976
1758
 
1977
- function config_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { config_reducer_ownKeys(Object(source), true).forEach(function (key) { config_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { config_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1759
+ function remove(array, predicate) {
1760
+ return array.find(function (item, index) {
1761
+ if (predicate(item)) {
1762
+ array.splice(index, 1);
1763
+ return item;
1764
+ }
1765
+ });
1766
+ }
1978
1767
 
1979
- function config_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1768
+ //# sourceMappingURL=array-utils.es.js.map
1769
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/function-utils/function-utils.es.js
1770
+ /**
1771
+ * A higher-order function to apply [memoization](https://en.wikipedia.org/wiki/Memoization).
1772
+ *
1773
+ * If memoizing a recursive function, then memoize and define the function at
1774
+ * the same time so you can make a call to the memoized function, eg:
1775
+ *
1776
+ * ```javascript
1777
+ * const myFunction = memoize(() => myFunction());
1778
+ * ```
1779
+ *
1780
+ * @param {Function} func
1781
+ * @return {Function}
1782
+ */
1783
+ function memoize(func) {
1784
+ var cache = {};
1785
+ return function () {
1786
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1787
+ args[_key] = arguments[_key];
1788
+ }
1980
1789
 
1790
+ var key = args.length ? args.map(function (arg) {
1791
+ return arg === null ? 'null' : arg === undefined ? 'undefined' : typeof arg === 'function' ? arg.toString() : arg instanceof Date ? arg.toISOString() : JSON.stringify(arg);
1792
+ }).join('|') : '_(no-args)_';
1981
1793
 
1794
+ if (Object.prototype.hasOwnProperty.call(cache, key)) {
1795
+ return cache[key];
1796
+ }
1982
1797
 
1798
+ var result = func.apply(void 0, args);
1799
+ cache[key] = result;
1800
+ return result;
1801
+ };
1802
+ }
1983
1803
 
1804
+ //# sourceMappingURL=function-utils.es.js.map
1805
+ ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/lib/icu-message-formatter.es.js
1984
1806
 
1985
1807
 
1986
- const config_reducer_initialState = config_reducer_objectSpread(config_reducer_objectSpread({}, defaultConfig), {}, {
1987
- hideOnNoUserResponse: false,
1988
- showDisclaimer: false,
1989
- showFaq: false,
1990
- customComponents: {},
1991
- defaults: {}
1992
- });
1993
1808
 
1994
- const configKeys = ['hideOnNoUserResponse', 'showDisclaimer', 'showFaq', 'namespace', 'customComponents', 'defaults', 'layoutMode', 'api', 'zIndex', 'context', 'appContainerClassNames', 'messages', 'visible', 'visibilityCallback'];
1995
1809
 
1996
- const updateState = (state, {
1997
- config
1998
- }) => {
1999
- const _pick = pick(config, configKeys),
2000
- {
2001
- messages
2002
- } = _pick,
2003
- partialConfig = reducer_objectWithoutProperties(_pick, reducer_excluded);
2004
1810
 
2005
- let newState = state;
2006
1811
 
2007
- if (Object.keys(partialConfig).length > 0) {
2008
- newState = config_reducer_objectSpread(config_reducer_objectSpread({}, newState), partialConfig);
2009
- }
2010
1812
 
2011
- if (messages) {
2012
- newState = config_reducer_objectSpread(config_reducer_objectSpread({}, newState), {}, {
2013
- messages: config_reducer_objectSpread(config_reducer_objectSpread({}, newState.messages), messages)
2014
- });
2015
- }
1813
+ /*
1814
+ * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
1815
+ *
1816
+ * Licensed under the Apache License, Version 2.0 (the "License");
1817
+ * you may not use this file except in compliance with the License.
1818
+ * You may obtain a copy of the License at
1819
+ *
1820
+ * http://www.apache.org/licenses/LICENSE-2.0
1821
+ *
1822
+ * Unless required by applicable law or agreed to in writing, software
1823
+ * distributed under the License is distributed on an "AS IS" BASIS,
1824
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1825
+ * See the License for the specific language governing permissions and
1826
+ * limitations under the License.
1827
+ */
2016
1828
 
2017
- return newState;
2018
- };
1829
+ /**
1830
+ * Most branch-based type handlers are based around "cases".
1831
+ * For example, `select` and `plural` compare compare a value
1832
+ * to "case keys" to choose a subtranslation.
1833
+ *
1834
+ * This util splits "matches" portions provided to the aforementioned
1835
+ * handlers into case strings, and extracts any prepended arguments
1836
+ * (for example, `plural` supports an `offset:n` argument used for
1837
+ * populating the magic `#` variable).
1838
+ *
1839
+ * @param {String} string
1840
+ * @return {Object} The `cases` key points to a map of all cases.
1841
+ * The `arguments` key points to a list of prepended arguments.
1842
+ */
1843
+ function parseCases(string) {
1844
+ var isWhitespace = function isWhitespace(ch) {
1845
+ return /\s/.test(ch);
1846
+ };
2019
1847
 
2020
- /* harmony default export */ const config_reducer = (config_utils_createReducer({
2021
- [initialize]: (state, action) => {
2022
- return updateState(state, action);
2023
- },
2024
- [update]: (state, action) => {
2025
- return updateState(state, action);
2026
- }
2027
- }, config_reducer_initialState));
2028
- ;// CONCATENATED MODULE: ./src/javascripts/domains/config/index.js
1848
+ var args = [];
1849
+ var cases = {};
1850
+ var currTermStart = 0;
1851
+ var latestTerm = null;
1852
+ var inTerm = false;
1853
+ var i = 0;
2029
1854
 
1855
+ while (i < string.length) {
1856
+ // Term ended
1857
+ if (inTerm && (isWhitespace(string[i]) || string[i] === '{')) {
1858
+ inTerm = false;
1859
+ latestTerm = string.slice(currTermStart, i); // We want to process the opening char again so the case will be properly registered.
2030
1860
 
1861
+ if (string[i] === '{') {
1862
+ i--;
1863
+ }
1864
+ } // New term
1865
+ else if (!inTerm && !isWhitespace(string[i])) {
1866
+ var caseBody = string[i] === '{'; // If there's a previous term, we can either handle a whole
1867
+ // case, or add that as an argument.
2031
1868
 
1869
+ if (latestTerm && caseBody) {
1870
+ var branchEndIndex = findClosingBracket(string, i);
2032
1871
 
1872
+ if (branchEndIndex === -1) {
1873
+ throw new Error("Unbalanced curly braces in string: \"".concat(string, "\""));
1874
+ }
2033
1875
 
1876
+ cases[latestTerm] = string.slice(i + 1, branchEndIndex); // Don't include the braces
2034
1877
 
2035
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/seamly-state-hooks.js
2036
- function seamly_state_hooks_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
1878
+ i = branchEndIndex; // Will be moved up where needed at end of loop.
2037
1879
 
2038
- function seamly_state_hooks_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { seamly_state_hooks_ownKeys(Object(source), true).forEach(function (key) { seamly_state_hooks_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { seamly_state_hooks_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
1880
+ latestTerm = null;
1881
+ } else {
1882
+ if (latestTerm) {
1883
+ args.push(latestTerm);
1884
+ latestTerm = null;
1885
+ }
2039
1886
 
2040
- function seamly_state_hooks_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
1887
+ inTerm = true;
1888
+ currTermStart = i;
1889
+ }
1890
+ }
2041
1891
 
1892
+ i++;
1893
+ }
2042
1894
 
1895
+ if (inTerm) {
1896
+ latestTerm = string.slice(currTermStart);
1897
+ }
2043
1898
 
1899
+ if (latestTerm) {
1900
+ args.push(latestTerm);
1901
+ }
2044
1902
 
1903
+ return {
1904
+ args: args,
1905
+ cases: cases
1906
+ };
1907
+ }
1908
+ /**
1909
+ * Finds the index of the matching closing curly bracket, including through
1910
+ * strings that could have nested brackets.
1911
+ *
1912
+ * @param {String} string
1913
+ * @param {Number} fromIndex
1914
+ * @return {Number} The index of the matching closing bracket, or -1 if no
1915
+ * closing bracket could be found.
1916
+ */
2045
1917
 
2046
- const seamly_state_hooks_selectState = state => state.state;
2047
- const seamly_state_hooks_useSeamlyStateContext = () => useSelector(seamly_state_hooks_selectState);
2048
- const selectEvents = createSelector(seamly_state_hooks_selectState, selectConfig, ({
2049
- events
2050
- }, config) => {
2051
- var _config$messages;
1918
+ function findClosingBracket(string, fromIndex) {
1919
+ var depth = 0;
2052
1920
 
2053
- const {
2054
- enabled,
2055
- threshold
2056
- } = (config === null || config === void 0 ? void 0 : (_config$messages = config.messages) === null || _config$messages === void 0 ? void 0 : _config$messages.timeIndicator) ?? {};
1921
+ for (var i = fromIndex + 1; i < string.length; i++) {
1922
+ var char = string.charAt(i);
2057
1923
 
2058
- if (!enabled) {
2059
- return events;
2060
- }
1924
+ if (char === '}') {
1925
+ if (depth === 0) {
1926
+ return i;
1927
+ }
2061
1928
 
2062
- const mappedEvents = [];
2063
- let previousEvent = null;
2064
- events.forEach((event, idx) => {
2065
- // always add timeIndicator to first message
2066
- if (idx === 0) {
2067
- mappedEvents.push(seamly_state_hooks_objectSpread(seamly_state_hooks_objectSpread({}, event), {}, {
2068
- timeIndicator: event.payload.occurredAt
2069
- })); // else check if diff is greater than threshold
2070
- } else {
2071
- const timeIndicator = previousEvent && microsecondsToMilliseconds(event.payload.occurredAt - previousEvent.payload.occurredAt) >= threshold ? event.payload.occurredAt : undefined;
2072
- mappedEvents.push(seamly_state_hooks_objectSpread(seamly_state_hooks_objectSpread({}, event), {}, {
2073
- timeIndicator
2074
- }));
1929
+ depth--;
1930
+ } else if (char === '{') {
1931
+ depth++;
2075
1932
  }
1933
+ }
2076
1934
 
2077
- previousEvent = event;
2078
- });
2079
- return mappedEvents;
2080
- });
2081
- const seamly_state_hooks_useEvents = () => useSelector(selectEvents, []);
2082
- const useSeamlyIsLoading = () => seamly_state_hooks_useSeamlyStateContext().isLoading;
2083
- const useSeamlyHeaderData = () => seamly_state_hooks_useSeamlyStateContext().headerTitles;
2084
- const seamly_state_hooks_useSeamlyUnreadCount = () => seamly_state_hooks_useSeamlyStateContext().unreadEvents;
2085
- const seamly_state_hooks_useSkiplink = () => seamly_state_hooks_useSeamlyStateContext().skiplinkTargetId;
2086
- const useSeamlyParticipant = participantId => seamly_state_hooks_useSeamlyStateContext().participantInfo.participants[participantId];
2087
- const useSeamlyServiceInfo = () => seamly_state_hooks_useSeamlyStateContext().serviceInfo;
2088
- const selectLastMessageEventId = createSelector(selectEvents, events => {
2089
- var _filteredEvents;
2090
-
2091
- const filteredEvents = events.filter(event => event.type === 'message');
2092
- return (_filteredEvents = filteredEvents[filteredEvents.length - 1]) === null || _filteredEvents === void 0 ? void 0 : _filteredEvents.payload.id;
2093
- });
2094
- const useLastMessageEventId = () => useSelector(selectLastMessageEventId);
2095
- const useSeamlyIsHistoryLoaded = () => seamly_state_hooks_useSeamlyStateContext().historyLoaded;
2096
- const useSeamlyCurrentAgent = () => {
2097
- const {
2098
- participants,
2099
- currentAgent
2100
- } = seamly_state_hooks_useSeamlyStateContext().participantInfo;
2101
- return currentAgent ? participants[currentAgent] : null;
2102
- };
2103
- const useSeamlyServiceData = key => seamly_state_hooks_useSeamlyStateContext().serviceData[key];
2104
- const useEntryTextLimit = () => {
2105
- const {
2106
- entryMeta: {
2107
- options: {
2108
- text
2109
- }
2110
- }
2111
- } = seamly_state_hooks_useSeamlyStateContext();
2112
- const {
2113
- limit
2114
- } = text || {};
2115
- return {
2116
- hasLimit: limit != null,
2117
- limit: limit != null ? limit : null
2118
- };
2119
- };
2120
- const useSeamlyLayoutMode = () => {
2121
- const {
2122
- layoutMode
2123
- } = useConfig();
2124
- return {
2125
- isInline: layoutMode === 'inline',
2126
- isModal: layoutMode === 'modal',
2127
- isWindow: layoutMode === 'window',
2128
- isResolving: !layoutMode
2129
- };
2130
- };
2131
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-dispatch.js
1935
+ return -1;
1936
+ }
1937
+ /**
1938
+ * Split a `{key, type, format}` block into those 3 parts, taking into account
1939
+ * nested message syntax that can exist in the `format` part.
1940
+ *
1941
+ * @param {String} block
1942
+ * @return {Array}
1943
+ * An array with `key`, `type`, and `format` items in that order, if present
1944
+ * in the formatted argument block.
1945
+ */
2132
1946
 
2133
- /* harmony default export */ const use_seamly_dispatch = ((/* unused pure expression or super */ null && (useStoreDispatch)));
2134
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/focus-helper-hooks.js
1947
+ function splitFormattedArgument(block) {
1948
+ return split(block.slice(1, -1), ',', 3);
1949
+ }
1950
+ /**
1951
+ * Like `String.prototype.split()` but where the limit parameter causes the
1952
+ * remainder of the string to be grouped together in a final entry.
1953
+ *
1954
+ * @private
1955
+ * @param {String} string
1956
+ * @param {String} separator
1957
+ * @param {Number} limit
1958
+ * @param {Array} [accumulator=[]]
1959
+ * @return {Array}
1960
+ */
2135
1961
 
1962
+ function split(string, separator, limit) {
1963
+ var accumulator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2136
1964
 
1965
+ if (!string) {
1966
+ return accumulator;
1967
+ }
2137
1968
 
1969
+ if (limit === 1) {
1970
+ accumulator.push(string);
1971
+ return accumulator;
1972
+ }
2138
1973
 
1974
+ var indexOfDelimiter = string.indexOf(separator);
2139
1975
 
2140
- const {
2141
- SET_SEAMLY_CONTAINER_ELEMENT: focus_helper_hooks_SET_SEAMLY_CONTAINER_ELEMENT
2142
- } = seamly_utils_seamlyActions;
1976
+ if (indexOfDelimiter === -1) {
1977
+ accumulator.push(string);
1978
+ return accumulator;
1979
+ }
2143
1980
 
2144
- const focusWithRaf = el => {
2145
- requestAnimationFrame(() => {
2146
- requestAnimationFrame(() => {
2147
- const focusEl = typeof el === 'string' ? document.getElementById(el) : el;
2148
- focusElement(focusEl);
2149
- });
2150
- });
2151
- };
1981
+ var head = string.substring(0, indexOfDelimiter).trim();
1982
+ var tail = string.substring(indexOfDelimiter + separator.length + 1).trim();
1983
+ accumulator.push(head);
1984
+ return split(tail, separator, limit - 1, accumulator);
1985
+ }
2152
1986
 
2153
- const useSeamlyContainerElement = () => {
2154
- const {
2155
- seamlyContainerElement
2156
- } = useSeamlyStateContext();
2157
- const dispatch = useSeamlyDispatchContext();
2158
- const setSeamlyContainerElement = useCallback(element => {
2159
- dispatch({
2160
- type: focus_helper_hooks_SET_SEAMLY_CONTAINER_ELEMENT,
2161
- element
2162
- });
2163
- }, [dispatch]);
2164
- return [seamlyContainerElement, setSeamlyContainerElement];
2165
- };
2166
- const focus_helper_hooks_useElementFocusingById = elementId => useCallback(() => {
2167
- focusWithRaf(elementId);
2168
- }, [elementId]);
2169
- const focus_helper_hooks_useSkiplinkTargetFocusing = () => {
2170
- const skiplinkTargetId = useSkiplink();
2171
- return focus_helper_hooks_useElementFocusingById(skiplinkTargetId);
2172
- };
2173
- const useFocusIfSeamlyContainedFocus = () => {
2174
- const containerElementRef = useRef(null);
2175
- const [seamlyContainerElement] = useSeamlyContainerElement();
2176
- containerElementRef.current = seamlyContainerElement;
2177
- return useCallback(elementToFocus => {
2178
- const focusFn = () => {
2179
- focusWithRaf(elementToFocus);
2180
- };
1987
+ /**
1988
+ * The main class for formatting messages.
1989
+ *
1990
+ * @author Emanuel Rabina
1991
+ */
2181
1992
 
2182
- runIfElementContainsOrHasFocus(containerElementRef.current, focusFn);
2183
- }, []);
2184
- };
2185
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/component-helper-hooks.js
1993
+ var MessageFormatter = /*#__PURE__*/function () {
1994
+ /**
1995
+ * Creates a new formatter that can work using any of the custom type handlers
1996
+ * you register.
1997
+ *
1998
+ * @param {String} locale
1999
+ * @param {Object} [typeHandlers={}]
2000
+ * Optional object where the keys are the names of the types to register,
2001
+ * their values being the functions that will return a nicely formatted
2002
+ * string for the data and locale they are given.
2003
+ */
2004
+ function MessageFormatter(locale) {
2005
+ var _this = this;
2186
2006
 
2007
+ var typeHandlers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2187
2008
 
2009
+ _classCallCheck(this, MessageFormatter);
2188
2010
 
2189
- const useSeamlyAppContainerClassNames = () => {
2190
- return useConfig().appContainerClassNames;
2191
- };
2192
- const useSeamlyMessageContainerClassNames = event => {
2193
- const {
2194
- fromClient
2195
- } = event.payload;
2196
- const classNames = ['message'];
2011
+ defineProperty_defineProperty(this, "format", memoize(function (message) {
2012
+ var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2013
+ return flatten(_this.process(message, values)).join('');
2014
+ }));
2197
2015
 
2198
- if (event.type === 'info') {
2199
- classNames.push('message--source-info');
2200
- } else if (!fromClient) {
2201
- classNames.push('message--source-agent');
2202
- } else {
2203
- classNames.push('message--source-user');
2016
+ this.locale = locale;
2017
+ this.typeHandlers = typeHandlers;
2204
2018
  }
2019
+ /**
2020
+ * Formats an ICU message syntax string using `values` for placeholder data
2021
+ * and any currently-registered type handlers.
2022
+ *
2023
+ * @param {String} message
2024
+ * @param {Object} [values={}]
2025
+ * @return {String}
2026
+ */
2205
2027
 
2206
- return classNames;
2207
- };
2208
- const useCobrowsingContainer = () => {
2209
- const {
2210
- cobrowsingContainerId: id
2211
- } = useSeamlyStateContext();
2212
- const focusContainer = useElementFocusingById(id);
2213
- return {
2214
- id,
2215
- focusContainer
2216
- };
2217
- };
2218
- ;// CONCATENATED MODULE: ./src/javascripts/lib/mutex.js
2219
- function createMutex() {
2220
- let isRunning = false;
2221
- const tasks = [];
2222
-
2223
- const next = async () => {
2224
- if (!isRunning) {
2225
- while (tasks.length) {
2226
- const task = tasks.shift();
2227
- isRunning = true; // eslint-disable-next-line no-await-in-loop
2228
2028
 
2229
- await task().catch(() => {});
2230
- isRunning = false;
2029
+ _createClass(MessageFormatter, [{
2030
+ key: "process",
2031
+ value:
2032
+ /**
2033
+ * Process an ICU message syntax string using `values` for placeholder data
2034
+ * and any currently-registered type handlers. The result of this method is
2035
+ * an array of the component parts after they have been processed in turn by
2036
+ * their own type handlers. This raw output is useful for other renderers,
2037
+ * eg: React where components can be used instead of being forced to return
2038
+ * raw strings.
2039
+ *
2040
+ * This method is used by {@link MessageFormatter#format} where it acts as a
2041
+ * string renderer.
2042
+ *
2043
+ * @param {String} message
2044
+ * @param {Object} [values={}]
2045
+ * @return {Array}
2046
+ */
2047
+ function process(message) {
2048
+ var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2049
+
2050
+ if (!message) {
2051
+ return [];
2231
2052
  }
2232
- }
2233
- };
2234
2053
 
2235
- const runExclusively = async task => {
2236
- const prms = new Promise((resolve, reject) => {
2237
- tasks.push(async () => {
2238
- try {
2239
- resolve(await task());
2240
- } catch (e) {
2241
- reject(e);
2242
- }
2243
- });
2244
- });
2245
- next();
2246
- return prms;
2247
- };
2054
+ var blockStartIndex = message.indexOf('{');
2248
2055
 
2249
- return {
2250
- next,
2251
- runExclusively
2252
- };
2253
- }
2254
- ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/utils.js
2056
+ if (blockStartIndex !== -1) {
2057
+ var blockEndIndex = findClosingBracket(message, blockStartIndex);
2255
2058
 
2256
- const {
2257
- createAction: i18n_utils_createAction,
2258
- createActions: i18n_utils_createActions,
2259
- createThunk: i18n_utils_createThunk,
2260
- createReducer: i18n_utils_createReducer,
2261
- selectState: i18n_utils_selectState
2262
- } = createDomain('i18n');
2263
- ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/selectors.js
2059
+ if (blockEndIndex !== -1) {
2060
+ var block = message.substring(blockStartIndex, blockEndIndex + 1);
2264
2061
 
2062
+ if (block) {
2063
+ var result = [];
2064
+ var head = message.substring(0, blockStartIndex);
2265
2065
 
2266
- const selectTranslations = createSelector(i18n_utils_selectState, state => state.translations);
2267
- const selectInitialLocale = createSelector(i18n_utils_selectState, state => state.initialLocale);
2268
- const selectLocale = createSelector(i18n_utils_selectState, state => state.locale);
2066
+ if (head) {
2067
+ result.push(head);
2068
+ }
2269
2069
 
2270
- ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/actions.js
2070
+ var _splitFormattedArgume = splitFormattedArgument(block),
2071
+ _splitFormattedArgume2 = _slicedToArray(_splitFormattedArgume, 3),
2072
+ key = _splitFormattedArgume2[0],
2073
+ type = _splitFormattedArgume2[1],
2074
+ format = _splitFormattedArgume2[2];
2271
2075
 
2076
+ var body = values[key];
2272
2077
 
2078
+ if (body === null || body === undefined) {
2079
+ body = '';
2080
+ }
2273
2081
 
2274
- const setInitialLocale = i18n_utils_createAction('setInitialLocale', locale => ({
2275
- locale
2276
- }));
2277
- const [setLocaleStart, setLocaleResolve, setLocaleReject] = i18n_utils_createActions('setLocale', {
2278
- start: locale => ({
2279
- locale
2280
- }),
2281
- resolve: (locale, translations) => ({
2282
- locale,
2283
- translations
2284
- }),
2285
- reject: (locale, error) => ({
2286
- locale,
2287
- error
2288
- })
2289
- });
2290
- const mutex = createMutex();
2291
- const setLocale = i18n_utils_createThunk('setLocale', locale => async (dispatch, getState, {
2292
- api
2293
- }) => {
2294
- await mutex.runExclusively(async () => {
2295
- const currentLocale = selectLocale(getState());
2082
+ var typeHandler = type && this.typeHandlers[type];
2083
+ result.push(typeHandler ? typeHandler(body, format, this.locale, values, this.process.bind(this)) : body);
2084
+ var tail = message.substring(blockEndIndex + 1);
2296
2085
 
2297
- if (currentLocale === locale) {
2298
- return;
2299
- }
2086
+ if (tail) {
2087
+ result.push(this.process(tail, values));
2088
+ }
2300
2089
 
2301
- dispatch(setLocaleStart(locale));
2090
+ return result;
2091
+ }
2092
+ } else {
2093
+ throw new Error("Unbalanced curly braces in string: \"".concat(message, "\""));
2094
+ }
2095
+ }
2302
2096
 
2303
- try {
2304
- const translations = await api.getTranslations(locale);
2305
- dispatch(setLocaleResolve(locale, translations));
2306
- } catch (error) {
2307
- dispatch(setLocaleReject(locale, error));
2097
+ return [message];
2308
2098
  }
2309
- });
2310
- });
2311
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js
2312
- function _arrayWithHoles(arr) {
2313
- if (Array.isArray(arr)) return arr;
2314
- }
2315
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js
2316
- function _iterableToArrayLimit(arr, i) {
2317
- var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
2099
+ }]);
2318
2100
 
2319
- if (_i == null) return;
2320
- var _arr = [];
2321
- var _n = true;
2322
- var _d = false;
2101
+ return MessageFormatter;
2102
+ }();
2323
2103
 
2324
- var _s, _e;
2104
+ function icu_message_formatter_es_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2325
2105
 
2326
- try {
2327
- for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
2328
- _arr.push(_s.value);
2106
+ function icu_message_formatter_es_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { icu_message_formatter_es_ownKeys(Object(source), true).forEach(function (key) { defineProperty_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { icu_message_formatter_es_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2107
+ var pluralFormatter;
2108
+ var keyCounter = 0; // All the special keywords that can be used in `plural` blocks for the various branches
2329
2109
 
2330
- if (i && _arr.length === i) break;
2331
- }
2332
- } catch (err) {
2333
- _d = true;
2334
- _e = err;
2335
- } finally {
2336
- try {
2337
- if (!_n && _i["return"] != null) _i["return"]();
2338
- } finally {
2339
- if (_d) throw _e;
2110
+ var ONE = 'one';
2111
+ var OTHER$1 = 'other';
2112
+ /**
2113
+ * @private
2114
+ * @param {String} caseBody
2115
+ * @param {Number} value
2116
+ * @return {Object} {caseBody: string, numberValues: object}
2117
+ */
2118
+
2119
+ function replaceNumberSign(caseBody, value) {
2120
+ var i = 0;
2121
+ var output = '';
2122
+ var numBraces = 0;
2123
+ var numberValues = {};
2124
+
2125
+ while (i < caseBody.length) {
2126
+ if (caseBody[i] === '#' && !numBraces) {
2127
+ var keyParam = "__hashToken".concat(keyCounter++);
2128
+ output += "{".concat(keyParam, ", number}");
2129
+ numberValues[keyParam] = value;
2130
+ } else {
2131
+ output += caseBody[i];
2340
2132
  }
2341
- }
2342
2133
 
2343
- return _arr;
2344
- }
2345
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js
2346
- function _arrayLikeToArray(arr, len) {
2347
- if (len == null || len > arr.length) len = arr.length;
2134
+ if (caseBody[i] === '{') {
2135
+ numBraces++;
2136
+ } else if (caseBody[i] === '}') {
2137
+ numBraces--;
2138
+ }
2348
2139
 
2349
- for (var i = 0, arr2 = new Array(len); i < len; i++) {
2350
- arr2[i] = arr[i];
2140
+ i++;
2351
2141
  }
2352
2142
 
2353
- return arr2;
2143
+ return {
2144
+ caseBody: output,
2145
+ numberValues: numberValues
2146
+ };
2354
2147
  }
2355
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js
2148
+ /**
2149
+ * Handler for `plural` statements within ICU message syntax strings. Returns
2150
+ * a formatted string for the branch that closely matches the current value.
2151
+ *
2152
+ * See https://formatjs.io/docs/core-concepts/icu-syntax#plural-format for more
2153
+ * details on how the `plural` statement works.
2154
+ *
2155
+ * @param {String} value
2156
+ * @param {String} matches
2157
+ * @param {String} locale
2158
+ * @param {String} values
2159
+ * @param {Function} format
2160
+ * @return {String}
2161
+ */
2356
2162
 
2357
- function _unsupportedIterableToArray(o, minLen) {
2358
- if (!o) return;
2359
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
2360
- var n = Object.prototype.toString.call(o).slice(8, -1);
2361
- if (n === "Object" && o.constructor) n = o.constructor.name;
2362
- if (n === "Map" || n === "Set") return Array.from(o);
2363
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
2364
- }
2365
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/nonIterableRest.js
2366
- function _nonIterableRest() {
2367
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2368
- }
2369
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/slicedToArray.js
2370
2163
 
2164
+ function pluralTypeHandler(value) {
2165
+ var matches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
2166
+ var locale = arguments.length > 2 ? arguments[2] : undefined;
2167
+ var values = arguments.length > 3 ? arguments[3] : undefined;
2168
+ var format = arguments.length > 4 ? arguments[4] : undefined;
2371
2169
 
2170
+ var _parseCases = parseCases(matches),
2171
+ args = _parseCases.args,
2172
+ cases = _parseCases.cases;
2372
2173
 
2174
+ var intValue = parseInt(value);
2175
+ args.forEach(function (arg) {
2176
+ if (arg.startsWith('offset:')) {
2177
+ intValue -= parseInt(arg.slice('offset:'.length));
2178
+ }
2179
+ });
2180
+ var keywordPossibilities = [];
2373
2181
 
2374
- function _slicedToArray(arr, i) {
2375
- return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
2376
- }
2377
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/classCallCheck.js
2378
- function _classCallCheck(instance, Constructor) {
2379
- if (!(instance instanceof Constructor)) {
2380
- throw new TypeError("Cannot call a class as a function");
2182
+ if ('PluralRules' in Intl) {
2183
+ // Effectively memoize because instantiation of `Int.*` objects is expensive.
2184
+ if (pluralFormatter === undefined || pluralFormatter.resolvedOptions().locale !== locale) {
2185
+ pluralFormatter = new Intl.PluralRules(locale);
2186
+ }
2187
+
2188
+ var pluralKeyword = pluralFormatter.select(intValue); // Other is always added last with least priority, so we don't want to add it here.
2189
+
2190
+ if (pluralKeyword !== OTHER$1) {
2191
+ keywordPossibilities.push(pluralKeyword);
2192
+ }
2381
2193
  }
2382
- }
2383
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/createClass.js
2384
- function _defineProperties(target, props) {
2385
- for (var i = 0; i < props.length; i++) {
2386
- var descriptor = props[i];
2387
- descriptor.enumerable = descriptor.enumerable || false;
2388
- descriptor.configurable = true;
2389
- if ("value" in descriptor) descriptor.writable = true;
2390
- Object.defineProperty(target, descriptor.key, descriptor);
2194
+
2195
+ if (intValue === 1) {
2196
+ keywordPossibilities.push(ONE);
2391
2197
  }
2392
- }
2393
2198
 
2394
- function _createClass(Constructor, protoProps, staticProps) {
2395
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
2396
- if (staticProps) _defineProperties(Constructor, staticProps);
2397
- return Constructor;
2398
- }
2399
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/node_modules/@babel/runtime/helpers/esm/defineProperty.js
2400
- function defineProperty_defineProperty(obj, key, value) {
2401
- if (key in obj) {
2402
- Object.defineProperty(obj, key, {
2403
- value: value,
2404
- enumerable: true,
2405
- configurable: true,
2406
- writable: true
2407
- });
2408
- } else {
2409
- obj[key] = value;
2199
+ keywordPossibilities.push("=".concat(intValue), OTHER$1);
2200
+
2201
+ for (var i = 0; i < keywordPossibilities.length; i++) {
2202
+ var keyword = keywordPossibilities[i];
2203
+
2204
+ if (keyword in cases) {
2205
+ var _replaceNumberSign = replaceNumberSign(cases[keyword], intValue),
2206
+ caseBody = _replaceNumberSign.caseBody,
2207
+ numberValues = _replaceNumberSign.numberValues;
2208
+
2209
+ return format(caseBody, icu_message_formatter_es_objectSpread(icu_message_formatter_es_objectSpread({}, values), numberValues));
2210
+ }
2410
2211
  }
2411
2212
 
2412
- return obj;
2213
+ return value;
2413
2214
  }
2414
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/array-utils/array-utils.es.js
2215
+
2415
2216
  /*
2416
- * Copyright 2017, Emanuel Rabina (http://www.ultraq.net.nz/)
2217
+ * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
2417
2218
  *
2418
2219
  * Licensed under the Apache License, Version 2.0 (the "License");
2419
2220
  * you may not use this file except in compliance with the License.
@@ -2427,646 +2228,1129 @@ function defineProperty_defineProperty(obj, key, value) {
2427
2228
  * See the License for the specific language governing permissions and
2428
2229
  * limitations under the License.
2429
2230
  */
2430
-
2431
- /**
2432
- * Flattens an array of arrays of infinite depth into a single-dimension array.
2433
- *
2434
- * > This is now natively in JavaScript as the `flat` method on an Array
2435
- * > instance. [Check MDN for which browsers have access to this feature](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat).
2436
- * > If you can't use `flat`, then this method will do the job 🙂
2437
- *
2438
- * @param {Array} array
2439
- * @return {Array} Flattened array.
2440
- */
2441
- function flatten(array) {
2442
- return array.reduce(function (accumulator, value) {
2443
- return accumulator.concat(Array.isArray(value) ? flatten(value) : value);
2444
- }, []);
2445
- }
2231
+ var OTHER = 'other';
2446
2232
  /**
2447
- * Creates an array of numbers from the starting value (inclusive) to the end
2448
- * (exclusive), with an optional step (the gap between values).
2233
+ * Handler for `select` statements within ICU message syntax strings. Returns
2234
+ * a formatted string for the branch that closely matches the current value.
2449
2235
  *
2450
- * @param {Number} start
2451
- * The value to start at, the first item in the returned array.
2452
- * @param {Number} end
2453
- * The value to end with, the last item in the returned array.
2454
- * @param {Number} [step=1]
2455
- * The increment/gap between values, defaults to 1.
2456
- * @return {Array} An array encompassing the given range.
2457
- */
2458
-
2459
- function range(start, end) {
2460
- var step = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
2461
- return Array.apply(0, Array(Math.ceil((end - start) / step))).map(function (empty, index) {
2462
- return index * step + start;
2463
- });
2464
- }
2465
- /**
2466
- * Remove and return the first item from `array` that matches the predicate
2467
- * function.
2236
+ * See https://formatjs.io/docs/core-concepts/icu-syntax#select-format for more
2237
+ * details on how the `select` statement works.
2468
2238
  *
2469
- * @param {Array} array
2470
- * @param {Function} predicate
2471
- * Invoked with the array item.
2472
- * @return {Object} The matching item, or `null` if no match was found.
2239
+ * @param {String} value
2240
+ * @param {String} matches
2241
+ * @param {String} locale
2242
+ * @param {String} values
2243
+ * @param {Function} format
2244
+ * @return {String}
2473
2245
  */
2474
2246
 
2475
- function remove(array, predicate) {
2476
- return array.find(function (item, index) {
2477
- if (predicate(item)) {
2478
- array.splice(index, 1);
2479
- return item;
2480
- }
2481
- });
2482
- }
2483
-
2484
- //# sourceMappingURL=array-utils.es.js.map
2485
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/function-utils/function-utils.es.js
2486
- /**
2487
- * A higher-order function to apply [memoization](https://en.wikipedia.org/wiki/Memoization).
2488
- *
2489
- * If memoizing a recursive function, then memoize and define the function at
2490
- * the same time so you can make a call to the memoized function, eg:
2491
- *
2492
- * ```javascript
2493
- * const myFunction = memoize(() => myFunction());
2494
- * ```
2495
- *
2496
- * @param {Function} func
2497
- * @return {Function}
2498
- */
2499
- function memoize(func) {
2500
- var cache = {};
2501
- return function () {
2502
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2503
- args[_key] = arguments[_key];
2504
- }
2247
+ function selectTypeHandler(value) {
2248
+ var matches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
2249
+ var values = arguments.length > 3 ? arguments[3] : undefined;
2250
+ var format = arguments.length > 4 ? arguments[4] : undefined;
2505
2251
 
2506
- var key = args.length ? args.map(function (arg) {
2507
- return arg === null ? 'null' : arg === undefined ? 'undefined' : typeof arg === 'function' ? arg.toString() : arg instanceof Date ? arg.toISOString() : JSON.stringify(arg);
2508
- }).join('|') : '_(no-args)_';
2252
+ var _parseCases = parseCases(matches),
2253
+ cases = _parseCases.cases;
2509
2254
 
2510
- if (Object.prototype.hasOwnProperty.call(cache, key)) {
2511
- return cache[key];
2512
- }
2255
+ if (value in cases) {
2256
+ return format(cases[value], values);
2257
+ } else if (OTHER in cases) {
2258
+ return format(cases[OTHER], values);
2259
+ }
2513
2260
 
2514
- var result = func.apply(void 0, args);
2515
- cache[key] = result;
2516
- return result;
2517
- };
2261
+ return value;
2518
2262
  }
2519
2263
 
2520
- //# sourceMappingURL=function-utils.es.js.map
2521
- ;// CONCATENATED MODULE: ./node_modules/@ultraq/icu-message-formatter/lib/icu-message-formatter.es.js
2522
2264
 
2265
+ //# sourceMappingURL=icu-message-formatter.es.js.map
2523
2266
 
2267
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/hooks.js
2524
2268
 
2525
2269
 
2526
2270
 
2271
+ // The passed in locale (en-GB) is only used to call Intl.PluralRules.select() in
2272
+ // pluralTypeHandler. Since we only use exact plural matches (=0, =1 etc) we can
2273
+ // safely use en-GB all the time.
2527
2274
 
2275
+ const formatter = new MessageFormatter('en-GB', {
2276
+ plural: pluralTypeHandler,
2277
+ select: selectTypeHandler
2278
+ });
2279
+ function hooks_useI18n() {
2280
+ const translations = useSelector(Selectors.selectTranslations);
2281
+ const locale = useSelector(Selectors.selectLocale);
2282
+ const initialLocale = useSelector(Selectors.selectInitialLocale);
2283
+ const t = useCallback((key, values = {}) => {
2284
+ const translation = translations[key];
2528
2285
 
2529
- /*
2530
- * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
2531
- *
2532
- * Licensed under the Apache License, Version 2.0 (the "License");
2533
- * you may not use this file except in compliance with the License.
2534
- * You may obtain a copy of the License at
2535
- *
2536
- * http://www.apache.org/licenses/LICENSE-2.0
2537
- *
2538
- * Unless required by applicable law or agreed to in writing, software
2539
- * distributed under the License is distributed on an "AS IS" BASIS,
2540
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2541
- * See the License for the specific language governing permissions and
2542
- * limitations under the License.
2543
- */
2286
+ if (!translation) {
2287
+ return null;
2288
+ }
2544
2289
 
2545
- /**
2546
- * Most branch-based type handlers are based around "cases".
2547
- * For example, `select` and `plural` compare compare a value
2548
- * to "case keys" to choose a subtranslation.
2549
- *
2550
- * This util splits "matches" portions provided to the aforementioned
2551
- * handlers into case strings, and extracts any prepended arguments
2552
- * (for example, `plural` supports an `offset:n` argument used for
2553
- * populating the magic `#` variable).
2554
- *
2555
- * @param {String} string
2556
- * @return {Object} The `cases` key points to a map of all cases.
2557
- * The `arguments` key points to a list of prepended arguments.
2558
- */
2559
- function parseCases(string) {
2560
- var isWhitespace = function isWhitespace(ch) {
2561
- return /\s/.test(ch);
2290
+ return formatter.format(translation, values);
2291
+ }, [translations]);
2292
+ return {
2293
+ t,
2294
+ locale,
2295
+ initialLocale
2562
2296
  };
2297
+ }
2298
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/reducer.js
2299
+ function i18n_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2563
2300
 
2564
- var args = [];
2565
- var cases = {};
2566
- var currTermStart = 0;
2567
- var latestTerm = null;
2568
- var inTerm = false;
2569
- var i = 0;
2570
-
2571
- while (i < string.length) {
2572
- // Term ended
2573
- if (inTerm && (isWhitespace(string[i]) || string[i] === '{')) {
2574
- inTerm = false;
2575
- latestTerm = string.slice(currTermStart, i); // We want to process the opening char again so the case will be properly registered.
2576
-
2577
- if (string[i] === '{') {
2578
- i--;
2579
- }
2580
- } // New term
2581
- else if (!inTerm && !isWhitespace(string[i])) {
2582
- var caseBody = string[i] === '{'; // If there's a previous term, we can either handle a whole
2583
- // case, or add that as an argument.
2584
-
2585
- if (latestTerm && caseBody) {
2586
- var branchEndIndex = findClosingBracket(string, i);
2301
+ function i18n_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { i18n_reducer_ownKeys(Object(source), true).forEach(function (key) { i18n_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { i18n_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2587
2302
 
2588
- if (branchEndIndex === -1) {
2589
- throw new Error("Unbalanced curly braces in string: \"".concat(string, "\""));
2590
- }
2303
+ function i18n_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2591
2304
 
2592
- cases[latestTerm] = string.slice(i + 1, branchEndIndex); // Don't include the braces
2593
2305
 
2594
- i = branchEndIndex; // Will be moved up where needed at end of loop.
2595
2306
 
2596
- latestTerm = null;
2597
- } else {
2598
- if (latestTerm) {
2599
- args.push(latestTerm);
2600
- latestTerm = null;
2601
- }
2602
-
2603
- inTerm = true;
2604
- currTermStart = i;
2605
- }
2307
+ const defaultState = {
2308
+ translations: {
2309
+ 'errors.configError.message': 'We are sorry this happened, please retry at a later time.',
2310
+ 'errors.configError.srText': 'A chat configuration error occurred. Our apologies, please retry at a later time.',
2311
+ 'errors.configError.title': 'Chat configuration error.',
2312
+ 'errors.general.buttonText': 'Restart chat',
2313
+ 'errors.general.message': 'Do you want to start a new chat session?',
2314
+ 'errors.general.srText': 'Something went wrong with the chat session. You can restart the chat.',
2315
+ 'errors.general.title': 'Something went wrong',
2316
+ 'errors.seamlyOffline.message': 'There might be a problem with your or our network connection. The chat session should resume as soon the connection is available again.',
2317
+ 'errors.seamlyOffline.srText': 'The chat has connection issues. There might be a problem with your or our network connection. The chat session should resume as soon as the connection is available again.',
2318
+ 'errors.seamlyOffline.title': 'Connection issues',
2319
+ 'errors.seamlyUnavailable.buttonText': 'Try again',
2320
+ 'errors.seamlyUnavailable.message': 'The server could not be reached. Try again in a little while.',
2321
+ 'errors.seamlyUnavailable.srText': 'The chat server could not be reached. Try again in a little while.',
2322
+ 'errors.seamlyUnavailable.title': 'Server unavailable'
2323
+ },
2324
+ isLoading: false,
2325
+ initialLocale: undefined
2326
+ };
2327
+ /* harmony default export */ const i18n_reducer = (i18n_utils_createReducer({
2328
+ [setInitialLocale]: (state, {
2329
+ locale
2330
+ }) => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
2331
+ initialLocale: locale
2332
+ }),
2333
+ [setLocale.pending]: state => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
2334
+ isLoading: true
2335
+ }),
2336
+ [setLocale.fulfilled]: (state, {
2337
+ payload: translations,
2338
+ meta: {
2339
+ arg: locale
2340
+ }
2341
+ }) => {
2342
+ if (!translations) {
2343
+ return i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
2344
+ isLoading: false
2345
+ });
2606
2346
  }
2607
2347
 
2608
- i++;
2609
- }
2348
+ return i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
2349
+ isLoading: false,
2350
+ locale,
2351
+ translations: Object.keys(translations).sort().reduce((accum, key) => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, accum), {}, {
2352
+ [key]: translations[key]
2353
+ }), {})
2354
+ });
2355
+ },
2356
+ [setLocale.rejected]: state => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
2357
+ isLoading: false
2358
+ })
2359
+ }, defaultState));
2360
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/index.js
2610
2361
 
2611
- if (inTerm) {
2612
- latestTerm = string.slice(currTermStart);
2613
- }
2614
2362
 
2615
- if (latestTerm) {
2616
- args.push(latestTerm);
2617
- }
2618
2363
 
2619
- return {
2620
- args: args,
2621
- cases: cases
2622
- };
2623
- }
2624
- /**
2625
- * Finds the index of the matching closing curly bracket, including through
2626
- * strings that could have nested brackets.
2627
- *
2628
- * @param {String} string
2629
- * @param {Number} fromIndex
2630
- * @return {Number} The index of the matching closing bracket, or -1 if no
2631
- * closing bracket could be found.
2632
- */
2633
2364
 
2634
- function findClosingBracket(string, fromIndex) {
2635
- var depth = 0;
2636
2365
 
2637
- for (var i = fromIndex + 1; i < string.length; i++) {
2638
- var char = string.charAt(i);
2366
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/utils.js
2639
2367
 
2640
- if (char === '}') {
2641
- if (depth === 0) {
2642
- return i;
2643
- }
2368
+ const {
2369
+ createAction: app_utils_createAction,
2370
+ createThunk: app_utils_createThunk,
2371
+ createReducer: app_utils_createReducer,
2372
+ selectState: app_utils_selectState
2373
+ } = createDomain('app');
2374
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/selectors.js
2644
2375
 
2645
- depth--;
2646
- } else if (char === '{') {
2647
- depth++;
2648
- }
2649
- }
2650
2376
 
2651
- return -1;
2652
- }
2653
- /**
2654
- * Split a `{key, type, format}` block into those 3 parts, taking into account
2655
- * nested message syntax that can exist in the `format` part.
2656
- *
2657
- * @param {String} block
2658
- * @return {Array}
2659
- * An array with `key`, `type`, and `format` items in that order, if present
2660
- * in the formatted argument block.
2661
- */
2377
+ const selectUserHasResponded = createSelector(app_utils_selectState, state => state.userHasResponded);
2662
2378
 
2663
- function splitFormattedArgument(block) {
2664
- return split(block.slice(1, -1), ',', 3);
2665
- }
2666
- /**
2667
- * Like `String.prototype.split()` but where the limit parameter causes the
2668
- * remainder of the string to be grouped together in a final entry.
2669
- *
2670
- * @private
2671
- * @param {String} string
2672
- * @param {String} separator
2673
- * @param {Number} limit
2674
- * @param {Array} [accumulator=[]]
2675
- * @return {Array}
2676
- */
2379
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/utils.js
2677
2380
 
2678
- function split(string, separator, limit) {
2679
- var accumulator = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2680
2381
 
2681
- if (!string) {
2682
- return accumulator;
2683
- }
2382
+ const {
2383
+ createAction: visibility_utils_createAction,
2384
+ createActions: utils_createActions,
2385
+ createThunk: visibility_utils_createThunk,
2386
+ createReducer: visibility_utils_createReducer,
2387
+ selectState: visibility_utils_selectState
2388
+ } = createDomain('visibility');
2389
+ const calculateVisibility = ({
2390
+ hasResponded,
2391
+ previousVisibility,
2392
+ requestedVisibility,
2393
+ config
2394
+ }) => {
2395
+ const {
2396
+ defaults,
2397
+ layoutMode,
2398
+ hideOnNoUserResponse
2399
+ } = config;
2400
+ const {
2401
+ visible: defaultVisibility
2402
+ } = defaults || {}; // Requesting open should override the responded check.
2684
2403
 
2685
- if (limit === 1) {
2686
- accumulator.push(string);
2687
- return accumulator;
2404
+ if (layoutMode === 'window' && hideOnNoUserResponse && requestedVisibility !== constants_visibilityStates.open) {
2405
+ return hasResponded ? requestedVisibility || previousVisibility || constants_visibilityStates.open : constants_visibilityStates.hidden;
2688
2406
  }
2689
2407
 
2690
- var indexOfDelimiter = string.indexOf(separator);
2408
+ const baseVisibility = layoutMode === 'inline' ? constants_visibilityStates.open : constants_visibilityStates.minimized;
2409
+ return requestedVisibility || previousVisibility || defaultVisibility || baseVisibility;
2410
+ };
2411
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/selectors.js
2691
2412
 
2692
- if (indexOfDelimiter === -1) {
2693
- accumulator.push(string);
2694
- return accumulator;
2695
- }
2696
2413
 
2697
- var head = string.substring(0, indexOfDelimiter).trim();
2698
- var tail = string.substring(indexOfDelimiter + separator.length + 1).trim();
2699
- accumulator.push(head);
2700
- return split(tail, separator, limit - 1, accumulator);
2701
- }
2414
+ const selectVisibility = createSelector(visibility_utils_selectState, state => state.visibility);
2702
2415
 
2703
- /**
2704
- * The main class for formatting messages.
2705
- *
2706
- * @author Emanuel Rabina
2707
- */
2416
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/seamly-state-hooks.js
2417
+ function seamly_state_hooks_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2708
2418
 
2709
- var MessageFormatter = /*#__PURE__*/function () {
2710
- /**
2711
- * Creates a new formatter that can work using any of the custom type handlers
2712
- * you register.
2713
- *
2714
- * @param {String} locale
2715
- * @param {Object} [typeHandlers={}]
2716
- * Optional object where the keys are the names of the types to register,
2717
- * their values being the functions that will return a nicely formatted
2718
- * string for the data and locale they are given.
2719
- */
2720
- function MessageFormatter(locale) {
2721
- var _this = this;
2419
+ function seamly_state_hooks_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { seamly_state_hooks_ownKeys(Object(source), true).forEach(function (key) { seamly_state_hooks_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { seamly_state_hooks_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2722
2420
 
2723
- var typeHandlers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2421
+ function seamly_state_hooks_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2724
2422
 
2725
- _classCallCheck(this, MessageFormatter);
2726
2423
 
2727
- defineProperty_defineProperty(this, "format", memoize(function (message) {
2728
- var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2729
- return flatten(_this.process(message, values)).join('');
2730
- }));
2731
2424
 
2732
- this.locale = locale;
2733
- this.typeHandlers = typeHandlers;
2425
+
2426
+
2427
+ const seamly_state_hooks_selectState = state => state.state;
2428
+ const seamly_state_hooks_useSeamlyStateContext = () => useSelector(seamly_state_hooks_selectState);
2429
+ const selectEvents = createSelector(seamly_state_hooks_selectState, selectConfig, ({
2430
+ events
2431
+ }, config) => {
2432
+ var _config$messages;
2433
+
2434
+ const {
2435
+ enabled,
2436
+ threshold
2437
+ } = (config === null || config === void 0 ? void 0 : (_config$messages = config.messages) === null || _config$messages === void 0 ? void 0 : _config$messages.timeIndicator) ?? {};
2438
+
2439
+ if (!enabled) {
2440
+ return events;
2734
2441
  }
2735
- /**
2736
- * Formats an ICU message syntax string using `values` for placeholder data
2737
- * and any currently-registered type handlers.
2738
- *
2739
- * @param {String} message
2740
- * @param {Object} [values={}]
2741
- * @return {String}
2742
- */
2743
2442
 
2443
+ const mappedEvents = [];
2444
+ let previousEvent = null;
2445
+ events.forEach((event, idx) => {
2446
+ // always add timeIndicator to first message
2447
+ if (idx === 0) {
2448
+ mappedEvents.push(seamly_state_hooks_objectSpread(seamly_state_hooks_objectSpread({}, event), {}, {
2449
+ timeIndicator: event.payload.occurredAt
2450
+ })); // else check if diff is greater than threshold
2451
+ } else {
2452
+ const timeIndicator = previousEvent && microsecondsToMilliseconds(event.payload.occurredAt - previousEvent.payload.occurredAt) >= threshold ? event.payload.occurredAt : undefined;
2453
+ mappedEvents.push(seamly_state_hooks_objectSpread(seamly_state_hooks_objectSpread({}, event), {}, {
2454
+ timeIndicator
2455
+ }));
2456
+ }
2457
+
2458
+ previousEvent = event;
2459
+ });
2460
+ return mappedEvents;
2461
+ });
2462
+ const seamly_state_hooks_useEvents = () => useSelector(selectEvents, []);
2463
+ const useSeamlyIsLoading = () => seamly_state_hooks_useSeamlyStateContext().isLoading;
2464
+ const useSeamlyHeaderData = () => seamly_state_hooks_useSeamlyStateContext().headerTitles;
2465
+ const seamly_state_hooks_useSeamlyUnreadCount = () => seamly_state_hooks_useSeamlyStateContext().unreadEvents;
2466
+ const seamly_state_hooks_useSkiplink = () => seamly_state_hooks_useSeamlyStateContext().skiplinkTargetId;
2467
+ const useSeamlyParticipant = participantId => seamly_state_hooks_useSeamlyStateContext().participantInfo.participants[participantId];
2468
+ const useSeamlyServiceInfo = () => seamly_state_hooks_useSeamlyStateContext().serviceInfo;
2469
+ const selectLastMessageEventId = createSelector(selectEvents, events => {
2470
+ var _filteredEvents;
2471
+
2472
+ const filteredEvents = events.filter(event => event.type === 'message');
2473
+ return (_filteredEvents = filteredEvents[filteredEvents.length - 1]) === null || _filteredEvents === void 0 ? void 0 : _filteredEvents.payload.id;
2474
+ });
2475
+ const useLastMessageEventId = () => useSelector(selectLastMessageEventId);
2476
+ const useSeamlyIsHistoryLoaded = () => seamly_state_hooks_useSeamlyStateContext().historyLoaded;
2477
+ const useSeamlyCurrentAgent = () => {
2478
+ const {
2479
+ participants,
2480
+ currentAgent
2481
+ } = seamly_state_hooks_useSeamlyStateContext().participantInfo;
2482
+ return currentAgent ? participants[currentAgent] : null;
2483
+ };
2484
+ const useSeamlyServiceData = key => seamly_state_hooks_useSeamlyStateContext().serviceData[key];
2485
+ const useEntryTextLimit = () => {
2486
+ const {
2487
+ entryMeta: {
2488
+ options: {
2489
+ text
2490
+ }
2491
+ }
2492
+ } = seamly_state_hooks_useSeamlyStateContext();
2493
+ const {
2494
+ limit
2495
+ } = text || {};
2496
+ return {
2497
+ hasLimit: limit != null,
2498
+ limit: limit != null ? limit : null
2499
+ };
2500
+ };
2501
+ const useSeamlyLayoutMode = () => {
2502
+ const {
2503
+ layoutMode
2504
+ } = useConfig();
2505
+ return {
2506
+ isInline: layoutMode === 'inline',
2507
+ isModal: layoutMode === 'modal',
2508
+ isWindow: layoutMode === 'window',
2509
+ isResolving: !layoutMode
2510
+ };
2511
+ };
2512
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/actions.js
2513
+ function actions_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2514
+
2515
+ function actions_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { actions_ownKeys(Object(source), true).forEach(function (key) { actions_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { actions_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2516
+
2517
+ function actions_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+ const setFromStorage = visibility_utils_createAction('setFromStorage', visibility => ({
2526
+ visibility
2527
+ }));
2528
+ const validVisibilityStates = [constants_visibilityStates.open, constants_visibilityStates.minimized, constants_visibilityStates.hidden];
2529
+ const setVisibility = visibility_utils_createThunk('set', (requestedVisibility, {
2530
+ getState,
2531
+ extra: {
2532
+ api,
2533
+ eventBus
2534
+ }
2535
+ }) => {
2536
+ const state = getState();
2537
+ const previousVisibility = selectVisibility(state);
2538
+ const hasResponded = selectUserHasResponded(state);
2539
+ const hasConversation = api.hasConversation();
2540
+ const config = selectConfig(state);
2541
+ const {
2542
+ visibilityCallback = calculateVisibility,
2543
+ layoutMode
2544
+ } = config;
2545
+ const {
2546
+ unreadEvents: unreadMessageCount
2547
+ } = seamly_state_hooks_selectState(state);
2548
+ const calculatedVisibility = visibilityCallback({
2549
+ hasConversation,
2550
+ hasResponded,
2551
+ previousVisibility,
2552
+ requestedVisibility,
2553
+ config
2554
+ });
2555
+
2556
+ if (!validVisibilityStates.includes(calculatedVisibility)) {
2557
+ console.error('The visibilityCallback function should return "open", "minimized" or "hidden".');
2558
+ return undefined;
2559
+ }
2560
+
2561
+ if (previousVisibility === calculatedVisibility) {
2562
+ return undefined;
2563
+ } // Store the user-requested visibility in order to reinitialize after refresh
2564
+
2565
+
2566
+ api.store.set(StoreKey, actions_objectSpread(actions_objectSpread({}, api.store.get(StoreKey) || {}), {}, {
2567
+ [layoutMode]: requestedVisibility
2568
+ }));
2569
+
2570
+ if (requestedVisibility) {
2571
+ eventBus.emit('ui.visible', requestedVisibility, {
2572
+ visibility: requestedVisibility,
2573
+ hasConversation,
2574
+ hasResponded,
2575
+ unreadMessageCount
2576
+ });
2577
+ }
2578
+
2579
+ return calculatedVisibility;
2580
+ });
2581
+ const actions_initialize = visibility_utils_createThunk('initialize', async (locale, {
2582
+ dispatch,
2583
+ getState,
2584
+ extra: {
2585
+ api
2586
+ }
2587
+ }) => {
2588
+ var _api$store$get;
2589
+
2590
+ // initialize stored visibility
2591
+ const {
2592
+ layoutMode
2593
+ } = selectConfig(getState());
2594
+ const storedVisibility = (_api$store$get = api.store.get(StoreKey)) === null || _api$store$get === void 0 ? void 0 : _api$store$get[layoutMode];
2595
+
2596
+ if (storedVisibility) {
2597
+ dispatch(setFromStorage(storedVisibility));
2598
+ }
2599
+
2600
+ dispatch(setVisibility(constants_visibilityStates.initialize));
2601
+ });
2602
+ ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-unavailable-error.js
2603
+ /**
2604
+ * This error is used to alert the user that there's a problem with the connection
2605
+ * when initialising the application because of a connection issue on either the server
2606
+ * or the client side.
2607
+ */
2608
+ class SeamlyUnavailableError extends Error {
2609
+ constructor(params) {
2610
+ super(params);
2611
+
2612
+ if (Error.captureStackTrace) {
2613
+ Error.captureStackTrace(this, SeamlyUnavailableError);
2614
+ }
2615
+
2616
+ this.name = 'SeamlyUnavailableError';
2617
+ this.langKey = 'errors.seamlyUnavailable';
2618
+ }
2619
+
2620
+ }
2621
+ ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-base-error.js
2622
+ class SeamlyBaseError extends Error {
2623
+ constructor(originalError, ...params) {
2624
+ super(...params);
2625
+
2626
+ if (Error.captureStackTrace) {
2627
+ Error.captureStackTrace(this, Object.getPrototypeOf(this));
2628
+ }
2629
+
2630
+ this.originalError = originalError;
2631
+ }
2632
+
2633
+ }
2634
+ ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-session-expired-error.js
2635
+
2636
+ class SeamlySessionExpiredError extends SeamlyBaseError {
2637
+ constructor(originalError, ...params) {
2638
+ super(originalError, ...params);
2639
+ this.name = 'SeamlySessionExpiredError';
2640
+ this.action = 'reset';
2641
+ }
2642
+
2643
+ }
2644
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/actions.js
2645
+
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+ const setHasResponded = app_utils_createAction('setHasResponded', hasResponded => ({
2653
+ hasResponded
2654
+ }));
2655
+ const app_actions_initialize = app_utils_createThunk('initialize', async (config, {
2656
+ dispatch,
2657
+ extra: {
2658
+ api
2659
+ }
2660
+ }) => {
2661
+ var _config$context;
2662
+
2663
+ dispatch(initialize(config));
2664
+ let locale = config === null || config === void 0 ? void 0 : (_config$context = config.context) === null || _config$context === void 0 ? void 0 : _config$context.locale;
2665
+
2666
+ try {
2667
+ const {
2668
+ features,
2669
+ defaultLocale
2670
+ } = await api.getConfig();
2671
+ dispatch({
2672
+ type: seamly_utils_seamlyActions.SET_FEATURES,
2673
+ features
2674
+ });
2675
+ locale = locale || defaultLocale;
2676
+ dispatch(setInitialLocale(locale));
2677
+ } catch (e) {
2678
+ throw new SeamlyUnavailableError();
2679
+ }
2680
+
2681
+ try {
2682
+ if (api.hasConversation()) {
2683
+ var _initialState$transla;
2684
+
2685
+ const initialState = await api.getConversationIntitialState();
2686
+ dispatch({
2687
+ type: seamly_utils_seamlyActions.SET_INITIAL_STATE,
2688
+ initialState
2689
+ });
2690
+ locale = ((_initialState$transla = initialState.translation) === null || _initialState$transla === void 0 ? void 0 : _initialState$transla.locale) || locale;
2691
+
2692
+ if ('userResponded' in initialState) {
2693
+ dispatch(setHasResponded(initialState.userResponded));
2694
+ }
2695
+ }
2696
+ } catch (e) {
2697
+ if (e instanceof SeamlySessionExpiredError) {
2698
+ throw e;
2699
+ }
2700
+
2701
+ throw new SeamlyUnavailableError();
2702
+ } finally {
2703
+ await dispatch(setLocale(locale));
2704
+ dispatch(actions_initialize());
2705
+ }
2706
+ });
2707
+ const actions_reset = app_utils_createAction('reset', () => {});
2708
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/hooks.js
2709
+
2710
+
2711
+ function hooks_useUserHasResponded() {
2712
+ return useSelector(Selectors.selectUserHasResponded);
2713
+ }
2714
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/reducer.js
2715
+ function app_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2716
+
2717
+ function app_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { app_reducer_ownKeys(Object(source), true).forEach(function (key) { app_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { app_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2718
+
2719
+ function app_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2720
+
2721
+
2722
+
2723
+ const reducer_initialState = {
2724
+ userHasResponded: false
2725
+ };
2726
+ /* harmony default export */ const app_reducer = (app_utils_createReducer({
2727
+ [setHasResponded]: (state, {
2728
+ hasResponded
2729
+ }) => app_reducer_objectSpread(app_reducer_objectSpread({}, state), {}, {
2730
+ userHasResponded: hasResponded
2731
+ })
2732
+ }, reducer_initialState));
2733
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/index.js
2734
+
2735
+
2736
+
2737
+
2738
+
2739
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/store/state-reducer.js
2740
+ function state_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2741
+
2742
+ function state_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { state_reducer_ownKeys(Object(source), true).forEach(function (key) { state_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { state_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2743
+
2744
+ function state_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2745
+
2746
+ // Legacy state reducer. Do not add new features here but extract/create new reducers as needed
2747
+
2748
+
2749
+
2750
+ const state_reducer_initialState = {
2751
+ events: [],
2752
+ initialState: {},
2753
+ unreadEvents: 0,
2754
+ isLoading: false,
2755
+ idleDetachCountdown: {
2756
+ hasCountdown: false,
2757
+ isActive: false
2758
+ },
2759
+ resumeConversationPrompt: false,
2760
+ serviceInfo: {
2761
+ activeServiceSessionId: ''
2762
+ },
2763
+ participantInfo: {
2764
+ participants: {},
2765
+ currentAgent: ''
2766
+ },
2767
+ headerTitles: {
2768
+ title: null,
2769
+ subTitle: ''
2770
+ },
2771
+ historyLoaded: false,
2772
+ skiplinkTargetId: id_randomId(),
2773
+ optionsButtonId: id_randomId(),
2774
+ cobrowsingContainerId: id_randomId(),
2775
+ headerCollapseButtonId: id_randomId(),
2776
+ serviceData: {},
2777
+ options: {
2778
+ features: {},
2779
+ panelActive: false,
2780
+ optionActive: '',
2781
+ userSelectedOptions: {}
2782
+ },
2783
+ showFileUpload: false,
2784
+ currentUploads: [],
2785
+ entryMeta: {
2786
+ default: entryTypes.text,
2787
+ active: entryTypes.text,
2788
+ userSelected: null,
2789
+ blockAutoEntrySwitch: false,
2790
+ options: {},
2791
+ optionsOverride: {}
2792
+ },
2793
+ seamlyContainerElement: null
2794
+ };
2795
+ function stateReducer(state = state_reducer_initialState, action) {
2796
+ if (action.type === String(actions_reset)) {
2797
+ const {
2798
+ visible
2799
+ } = state;
2800
+ return state_reducer_objectSpread(state_reducer_objectSpread({}, state_reducer_initialState), {}, {
2801
+ visible
2802
+ });
2803
+ }
2804
+
2805
+ return seamlyStateReducer(state, action);
2806
+ }
2807
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/utils.js
2808
+
2809
+ const {
2810
+ createActions: forms_utils_createActions,
2811
+ createReducer: forms_utils_createReducer,
2812
+ selectState: forms_utils_selectState
2813
+ } = createDomain('forms');
2814
+ function utils_validate(values, schema = {}) {
2815
+ return Object.entries(schema).reduce((errors, [key, validations]) => {
2816
+ if (validations && !Array.isArray(validations)) {
2817
+ // eslint-disable-next-line no-param-reassign
2818
+ validations = [validations];
2819
+ }
2820
+
2821
+ for (let i = 0; i < ((_validations = validations) === null || _validations === void 0 ? void 0 : _validations.length) ?? 0; i++) {
2822
+ var _validations;
2823
+
2824
+ if (!validations[i].fn(values[key], validations[i].compareValue)) {
2825
+ errors[key] = validations[i].errorText;
2826
+ break;
2827
+ }
2828
+ }
2829
+
2830
+ return errors;
2831
+ }, {});
2832
+ }
2833
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/actions.js
2834
+
2835
+ const [registerForm, deregisterForm] = forms_utils_createActions('form', {
2836
+ register: (formId, persistData) => ({
2837
+ formId,
2838
+ persistData
2839
+ }),
2840
+ deregister: formId => ({
2841
+ formId
2842
+ })
2843
+ });
2844
+ const [registerControl, deregisterControl, updateControlValue, updateControlTouched] = forms_utils_createActions('control', {
2845
+ register: (formId, name) => ({
2846
+ formId,
2847
+ name
2848
+ }),
2849
+ deregister: (formId, name) => ({
2850
+ formId,
2851
+ name
2852
+ }),
2853
+ updateValue: (formId, name, value) => ({
2854
+ formId,
2855
+ name,
2856
+ value
2857
+ }),
2858
+ updateTouched: (formId, name, touched) => ({
2859
+ formId,
2860
+ name,
2861
+ touched
2862
+ })
2863
+ });
2864
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/redux/utils.js
2865
+ const arrayContentEquals = (a, b) => {
2866
+ if (a === b) {
2867
+ return true;
2868
+ }
2869
+
2870
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {
2871
+ return false;
2872
+ }
2873
+
2874
+ return a.every((value, idx) => b[idx] === value);
2875
+ };
2876
+ const getPropSelector = (propName, orDefault) => (_, props) => props[propName] || orDefault;
2877
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/selectors.js
2878
+
2879
+
2880
+
2881
+ const getState = forms_utils_selectState;
2882
+ const selectors_getFormById = createSelector(getState, getPropSelector('formId'), (forms, formId) => forms[formId]);
2883
+ const getFormControlsByFormId = createSelector(selectors_getFormById, form => (form === null || form === void 0 ? void 0 : form.controls) || {});
2884
+ const selectors_getFormValuesByFormId = createSelector(getFormControlsByFormId, controls => {
2885
+ const valuesObj = {};
2886
+ Object.entries(controls).forEach(([key, {
2887
+ value
2888
+ }]) => {
2889
+ valuesObj[key] = value;
2890
+ });
2891
+ return valuesObj;
2892
+ });
2893
+ const selectors_getControlValueByName = createSelector(getFormControlsByFormId, getPropSelector('name'), (controls, name) => {
2894
+ var _controls$name;
2895
+
2896
+ return (_controls$name = controls[name]) === null || _controls$name === void 0 ? void 0 : _controls$name.value;
2897
+ });
2898
+ const selectors_getControlTouchedByName = createSelector(getFormControlsByFormId, getPropSelector('name'), (controls, name) => {
2899
+ var _controls$name2;
2900
+
2901
+ return (_controls$name2 = controls[name]) === null || _controls$name2 === void 0 ? void 0 : _controls$name2.touched;
2902
+ });
2903
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/context.js
2904
+
2905
+ const context_FormContext = (0,external_preact_namespaceObject.createContext)({});
2906
+ /* harmony default export */ const forms_context = ((/* unused pure expression or super */ null && (context_FormContext)));
2907
+ const {
2908
+ Provider: forms_context_Provider,
2909
+ Consumer: context_Consumer
2910
+ } = context_FormContext;
2911
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/hooks.js
2912
+
2913
+
2914
+
2915
+
2916
+
2917
+
2918
+ function hooks_useFormContext() {
2919
+ return useContext(FormContext);
2920
+ }
2921
+ function hooks_useForm() {
2922
+ const {
2923
+ handleSubmit
2924
+ } = hooks_useFormContext();
2925
+ return {
2926
+ handleSubmit
2927
+ };
2928
+ }
2929
+ function hooks_useValidations(values, validationSchema) {
2930
+ const errors = useMemo(() => validate(values, validationSchema), [values, validationSchema]);
2931
+ return {
2932
+ isValid: Object.keys(errors).length === 0,
2933
+ errors
2934
+ };
2935
+ }
2936
+ function hooks_useFormControl(name) {
2937
+ const dispatch = useStoreDispatch();
2938
+ const {
2939
+ formId,
2940
+ updateControlValue,
2941
+ updateControlTouched,
2942
+ errors
2943
+ } = hooks_useFormContext();
2944
+ const form = useSelectorWithProps(getFormById, {
2945
+ formId
2946
+ }, [formId]);
2947
+ const isRegistered = !!form;
2948
+ const isRegisteredRef = useRef();
2949
+ isRegisteredRef.current = isRegistered;
2950
+ const value = useSelectorWithProps(getControlValueByName, {
2951
+ formId,
2952
+ name
2953
+ }, [formId, name]);
2954
+ const touched = useSelectorWithProps(getControlTouchedByName, {
2955
+ formId,
2956
+ name
2957
+ }, [formId, name]);
2958
+ const error = errors === null || errors === void 0 ? void 0 : errors[name];
2959
+ const isValid = !error;
2960
+ useEffect(() => {
2961
+ // Make sure the form is registered
2962
+ // Since child useEffect runs before FormProvider useEffect
2963
+ if (isRegisteredRef.current) {
2964
+ dispatch(Actions.registerControl(formId, name));
2965
+ }
2966
+ }, [isRegistered, formId, name, dispatch]);
2967
+ useLayoutEffect(() => {
2968
+ return () => {
2969
+ dispatch(Actions.deregisterControl(formId, name));
2970
+ };
2971
+ }, [isRegistered, formId, name, dispatch]); // preact uses onInput instead of onChange
2972
+
2973
+ const onInput = useCallback(e => updateControlValue(name, e.target.value), [name, updateControlValue]);
2974
+ const onBlur = useCallback(() => {
2975
+ updateControlTouched(name, true);
2976
+ }, [updateControlTouched, name]);
2977
+ const field = useMemo(() => ({
2978
+ name,
2979
+ onInput,
2980
+ onBlur,
2981
+ value
2982
+ }), [name, onInput, onBlur, value]);
2983
+ const meta = useMemo(() => ({
2984
+ isValid,
2985
+ error,
2986
+ touched
2987
+ }), [isValid, error, touched]);
2988
+ return [field, meta];
2989
+ }
2990
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/provider.js
2991
+ const provider_excluded = (/* unused pure expression or super */ null && (["children", "formId", "persistData", "onSubmit", "validationSchema"]));
2992
+
2993
+ function provider_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2994
+
2995
+ function provider_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { provider_ownKeys(Object(source), true).forEach(function (key) { provider_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { provider_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2996
+
2997
+ function provider_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2744
2998
 
2745
- _createClass(MessageFormatter, [{
2746
- key: "process",
2747
- value:
2748
- /**
2749
- * Process an ICU message syntax string using `values` for placeholder data
2750
- * and any currently-registered type handlers. The result of this method is
2751
- * an array of the component parts after they have been processed in turn by
2752
- * their own type handlers. This raw output is useful for other renderers,
2753
- * eg: React where components can be used instead of being forced to return
2754
- * raw strings.
2755
- *
2756
- * This method is used by {@link MessageFormatter#format} where it acts as a
2757
- * string renderer.
2758
- *
2759
- * @param {String} message
2760
- * @param {Object} [values={}]
2761
- * @return {Array}
2762
- */
2763
- function process(message) {
2764
- var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2999
+ function provider_objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = provider_objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
2765
3000
 
2766
- if (!message) {
2767
- return [];
2768
- }
3001
+ function provider_objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
2769
3002
 
2770
- var blockStartIndex = message.indexOf('{');
2771
3003
 
2772
- if (blockStartIndex !== -1) {
2773
- var blockEndIndex = findClosingBracket(message, blockStartIndex);
2774
3004
 
2775
- if (blockEndIndex !== -1) {
2776
- var block = message.substring(blockStartIndex, blockEndIndex + 1);
2777
3005
 
2778
- if (block) {
2779
- var result = [];
2780
- var head = message.substring(0, blockStartIndex);
2781
3006
 
2782
- if (head) {
2783
- result.push(head);
2784
- }
2785
3007
 
2786
- var _splitFormattedArgume = splitFormattedArgument(block),
2787
- _splitFormattedArgume2 = _slicedToArray(_splitFormattedArgume, 3),
2788
- key = _splitFormattedArgume2[0],
2789
- type = _splitFormattedArgume2[1],
2790
- format = _splitFormattedArgume2[2];
2791
3008
 
2792
- var body = values[key];
2793
3009
 
2794
- if (body === null || body === undefined) {
2795
- body = '';
2796
- }
3010
+ function provider_FormProvider(_ref) {
3011
+ let {
3012
+ children,
3013
+ formId,
3014
+ persistData,
3015
+ onSubmit,
3016
+ validationSchema
3017
+ } = _ref,
3018
+ props = provider_objectWithoutProperties(_ref, provider_excluded);
2797
3019
 
2798
- var typeHandler = type && this.typeHandlers[type];
2799
- result.push(typeHandler ? typeHandler(body, format, this.locale, values, this.process.bind(this)) : body);
2800
- var tail = message.substring(blockEndIndex + 1);
3020
+ const dispatch = useStoreDispatch();
3021
+ const values = useSelectorWithProps(getFormValuesByFormId, {
3022
+ formId
3023
+ }, [formId]);
3024
+ const [isSubmitted, setIsSubmitted] = useState(false);
3025
+ const [externalErrors, setExternalErrors] = useState({});
3026
+ const {
3027
+ isValid: validationIsValid,
3028
+ errors: validationErrors
3029
+ } = useValidations(values, validationSchema);
3030
+ const errors = useMemo(() => provider_objectSpread(provider_objectSpread({}, validationErrors), externalErrors), [validationErrors, externalErrors]); // register
2801
3031
 
2802
- if (tail) {
2803
- result.push(this.process(tail, values));
2804
- }
3032
+ useLayoutEffect(() => {
3033
+ // register form in redux store
3034
+ dispatch(Actions.registerForm(formId, persistData));
3035
+ }, [formId, persistData, dispatch]); // deregister
2805
3036
 
2806
- return result;
2807
- }
2808
- } else {
2809
- throw new Error("Unbalanced curly braces in string: \"".concat(message, "\""));
2810
- }
2811
- }
3037
+ useEffect(() => {
3038
+ return () => {
3039
+ // deregister form from redux store
3040
+ dispatch(Actions.deregisterForm(formId));
3041
+ };
3042
+ }, [formId, persistData, dispatch]);
3043
+ const updateControlValue = useCallback((name, value) => {
3044
+ dispatch(Actions.updateControlValue(formId, name, value));
3045
+ }, [formId, dispatch]);
3046
+ const updateControlTouched = useCallback((name, touched) => {
3047
+ dispatch(Actions.updateControlTouched(formId, name, touched));
3048
+ }, [dispatch, formId]); // Function to manually set an error
2812
3049
 
2813
- return [message];
3050
+ const setError = useCallback((name, error) => {
3051
+ setExternalErrors(val => {
3052
+ return provider_objectSpread(provider_objectSpread({}, val), {}, {
3053
+ [name]: error
3054
+ });
3055
+ });
3056
+ }, [setExternalErrors]);
3057
+ const handleSubmit = useCallback(e => {
3058
+ e.preventDefault();
3059
+ setIsSubmitted(true);
3060
+
3061
+ if (validationIsValid) {
3062
+ onSubmit(values, {
3063
+ updateControlValue,
3064
+ setError
3065
+ });
2814
3066
  }
2815
- }]);
3067
+ }, [validationIsValid, onSubmit, values, updateControlValue, setError]);
3068
+ const contextValue = useMemo(() => ({
3069
+ formId,
3070
+ values,
3071
+ errors,
3072
+ isValid: Object.keys(errors).length === 0,
3073
+ isSubmitted,
3074
+ handleSubmit,
3075
+ validationSchema,
3076
+ updateControlValue,
3077
+ updateControlTouched
3078
+ }), [formId, values, errors, isSubmitted, handleSubmit, validationSchema, updateControlValue, updateControlTouched]);
2816
3079
 
2817
- return MessageFormatter;
2818
- }();
3080
+ if (!formId) {
3081
+ console.error('"formId" is required.');
3082
+ return null;
3083
+ }
2819
3084
 
2820
- function icu_message_formatter_es_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
3085
+ if (!onSubmit) {
3086
+ console.error('"onSubmit" is required.');
3087
+ return null;
3088
+ }
2821
3089
 
2822
- function icu_message_formatter_es_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { icu_message_formatter_es_ownKeys(Object(source), true).forEach(function (key) { defineProperty_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { icu_message_formatter_es_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2823
- var pluralFormatter;
2824
- var keyCounter = 0; // All the special keywords that can be used in `plural` blocks for the various branches
3090
+ return _jsx(Provider, provider_objectSpread(provider_objectSpread({}, props), {}, {
3091
+ value: contextValue,
3092
+ children: children
3093
+ }));
3094
+ }
3095
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/reducer.js
3096
+ function forms_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
2825
3097
 
2826
- var ONE = 'one';
2827
- var OTHER$1 = 'other';
2828
- /**
2829
- * @private
2830
- * @param {String} caseBody
2831
- * @param {Number} value
2832
- * @return {Object} {caseBody: string, numberValues: object}
2833
- */
3098
+ function forms_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { forms_reducer_ownKeys(Object(source), true).forEach(function (key) { forms_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { forms_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2834
3099
 
2835
- function replaceNumberSign(caseBody, value) {
2836
- var i = 0;
2837
- var output = '';
2838
- var numBraces = 0;
2839
- var numberValues = {};
3100
+ function forms_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2840
3101
 
2841
- while (i < caseBody.length) {
2842
- if (caseBody[i] === '#' && !numBraces) {
2843
- var keyParam = "__hashToken".concat(keyCounter++);
2844
- output += "{".concat(keyParam, ", number}");
2845
- numberValues[keyParam] = value;
2846
- } else {
2847
- output += caseBody[i];
2848
- }
2849
3102
 
2850
- if (caseBody[i] === '{') {
2851
- numBraces++;
2852
- } else if (caseBody[i] === '}') {
2853
- numBraces--;
2854
- }
2855
3103
 
2856
- i++;
2857
- }
3104
+ const forms_reducer_initialState = {};
3105
+ const initialFormState = {
3106
+ controls: {}
3107
+ };
3108
+ const initialControlState = {
3109
+ value: '',
3110
+ touched: false
3111
+ };
2858
3112
 
2859
- return {
2860
- caseBody: output,
2861
- numberValues: numberValues
2862
- };
3113
+ function updateFormControl(state, formId, name, controlState) {
3114
+ var _state$formId;
3115
+
3116
+ const currentControlState = ((_state$formId = state[formId]) === null || _state$formId === void 0 ? void 0 : _state$formId.controls[name]) || initialControlState;
3117
+ return forms_reducer_objectSpread(forms_reducer_objectSpread({}, state), {}, {
3118
+ [formId]: forms_reducer_objectSpread(forms_reducer_objectSpread({}, state[formId]), {}, {
3119
+ controls: forms_reducer_objectSpread(forms_reducer_objectSpread({}, state[formId].controls), {}, {
3120
+ [name]: forms_reducer_objectSpread(forms_reducer_objectSpread({}, currentControlState), controlState)
3121
+ })
3122
+ })
3123
+ });
2863
3124
  }
2864
- /**
2865
- * Handler for `plural` statements within ICU message syntax strings. Returns
2866
- * a formatted string for the branch that closely matches the current value.
2867
- *
2868
- * See https://formatjs.io/docs/core-concepts/icu-syntax#plural-format for more
2869
- * details on how the `plural` statement works.
2870
- *
2871
- * @param {String} value
2872
- * @param {String} matches
2873
- * @param {String} locale
2874
- * @param {String} values
2875
- * @param {Function} format
2876
- * @return {String}
2877
- */
2878
3125
 
3126
+ /* harmony default export */ const forms_reducer = (forms_utils_createReducer({
3127
+ // Form handlers
3128
+ [registerForm]: (state, {
3129
+ formId,
3130
+ persistData
3131
+ }) => {
3132
+ const formState = persistData ? state[formId] ?? forms_reducer_objectSpread(forms_reducer_objectSpread({}, initialFormState), {}, {
3133
+ persistData
3134
+ }) : forms_reducer_objectSpread(forms_reducer_objectSpread({}, initialFormState), {}, {
3135
+ persistData
3136
+ });
3137
+ return forms_reducer_objectSpread(forms_reducer_objectSpread({}, state), {}, {
3138
+ [formId]: formState
3139
+ });
3140
+ },
3141
+ [deregisterForm]: (state, {
3142
+ formId
3143
+ }) => {
3144
+ var _newState$formId;
2879
3145
 
2880
- function pluralTypeHandler(value) {
2881
- var matches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
2882
- var locale = arguments.length > 2 ? arguments[2] : undefined;
2883
- var values = arguments.length > 3 ? arguments[3] : undefined;
2884
- var format = arguments.length > 4 ? arguments[4] : undefined;
3146
+ const newState = forms_reducer_objectSpread({}, state);
2885
3147
 
2886
- var _parseCases = parseCases(matches),
2887
- args = _parseCases.args,
2888
- cases = _parseCases.cases;
3148
+ if (!((_newState$formId = newState[formId]) !== null && _newState$formId !== void 0 && _newState$formId.persistData)) {
3149
+ delete newState[formId];
3150
+ }
2889
3151
 
2890
- var intValue = parseInt(value);
2891
- args.forEach(function (arg) {
2892
- if (arg.startsWith('offset:')) {
2893
- intValue -= parseInt(arg.slice('offset:'.length));
3152
+ return newState;
3153
+ },
3154
+ // Form control handlers
3155
+ [registerControl]: (state, {
3156
+ name,
3157
+ formId
3158
+ }) => {
3159
+ return updateFormControl(state, formId, name);
3160
+ },
3161
+ [deregisterControl]: (state, {
3162
+ formId,
3163
+ name
3164
+ }) => {
3165
+ const form = state[formId];
3166
+
3167
+ if (!form) {
3168
+ return state;
2894
3169
  }
2895
- });
2896
- var keywordPossibilities = [];
2897
3170
 
2898
- if ('PluralRules' in Intl) {
2899
- // Effectively memoize because instantiation of `Int.*` objects is expensive.
2900
- if (pluralFormatter === undefined || pluralFormatter.resolvedOptions().locale !== locale) {
2901
- pluralFormatter = new Intl.PluralRules(locale);
3171
+ if (form.persistData) {
3172
+ return state;
2902
3173
  }
2903
3174
 
2904
- var pluralKeyword = pluralFormatter.select(intValue); // Other is always added last with least priority, so we don't want to add it here.
3175
+ const controls = forms_reducer_objectSpread({}, form.controls);
2905
3176
 
2906
- if (pluralKeyword !== OTHER$1) {
2907
- keywordPossibilities.push(pluralKeyword);
2908
- }
3177
+ delete controls[name];
3178
+ return forms_reducer_objectSpread(forms_reducer_objectSpread({}, state), {}, {
3179
+ [formId]: forms_reducer_objectSpread(forms_reducer_objectSpread({}, form), {}, {
3180
+ controls
3181
+ })
3182
+ });
3183
+ },
3184
+ [updateControlValue]: (state, {
3185
+ formId,
3186
+ name,
3187
+ value
3188
+ }) => {
3189
+ return updateFormControl(state, formId, name, {
3190
+ value
3191
+ });
3192
+ },
3193
+ [updateControlTouched]: (state, {
3194
+ formId,
3195
+ name,
3196
+ touched
3197
+ }) => {
3198
+ return updateFormControl(state, formId, name, {
3199
+ touched
3200
+ });
2909
3201
  }
3202
+ }, forms_reducer_initialState));
3203
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/forms/index.js
2910
3204
 
2911
- if (intValue === 1) {
2912
- keywordPossibilities.push(ONE);
2913
- }
2914
3205
 
2915
- keywordPossibilities.push("=".concat(intValue), OTHER$1);
2916
3206
 
2917
- for (var i = 0; i < keywordPossibilities.length; i++) {
2918
- var keyword = keywordPossibilities[i];
2919
3207
 
2920
- if (keyword in cases) {
2921
- var _replaceNumberSign = replaceNumberSign(cases[keyword], intValue),
2922
- caseBody = _replaceNumberSign.caseBody,
2923
- numberValues = _replaceNumberSign.numberValues;
2924
3208
 
2925
- return format(caseBody, icu_message_formatter_es_objectSpread(icu_message_formatter_es_objectSpread({}, values), numberValues));
2926
- }
2927
- }
2928
3209
 
2929
- return value;
2930
- }
3210
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/utils.js
2931
3211
 
2932
- /*
2933
- * Copyright 2019, Emanuel Rabina (http://www.ultraq.net.nz/)
2934
- *
2935
- * Licensed under the Apache License, Version 2.0 (the "License");
2936
- * you may not use this file except in compliance with the License.
2937
- * You may obtain a copy of the License at
2938
- *
2939
- * http://www.apache.org/licenses/LICENSE-2.0
2940
- *
2941
- * Unless required by applicable law or agreed to in writing, software
2942
- * distributed under the License is distributed on an "AS IS" BASIS,
2943
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2944
- * See the License for the specific language governing permissions and
2945
- * limitations under the License.
2946
- */
2947
- var OTHER = 'other';
2948
- /**
2949
- * Handler for `select` statements within ICU message syntax strings. Returns
2950
- * a formatted string for the branch that closely matches the current value.
2951
- *
2952
- * See https://formatjs.io/docs/core-concepts/icu-syntax#select-format for more
2953
- * details on how the `select` statement works.
2954
- *
2955
- * @param {String} value
2956
- * @param {String} matches
2957
- * @param {String} locale
2958
- * @param {String} values
2959
- * @param {Function} format
2960
- * @return {String}
2961
- */
3212
+ const {
3213
+ createActions: translations_utils_createActions,
3214
+ createReducer: translations_utils_createReducer,
3215
+ selectState: translations_utils_selectState
3216
+ } = createDomain('translations');
3217
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/actions.js
2962
3218
 
2963
- function selectTypeHandler(value) {
2964
- var matches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
2965
- var values = arguments.length > 3 ? arguments[3] : undefined;
2966
- var format = arguments.length > 4 ? arguments[4] : undefined;
3219
+ const [enable, disable] = translations_utils_createActions('translate', {
3220
+ enable: locale => ({
3221
+ locale
3222
+ }),
3223
+ disable: () => ({})
3224
+ });
3225
+ const [enableEvent, disableEvent] = translations_utils_createActions('event', {
3226
+ enable: payloadId => ({
3227
+ payloadId
3228
+ }),
3229
+ disable: payloadId => ({
3230
+ payloadId
3231
+ })
3232
+ });
3233
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/selectors.js
2967
3234
 
2968
- var _parseCases = parseCases(matches),
2969
- cases = _parseCases.cases;
2970
3235
 
2971
- if (value in cases) {
2972
- return format(cases[value], values);
2973
- } else if (OTHER in cases) {
2974
- return format(cases[OTHER], values);
2975
- }
2976
3236
 
2977
- return value;
2978
- }
3237
+ const selectors_getState = translations_utils_selectState;
3238
+ const getOriginalPayloadIds = createSelector(selectors_getState, state => state.originalPayloadIds);
3239
+ const getIsPayloadTranslated = createSelector(getOriginalPayloadIds, getPropSelector('payloadId'), (payloadIds, payloadId) => !payloadIds.includes(payloadId));
3240
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/components/core/seamly-api-context.js
2979
3241
 
3242
+ const seamly_api_context_SeamlyApiContext = (0,external_preact_namespaceObject.createContext)(null);
3243
+ const seamly_api_context_SeamlyEventBusContext = (0,external_preact_namespaceObject.createContext)('');
3244
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/seamly-api-hooks.js
2980
3245
 
2981
- //# sourceMappingURL=icu-message-formatter.es.js.map
2982
3246
 
2983
- ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/hooks.js
3247
+ const seamly_api_hooks_useSeamlyApiContext = () => useContext(SeamlyApiContext);
3248
+ const seamly_api_hooks_useSeamlyObjectStore = () => {
3249
+ const api = seamly_api_hooks_useSeamlyApiContext();
3250
+ return api.store || {};
3251
+ };
3252
+ const useSeamlyConversationUrl = () => {
3253
+ const {
3254
+ get
3255
+ } = seamly_api_hooks_useSeamlyObjectStore();
2984
3256
 
3257
+ if (get) {
3258
+ return get('conversationUrl');
3259
+ }
2985
3260
 
3261
+ return null;
3262
+ };
3263
+ const seamly_api_hooks_useSeamlyHasConversation = () => {
3264
+ const url = useSeamlyConversationUrl();
3265
+ return !!url;
3266
+ };
3267
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-dispatch.js
2986
3268
 
2987
- // The passed in locale (en-GB) is only used to call Intl.PluralRules.select() in
2988
- // pluralTypeHandler. Since we only use exact plural matches (=0, =1 etc) we can
2989
- // safely use en-GB all the time.
3269
+ /* harmony default export */ const use_seamly_dispatch = ((/* unused pure expression or super */ null && (useStoreDispatch)));
3270
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/focus-helper-hooks.js
2990
3271
 
2991
- const formatter = new MessageFormatter('en-GB', {
2992
- plural: pluralTypeHandler,
2993
- select: selectTypeHandler
2994
- });
2995
- function hooks_useI18n() {
2996
- const translations = useSelector(Selectors.selectTranslations);
2997
- const locale = useSelector(Selectors.selectLocale);
2998
- const initialLocale = useSelector(Selectors.selectInitialLocale);
2999
- const t = useCallback((key, values = {}) => {
3000
- const translation = translations[key];
3001
3272
 
3002
- if (!translation) {
3003
- return null;
3004
- }
3005
3273
 
3006
- return formatter.format(translation, values);
3007
- }, [translations]);
3008
- return {
3009
- t,
3010
- locale,
3011
- initialLocale
3012
- };
3013
- }
3014
- ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/reducer.js
3015
- function i18n_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
3016
3274
 
3017
- function i18n_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { i18n_reducer_ownKeys(Object(source), true).forEach(function (key) { i18n_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { i18n_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
3018
3275
 
3019
- function i18n_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3276
+ const {
3277
+ SET_SEAMLY_CONTAINER_ELEMENT: focus_helper_hooks_SET_SEAMLY_CONTAINER_ELEMENT
3278
+ } = seamly_utils_seamlyActions;
3020
3279
 
3280
+ const focusWithRaf = el => {
3281
+ requestAnimationFrame(() => {
3282
+ requestAnimationFrame(() => {
3283
+ const focusEl = typeof el === 'string' ? document.getElementById(el) : el;
3284
+ focusElement(focusEl);
3285
+ });
3286
+ });
3287
+ };
3021
3288
 
3289
+ const useSeamlyContainerElement = () => {
3290
+ const {
3291
+ seamlyContainerElement
3292
+ } = useSeamlyStateContext();
3293
+ const dispatch = useSeamlyDispatchContext();
3294
+ const setSeamlyContainerElement = useCallback(element => {
3295
+ dispatch({
3296
+ type: focus_helper_hooks_SET_SEAMLY_CONTAINER_ELEMENT,
3297
+ element
3298
+ });
3299
+ }, [dispatch]);
3300
+ return [seamlyContainerElement, setSeamlyContainerElement];
3301
+ };
3302
+ const focus_helper_hooks_useElementFocusingById = elementId => useCallback(() => {
3303
+ focusWithRaf(elementId);
3304
+ }, [elementId]);
3305
+ const focus_helper_hooks_useSkiplinkTargetFocusing = () => {
3306
+ const skiplinkTargetId = useSkiplink();
3307
+ return focus_helper_hooks_useElementFocusingById(skiplinkTargetId);
3308
+ };
3309
+ const useFocusIfSeamlyContainedFocus = () => {
3310
+ const containerElementRef = useRef(null);
3311
+ const [seamlyContainerElement] = useSeamlyContainerElement();
3312
+ containerElementRef.current = seamlyContainerElement;
3313
+ return useCallback(elementToFocus => {
3314
+ const focusFn = () => {
3315
+ focusWithRaf(elementToFocus);
3316
+ };
3022
3317
 
3023
- const defaultState = {
3024
- translations: {
3025
- 'errors.configError.message': 'We are sorry this happened, please retry at a later time.',
3026
- 'errors.configError.srText': 'A chat configuration error occurred. Our apologies, please retry at a later time.',
3027
- 'errors.configError.title': 'Chat configuration error.',
3028
- 'errors.general.buttonText': 'Restart chat',
3029
- 'errors.general.message': 'Do you want to start a new chat session?',
3030
- 'errors.general.srText': 'Something went wrong with the chat session. You can restart the chat.',
3031
- 'errors.general.title': 'Something went wrong',
3032
- 'errors.seamlyOffline.message': 'There might be a problem with your or our network connection. The chat session should resume as soon the connection is available again.',
3033
- 'errors.seamlyOffline.srText': 'The chat has connection issues. There might be a problem with your or our network connection. The chat session should resume as soon as the connection is available again.',
3034
- 'errors.seamlyOffline.title': 'Connection issues'
3035
- },
3036
- isLoading: false,
3037
- initialLocale: undefined
3318
+ runIfElementContainsOrHasFocus(containerElementRef.current, focusFn);
3319
+ }, []);
3038
3320
  };
3039
- /* harmony default export */ const i18n_reducer = (i18n_utils_createReducer({
3040
- [setInitialLocale]: (state, {
3041
- locale
3042
- }) => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
3043
- initialLocale: locale
3044
- }),
3045
- [setLocaleStart]: state => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
3046
- isLoading: true
3047
- }),
3048
- [setLocaleResolve]: (state, {
3049
- locale,
3050
- translations
3051
- }) => {
3052
- return i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
3053
- isLoading: false,
3054
- locale,
3055
- translations: Object.keys(translations).sort().reduce((accum, key) => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, accum), {}, {
3056
- [key]: translations[key]
3057
- }), {})
3058
- });
3059
- },
3060
- [setLocaleReject]: state => i18n_reducer_objectSpread(i18n_reducer_objectSpread({}, state), {}, {
3061
- isLoading: false
3062
- })
3063
- }, defaultState));
3064
- ;// CONCATENATED MODULE: ./src/javascripts/domains/i18n/index.js
3321
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/component-helper-hooks.js
3065
3322
 
3066
3323
 
3067
3324
 
3325
+ const useSeamlyAppContainerClassNames = () => {
3326
+ return useConfig().appContainerClassNames;
3327
+ };
3328
+ const useSeamlyMessageContainerClassNames = event => {
3329
+ const {
3330
+ fromClient
3331
+ } = event.payload;
3332
+ const classNames = ['message'];
3068
3333
 
3334
+ if (event.type === 'info') {
3335
+ classNames.push('message--source-info');
3336
+ } else if (!fromClient) {
3337
+ classNames.push('message--source-agent');
3338
+ } else {
3339
+ classNames.push('message--source-user');
3340
+ }
3069
3341
 
3342
+ return classNames;
3343
+ };
3344
+ const useCobrowsingContainer = () => {
3345
+ const {
3346
+ cobrowsingContainerId: id
3347
+ } = useSeamlyStateContext();
3348
+ const focusContainer = useElementFocusingById(id);
3349
+ return {
3350
+ id,
3351
+ focusContainer
3352
+ };
3353
+ };
3070
3354
  ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/seamly-option-hooks.js
3071
3355
  function seamly_option_hooks_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
3072
3356
 
@@ -3363,14 +3647,10 @@ function hooks_useInterrupt() {
3363
3647
  };
3364
3648
  }
3365
3649
  ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-general-error.js
3366
- class SeamlyGeneralError extends Error {
3367
- constructor(params) {
3368
- super(params);
3369
-
3370
- if (Error.captureStackTrace) {
3371
- Error.captureStackTrace(this, SeamlyGeneralError);
3372
- }
3373
3650
 
3651
+ class SeamlyGeneralError extends SeamlyBaseError {
3652
+ constructor(originalError, ...params) {
3653
+ super(originalError, ...params);
3374
3654
  this.name = 'SeamlyGeneralError';
3375
3655
  this.langKey = 'errors.general';
3376
3656
  this.action = 'reset';
@@ -3378,56 +3658,30 @@ class SeamlyGeneralError extends Error {
3378
3658
 
3379
3659
  }
3380
3660
  ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-configuration-error.js
3381
- class SeamlyConfigurationError extends Error {
3382
- constructor(params) {
3383
- super(params);
3384
-
3385
- if (Error.captureStackTrace) {
3386
- Error.captureStackTrace(this, SeamlyConfigurationError);
3387
- }
3388
3661
 
3662
+ class SeamlyConfigurationError extends SeamlyBaseError {
3663
+ constructor(originalError, ...params) {
3664
+ super(originalError, ...params);
3389
3665
  this.name = 'SeamlyConfigurationError';
3390
3666
  this.langKey = 'errors.configError';
3391
3667
  }
3392
3668
 
3393
- }
3394
- ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-session-expired-error.js
3395
- class SeamlySessionExpiredError extends Error {
3396
- constructor(params) {
3397
- super(params);
3398
-
3399
- if (Error.captureStackTrace) {
3400
- Error.captureStackTrace(this, SeamlySessionExpiredError);
3401
- }
3402
-
3403
- this.name = 'SeamlySessionExpiredError';
3404
- this.action = 'reset';
3405
- }
3406
-
3407
3669
  }
3408
3670
  ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-offline-error.js
3409
- class SeamlyOfflineError extends Error {
3410
- constructor(params) {
3411
- super(params);
3412
-
3413
- if (Error.captureStackTrace) {
3414
- Error.captureStackTrace(this, SeamlyOfflineError);
3415
- }
3416
3671
 
3672
+ class SeamlyOfflineError extends SeamlyBaseError {
3673
+ constructor(originalError, ...params) {
3674
+ super(originalError, ...params);
3417
3675
  this.name = 'SeamlyOfflineError';
3418
3676
  this.langKey = 'errors.seamlyOffline';
3419
3677
  }
3420
3678
 
3421
3679
  }
3422
3680
  ;// CONCATENATED MODULE: ./src/javascripts/api/errors/seamly-unauthorized-error.js
3423
- class SeamlyUnauthorizedError extends Error {
3424
- constructor(params) {
3425
- super(params);
3426
-
3427
- if (Error.captureStackTrace) {
3428
- Error.captureStackTrace(this, SeamlyUnauthorizedError);
3429
- }
3430
3681
 
3682
+ class SeamlyUnauthorizedError extends SeamlyBaseError {
3683
+ constructor(originalError, ...params) {
3684
+ super(originalError, ...params);
3431
3685
  this.name = 'SeamlyUnauthorizedError';
3432
3686
  this.langKey = 'errors.general';
3433
3687
  this.action = 'reset';
@@ -3441,12 +3695,23 @@ class SeamlyUnauthorizedError extends Error {
3441
3695
 
3442
3696
 
3443
3697
 
3444
- const handledErrorTypes = [SeamlyGeneralError, SeamlyConfigurationError, SeamlySessionExpiredError, SeamlyOfflineError, SeamlyUnauthorizedError];
3445
- function middleware_createMiddleware() {
3698
+ const handledErrorTypes = [SeamlyGeneralError, SeamlyConfigurationError, SeamlySessionExpiredError, SeamlyOfflineError, SeamlyUnauthorizedError, SeamlyUnavailableError];
3699
+ function middleware_createMiddleware({
3700
+ api
3701
+ }) {
3446
3702
  return () => next => action => {
3447
- if (action.type === String(Actions.set)) {
3448
- if (!handledErrorTypes.some(ErrorType => action.error instanceof ErrorType)) {
3449
- throw action.error;
3703
+ const {
3704
+ error
3705
+ } = action;
3706
+
3707
+ if (error) {
3708
+ if (!handledErrorTypes.some(ErrorType => error instanceof ErrorType)) {
3709
+ throw error;
3710
+ } else if (error.action === 'reset') {
3711
+ // [SMLY-942] We clear the store before a reset to force a new conversation if the page is refreshed before the conversation is reset
3712
+ api.disconnect().then(() => {
3713
+ api.clearStore();
3714
+ });
3450
3715
  }
3451
3716
  }
3452
3717
 
@@ -3462,20 +3727,22 @@ function interrupt_reducer_defineProperty(obj, key, value) { if (key in obj) { O
3462
3727
 
3463
3728
 
3464
3729
 
3730
+
3465
3731
  const interrupt_reducer_initialState = {
3466
3732
  error: undefined
3467
3733
  };
3734
+
3735
+ const handleError = (state, {
3736
+ error
3737
+ }) => interrupt_reducer_objectSpread(interrupt_reducer_objectSpread({}, state), {}, {
3738
+ error
3739
+ });
3740
+
3468
3741
  /* harmony default export */ const interrupt_reducer = (interrupt_utils_createReducer({
3469
- [set]: (state, {
3470
- error
3471
- }) => {
3472
- return interrupt_reducer_objectSpread(interrupt_reducer_objectSpread({}, state), {}, {
3473
- error
3474
- });
3475
- },
3476
- [clear]: () => {
3477
- return interrupt_reducer_initialState;
3478
- }
3742
+ [set]: handleError,
3743
+ [app_actions_initialize.rejected]: handleError,
3744
+ [clear]: () => interrupt_reducer_initialState,
3745
+ [actions_reset]: () => interrupt_reducer_initialState
3479
3746
  }, interrupt_reducer_initialState));
3480
3747
  ;// CONCATENATED MODULE: ./src/javascripts/domains/interrupt/index.js
3481
3748
 
@@ -3484,96 +3751,58 @@ const interrupt_reducer_initialState = {
3484
3751
 
3485
3752
 
3486
3753
 
3487
- ;// CONCATENATED MODULE: ./src/javascripts/domains/app/utils.js
3488
-
3489
- const {
3490
- createAction: app_utils_createAction,
3491
- createThunk: app_utils_createThunk,
3492
- createReducer: app_utils_createReducer,
3493
- selectState: app_utils_selectState
3494
- } = createDomain('app');
3495
- ;// CONCATENATED MODULE: ./src/javascripts/domains/app/actions.js
3496
-
3497
-
3498
-
3499
-
3500
-
3501
- const setHasResponded = app_utils_createAction('setHasResponded', hasResponded => ({
3502
- hasResponded
3503
- }));
3504
- const actions_initialize = app_utils_createThunk('initialize', config => async (dispatch, getState, {
3505
- api
3506
- }) => {
3507
- try {
3508
- var _config$context;
3754
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/hooks.js
3509
3755
 
3510
- dispatch(initialize(config));
3511
- const {
3512
- features,
3513
- defaultLocale
3514
- } = await api.getConfig();
3515
- dispatch({
3516
- type: seamly_utils_seamlyActions.SET_FEATURES,
3517
- features
3518
- });
3519
- let locale = (config === null || config === void 0 ? void 0 : (_config$context = config.context) === null || _config$context === void 0 ? void 0 : _config$context.locale) || defaultLocale;
3520
- dispatch(setInitialLocale(locale));
3521
3756
 
3522
- try {
3523
- if (api.hasConversation()) {
3524
- var _initialState$transla;
3525
3757
 
3526
- const initialState = await api.getConversationIntitialState();
3527
- dispatch({
3528
- type: seamly_utils_seamlyActions.SET_INITIAL_STATE,
3529
- initialState
3530
- });
3531
- locale = ((_initialState$transla = initialState.translation) === null || _initialState$transla === void 0 ? void 0 : _initialState$transla.locale) || locale;
3532
3758
 
3533
- if ('userResponded' in initialState) {
3534
- dispatch(setHasResponded(initialState.userResponded));
3535
- }
3536
- }
3537
- } catch (error) {
3538
- dispatch(set(error));
3539
- }
3540
3759
 
3541
- await dispatch(setLocale(locale));
3542
- } catch (error) {
3543
- dispatch(set(error));
3544
- }
3545
- });
3546
- ;// CONCATENATED MODULE: ./src/javascripts/domains/app/selectors.js
3547
3760
 
3761
+ const hooks_useVisibility = () => {
3762
+ const dispatch = useStoreDispatch();
3763
+ const visible = useSelector(Selectors.selectVisibility);
3764
+ const isVisible = visible ? visible !== visibilityStates.hidden : false;
3765
+ const {
3766
+ layoutMode
3767
+ } = useConfig();
3768
+ const isOpen = visible && layoutMode ? visible === visibilityStates.open || layoutMode === 'inline' && visible !== visibilityStates.hidden : false;
3769
+ const setVisibility = useCallback(visibility => dispatch(Actions.setVisibility(visibility)), [dispatch]);
3770
+ return {
3771
+ isVisible,
3772
+ isOpen,
3773
+ visible,
3774
+ setVisibility
3775
+ };
3776
+ };
3777
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/reducer.js
3778
+ function visibility_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
3548
3779
 
3549
- const selectUserHasResponded = createSelector(app_utils_selectState, state => state.userHasResponded);
3780
+ function visibility_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { visibility_reducer_ownKeys(Object(source), true).forEach(function (key) { visibility_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { visibility_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
3550
3781
 
3551
- ;// CONCATENATED MODULE: ./src/javascripts/domains/app/hooks.js
3782
+ function visibility_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3552
3783
 
3553
3784
 
3554
- function hooks_useUserHasResponded() {
3555
- return useSelector(Selectors.selectUserHasResponded);
3556
- }
3557
- ;// CONCATENATED MODULE: ./src/javascripts/domains/app/reducer.js
3558
- function app_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
3559
3785
 
3560
- function app_reducer_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { app_reducer_ownKeys(Object(source), true).forEach(function (key) { app_reducer_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { app_reducer_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
3561
3786
 
3562
- function app_reducer_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3787
+ const visibility_reducer_initialState = {
3788
+ visibility: constants_visibilityStates.initialize
3789
+ };
3790
+ /* harmony default export */ const visibility_reducer = (visibility_utils_createReducer({
3791
+ [setFromStorage]: (state, {
3792
+ visibility
3793
+ }) => visibility_reducer_objectSpread(visibility_reducer_objectSpread({}, state), {}, {
3794
+ visibility
3795
+ }),
3796
+ [setVisibility.fulfilled]: (state, {
3797
+ payload: visibility
3798
+ }) => visibility ? visibility_reducer_objectSpread(visibility_reducer_objectSpread({}, state), {}, {
3799
+ visibility
3800
+ }) : state
3801
+ }, visibility_reducer_initialState));
3802
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/index.js
3563
3803
 
3564
3804
 
3565
3805
 
3566
- const app_reducer_initialState = {
3567
- userHasResponded: false
3568
- };
3569
- /* harmony default export */ const app_reducer = (app_utils_createReducer({
3570
- [setHasResponded]: (state, {
3571
- hasResponded
3572
- }) => app_reducer_objectSpread(app_reducer_objectSpread({}, state), {}, {
3573
- userHasResponded: hasResponded
3574
- })
3575
- }, app_reducer_initialState));
3576
- ;// CONCATENATED MODULE: ./src/javascripts/domains/app/index.js
3577
3806
 
3578
3807
 
3579
3808
 
@@ -3600,15 +3829,10 @@ function use_seamly_commands_defineProperty(obj, key, value) { if (key in obj) {
3600
3829
 
3601
3830
  const {
3602
3831
  ADD_EVENT: use_seamly_commands_ADD_EVENT,
3603
- CLEAR_EVENTS: use_seamly_commands_CLEAR_EVENTS,
3604
3832
  SET_IS_LOADING: use_seamly_commands_SET_IS_LOADING,
3605
- CLEAR_PARTICIPANTS: use_seamly_commands_CLEAR_PARTICIPANTS,
3606
3833
  SET_HEADER_SUB_TITLE: use_seamly_commands_SET_HEADER_SUB_TITLE,
3607
3834
  SET_INITIAL_STATE: use_seamly_commands_SET_INITIAL_STATE,
3608
- CLEAR_FEATURES: use_seamly_commands_CLEAR_FEATURES,
3609
- SET_FEATURES: use_seamly_commands_SET_FEATURES,
3610
- RESET_UPLOAD_STATE: use_seamly_commands_RESET_UPLOAD_STATE,
3611
- RESET_ENTRY_STATE: use_seamly_commands_RESET_ENTRY_STATE
3835
+ SET_FEATURES: use_seamly_commands_SET_FEATURES
3612
3836
  } = seamly_utils_seamlyActions;
3613
3837
 
3614
3838
  const use_seamly_commands_useSeamlyCommands = () => {
@@ -3620,7 +3844,7 @@ const use_seamly_commands_useSeamlyCommands = () => {
3620
3844
  const hasConversation = useSeamlyHasConversation();
3621
3845
  const {
3622
3846
  visible: visibility
3623
- } = useSeamlyStateContext();
3847
+ } = useVisibility();
3624
3848
  const unreadMessageCount = useSeamlyUnreadCount();
3625
3849
  const emitEvent = useCallback((...args) => {
3626
3850
  eventBus.emit(...args);
@@ -3642,26 +3866,12 @@ const use_seamly_commands_useSeamlyCommands = () => {
3642
3866
  });
3643
3867
  }, [api, appConfig, emitEvent, hasResponded, hasConversation, visibility, unreadMessageCount]);
3644
3868
  const reset = useCallback(async () => {
3869
+ dispatch(AppActions.reset());
3645
3870
  dispatch(InterruptActions.clear());
3646
- dispatch({
3647
- type: use_seamly_commands_CLEAR_EVENTS
3648
- });
3649
3871
  dispatch({
3650
3872
  type: use_seamly_commands_SET_IS_LOADING,
3651
3873
  isLoading: true
3652
3874
  });
3653
- dispatch({
3654
- type: use_seamly_commands_CLEAR_PARTICIPANTS
3655
- });
3656
- dispatch({
3657
- type: use_seamly_commands_RESET_UPLOAD_STATE
3658
- });
3659
- dispatch({
3660
- type: use_seamly_commands_RESET_ENTRY_STATE
3661
- });
3662
- dispatch({
3663
- type: use_seamly_commands_CLEAR_FEATURES
3664
- });
3665
3875
  const {
3666
3876
  agentName
3667
3877
  } = appConfig.defaults || {};
@@ -3713,21 +3923,13 @@ const use_seamly_commands_useSeamlyCommands = () => {
3713
3923
 
3714
3924
  const message = use_seamly_commands_objectSpread(use_seamly_commands_objectSpread({}, getTextMessageBase(body)), config);
3715
3925
 
3716
- const sanitizedText = sanitizeText(body);
3717
-
3718
- const sanitizedMessage = use_seamly_commands_objectSpread(use_seamly_commands_objectSpread({}, message), {}, {
3719
- body: {
3720
- text: sanitizedText
3721
- }
3722
- });
3723
-
3724
3926
  api.send('message', message);
3725
3927
  emitEvent('message', message);
3726
3928
  dispatch({
3727
3929
  type: use_seamly_commands_ADD_EVENT,
3728
3930
  event: {
3729
3931
  type: 'message',
3730
- payload: sanitizedMessage
3932
+ payload: message
3731
3933
  }
3732
3934
  });
3733
3935
  }, [api, dispatch, emitEvent, getTextMessageBase]);
@@ -4010,121 +4212,6 @@ const useSeamlyEntry = () => {
4010
4212
  setBlockAutoEntrySwitch
4011
4213
  };
4012
4214
  };
4013
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-stored-visibility.js
4014
- function use_seamly_stored_visibility_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
4015
-
4016
- function use_seamly_stored_visibility_objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { use_seamly_stored_visibility_ownKeys(Object(source), true).forEach(function (key) { use_seamly_stored_visibility_defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { use_seamly_stored_visibility_ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
4017
-
4018
- function use_seamly_stored_visibility_defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
4019
-
4020
-
4021
-
4022
-
4023
-
4024
- const use_seamly_stored_visibility_useSeamlyStoredVisibility = () => {
4025
- const {
4026
- layoutMode
4027
- } = useConfig();
4028
- const key = 'visibility';
4029
- const {
4030
- get,
4031
- set
4032
- } = useSeamlyObjectStore();
4033
- let storedVisibilityObj = {};
4034
- const savedVisibility = get ? get(key) : {};
4035
-
4036
- if (savedVisibility) {
4037
- storedVisibilityObj = savedVisibility;
4038
- }
4039
-
4040
- const setStoredVisibility = useCallback(state => {
4041
- const saved = get ? get(key) : {};
4042
- set(key, use_seamly_stored_visibility_objectSpread(use_seamly_stored_visibility_objectSpread({}, saved), {}, {
4043
- [layoutMode]: state
4044
- }));
4045
- }, [set, get, layoutMode]);
4046
- return [layoutMode ? storedVisibilityObj[layoutMode] : null, set && layoutMode ? setStoredVisibility : null];
4047
- };
4048
-
4049
- /* harmony default export */ const use_seamly_stored_visibility = ((/* unused pure expression or super */ null && (use_seamly_stored_visibility_useSeamlyStoredVisibility)));
4050
- ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-visibility.js
4051
-
4052
-
4053
-
4054
-
4055
-
4056
-
4057
-
4058
-
4059
-
4060
- const {
4061
- SET_VISIBILITY: use_seamly_visibility_SET_VISIBILITY
4062
- } = seamly_utils_seamlyActions;
4063
-
4064
- const use_seamly_visibility_useSeamlyVisibility = () => {
4065
- const config = useConfig();
4066
- const {
4067
- layoutMode,
4068
- visibilityCallback
4069
- } = config;
4070
- const {
4071
- visible
4072
- } = useSeamlyStateContext();
4073
- const {
4074
- emitEvent
4075
- } = useSeamlyCommands();
4076
- const dispatch = useSeamlyDispatchContext();
4077
- const [storedVisibility, setStoredVisibility] = useSeamlyStoredVisibility();
4078
- const hasResponded = useUserHasResponded();
4079
- const hasConversation = useSeamlyHasConversation();
4080
- const unreadMessageCount = useSeamlyUnreadCount();
4081
- const isVisible = visible ? visible !== visibilityStates.hidden : false;
4082
- const isOpen = visible && layoutMode ? visible === visibilityStates.open || layoutMode === 'inline' && visible !== visibilityStates.hidden : false;
4083
- const setVisibility = useCallback(visibility => {
4084
- const visibilityFn = visibilityCallback || calculateVisibility;
4085
- const requestedVisibility = visibilityFn({
4086
- hasConversation,
4087
- hasResponded,
4088
- previousVisibility: storedVisibility || null,
4089
- requestedVisibility: visibility,
4090
- config
4091
- });
4092
-
4093
- if (![visibilityStates.open, visibilityStates.minimized, visibilityStates.hidden].includes(requestedVisibility)) {
4094
- console.error('The visibilityCallback function should return "open", "minimized" or "hidden".');
4095
- return;
4096
- }
4097
-
4098
- if (requestedVisibility !== visible) {
4099
- if (setStoredVisibility) {
4100
- setStoredVisibility(requestedVisibility);
4101
- } // Don't broadcast the init visibility state
4102
-
4103
-
4104
- if (visibility) {
4105
- emitEvent('ui.visible', requestedVisibility, {
4106
- visibility: requestedVisibility,
4107
- hasConversation,
4108
- hasResponded,
4109
- unreadMessageCount
4110
- });
4111
- }
4112
-
4113
- dispatch({
4114
- type: use_seamly_visibility_SET_VISIBILITY,
4115
- visible: requestedVisibility
4116
- });
4117
- }
4118
- }, [visible, emitEvent, dispatch, hasConversation, hasResponded, storedVisibility, visibilityCallback, config, setStoredVisibility, unreadMessageCount]);
4119
- return {
4120
- isVisible,
4121
- isOpen,
4122
- visible,
4123
- setVisibility
4124
- };
4125
- };
4126
-
4127
- /* harmony default export */ const use_seamly_visibility = ((/* unused pure expression or super */ null && (use_seamly_visibility_useSeamlyVisibility)));
4128
4215
  ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-chat.js
4129
4216
 
4130
4217
 
@@ -4146,9 +4233,8 @@ const useSeamlyChat = () => {
4146
4233
  const {
4147
4234
  isOpen,
4148
4235
  isVisible,
4149
- visible,
4150
4236
  setVisibility
4151
- } = useSeamlyVisibility();
4237
+ } = useVisibility();
4152
4238
  const dispatch = useSeamlyDispatchContext();
4153
4239
  const events = useEvents();
4154
4240
  const spinnerTimeout = useRef(null);
@@ -4192,7 +4278,6 @@ const useSeamlyChat = () => {
4192
4278
  prevIsOpen.current = isOpen;
4193
4279
  prevIsVisible.current = isVisible;
4194
4280
  }, [isOpen, isVisible, sendAssertive, t]);
4195
- useEffect(() => {}, [visible, sendAssertive]);
4196
4281
  useEffect(() => {
4197
4282
  // This delays the start of the loading inidicator we set when we initialise
4198
4283
  // the application. This is done to only avoid BSOD on initial load if DCX is slow.
@@ -4290,7 +4375,7 @@ const useSeamlyIdleDetachCountdown = () => {
4290
4375
  } = useSeamlyStateContext();
4291
4376
  const {
4292
4377
  isOpen: isSeamlyOpen
4293
- } = useSeamlyVisibility();
4378
+ } = useVisibility();
4294
4379
  const stableState = useRef({});
4295
4380
  stableState.current = {
4296
4381
  hasCountdown: idleDetachCountdown.hasCountdown,
@@ -4489,8 +4574,6 @@ const useSeamlyResumeConversationPrompt = () => {
4489
4574
 
4490
4575
 
4491
4576
 
4492
-
4493
-
4494
4577
  // This hook isn't used within the core
4495
4578
  // But it is used in implementations
4496
4579
  // and imported directly from this file
@@ -5659,7 +5742,7 @@ function TranslationsChatStatus() {
5659
5742
 
5660
5743
 
5661
5744
  ;// CONCATENATED MODULE: ./src/javascripts/style-guide/components/static-core.js
5662
- const static_core_excluded = ["translations", "interrupt", "config"];
5745
+ const static_core_excluded = ["translations", "interrupt", "config", "visibility"];
5663
5746
 
5664
5747
  function static_core_objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = static_core_objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
5665
5748
 
@@ -5675,6 +5758,7 @@ function static_core_objectWithoutPropertiesLoose(source, excluded) { if (source
5675
5758
 
5676
5759
 
5677
5760
 
5761
+
5678
5762
  const bareApi = {
5679
5763
  send: () => {},
5680
5764
  reset: () => {
@@ -5700,7 +5784,8 @@ const SeamlyTestCore = ({
5700
5784
  {
5701
5785
  translations: translationsSlice,
5702
5786
  interrupt: interruptSlice,
5703
- config: configSlice
5787
+ config: configSlice,
5788
+ visibility: visibilitySlice
5704
5789
  } = _ref,
5705
5790
  restState = static_core_objectWithoutProperties(_ref, static_core_excluded);
5706
5791
 
@@ -5708,20 +5793,22 @@ const SeamlyTestCore = ({
5708
5793
  reducers: {
5709
5794
  state: stateReducer,
5710
5795
  [String(app_reducer)]: app_reducer,
5711
- [String(config_reducer)]: config_reducer,
5712
5796
  [String(reducer)]: reducer,
5797
+ [String(forms_reducer)]: forms_reducer,
5713
5798
  [String(translations_reducer)]: translations_reducer,
5714
5799
  [String(i18n_reducer)]: i18n_reducer,
5715
- [String(interrupt_reducer)]: interrupt_reducer
5800
+ [String(interrupt_reducer)]: interrupt_reducer,
5801
+ [String(visibility_reducer)]: visibility_reducer
5716
5802
  },
5717
5803
  initialState: {
5718
5804
  state: restState,
5719
5805
  [String(translations_reducer)]: translationsSlice,
5720
- [String(interrupt_reducer)]: interruptSlice
5806
+ [String(interrupt_reducer)]: interruptSlice,
5807
+ [String(visibility_reducer)]: visibilitySlice
5721
5808
  }
5722
5809
  });
5723
5810
  newStore.dispatch(initialize(configSlice || {}));
5724
- newStore.dispatch(setLocaleResolve('en-GB', translations));
5811
+ newStore.dispatch(setLocale.fulfilled('en-GB', translations));
5725
5812
  return newStore;
5726
5813
  }, [state, translations]);
5727
5814
  return state && (0,jsx_runtime_namespaceObject.jsx)(web_ui_namespaceObject.StoreProvider, {
@@ -5873,7 +5960,9 @@ const baseState = {
5873
5960
  isActive: false
5874
5961
  },
5875
5962
  resumeConversationPrompt: false,
5876
- visible: web_ui_namespaceObject.visibilityStates.open,
5963
+ visibility: {
5964
+ visibility: web_ui_namespaceObject.visibilityStates.open
5965
+ },
5877
5966
  serviceInfo: {
5878
5967
  activeServiceSessionId: ''
5879
5968
  },
@@ -6797,8 +6886,27 @@ const standardState = {
6797
6886
  headingText: 'System messages',
6798
6887
  description: ''
6799
6888
  }, baseState), {}, {
6889
+ config: {
6890
+ overrideMessages: {
6891
+ timeIndicator: {
6892
+ enabled: true,
6893
+ threshold: 3600000
6894
+ }
6895
+ }
6896
+ },
6800
6897
  participantInfo,
6801
- events: [participantMessage, participantMessageDefaultIcon, newTopicDivider, infoMessage, transcriptInfoMessage]
6898
+ events: [{
6899
+ type: 'message',
6900
+ payload: states_objectSpread(states_objectSpread({}, shortTextMessage.payload), {}, {
6901
+ occurredAt: (Date.now() - 86400000 * 5) * 1000,
6902
+ id: (0,web_ui_namespaceObject.randomId)(),
6903
+ body: {
6904
+ text: 'Long ago when a dialog started',
6905
+ type: 'text',
6906
+ variables: {}
6907
+ }
6908
+ })
6909
+ }, participantMessage, participantMessageDefaultIcon, newTopicDivider, transcriptInfoMessage, ...[newTranslationDividerStart, newTranslationDividerStop].map(addTranslationData), infoMessage]
6802
6910
  }),
6803
6911
  choicePromptMessages: states_objectSpread(states_objectSpread({
6804
6912
  category: categoryKeys.messages,
@@ -6951,34 +7059,24 @@ const standardState = {
6951
7059
  }
6952
7060
  }]
6953
7061
  }),
6954
- disconnectedInterrupt: states_objectSpread(states_objectSpread({
6955
- // Important: This cannot pick up the language files so the text is hard set here.
6956
- category: categoryKeys.errors,
6957
- headingText: 'Disconnected interrupt',
6958
- description: ''
6959
- }, baseState), {}, {
6960
- interrupt: {
6961
- error: new web_ui_namespaceObject.SeamlyOfflineError()
6962
- }
6963
- }),
6964
- generalErrorInterrupt: states_objectSpread(states_objectSpread({
7062
+ errorWithAction: states_objectSpread(states_objectSpread({
6965
7063
  // Important: This cannot pick up the language files so the text is hard set here.
6966
7064
  category: categoryKeys.errors,
6967
- headingText: 'General error interrupt',
7065
+ headingText: 'Error with a user action',
6968
7066
  description: ''
6969
7067
  }, baseState), {}, {
6970
7068
  interrupt: {
6971
7069
  error: new web_ui_namespaceObject.SeamlyGeneralError()
6972
7070
  }
6973
7071
  }),
6974
- configErrorInterrupt: states_objectSpread(states_objectSpread({
7072
+ errorWithoutAction: states_objectSpread(states_objectSpread({
6975
7073
  // Important: This cannot pick up the language files so the text is hard set here.
6976
7074
  category: categoryKeys.errors,
6977
- headingText: 'Config error interrupt',
7075
+ headingText: 'Error without a user action',
6978
7076
  description: ''
6979
7077
  }, baseState), {}, {
6980
7078
  interrupt: {
6981
- error: new web_ui_namespaceObject.SeamlyConfigurationError()
7079
+ error: new web_ui_namespaceObject.SeamlyOfflineError()
6982
7080
  }
6983
7081
  }),
6984
7082
  privacyDisclaimer: states_objectSpread(states_objectSpread({
@@ -7526,11 +7624,11 @@ const standardState = {
7526
7624
  serviceInfo: {
7527
7625
  activeServiceSessionId: '3942159e-9878-469e-9120-f44fd6be0f35'
7528
7626
  },
7529
- events: [infoMessage, shortTextMessage, states_objectSpread(states_objectSpread({}, choicePromptMessage), {}, {
7627
+ events: [newTranslationDividerStart, infoMessage, shortTextMessage, states_objectSpread(states_objectSpread({}, choicePromptMessage), {}, {
7530
7628
  payload: states_objectSpread(states_objectSpread({}, choicePromptMessage.payload), {}, {
7531
7629
  id: `${choicePromptMessage.payload.id}XXX`
7532
7630
  })
7533
- }), longTextMessage, userMessage, textMessageBoldItalicUnderline, newTopicDivider, newTranslationDividerStart, newTranslationDividerStop, imageMessage, fileDownloadAgentMessage, deletedFileDownloadAgentMessage, userMessageLong, videoMessage, textMessageWithLinks, textMessageWithLongLink, imageMessageWithLightbox, fileDownloadUserMessage, emptyUrlFileDownloadUserMessage, textMesageWithBullets, choicePromptMessage, ctaMessage].map(addTranslationData),
7631
+ }), longTextMessage, userMessage, textMessageBoldItalicUnderline, newTopicDivider, newTranslationDividerStart, newTranslationDividerStop, imageMessage, fileDownloadAgentMessage, deletedFileDownloadAgentMessage, userMessageLong, videoMessage, textMessageWithLinks, textMessageWithLongLink, imageMessageWithLightbox, fileDownloadUserMessage, emptyUrlFileDownloadUserMessage, textMesageWithBullets, choicePromptMessage, ctaMessage, newTranslationDividerStop, newTranslationDividerStart].map(addTranslationData),
7534
7632
  translations: states_objectSpread(states_objectSpread({}, translationsSlice), {}, {
7535
7633
  currentLocale: 'nl',
7536
7634
  isActive: true,
@@ -7600,7 +7698,9 @@ const getStateObj = (layoutModes, customComponentEventBodies) => states_objectSp
7600
7698
  config: states_objectSpread(states_objectSpread({}, baseState.config), {}, {
7601
7699
  layoutMode: 'window'
7602
7700
  }),
7603
- visible: web_ui_namespaceObject.visibilityStates.minimized
7701
+ visibility: states_objectSpread(states_objectSpread({}, baseState.visibility), {}, {
7702
+ visibility: web_ui_namespaceObject.visibilityStates.minimized
7703
+ })
7604
7704
  })
7605
7705
  },
7606
7706
  minimizedStarted: {
@@ -7611,7 +7711,9 @@ const getStateObj = (layoutModes, customComponentEventBodies) => states_objectSp
7611
7711
  config: states_objectSpread(states_objectSpread({}, baseState.config), {}, {
7612
7712
  layoutMode: 'window'
7613
7713
  }),
7614
- visible: web_ui_namespaceObject.visibilityStates.minimized,
7714
+ visibility: states_objectSpread(states_objectSpread({}, baseState.visibility), {}, {
7715
+ visibility: web_ui_namespaceObject.visibilityStates.minimized
7716
+ }),
7615
7717
  participantInfo,
7616
7718
  headerTitles
7617
7719
  })
@@ -7624,7 +7726,9 @@ const getStateObj = (layoutModes, customComponentEventBodies) => states_objectSp
7624
7726
  config: states_objectSpread(states_objectSpread({}, baseState.config), {}, {
7625
7727
  layoutMode: 'window'
7626
7728
  }),
7627
- visible: web_ui_namespaceObject.visibilityStates.minimized,
7729
+ visibility: states_objectSpread(states_objectSpread({}, baseState.visibility), {}, {
7730
+ visibility: web_ui_namespaceObject.visibilityStates.minimized
7731
+ }),
7628
7732
  participantInfo,
7629
7733
  headerTitles,
7630
7734
  unreadEvents: 12
@@ -7831,7 +7935,9 @@ const StyleGuideApp = ({
7831
7935
  if (overlay) {
7832
7936
  overlay.addEventListener('click', () => {
7833
7937
  setStaticState(s => app_objectSpread(app_objectSpread({}, s), {}, {
7834
- visible: 'minimized'
7938
+ visibility: app_objectSpread(app_objectSpread({}, s.visibility), {}, {
7939
+ visible: 'minimized'
7940
+ })
7835
7941
  }));
7836
7942
  });
7837
7943
  }