@seamly/web-ui 22.1.0 → 22.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/build/dist/lib/components.js +698 -318
  2. package/build/dist/lib/components.js.map +1 -1
  3. package/build/dist/lib/components.min.js +1 -1
  4. package/build/dist/lib/components.min.js.LICENSE.txt +2 -2
  5. package/build/dist/lib/components.min.js.map +1 -1
  6. package/build/dist/lib/hooks.js +301 -60
  7. package/build/dist/lib/hooks.js.map +1 -1
  8. package/build/dist/lib/hooks.min.js +1 -1
  9. package/build/dist/lib/hooks.min.js.map +1 -1
  10. package/build/dist/lib/index.debug.js +80 -58
  11. package/build/dist/lib/index.debug.js.map +1 -1
  12. package/build/dist/lib/index.debug.min.js +1 -1
  13. package/build/dist/lib/index.debug.min.js.LICENSE.txt +12 -4
  14. package/build/dist/lib/index.debug.min.js.map +1 -1
  15. package/build/dist/lib/index.js +718 -325
  16. package/build/dist/lib/index.js.map +1 -1
  17. package/build/dist/lib/index.min.js +1 -1
  18. package/build/dist/lib/index.min.js.LICENSE.txt +2 -2
  19. package/build/dist/lib/index.min.js.map +1 -1
  20. package/build/dist/lib/standalone.js +803 -348
  21. package/build/dist/lib/standalone.js.map +1 -1
  22. package/build/dist/lib/standalone.min.js +1 -1
  23. package/build/dist/lib/standalone.min.js.LICENSE.txt +1 -1
  24. package/build/dist/lib/standalone.min.js.map +1 -1
  25. package/build/dist/lib/style-guide.js +830 -323
  26. package/build/dist/lib/style-guide.js.map +1 -1
  27. package/build/dist/lib/style-guide.min.js +1 -1
  28. package/build/dist/lib/style-guide.min.js.LICENSE.txt +2 -2
  29. package/build/dist/lib/style-guide.min.js.map +1 -1
  30. package/build/dist/lib/styles-default-implementation.js +1 -1
  31. package/build/dist/lib/styles.css +1 -1
  32. package/build/dist/lib/styles.js +1 -1
  33. package/build/dist/lib/utils.js +783 -360
  34. package/build/dist/lib/utils.js.map +1 -1
  35. package/build/dist/lib/utils.min.js +1 -1
  36. package/build/dist/lib/utils.min.js.LICENSE.txt +1 -1
  37. package/build/dist/lib/utils.min.js.map +1 -1
  38. package/package.json +28 -28
  39. package/src/javascripts/api/errors/seamly-api-error.ts +0 -1
  40. package/src/javascripts/api/index.ts +29 -9
  41. package/src/javascripts/domains/app/actions.ts +8 -3
  42. package/src/javascripts/domains/config/slice.ts +2 -1
  43. package/src/javascripts/domains/forms/selectors.ts +6 -8
  44. package/src/javascripts/domains/forms/slice.ts +1 -1
  45. package/src/javascripts/domains/interrupt/selectors.ts +3 -2
  46. package/src/javascripts/domains/interrupt/slice.ts +2 -0
  47. package/src/javascripts/domains/redux/create-debounced-async-thunk.ts +109 -0
  48. package/src/javascripts/domains/redux/redux.types.ts +2 -1
  49. package/src/javascripts/domains/store/actions.ts +38 -0
  50. package/src/javascripts/domains/translations/components/options-dialog/translation-option.tsx +3 -1
  51. package/src/javascripts/domains/translations/components/options-dialog/translation-options.tsx +62 -35
  52. package/src/javascripts/domains/translations/slice.ts +8 -1
  53. package/src/javascripts/domains/visibility/actions.ts +4 -1
  54. package/src/javascripts/lib/engine/index.tsx +3 -1
  55. package/src/javascripts/style-guide/states.js +65 -1
  56. package/src/javascripts/ui/components/conversation/event/{card-component.js → card-component.tsx} +6 -4
  57. package/src/javascripts/ui/components/conversation/event/event-participant.js +1 -1
  58. package/src/javascripts/ui/components/core/seamly-event-subscriber.ts +14 -30
  59. package/src/javascripts/ui/components/entry/text-entry/hooks.ts +2 -2
  60. package/src/javascripts/ui/components/form-controls/wrapper.tsx +13 -3
  61. package/src/javascripts/ui/components/view/window-view/window-open-button.js +8 -3
  62. package/src/javascripts/ui/hooks/use-session-expired-command.ts +31 -2
  63. package/src/stylesheets/5-components/_input.scss +0 -5
  64. package/src/stylesheets/5-components/_message-count.scss +11 -9
  65. package/src/stylesheets/5-components/_options.scss +2 -2
  66. package/src/stylesheets/5-components/_translation-options.scss +23 -3
@@ -2700,21 +2700,88 @@ const defaultConfig = {
2700
2700
 
2701
2701
  /***/ }),
2702
2702
 
2703
- /***/ 9201:
2703
+ /***/ 526:
2704
2704
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2705
2705
 
2706
2706
  "use strict";
2707
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
2708
- /* harmony export */ Z: () => (/* binding */ initializeApp),
2709
- /* harmony export */ m: () => (/* binding */ resetApp)
2710
- /* harmony export */ });
2711
- /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9639);
2712
- /* harmony import */ var api_errors_seamly_session_expired_error__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(6821);
2713
- /* harmony import */ var api_errors_seamly_unavailable_error__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7265);
2714
- /* harmony import */ var ui_utils_seamly_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1149);
2715
- /* harmony import */ var domains_config_actions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(257);
2716
- /* harmony import */ var domains_i18n_actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5409);
2717
- /* harmony import */ var domains_visibility_actions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9586);
2707
+
2708
+ // EXPORTS
2709
+ __webpack_require__.d(__webpack_exports__, {
2710
+ Z: () => (/* binding */ initializeApp),
2711
+ m: () => (/* binding */ resetApp)
2712
+ });
2713
+
2714
+ // EXTERNAL MODULE: ./node_modules/@reduxjs/toolkit/dist/redux-toolkit.esm.js + 2 modules
2715
+ var redux_toolkit_esm = __webpack_require__(9639);
2716
+ // EXTERNAL MODULE: ./src/javascripts/api/errors/seamly-session-expired-error.js
2717
+ var seamly_session_expired_error = __webpack_require__(6821);
2718
+ // EXTERNAL MODULE: ./src/javascripts/api/errors/seamly-unavailable-error.js
2719
+ var seamly_unavailable_error = __webpack_require__(7265);
2720
+ // EXTERNAL MODULE: ./src/javascripts/ui/utils/seamly-utils.ts
2721
+ var seamly_utils = __webpack_require__(1149);
2722
+ // EXTERNAL MODULE: ./src/javascripts/domains/config/actions.ts
2723
+ var actions = __webpack_require__(257);
2724
+ // EXTERNAL MODULE: ./src/javascripts/domains/i18n/actions.ts
2725
+ var i18n_actions = __webpack_require__(5409);
2726
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/redux/create-debounced-async-thunk.ts
2727
+
2728
+ /**
2729
+ * A debounced analogue of the `createAsyncThunk` from `@reduxjs/toolkit`
2730
+ * @param typePrefix - a string action type value
2731
+ * @param payloadCreator - a callback function that should return a promise containing the result of some asynchronous logic
2732
+ * @param debounceOptions - the debounce options object
2733
+ */
2734
+ const createDebouncedAsyncThunk = (typePrefix, payloadCreator, debounceOptions) => {
2735
+ const {
2736
+ wait = 300,
2737
+ maxWait = 0,
2738
+ leading = false
2739
+ } = debounceOptions !== null && debounceOptions !== void 0 ? debounceOptions : {};
2740
+ let debounceTimer = null;
2741
+ let maxWaitTimer = null;
2742
+ let resolve;
2743
+ const cancel = () => {
2744
+ if (resolve) {
2745
+ resolve(false);
2746
+ resolve = undefined;
2747
+ }
2748
+ };
2749
+ const invoke = () => {
2750
+ clearTimeout(maxWaitTimer);
2751
+ maxWaitTimer = undefined;
2752
+ if (resolve) {
2753
+ resolve(true);
2754
+ resolve = undefined;
2755
+ }
2756
+ };
2757
+ const debounceExecutionCondition = () => {
2758
+ const immediate = leading && !debounceTimer;
2759
+ // Start debounced condition resolution
2760
+ clearTimeout(debounceTimer);
2761
+ debounceTimer = setTimeout(() => {
2762
+ invoke();
2763
+ debounceTimer = null;
2764
+ }, wait);
2765
+ if (immediate) {
2766
+ return true;
2767
+ }
2768
+ cancel();
2769
+ // Start max wait condition resolution
2770
+ if (maxWait && !maxWaitTimer) {
2771
+ maxWaitTimer = setTimeout(invoke, maxWait);
2772
+ }
2773
+ return new Promise(res => {
2774
+ resolve = res;
2775
+ });
2776
+ };
2777
+ return (0,redux_toolkit_esm/* createAsyncThunk */.hg)(typePrefix, payloadCreator, {
2778
+ condition: debounceExecutionCondition
2779
+ });
2780
+ };
2781
+ /* harmony default export */ const create_debounced_async_thunk = (createDebouncedAsyncThunk);
2782
+ // EXTERNAL MODULE: ./src/javascripts/domains/visibility/actions.ts
2783
+ var visibility_actions = __webpack_require__(9586);
2784
+ ;// CONCATENATED MODULE: ./src/javascripts/domains/app/actions.ts
2718
2785
  var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
2719
2786
  function adopt(value) {
2720
2787
  return value instanceof P ? value : new P(function (resolve) {
@@ -2749,7 +2816,8 @@ var __awaiter = undefined && undefined.__awaiter || function (thisArg, _argument
2749
2816
 
2750
2817
 
2751
2818
 
2752
- const initializeApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .createAsyncThunk */ .hg)('initializeApp', (_, {
2819
+
2820
+ const initializeApp = (0,redux_toolkit_esm/* createAsyncThunk */.hg)('initializeApp', (_, {
2753
2821
  extra: {
2754
2822
  api,
2755
2823
  config
@@ -2770,7 +2838,7 @@ const initializeApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .create
2770
2838
  } else {
2771
2839
  if ((_c = config === null || config === void 0 ? void 0 : config.context) === null || _c === void 0 ? void 0 : _c.topic) {
2772
2840
  api.send('action', {
2773
- type: ui_utils_seamly_utils__WEBPACK_IMPORTED_MODULE_0__/* .actionTypes */ .Hp.setTopic,
2841
+ type: seamly_utils/* actionTypes */.Hp.setTopic,
2774
2842
  body: {
2775
2843
  name: config.context.topic,
2776
2844
  // Separate fallback message is not needed here. Only an attached service will use this, but none will
@@ -2782,7 +2850,7 @@ const initializeApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .create
2782
2850
  if ((_d = config === null || config === void 0 ? void 0 : config.context) === null || _d === void 0 ? void 0 : _d.translationLocale) {
2783
2851
  locale = config.context.translationLocale;
2784
2852
  api.send('action', {
2785
- type: ui_utils_seamly_utils__WEBPACK_IMPORTED_MODULE_0__/* .actionTypes */ .Hp.setTranslation,
2853
+ type: seamly_utils/* actionTypes */.Hp.setTranslation,
2786
2854
  body: {
2787
2855
  enabled: true,
2788
2856
  locale
@@ -2796,8 +2864,8 @@ const initializeApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .create
2796
2864
  };
2797
2865
  }
2798
2866
  } catch (e) {
2799
- if (e instanceof api_errors_seamly_session_expired_error__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z) {
2800
- const err = new api_errors_seamly_session_expired_error__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z();
2867
+ if (e instanceof seamly_session_expired_error/* default */.Z) {
2868
+ const err = new seamly_session_expired_error/* default */.Z();
2801
2869
  return rejectWithValue({
2802
2870
  name: err.name,
2803
2871
  message: err.message,
@@ -2806,7 +2874,7 @@ const initializeApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .create
2806
2874
  action: err.action
2807
2875
  });
2808
2876
  }
2809
- const err = new api_errors_seamly_unavailable_error__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .Z();
2877
+ const err = new seamly_unavailable_error/* default */.Z();
2810
2878
  return rejectWithValue({
2811
2879
  name: err.name,
2812
2880
  message: err.message,
@@ -2814,26 +2882,29 @@ const initializeApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .create
2814
2882
  });
2815
2883
  }
2816
2884
  }));
2817
- const resetApp = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .createAsyncThunk */ .hg)('resetApp', (_, {
2885
+ const resetApp = create_debounced_async_thunk('resetApp', (_, {
2818
2886
  dispatch,
2819
2887
  extra: {
2820
2888
  api
2821
2889
  }
2822
2890
  }) => __awaiter(void 0, void 0, void 0, function* () {
2823
2891
  yield api.disconnect();
2824
- yield api.clearStore();
2825
- dispatch((0,domains_config_actions__WEBPACK_IMPORTED_MODULE_1__/* .resetConfig */ .I)());
2826
- yield dispatch((0,domains_config_actions__WEBPACK_IMPORTED_MODULE_1__/* .initializeConfig */ .t)());
2892
+ api.clearStore();
2893
+ dispatch((0,actions/* resetConfig */.I)());
2894
+ yield dispatch((0,actions/* initializeConfig */.t)());
2827
2895
  try {
2828
2896
  const {
2829
2897
  locale
2830
2898
  } = yield dispatch(initializeApp()).unwrap();
2831
- yield dispatch((0,domains_i18n_actions__WEBPACK_IMPORTED_MODULE_2__/* .setLocale */ .i)(locale));
2832
- } catch (rejectedValueOrSerializedError) {
2899
+ yield dispatch((0,i18n_actions/* setLocale */.i)(locale));
2900
+ } catch (e) {
2833
2901
  // nothing to do
2834
2902
  }
2835
- dispatch((0,domains_visibility_actions__WEBPACK_IMPORTED_MODULE_3__/* .initializeVisibility */ .Z)());
2836
- }));
2903
+ dispatch((0,visibility_actions/* initializeVisibility */.Z)());
2904
+ }), {
2905
+ wait: 2000,
2906
+ leading: true
2907
+ });
2837
2908
 
2838
2909
  /***/ }),
2839
2910
 
@@ -2864,7 +2935,7 @@ const selectUserHasResponded = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_0__/
2864
2935
  /* harmony export */ });
2865
2936
  /* unused harmony export appSlice */
2866
2937
  /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9639);
2867
- /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9201);
2938
+ /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(526);
2868
2939
 
2869
2940
 
2870
2941
  const initialState = {
@@ -3132,13 +3203,15 @@ const configSlice = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_3__/* .createSl
3132
3203
  preChat,
3133
3204
  agentParticipant,
3134
3205
  userParticipant,
3135
- startChatIcon
3206
+ startChatIcon,
3207
+ locale
3136
3208
  }
3137
3209
  }) => {
3138
3210
  state.preChatEvents = preChat.map(payload => ({
3139
3211
  type: 'message',
3140
3212
  payload
3141
3213
  }));
3214
+ state.context.locale = locale;
3142
3215
  state.agentParticipant = agentParticipant;
3143
3216
  state.userParticipant = userParticipant;
3144
3217
  state.startChatIcon = startChatIcon;
@@ -3259,7 +3332,7 @@ function createErrorsMiddleware({
3259
3332
  /* harmony export */ });
3260
3333
  /* unused harmony export formsSlice */
3261
3334
  /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9639);
3262
- /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9201);
3335
+ /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(526);
3263
3336
 
3264
3337
 
3265
3338
  const initialFormState = {
@@ -4277,11 +4350,13 @@ const selectHasError = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_0__/* .creat
4277
4350
  /* harmony export */ uc: () => (/* binding */ setInterrupt)
4278
4351
  /* harmony export */ });
4279
4352
  /* unused harmony export interruptSlice */
4280
- /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9639);
4281
- /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9201);
4353
+ /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9639);
4354
+ /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(526);
4282
4355
  /* harmony import */ var domains_config_actions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(257);
4283
4356
  /* harmony import */ var domains_i18n_actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5409);
4284
- /* harmony import */ var domains_visibility_actions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9586);
4357
+ /* harmony import */ var domains_store_actions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2770);
4358
+ /* harmony import */ var domains_visibility_actions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9586);
4359
+
4285
4360
 
4286
4361
 
4287
4362
 
@@ -4290,7 +4365,7 @@ const selectHasError = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_0__/* .creat
4290
4365
  const initialState = {
4291
4366
  error: undefined
4292
4367
  };
4293
- const interruptSlice = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .createSlice */ .oM)({
4368
+ const interruptSlice = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_5__/* .createSlice */ .oM)({
4294
4369
  name: 'interrupt',
4295
4370
  initialState,
4296
4371
  reducers: {
@@ -4300,7 +4375,7 @@ const interruptSlice = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .creat
4300
4375
  clearInterrupt: () => initialState
4301
4376
  },
4302
4377
  extraReducers: builder => {
4303
- builder.addCase(domains_config_actions__WEBPACK_IMPORTED_MODULE_1__/* .initializeConfig */ .t.pending, () => initialState).addMatcher((0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_4__/* .isAnyOf */ .Q)(domains_app_actions__WEBPACK_IMPORTED_MODULE_0__/* .initializeApp */ .Z.rejected, domains_config_actions__WEBPACK_IMPORTED_MODULE_1__/* .initializeConfig */ .t.rejected, domains_i18n_actions__WEBPACK_IMPORTED_MODULE_2__/* .setLocale */ .i.rejected, domains_visibility_actions__WEBPACK_IMPORTED_MODULE_3__/* .setVisibility */ .i.rejected, domains_visibility_actions__WEBPACK_IMPORTED_MODULE_3__/* .initializeVisibility */ .Z.rejected), (state, {
4378
+ builder.addCase(domains_config_actions__WEBPACK_IMPORTED_MODULE_1__/* .initializeConfig */ .t.pending, () => initialState).addMatcher((0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_5__/* .isAnyOf */ .Q)(domains_app_actions__WEBPACK_IMPORTED_MODULE_0__/* .initializeApp */ .Z.rejected, domains_config_actions__WEBPACK_IMPORTED_MODULE_1__/* .initializeConfig */ .t.rejected, domains_i18n_actions__WEBPACK_IMPORTED_MODULE_2__/* .setLocale */ .i.rejected, domains_visibility_actions__WEBPACK_IMPORTED_MODULE_4__/* .setVisibility */ .i.rejected, domains_visibility_actions__WEBPACK_IMPORTED_MODULE_4__/* .initializeVisibility */ .Z.rejected, domains_store_actions__WEBPACK_IMPORTED_MODULE_3__/* .getConversation */ .c.rejected), (state, {
4304
4379
  payload
4305
4380
  }) => {
4306
4381
  state.error = payload;
@@ -4315,6 +4390,78 @@ const {
4315
4390
 
4316
4391
  /***/ }),
4317
4392
 
4393
+ /***/ 2770:
4394
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4395
+
4396
+ "use strict";
4397
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
4398
+ /* harmony export */ c: () => (/* binding */ getConversation)
4399
+ /* harmony export */ });
4400
+ /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9639);
4401
+ var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
4402
+ function adopt(value) {
4403
+ return value instanceof P ? value : new P(function (resolve) {
4404
+ resolve(value);
4405
+ });
4406
+ }
4407
+ return new (P || (P = Promise))(function (resolve, reject) {
4408
+ function fulfilled(value) {
4409
+ try {
4410
+ step(generator.next(value));
4411
+ } catch (e) {
4412
+ reject(e);
4413
+ }
4414
+ }
4415
+ function rejected(value) {
4416
+ try {
4417
+ step(generator["throw"](value));
4418
+ } catch (e) {
4419
+ reject(e);
4420
+ }
4421
+ }
4422
+ function step(result) {
4423
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
4424
+ }
4425
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
4426
+ });
4427
+ };
4428
+
4429
+ const getConversation = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_0__/* .createAsyncThunk */ .hg)('getConversation', (_, {
4430
+ extra: {
4431
+ api
4432
+ },
4433
+ rejectWithValue
4434
+ }) => __awaiter(void 0, void 0, void 0, function* () {
4435
+ try {
4436
+ return api.getConversation();
4437
+ } catch (error) {
4438
+ return rejectWithValue({
4439
+ name: error === null || error === void 0 ? void 0 : error.name,
4440
+ message: error === null || error === void 0 ? void 0 : error.message,
4441
+ langKey: error === null || error === void 0 ? void 0 : error.langKey,
4442
+ action: error === null || error === void 0 ? void 0 : error.action,
4443
+ originalEvent: error === null || error === void 0 ? void 0 : error.originalEvent,
4444
+ originalError: error === null || error === void 0 ? void 0 : error.originalError
4445
+ });
4446
+ }
4447
+ }), {
4448
+ condition(payload, {
4449
+ getState
4450
+ }) {
4451
+ var _a;
4452
+ const {
4453
+ state: {
4454
+ events
4455
+ }
4456
+ } = getState();
4457
+ const lastEvent = events[events.length - 1];
4458
+ const payloadLastEventId = (_a = payload === null || payload === void 0 ? void 0 : payload.lastEvent) === null || _a === void 0 ? void 0 : _a.id;
4459
+ return lastEvent && payloadLastEventId !== lastEvent.payload.id;
4460
+ }
4461
+ });
4462
+
4463
+ /***/ }),
4464
+
4318
4465
  /***/ 7271:
4319
4466
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
4320
4467
 
@@ -4338,8 +4485,8 @@ var config_slice = __webpack_require__(3701);
4338
4485
  var errors = __webpack_require__(9792);
4339
4486
  // EXTERNAL MODULE: ./src/javascripts/domains/forms/slice.ts
4340
4487
  var forms_slice = __webpack_require__(3939);
4341
- // EXTERNAL MODULE: ./src/javascripts/domains/app/actions.ts
4342
- var actions = __webpack_require__(9201);
4488
+ // EXTERNAL MODULE: ./src/javascripts/domains/app/actions.ts + 1 modules
4489
+ var actions = __webpack_require__(526);
4343
4490
  // EXTERNAL MODULE: ./src/javascripts/domains/config/actions.ts
4344
4491
  var config_actions = __webpack_require__(257);
4345
4492
  // EXTERNAL MODULE: ./src/javascripts/domains/i18n/actions.ts
@@ -4623,7 +4770,7 @@ const useAppDispatch = es/* useDispatch */.I0;
4623
4770
  /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9639);
4624
4771
  /* harmony import */ var ui_utils_general_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(822);
4625
4772
  /* harmony import */ var ui_utils_seamly_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1149);
4626
- /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9201);
4773
+ /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(526);
4627
4774
  /* harmony import */ var domains_config_actions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(257);
4628
4775
  /* harmony import */ var lib_id__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8527);
4629
4776
 
@@ -5460,7 +5607,7 @@ const useTranslationProposal = () => {
5460
5607
  /* harmony export */ });
5461
5608
  /* unused harmony exports translationsInitialState, translationSlice */
5462
5609
  /* harmony import */ var _reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9639);
5463
- /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9201);
5610
+ /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(526);
5464
5611
  /* harmony import */ var domains_config_actions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(257);
5465
5612
  /* harmony import */ var domains_store_slice__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8801);
5466
5613
 
@@ -5564,7 +5711,13 @@ const translationSlice = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_3__/* .cre
5564
5711
  const feature = (_a = payload === null || payload === void 0 ? void 0 : payload.features) === null || _a === void 0 ? void 0 : _a.translation;
5565
5712
  if (!feature) return;
5566
5713
  state.isAvailable = feature.enabled === true;
5567
- state.languages = feature.languages;
5714
+ state.languages = [...feature.languages].sort((a, b) => {
5715
+ if (a.locale === payload.locale) return -1;
5716
+ if (b.locale === payload.locale) return 1;
5717
+ return a.nativeName.localeCompare(b.nativeName, undefined, {
5718
+ sensitivity: 'base'
5719
+ });
5720
+ });
5568
5721
  }).addCase(domains_store_slice__WEBPACK_IMPORTED_MODULE_2__/* .setHistory */ .JB, (state, {
5569
5722
  payload
5570
5723
  }) => {
@@ -5672,8 +5825,9 @@ const setVisibility = (0,_reduxjs_toolkit__WEBPACK_IMPORTED_MODULE_6__/* .create
5672
5825
  if (previousVisibility === calculatedVisibility) {
5673
5826
  return undefined;
5674
5827
  }
5828
+ const visibility = api.store.get(_constants__WEBPACK_IMPORTED_MODULE_4__/* .StoreKey */ .K);
5675
5829
  // Store the user-requested visibility in order to reinitialize after refresh
5676
- api.store.set(_constants__WEBPACK_IMPORTED_MODULE_4__/* .StoreKey */ .K, Object.assign(Object.assign({}, api.store.get(_constants__WEBPACK_IMPORTED_MODULE_4__/* .StoreKey */ .K) || {}), {
5830
+ api.store.set(_constants__WEBPACK_IMPORTED_MODULE_4__/* .StoreKey */ .K, Object.assign(Object.assign({}, visibility || {}), {
5677
5831
  [layoutMode]: requestedVisibility
5678
5832
  }));
5679
5833
  if (requestedVisibility) {
@@ -6130,12 +6284,21 @@ var selectors = __webpack_require__(703);
6130
6284
  var live_region_hooks = __webpack_require__(5136);
6131
6285
  // EXTERNAL MODULE: ./src/javascripts/ui/hooks/seamly-state-hooks.ts
6132
6286
  var seamly_state_hooks = __webpack_require__(2140);
6287
+ // EXTERNAL MODULE: ./src/javascripts/api/errors/seamly-general-error.js
6288
+ var seamly_general_error = __webpack_require__(5332);
6133
6289
  // EXTERNAL MODULE: ./src/javascripts/domains/interrupt/hooks.ts
6134
6290
  var interrupt_hooks = __webpack_require__(5889);
6291
+ // EXTERNAL MODULE: ./src/javascripts/domains/interrupt/slice.ts
6292
+ var slice = __webpack_require__(6160);
6293
+ // EXTERNAL MODULE: ./src/javascripts/domains/store/index.ts + 4 modules
6294
+ var store = __webpack_require__(7271);
6135
6295
  ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-session-expired-command.ts
6136
6296
 
6137
6297
 
6138
6298
 
6299
+
6300
+
6301
+
6139
6302
  function useSessionExpiredCommand() {
6140
6303
  const {
6141
6304
  meta: {
@@ -6143,13 +6306,35 @@ function useSessionExpiredCommand() {
6143
6306
  action
6144
6307
  }
6145
6308
  } = (0,interrupt_hooks/* useInterrupt */.i)();
6309
+ const dispatch = (0,store/* useAppDispatch */.T)();
6146
6310
  const seamlyCommands = (0,use_seamly_commands/* default */.Z)();
6147
6311
  const isExpiredError = (originalError === null || originalError === void 0 ? void 0 : originalError.name) === 'SeamlySessionExpiredError';
6312
+ const limit = (0,hooks_.useRef)(0);
6313
+ const limitTimer = (0,hooks_.useRef)(null);
6148
6314
  (0,hooks_.useEffect)(() => {
6149
6315
  if (isExpiredError && seamlyCommands[action]) {
6316
+ if (limit.current >= 10) {
6317
+ limitTimer.current = setTimeout(() => {
6318
+ limit.current = 0;
6319
+ }, 10000);
6320
+ const error = new seamly_general_error/* default */.Z();
6321
+ dispatch((0,slice/* setInterrupt */.uc)({
6322
+ name: error.name,
6323
+ message: error.message,
6324
+ langKey: error.langKey,
6325
+ originalEvent: error.originalEvent,
6326
+ originalError: error.originalError,
6327
+ action: error.action
6328
+ }));
6329
+ return () => {};
6330
+ }
6331
+ limit.current += 1;
6150
6332
  seamlyCommands[action]();
6151
6333
  }
6152
- }, [action, seamlyCommands, isExpiredError]);
6334
+ return () => {
6335
+ if (limitTimer.current) clearTimeout(limitTimer.current);
6336
+ };
6337
+ }, [action, seamlyCommands, isExpiredError, dispatch]);
6153
6338
  }
6154
6339
  ;// CONCATENATED MODULE: ./src/javascripts/ui/hooks/use-seamly-chat.ts
6155
6340
  var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
@@ -6880,7 +7065,7 @@ const EventParticipant = ({
6880
7065
  })
6881
7066
  }));
6882
7067
  }
6883
- if (showName) {
7068
+ if (showName && participantName) {
6884
7069
  authorInfo.push((0,preact_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
6885
7070
  className: (0,lib_css__WEBPACK_IMPORTED_MODULE_3__/* .className */ .o)('message__author-name'),
6886
7071
  children: participantName
@@ -7609,7 +7794,7 @@ const useSeamlyActivityEventHandler = () => (0,preact_hooks__WEBPACK_IMPORTED_MO
7609
7794
  /* harmony import */ var config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9787);
7610
7795
  /* harmony import */ var ui_components_core_seamly_api_context__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2871);
7611
7796
  /* harmony import */ var ui_utils_seamly_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(1149);
7612
- /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9201);
7797
+ /* harmony import */ var domains_app_actions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(526);
7613
7798
  /* harmony import */ var domains_app_hooks__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3423);
7614
7799
  /* harmony import */ var domains_app_slice__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1322);
7615
7800
  /* harmony import */ var domains_config_hooks__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(6134);
@@ -8455,15 +8640,52 @@ var compat_module = __webpack_require__(8661);
8455
8640
  var utils_batch = __webpack_require__(9256);
8456
8641
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/components/Context.js
8457
8642
 
8458
- const Context_ReactReduxContext = /*#__PURE__*/(0,compat_module.createContext)(null);
8643
+ const ContextKey = Symbol.for(`react-redux-context-${compat_module.version}`);
8644
+ const gT = globalThis;
8645
+
8646
+ function getContext() {
8647
+ let realContext = gT[ContextKey];
8648
+
8649
+ if (!realContext) {
8650
+ realContext = (0,compat_module.createContext)(null);
8651
+
8652
+ if (false) {}
8653
+
8654
+ gT[ContextKey] = realContext;
8655
+ }
8459
8656
 
8460
- if (false) {}
8657
+ return realContext;
8658
+ }
8659
+
8660
+ const Context_ReactReduxContext = /*#__PURE__*/new Proxy({}, /*#__PURE__*/new Proxy({}, {
8661
+ get(_, handler) {
8662
+ const target = getContext(); // @ts-ignore
8663
+
8664
+ return (_target, ...args) => Reflect[handler](target, ...args);
8665
+ }
8461
8666
 
8667
+ }));
8462
8668
  /* harmony default export */ const Context = ((/* unused pure expression or super */ null && (Context_ReactReduxContext)));
8463
8669
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/hooks/useReduxContext.js
8464
8670
 
8465
8671
 
8466
8672
 
8673
+ /**
8674
+ * Hook factory, which creates a `useReduxContext` hook bound to a given context. This is a low-level
8675
+ * hook that you should usually not need to call directly.
8676
+ *
8677
+ * @param {React.Context} [context=ReactReduxContext] Context passed to your `<Provider>`.
8678
+ * @returns {Function} A `useReduxContext` hook bound to the specified context.
8679
+ */
8680
+ function createReduxContextHook(context = Context_ReactReduxContext) {
8681
+ return function useReduxContext() {
8682
+ const contextValue = (0,compat_module.useContext)(context);
8683
+
8684
+ if (false) {}
8685
+
8686
+ return contextValue;
8687
+ };
8688
+ }
8467
8689
  /**
8468
8690
  * A hook to access the value of the `ReactReduxContext`. This is a low-level
8469
8691
  * hook that you should usually not need to call directly.
@@ -8480,13 +8702,8 @@ if (false) {}
8480
8702
  * return <div>{store.getState()}</div>
8481
8703
  * }
8482
8704
  */
8483
- function useReduxContext_useReduxContext() {
8484
- const contextValue = (0,compat_module.useContext)(Context_ReactReduxContext);
8485
-
8486
- if (false) {}
8487
8705
 
8488
- return contextValue;
8489
- }
8706
+ const useReduxContext_useReduxContext = /*#__PURE__*/createReduxContextHook();
8490
8707
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/utils/useSyncExternalStore.js
8491
8708
  const useSyncExternalStore_notInitialized = () => {
8492
8709
  throw new Error('uSES not initialized!');
@@ -8511,16 +8728,37 @@ const refEquality = (a, b) => a === b;
8511
8728
 
8512
8729
 
8513
8730
  function createSelectorHook(context = Context_ReactReduxContext) {
8514
- const useReduxContext = context === Context_ReactReduxContext ? useReduxContext_useReduxContext : () => (0,compat_module.useContext)(context);
8515
- return function useSelector(selector, equalityFn = refEquality) {
8731
+ const useReduxContext = context === Context_ReactReduxContext ? useReduxContext_useReduxContext : createReduxContextHook(context);
8732
+ return function useSelector(selector, equalityFnOrOptions = {}) {
8733
+ const {
8734
+ equalityFn = refEquality,
8735
+ stabilityCheck = undefined,
8736
+ noopCheck = undefined
8737
+ } = typeof equalityFnOrOptions === 'function' ? {
8738
+ equalityFn: equalityFnOrOptions
8739
+ } : equalityFnOrOptions;
8740
+
8516
8741
  if (false) {}
8517
8742
 
8518
8743
  const {
8519
8744
  store,
8520
8745
  subscription,
8521
- getServerState
8746
+ getServerState,
8747
+ stabilityCheck: globalStabilityCheck,
8748
+ noopCheck: globalNoopCheck
8522
8749
  } = useReduxContext();
8523
- const selectedState = useSyncExternalStoreWithSelector(subscription.addNestedSub, store.getState, getServerState || store.getState, selector, equalityFn);
8750
+ const firstRun = (0,compat_module.useRef)(true);
8751
+ const wrappedSelector = (0,compat_module.useCallback)({
8752
+ [selector.name](state) {
8753
+ const selected = selector(state);
8754
+
8755
+ if (false) {}
8756
+
8757
+ return selected;
8758
+ }
8759
+
8760
+ }[selector.name], [selector, globalStabilityCheck, stabilityCheck]);
8761
+ const selectedState = useSyncExternalStoreWithSelector(subscription.addNestedSub, store.getState, getServerState || store.getState, wrappedSelector, equalityFn);
8524
8762
  (0,compat_module.useDebugValue)(selectedState);
8525
8763
  return selectedState;
8526
8764
  };
@@ -9107,16 +9345,20 @@ function Provider({
9107
9345
  store,
9108
9346
  context,
9109
9347
  children,
9110
- serverState
9348
+ serverState,
9349
+ stabilityCheck = 'once',
9350
+ noopCheck = 'once'
9111
9351
  }) {
9112
9352
  const contextValue = (0,compat_module.useMemo)(() => {
9113
9353
  const subscription = Subscription_createSubscription(store);
9114
9354
  return {
9115
9355
  store,
9116
9356
  subscription,
9117
- getServerState: serverState ? () => serverState : undefined
9357
+ getServerState: serverState ? () => serverState : undefined,
9358
+ stabilityCheck,
9359
+ noopCheck
9118
9360
  };
9119
- }, [store, serverState]);
9361
+ }, [store, serverState, stabilityCheck, noopCheck]);
9120
9362
  const previousState = (0,compat_module.useMemo)(() => store.getState(), [store]);
9121
9363
  useIsomorphicLayoutEffect_useIsomorphicLayoutEffect(() => {
9122
9364
  const {
@@ -9145,7 +9387,6 @@ function Provider({
9145
9387
  ;// CONCATENATED MODULE: ./node_modules/react-redux/es/hooks/useStore.js
9146
9388
 
9147
9389
 
9148
-
9149
9390
  /**
9150
9391
  * Hook factory, which creates a `useStore` hook bound to a given context.
9151
9392
  *
@@ -9155,7 +9396,8 @@ function Provider({
9155
9396
 
9156
9397
  function createStoreHook(context = Context_ReactReduxContext) {
9157
9398
  const useReduxContext = // @ts-ignore
9158
- context === Context_ReactReduxContext ? useReduxContext_useReduxContext : () => (0,compat_module.useContext)(context);
9399
+ context === Context_ReactReduxContext ? useReduxContext_useReduxContext : // @ts-ignore
9400
+ createReduxContextHook(context);
9159
9401
  return function useStore() {
9160
9402
  const {
9161
9403
  store
@@ -11379,6 +11621,7 @@ _ConversationConnector_connectionListeners = new WeakMap(), _ConversationConnect
11379
11621
  return !complete;
11380
11622
  }), "f");
11381
11623
  };
11624
+ /* harmony default export */ const conversation_connector = (ConversationConnector);
11382
11625
  ;// CONCATENATED MODULE: ./src/javascripts/api/index.ts
11383
11626
  var api_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
11384
11627
  function adopt(value) {
@@ -11418,6 +11661,14 @@ var api_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet ||
11418
11661
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11419
11662
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11420
11663
  };
11664
+ var __rest = undefined && undefined.__rest || function (s, e) {
11665
+ var t = {};
11666
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
11667
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
11668
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
11669
+ }
11670
+ return t;
11671
+ };
11421
11672
  var _API_instances, _API_ready, _API_externalId, _API_conversationAuthToken, _API_layoutMode, _API_config, _API_getAccessToken, _API_setAccessToken, _API_setConversationUrl, _API_getChannelTopic, _API_setChannelTopic, _API_getLocale, _API_getUrlPrefix, _API_updateUrls, _API_createConversation, _API_getEnvironment;
11422
11673
 
11423
11674
 
@@ -11505,7 +11756,7 @@ class API {
11505
11756
  _API_conversationAuthToken.set(this, void 0);
11506
11757
  _API_layoutMode.set(this, void 0);
11507
11758
  _API_config.set(this, void 0);
11508
- this.conversation = new ConversationConnector();
11759
+ this.conversation = new conversation_connector();
11509
11760
  _API_getLocale.set(this, locale => locale || this.locale);
11510
11761
  this.store = objectStore(`${namespace}.connection${context.locale ? `.${context.locale}` : ''}`, config.storageProvider || store);
11511
11762
  this.connectionInfo = {
@@ -11535,7 +11786,8 @@ class API {
11535
11786
  });
11536
11787
  }
11537
11788
  getConversationUrl() {
11538
- return this.store.get('conversationUrl');
11789
+ const conversationUrl = this.store.get('conversationUrl');
11790
+ return conversationUrl;
11539
11791
  }
11540
11792
  hasConversation() {
11541
11793
  return !!this.getConversationUrl();
@@ -11643,7 +11895,7 @@ class API {
11643
11895
  if (error.status >= 500) {
11644
11896
  throw new seamly_general_error/* default */.Z(error);
11645
11897
  }
11646
- throw error;
11898
+ throw new ApiError(error);
11647
11899
  }
11648
11900
  });
11649
11901
  }
@@ -11752,7 +12004,7 @@ class API {
11752
12004
  if (error.status >= 500) {
11753
12005
  throw new seamly_general_error/* default */.Z(error);
11754
12006
  }
11755
- throw error;
12007
+ throw new ApiError(error);
11756
12008
  }
11757
12009
  });
11758
12010
  }
@@ -11778,6 +12030,7 @@ class API {
11778
12030
  this.conversation.pushToChannel(command, buildPayload(command, payload), 10000);
11779
12031
  }
11780
12032
  sendContext(context) {
12033
+ var _a;
11781
12034
  const {
11782
12035
  locale,
11783
12036
  variables
@@ -11799,19 +12052,29 @@ class API {
11799
12052
  if (Object.keys(payload).length === 0 && payload.constructor === Object) {
11800
12053
  return;
11801
12054
  }
11802
- this.send('context', payload, false);
12055
+ // Destructure the server locale from the payload
12056
+ const {
12057
+ locale: _
12058
+ } = payload,
12059
+ restPayload = __rest(payload, ["locale"]);
12060
+ const configLocale = (_a = api_classPrivateFieldGet(this, _API_config, "f").context) === null || _a === void 0 ? void 0 : _a.locale;
12061
+ this.send('context', Object.assign(Object.assign({}, configLocale ? {
12062
+ locale: configLocale
12063
+ } : {}), restPayload), false);
11803
12064
  }
11804
12065
  }
11805
12066
  _API_ready = new WeakMap(), _API_externalId = new WeakMap(), _API_conversationAuthToken = new WeakMap(), _API_layoutMode = new WeakMap(), _API_config = new WeakMap(), _API_getLocale = new WeakMap(), _API_instances = new WeakSet(), _API_getAccessToken = function _API_getAccessToken() {
11806
- return this.store.get('accessToken');
12067
+ const accessToken = this.store.get('accessToken');
12068
+ return accessToken;
11807
12069
  }, _API_setAccessToken = function _API_setAccessToken(accessToken) {
11808
12070
  this.store.set('accessToken', accessToken);
11809
12071
  }, _API_setConversationUrl = function _API_setConversationUrl(url) {
11810
12072
  this.store.set('conversationUrl', url);
11811
12073
  }, _API_getChannelTopic = function _API_getChannelTopic() {
12074
+ const channelTopic = this.store.get('channelTopic') || this.store.get('channelName');
11812
12075
  // The `channelName` fallback is needed for seamless client upgrades.
11813
12076
  // TODO: Remove when all clients have been upgraded past v20.
11814
- return this.store.get('channelTopic') || this.store.get('channelName');
12077
+ return channelTopic;
11815
12078
  }, _API_setChannelTopic = function _API_setChannelTopic(topic) {
11816
12079
  this.store.set('channelTopic', topic);
11817
12080
  }, _API_getUrlPrefix = function _API_getUrlPrefix(protocol) {
@@ -11876,7 +12139,7 @@ _API_ready = new WeakMap(), _API_externalId = new WeakMap(), _API_conversationAu
11876
12139
  return {
11877
12140
  clientName: "@seamly/web-ui",
11878
12141
  clientVariant: api_classPrivateFieldGet(this, _API_layoutMode, "f"),
11879
- clientVersion: "22.1.0",
12142
+ clientVersion: "22.3.0-beta.1",
11880
12143
  currentUrl: window.location.toString(),
11881
12144
  screenResolution: `${window.screen.width}x${window.screen.height}`,
11882
12145
  timezone: getTimeZone(),
@@ -11918,108 +12181,61 @@ var message_container = __webpack_require__(2480);
11918
12181
  var seamly_hooks = __webpack_require__(9470);
11919
12182
  // EXTERNAL MODULE: ./src/javascripts/domains/translations/hooks.ts + 1 modules
11920
12183
  var translations_hooks = __webpack_require__(4398);
11921
- ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/card-component.js
12184
+ ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/card-component.tsx
11922
12185
 
11923
12186
 
11924
12187
 
11925
12188
 
11926
12189
 
11927
-
11928
- const CardComponent = ({
11929
- id,
11930
- action,
11931
- buttonText,
11932
- description,
11933
- hasFocus,
11934
- image,
11935
- title,
11936
- isCarouselItem
11937
- }) => {
11938
- const cardRef = (0,hooks_.useRef)(null);
11939
- const {
11940
- sendMessage,
11941
- sendAction,
11942
- emitEvent
11943
- } = (0,seamly_hooks/* useSeamlyCommands */.bs)();
11944
- const descriptionId = (0,seamly_hooks/* useGeneratedId */.I8)();
11945
- const isMounted = (0,hooks_.useRef)();
11946
- const CardActionComponent = action.type === seamly_utils/* cardTypes */.wh.navigate ? 'a' : 'button';
11947
- const emitCardEvent = (0,hooks_.useCallback)(() => emitEvent(`action.${seamly_utils/* actionTypes */.Hp.clickCard}`, {
11948
- type: seamly_utils/* actionTypes */.Hp.clickCta,
11949
- originMessage: id,
11950
- action
11951
- }), [emitEvent, id, action]);
11952
- const handleClick = (0,hooks_.useCallback)(() => {
11953
- emitCardEvent();
11954
- if (action.type === seamly_utils/* cardTypes */.wh.ask) {
11955
- sendMessage({
11956
- body: action.ask
11957
- });
11958
- } else if (action.type === seamly_utils/* cardTypes */.wh.topic) {
11959
- const {
11960
- topic: name,
11961
- fallbackMessage
11962
- } = action;
11963
- sendAction({
11964
- type: seamly_utils/* actionTypes */.Hp.setTopic,
11965
- body: {
11966
- name,
11967
- fallbackMessage
12190
+ const CardComponent = ({ id, action, buttonText, description, hasFocus, image, title, isCarouselItem, }) => {
12191
+ const cardRef = (0,hooks_.useRef)(null);
12192
+ const { sendMessage, sendAction, emitEvent } = (0,seamly_hooks/* useSeamlyCommands */.bs)();
12193
+ const descriptionId = (0,seamly_hooks/* useGeneratedId */.I8)();
12194
+ const isMounted = (0,hooks_.useRef)(false);
12195
+ const CardActionComponent = action.type === seamly_utils/* cardTypes */.wh.navigate ? 'a' : 'button';
12196
+ const emitCardEvent = (0,hooks_.useCallback)(() => emitEvent(`action.${seamly_utils/* actionTypes */.Hp.clickCard}`, {
12197
+ type: seamly_utils/* actionTypes */.Hp.clickCta,
12198
+ originMessage: id,
12199
+ action,
12200
+ }), [emitEvent, id, action]);
12201
+ const handleClick = (0,hooks_.useCallback)(() => {
12202
+ emitCardEvent();
12203
+ if (action.type === seamly_utils/* cardTypes */.wh.ask) {
12204
+ sendMessage({ body: action.ask });
11968
12205
  }
11969
- });
11970
- }
11971
- }, [sendMessage, action, sendAction, emitCardEvent]);
11972
- const actionProps = (0,hooks_.useMemo)(() => action.type === seamly_utils/* cardTypes */.wh.navigate ? {
11973
- href: action.link,
11974
- rel: 'noopener noreferrer',
11975
- target: action.newTab ? '_blank' : '_self',
11976
- onClick: emitCardEvent
11977
- } : {
11978
- onClick: handleClick
11979
- }, [action, handleClick, emitCardEvent]);
11980
- (0,hooks_.useEffect)(() => {
11981
- if (isCarouselItem) {
11982
- if (hasFocus && isMounted.current) {
11983
- window.requestAnimationFrame(() => cardRef.current.focus());
11984
- } else {
11985
- cardRef.current.blur();
11986
- }
11987
- }
11988
- isMounted.current = true;
11989
- }, [hasFocus, isCarouselItem]);
11990
- return (0,jsx_runtime_.jsxs)("div", {
11991
- className: (0,css/* className */.o)('card__wrapper'),
11992
- id: id,
11993
- tabIndex: "-1" // set tabIndex of -1 so card can be focussed
11994
- ,
11995
- ref: cardRef,
11996
- children: [(0,jsx_runtime_.jsx)("img", {
11997
- className: (0,css/* className */.o)('card__image'),
11998
- src: image,
11999
- alt: ""
12000
- }), (0,jsx_runtime_.jsxs)("div", {
12001
- className: (0,css/* className */.o)('card__content'),
12002
- id: id,
12003
- children: [title && (0,jsx_runtime_.jsx)("h2", {
12004
- className: (0,css/* className */.o)('card__title'),
12005
- children: title
12006
- }), description && (0,jsx_runtime_.jsx)("div", {
12007
- className: (0,css/* className */.o)('card__description'),
12008
- dangerouslySetInnerHTML: {
12009
- __html: description
12206
+ else if (action.type === seamly_utils/* cardTypes */.wh.topic) {
12207
+ const { topic: name, fallbackMessage } = action;
12208
+ sendAction({
12209
+ type: seamly_utils/* actionTypes */.Hp.setTopic,
12210
+ body: { name, fallbackMessage },
12211
+ });
12010
12212
  }
12011
- }), (0,jsx_runtime_.jsx)(CardActionComponent, {
12012
- tabIndex: isCarouselItem && !hasFocus ? '-1' : undefined // disable to prevent tabbing through cards
12013
- ,
12014
- className: (0,css/* className */.o)('button', 'button--primary'),
12015
- "aria-describedby": descriptionId,
12016
- ...actionProps,
12017
- children: buttonText
12018
- })]
12019
- })]
12020
- });
12213
+ }, [sendMessage, action, sendAction, emitCardEvent]);
12214
+ const actionProps = (0,hooks_.useMemo)(() => action.type === seamly_utils/* cardTypes */.wh.navigate
12215
+ ? {
12216
+ href: action.link,
12217
+ rel: 'noopener noreferrer',
12218
+ target: action.newTab ? '_blank' : '_self',
12219
+ onClick: emitCardEvent,
12220
+ }
12221
+ : {
12222
+ onClick: handleClick,
12223
+ }, [action, handleClick, emitCardEvent]);
12224
+ (0,hooks_.useEffect)(() => {
12225
+ if (isCarouselItem) {
12226
+ if (hasFocus && isMounted.current) {
12227
+ window.requestAnimationFrame(() => cardRef.current.focus());
12228
+ }
12229
+ else {
12230
+ cardRef.current.blur();
12231
+ }
12232
+ }
12233
+ isMounted.current = true;
12234
+ }, [hasFocus, isCarouselItem]);
12235
+ return ((0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('card__wrapper'), id: id, tabIndex: -1, ref: cardRef, children: [image ? ((0,jsx_runtime_.jsx)("img", { className: (0,css/* className */.o)('card__image'), src: image, alt: "" })) : null, (0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('card__content'), id: id, children: [title && (0,jsx_runtime_.jsx)("h2", { className: (0,css/* className */.o)('card__title'), children: title }), description && ((0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('card__description'), dangerouslySetInnerHTML: { __html: description } })), (0,jsx_runtime_.jsx)(CardActionComponent, Object.assign({ tabIndex: isCarouselItem && !hasFocus ? -1 : undefined, className: (0,css/* className */.o)('button', 'button--primary'), "aria-describedby": descriptionId }, actionProps, { children: buttonText }))] })] }));
12021
12236
  };
12022
12237
  /* harmony default export */ const card_component = (CardComponent);
12238
+
12023
12239
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/conversation/event/card-message.js
12024
12240
 
12025
12241
 
@@ -12794,7 +13010,7 @@ const TimeIndicator = ({
12794
13010
  var store_slice = __webpack_require__(8801);
12795
13011
  ;// CONCATENATED MODULE: ./node_modules/tabbable/dist/index.esm.js
12796
13012
  /*!
12797
- * tabbable 6.1.2
13013
+ * tabbable 6.2.0
12798
13014
  * @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
12799
13015
  */
12800
13016
  // NOTE: separate `:not()` selectors has broader browser support than the newer
@@ -12974,7 +13190,27 @@ var getCandidatesIteratively = function getCandidatesIteratively(elements, inclu
12974
13190
  }
12975
13191
  return candidates;
12976
13192
  };
12977
- var getTabindex = function getTabindex(node, isScope) {
13193
+
13194
+ /**
13195
+ * @private
13196
+ * Determines if the node has an explicitly specified `tabindex` attribute.
13197
+ * @param {HTMLElement} node
13198
+ * @returns {boolean} True if so; false if not.
13199
+ */
13200
+ var hasTabIndex = function hasTabIndex(node) {
13201
+ return !isNaN(parseInt(node.getAttribute('tabindex'), 10));
13202
+ };
13203
+
13204
+ /**
13205
+ * Determine the tab index of a given node.
13206
+ * @param {HTMLElement} node
13207
+ * @returns {number} Tab order (negative, 0, or positive number).
13208
+ * @throws {Error} If `node` is falsy.
13209
+ */
13210
+ var getTabIndex = function getTabIndex(node) {
13211
+ if (!node) {
13212
+ throw new Error('No node provided');
13213
+ }
12978
13214
  if (node.tabIndex < 0) {
12979
13215
  // in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
12980
13216
  // `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
@@ -12983,16 +13219,28 @@ var getTabindex = function getTabindex(node, isScope) {
12983
13219
  // order, consider their tab index to be 0.
12984
13220
  // Also browsers do not return `tabIndex` correctly for contentEditable nodes;
12985
13221
  // so if they don't have a tabindex attribute specifically set, assume it's 0.
12986
- //
12987
- // isScope is positive for custom element with shadow root or slot that by default
12988
- // have tabIndex -1, but need to be sorted by document order in order for their
12989
- // content to be inserted in the correct position
12990
- if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
13222
+ if ((/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || isContentEditable(node)) && !hasTabIndex(node)) {
12991
13223
  return 0;
12992
13224
  }
12993
13225
  }
12994
13226
  return node.tabIndex;
12995
13227
  };
13228
+
13229
+ /**
13230
+ * Determine the tab index of a given node __for sort order purposes__.
13231
+ * @param {HTMLElement} node
13232
+ * @param {boolean} [isScope] True for a custom element with shadow root or slot that, by default,
13233
+ * has tabIndex -1, but needs to be sorted by document order in order for its content to be
13234
+ * inserted into the correct sort position.
13235
+ * @returns {number} Tab order (negative, 0, or positive number).
13236
+ */
13237
+ var getSortOrderTabIndex = function getSortOrderTabIndex(node, isScope) {
13238
+ var tabIndex = getTabIndex(node);
13239
+ if (tabIndex < 0 && isScope && !hasTabIndex(node)) {
13240
+ return 0;
13241
+ }
13242
+ return tabIndex;
13243
+ };
12996
13244
  var sortOrderedTabbables = function sortOrderedTabbables(a, b) {
12997
13245
  return a.tabIndex === b.tabIndex ? a.documentOrder - b.documentOrder : a.tabIndex - b.tabIndex;
12998
13246
  };
@@ -13235,7 +13483,7 @@ var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(o
13235
13483
  return true;
13236
13484
  };
13237
13485
  var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
13238
- if (isNonTabbableRadio(node) || getTabindex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
13486
+ if (isNonTabbableRadio(node) || getTabIndex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
13239
13487
  return false;
13240
13488
  }
13241
13489
  return true;
@@ -13260,7 +13508,7 @@ var sortByOrder = function sortByOrder(candidates) {
13260
13508
  candidates.forEach(function (item, i) {
13261
13509
  var isScope = !!item.scopeParent;
13262
13510
  var element = isScope ? item.scopeParent : item;
13263
- var candidateTabindex = getTabindex(element, isScope);
13511
+ var candidateTabindex = getSortOrderTabIndex(element, isScope);
13264
13512
  var elements = isScope ? sortByOrder(item.candidates) : element;
13265
13513
  if (candidateTabindex === 0) {
13266
13514
  isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
@@ -13279,32 +13527,32 @@ var sortByOrder = function sortByOrder(candidates) {
13279
13527
  return acc;
13280
13528
  }, []).concat(regularTabbables);
13281
13529
  };
13282
- var tabbable = function tabbable(el, options) {
13530
+ var tabbable = function tabbable(container, options) {
13283
13531
  options = options || {};
13284
13532
  var candidates;
13285
13533
  if (options.getShadowRoot) {
13286
- candidates = getCandidatesIteratively([el], options.includeContainer, {
13534
+ candidates = getCandidatesIteratively([container], options.includeContainer, {
13287
13535
  filter: isNodeMatchingSelectorTabbable.bind(null, options),
13288
13536
  flatten: false,
13289
13537
  getShadowRoot: options.getShadowRoot,
13290
13538
  shadowRootFilter: isValidShadowRootTabbable
13291
13539
  });
13292
13540
  } else {
13293
- candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
13541
+ candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
13294
13542
  }
13295
13543
  return sortByOrder(candidates);
13296
13544
  };
13297
- var focusable = function focusable(el, options) {
13545
+ var focusable = function focusable(container, options) {
13298
13546
  options = options || {};
13299
13547
  var candidates;
13300
13548
  if (options.getShadowRoot) {
13301
- candidates = getCandidatesIteratively([el], options.includeContainer, {
13549
+ candidates = getCandidatesIteratively([container], options.includeContainer, {
13302
13550
  filter: isNodeMatchingSelectorFocusable.bind(null, options),
13303
13551
  flatten: true,
13304
13552
  getShadowRoot: options.getShadowRoot
13305
13553
  });
13306
13554
  } else {
13307
- candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
13555
+ candidates = getCandidates(container, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
13308
13556
  }
13309
13557
  return candidates;
13310
13558
  };
@@ -13335,7 +13583,7 @@ var isFocusable = function isFocusable(node, options) {
13335
13583
 
13336
13584
  ;// CONCATENATED MODULE: ./node_modules/focus-trap/dist/focus-trap.esm.js
13337
13585
  /*!
13338
- * focus-trap 7.4.3
13586
+ * focus-trap 7.5.2
13339
13587
  * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
13340
13588
  */
13341
13589
 
@@ -13421,10 +13669,10 @@ var isSelectableInput = function isSelectableInput(node) {
13421
13669
  return node.tagName && node.tagName.toLowerCase() === 'input' && typeof node.select === 'function';
13422
13670
  };
13423
13671
  var isEscapeEvent = function isEscapeEvent(e) {
13424
- return e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27;
13672
+ return (e === null || e === void 0 ? void 0 : e.key) === 'Escape' || (e === null || e === void 0 ? void 0 : e.key) === 'Esc' || (e === null || e === void 0 ? void 0 : e.keyCode) === 27;
13425
13673
  };
13426
13674
  var isTabEvent = function isTabEvent(e) {
13427
- return e.key === 'Tab' || e.keyCode === 9;
13675
+ return (e === null || e === void 0 ? void 0 : e.key) === 'Tab' || (e === null || e === void 0 ? void 0 : e.keyCode) === 9;
13428
13676
  };
13429
13677
 
13430
13678
  // checks for TAB by default
@@ -13508,8 +13756,11 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13508
13756
  // container: HTMLElement,
13509
13757
  // tabbableNodes: Array<HTMLElement>, // empty if none
13510
13758
  // focusableNodes: Array<HTMLElement>, // empty if none
13511
- // firstTabbableNode: HTMLElement|null,
13512
- // lastTabbableNode: HTMLElement|null,
13759
+ // posTabIndexesFound: boolean,
13760
+ // firstTabbableNode: HTMLElement|undefined,
13761
+ // lastTabbableNode: HTMLElement|undefined,
13762
+ // firstDomTabbableNode: HTMLElement|undefined,
13763
+ // lastDomTabbableNode: HTMLElement|undefined,
13513
13764
  // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
13514
13765
  // }>}
13515
13766
  containerGroups: [],
@@ -13526,7 +13777,9 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13526
13777
  paused: false,
13527
13778
  // timer ID for when delayInitialFocus is true and initial focus in this trap
13528
13779
  // has been delayed during activation
13529
- delayInitialFocusTimer: undefined
13780
+ delayInitialFocusTimer: undefined,
13781
+ // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any
13782
+ recentNavEvent: undefined
13530
13783
  };
13531
13784
  var trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later
13532
13785
 
@@ -13545,7 +13798,9 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13545
13798
  /**
13546
13799
  * Finds the index of the container that contains the element.
13547
13800
  * @param {HTMLElement} element
13548
- * @param {Event} [event]
13801
+ * @param {Event} [event] If available, and `element` isn't directly found in any container,
13802
+ * the event's composed path is used to see if includes any known trap containers in the
13803
+ * case where the element is inside a Shadow DOM.
13549
13804
  * @returns {number} Index of the container in either `state.containers` or
13550
13805
  * `state.containerGroups` (the order/length of these lists are the same); -1
13551
13806
  * if the element isn't found.
@@ -13640,14 +13895,41 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13640
13895
  var tabbableNodes = tabbable(container, config.tabbableOptions);
13641
13896
 
13642
13897
  // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes
13643
- // are a superset of tabbable nodes
13898
+ // are a superset of tabbable nodes since nodes with negative `tabindex` attributes
13899
+ // are focusable but not tabbable
13644
13900
  var focusableNodes = focusable(container, config.tabbableOptions);
13901
+ var firstTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[0] : undefined;
13902
+ var lastTabbableNode = tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : undefined;
13903
+ var firstDomTabbableNode = focusableNodes.find(function (node) {
13904
+ return isTabbable(node);
13905
+ });
13906
+ var lastDomTabbableNode = focusableNodes.slice().reverse().find(function (node) {
13907
+ return isTabbable(node);
13908
+ });
13909
+ var posTabIndexesFound = !!tabbableNodes.find(function (node) {
13910
+ return getTabIndex(node) > 0;
13911
+ });
13645
13912
  return {
13646
13913
  container: container,
13647
13914
  tabbableNodes: tabbableNodes,
13648
13915
  focusableNodes: focusableNodes,
13649
- firstTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[0] : null,
13650
- lastTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : null,
13916
+ /** True if at least one node with positive `tabindex` was found in this container. */
13917
+ posTabIndexesFound: posTabIndexesFound,
13918
+ /** First tabbable node in container, __tabindex__ order; `undefined` if none. */
13919
+ firstTabbableNode: firstTabbableNode,
13920
+ /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */
13921
+ lastTabbableNode: lastTabbableNode,
13922
+ // NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out
13923
+ // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
13924
+ // because that API doesn't work with Shadow DOM as well as it should (@see
13925
+ // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,
13926
+ // to address an edge case related to positive tabindex support, this seems like a much easier,
13927
+ // "close enough most of the time" alternative for positive tabindexes which should generally
13928
+ // be avoided anyway...
13929
+ /** First tabbable node in container, __DOM__ order; `undefined` if none. */
13930
+ firstDomTabbableNode: firstDomTabbableNode,
13931
+ /** Last tabbable node in container, __DOM__ order; `undefined` if none. */
13932
+ lastDomTabbableNode: lastDomTabbableNode,
13651
13933
  /**
13652
13934
  * Finds the __tabbable__ node that follows the given node in the specified direction,
13653
13935
  * in this container, if any.
@@ -13658,30 +13940,24 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13658
13940
  */
13659
13941
  nextTabbableNode: function nextTabbableNode(node) {
13660
13942
  var forward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
13661
- // NOTE: If tabindex is positive (in order to manipulate the tab order separate
13662
- // from the DOM order), this __will not work__ because the list of focusableNodes,
13663
- // while it contains tabbable nodes, does not sort its nodes in any order other
13664
- // than DOM order, because it can't: Where would you place focusable (but not
13665
- // tabbable) nodes in that order? They have no order, because they aren't tabbale...
13666
- // Support for positive tabindex is already broken and hard to manage (possibly
13667
- // not supportable, TBD), so this isn't going to make things worse than they
13668
- // already are, and at least makes things better for the majority of cases where
13669
- // tabindex is either 0/unset or negative.
13670
- // FYI, positive tabindex issue: https://github.com/focus-trap/focus-trap/issues/375
13671
- var nodeIdx = focusableNodes.findIndex(function (n) {
13672
- return n === node;
13673
- });
13943
+ var nodeIdx = tabbableNodes.indexOf(node);
13674
13944
  if (nodeIdx < 0) {
13675
- return undefined;
13676
- }
13677
- if (forward) {
13678
- return focusableNodes.slice(nodeIdx + 1).find(function (n) {
13679
- return isTabbable(n, config.tabbableOptions);
13945
+ // either not tabbable nor focusable, or was focused but not tabbable (negative tabindex):
13946
+ // since `node` should at least have been focusable, we assume that's the case and mimic
13947
+ // what browsers do, which is set focus to the next node in __document position order__,
13948
+ // regardless of positive tabindexes, if any -- and for reasons explained in the NOTE
13949
+ // above related to `firstDomTabbable` and `lastDomTabbable` properties, we fall back to
13950
+ // basic DOM order
13951
+ if (forward) {
13952
+ return focusableNodes.slice(focusableNodes.indexOf(node) + 1).find(function (el) {
13953
+ return isTabbable(el);
13954
+ });
13955
+ }
13956
+ return focusableNodes.slice(0, focusableNodes.indexOf(node)).reverse().find(function (el) {
13957
+ return isTabbable(el);
13680
13958
  });
13681
13959
  }
13682
- return focusableNodes.slice(0, nodeIdx).reverse().find(function (n) {
13683
- return isTabbable(n, config.tabbableOptions);
13684
- });
13960
+ return tabbableNodes[nodeIdx + (forward ? 1 : -1)];
13685
13961
  }
13686
13962
  };
13687
13963
  });
@@ -13694,6 +13970,19 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13694
13970
  ) {
13695
13971
  throw new Error('Your focus-trap must have at least one container with at least one tabbable node in it at all times');
13696
13972
  }
13973
+
13974
+ // NOTE: Positive tabindexes are only properly supported in single-container traps because
13975
+ // doing it across multiple containers where tabindexes could be all over the place
13976
+ // would require Tabbable to support multiple containers, would require additional
13977
+ // specialized Shadow DOM support, and would require Tabbable's multi-container support
13978
+ // to look at those containers in document position order rather than user-provided
13979
+ // order (as they are treated in Focus-trap, for legacy reasons). See discussion on
13980
+ // https://github.com/focus-trap/focus-trap/issues/375 for more details.
13981
+ if (state.containerGroups.find(function (g) {
13982
+ return g.posTabIndexesFound;
13983
+ }) && state.containerGroups.length > 1) {
13984
+ throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.");
13985
+ }
13697
13986
  };
13698
13987
  var tryFocus = function tryFocus(node) {
13699
13988
  if (node === false) {
@@ -13709,6 +13998,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13709
13998
  node.focus({
13710
13999
  preventScroll: !!config.preventScroll
13711
14000
  });
14001
+ // NOTE: focus() API does not trigger focusIn event so set MRU node manually
13712
14002
  state.mostRecentlyFocusedNode = node;
13713
14003
  if (isSelectableInput(node)) {
13714
14004
  node.select();
@@ -13719,64 +14009,23 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13719
14009
  return node ? node : node === false ? false : previousActiveElement;
13720
14010
  };
13721
14011
 
13722
- // This needs to be done on mousedown and touchstart instead of click
13723
- // so that it precedes the focus event.
13724
- var checkPointerDown = function checkPointerDown(e) {
13725
- var target = getActualTarget(e);
13726
- if (findContainerIndex(target, e) >= 0) {
13727
- // allow the click since it ocurred inside the trap
13728
- return;
13729
- }
13730
- if (valueOrHandler(config.clickOutsideDeactivates, e)) {
13731
- // immediately deactivate the trap
13732
- trap.deactivate({
13733
- // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
13734
- // which will result in the outside click setting focus to the node
13735
- // that was clicked (and if not focusable, to "nothing"); by setting
13736
- // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
13737
- // on activation (or the configured `setReturnFocus` node), whether the
13738
- // outside click was on a focusable node or not
13739
- returnFocus: config.returnFocusOnDeactivate
13740
- });
13741
- return;
13742
- }
13743
-
13744
- // This is needed for mobile devices.
13745
- // (If we'll only let `click` events through,
13746
- // then on mobile they will be blocked anyways if `touchstart` is blocked.)
13747
- if (valueOrHandler(config.allowOutsideClick, e)) {
13748
- // allow the click outside the trap to take place
13749
- return;
13750
- }
13751
-
13752
- // otherwise, prevent the click
13753
- e.preventDefault();
13754
- };
13755
-
13756
- // In case focus escapes the trap for some strange reason, pull it back in.
13757
- var checkFocusIn = function checkFocusIn(e) {
13758
- var target = getActualTarget(e);
13759
- var targetContained = findContainerIndex(target, e) >= 0;
13760
-
13761
- // In Firefox when you Tab out of an iframe the Document is briefly focused.
13762
- if (targetContained || target instanceof Document) {
13763
- if (targetContained) {
13764
- state.mostRecentlyFocusedNode = target;
13765
- }
13766
- } else {
13767
- // escaped! pull it back in to where it just left
13768
- e.stopImmediatePropagation();
13769
- tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
13770
- }
13771
- };
13772
-
13773
- // Hijack key nav events on the first and last focusable nodes of the trap,
13774
- // in order to prevent focus from escaping. If it escapes for even a
13775
- // moment it can end up scrolling the page and causing confusion so we
13776
- // kind of need to capture the action at the keydown phase.
13777
- var checkKeyNav = function checkKeyNav(event) {
13778
- var isBackward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
13779
- var target = getActualTarget(event);
14012
+ /**
14013
+ * Finds the next node (in either direction) where focus should move according to a
14014
+ * keyboard focus-in event.
14015
+ * @param {Object} params
14016
+ * @param {Node} [params.target] Known target __from which__ to navigate, if any.
14017
+ * @param {KeyboardEvent|FocusEvent} [params.event] Event to use if `target` isn't known (event
14018
+ * will be used to determine the `target`). Ignored if `target` is specified.
14019
+ * @param {boolean} [params.isBackward] True if focus should move backward.
14020
+ * @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be
14021
+ * determined given the current state of the trap.
14022
+ */
14023
+ var findNextNavNode = function findNextNavNode(_ref2) {
14024
+ var target = _ref2.target,
14025
+ event = _ref2.event,
14026
+ _ref2$isBackward = _ref2.isBackward,
14027
+ isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward;
14028
+ target = target || getActualTarget(event);
13780
14029
  updateTabbableNodes();
13781
14030
  var destinationNode = null;
13782
14031
  if (state.tabbableGroups.length > 0) {
@@ -13799,8 +14048,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13799
14048
  // REVERSE
13800
14049
 
13801
14050
  // is the target the first tabbable node in a group?
13802
- var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref2) {
13803
- var firstTabbableNode = _ref2.firstTabbableNode;
14051
+ var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
14052
+ var firstTabbableNode = _ref3.firstTabbableNode;
13804
14053
  return target === firstTabbableNode;
13805
14054
  });
13806
14055
  if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
@@ -13818,7 +14067,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13818
14067
  // the LAST group if it's the first tabbable node of the FIRST group)
13819
14068
  var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
13820
14069
  var destinationGroup = state.tabbableGroups[destinationGroupIndex];
13821
- destinationNode = destinationGroup.lastTabbableNode;
14070
+ destinationNode = getTabIndex(target) >= 0 ? destinationGroup.lastTabbableNode : destinationGroup.lastDomTabbableNode;
13822
14071
  } else if (!isTabEvent(event)) {
13823
14072
  // user must have customized the nav keys so we have to move focus manually _within_
13824
14073
  // the active group: do this based on the order determined by tabbable()
@@ -13828,8 +14077,8 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13828
14077
  // FORWARD
13829
14078
 
13830
14079
  // is the target the last tabbable node in a group?
13831
- var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
13832
- var lastTabbableNode = _ref3.lastTabbableNode;
14080
+ var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref4) {
14081
+ var lastTabbableNode = _ref4.lastTabbableNode;
13833
14082
  return target === lastTabbableNode;
13834
14083
  });
13835
14084
  if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
@@ -13847,7 +14096,7 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13847
14096
  // group if it's the last tabbable node of the LAST group)
13848
14097
  var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
13849
14098
  var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
13850
- destinationNode = _destinationGroup.firstTabbableNode;
14099
+ destinationNode = getTabIndex(target) >= 0 ? _destinationGroup.firstTabbableNode : _destinationGroup.firstDomTabbableNode;
13851
14100
  } else if (!isTabEvent(event)) {
13852
14101
  // user must have customized the nav keys so we have to move focus manually _within_
13853
14102
  // the active group: do this based on the order determined by tabbable()
@@ -13859,6 +14108,153 @@ var createFocusTrap = function createFocusTrap(elements, userOptions) {
13859
14108
  // NOTE: the fallbackFocus option does not support returning false to opt-out
13860
14109
  destinationNode = getNodeForOption('fallbackFocus');
13861
14110
  }
14111
+ return destinationNode;
14112
+ };
14113
+
14114
+ // This needs to be done on mousedown and touchstart instead of click
14115
+ // so that it precedes the focus event.
14116
+ var checkPointerDown = function checkPointerDown(e) {
14117
+ var target = getActualTarget(e);
14118
+ if (findContainerIndex(target, e) >= 0) {
14119
+ // allow the click since it ocurred inside the trap
14120
+ return;
14121
+ }
14122
+ if (valueOrHandler(config.clickOutsideDeactivates, e)) {
14123
+ // immediately deactivate the trap
14124
+ trap.deactivate({
14125
+ // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
14126
+ // which will result in the outside click setting focus to the node
14127
+ // that was clicked (and if not focusable, to "nothing"); by setting
14128
+ // `returnFocus: true`, we'll attempt to re-focus the node originally-focused
14129
+ // on activation (or the configured `setReturnFocus` node), whether the
14130
+ // outside click was on a focusable node or not
14131
+ returnFocus: config.returnFocusOnDeactivate
14132
+ });
14133
+ return;
14134
+ }
14135
+
14136
+ // This is needed for mobile devices.
14137
+ // (If we'll only let `click` events through,
14138
+ // then on mobile they will be blocked anyways if `touchstart` is blocked.)
14139
+ if (valueOrHandler(config.allowOutsideClick, e)) {
14140
+ // allow the click outside the trap to take place
14141
+ return;
14142
+ }
14143
+
14144
+ // otherwise, prevent the click
14145
+ e.preventDefault();
14146
+ };
14147
+
14148
+ // In case focus escapes the trap for some strange reason, pull it back in.
14149
+ // NOTE: the focusIn event is NOT cancelable, so if focus escapes, it may cause unexpected
14150
+ // scrolling if the node that got focused was out of view; there's nothing we can do to
14151
+ // prevent that from happening by the time we discover that focus escaped
14152
+ var checkFocusIn = function checkFocusIn(event) {
14153
+ var target = getActualTarget(event);
14154
+ var targetContained = findContainerIndex(target, event) >= 0;
14155
+
14156
+ // In Firefox when you Tab out of an iframe the Document is briefly focused.
14157
+ if (targetContained || target instanceof Document) {
14158
+ if (targetContained) {
14159
+ state.mostRecentlyFocusedNode = target;
14160
+ }
14161
+ } else {
14162
+ // escaped! pull it back in to where it just left
14163
+ event.stopImmediatePropagation();
14164
+
14165
+ // focus will escape if the MRU node had a positive tab index and user tried to nav forward;
14166
+ // it will also escape if the MRU node had a 0 tab index and user tried to nav backward
14167
+ // toward a node with a positive tab index
14168
+ var nextNode; // next node to focus, if we find one
14169
+ var navAcrossContainers = true;
14170
+ if (state.mostRecentlyFocusedNode) {
14171
+ if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {
14172
+ // MRU container index must be >=0 otherwise we wouldn't have it as an MRU node...
14173
+ var mruContainerIdx = findContainerIndex(state.mostRecentlyFocusedNode);
14174
+ // there MAY not be any tabbable nodes in the container if there are at least 2 containers
14175
+ // and the MRU node is focusable but not tabbable (focus-trap requires at least 1 container
14176
+ // with at least one tabbable node in order to function, so this could be the other container
14177
+ // with nothing tabbable in it)
14178
+ var tabbableNodes = state.containerGroups[mruContainerIdx].tabbableNodes;
14179
+ if (tabbableNodes.length > 0) {
14180
+ // MRU tab index MAY not be found if the MRU node is focusable but not tabbable
14181
+ var mruTabIdx = tabbableNodes.findIndex(function (node) {
14182
+ return node === state.mostRecentlyFocusedNode;
14183
+ });
14184
+ if (mruTabIdx >= 0) {
14185
+ if (config.isKeyForward(state.recentNavEvent)) {
14186
+ if (mruTabIdx + 1 < tabbableNodes.length) {
14187
+ nextNode = tabbableNodes[mruTabIdx + 1];
14188
+ navAcrossContainers = false;
14189
+ }
14190
+ // else, don't wrap within the container as focus should move to next/previous
14191
+ // container
14192
+ } else {
14193
+ if (mruTabIdx - 1 >= 0) {
14194
+ nextNode = tabbableNodes[mruTabIdx - 1];
14195
+ navAcrossContainers = false;
14196
+ }
14197
+ // else, don't wrap within the container as focus should move to next/previous
14198
+ // container
14199
+ }
14200
+ // else, don't find in container order without considering direction too
14201
+ }
14202
+ }
14203
+ // else, no tabbable nodes in that container (which means we must have at least one other
14204
+ // container with at least one tabbable node in it, otherwise focus-trap would've thrown
14205
+ // an error the last time updateTabbableNodes() was run): find next node among all known
14206
+ // containers
14207
+ } else {
14208
+ // check to see if there's at least one tabbable node with a positive tab index inside
14209
+ // the trap because focus seems to escape when navigating backward from a tabbable node
14210
+ // with tabindex=0 when this is the case (instead of wrapping to the tabbable node with
14211
+ // the greatest positive tab index like it should)
14212
+ if (!state.containerGroups.some(function (g) {
14213
+ return g.tabbableNodes.some(function (n) {
14214
+ return getTabIndex(n) > 0;
14215
+ });
14216
+ })) {
14217
+ // no containers with tabbable nodes with positive tab indexes which means the focus
14218
+ // escaped for some other reason and we should just execute the fallback to the
14219
+ // MRU node or initial focus node, if any
14220
+ navAcrossContainers = false;
14221
+ }
14222
+ }
14223
+ } else {
14224
+ // no MRU node means we're likely in some initial condition when the trap has just
14225
+ // been activated and initial focus hasn't been given yet, in which case we should
14226
+ // fall through to trying to focus the initial focus node, which is what should
14227
+ // happen below at this point in the logic
14228
+ navAcrossContainers = false;
14229
+ }
14230
+ if (navAcrossContainers) {
14231
+ nextNode = findNextNavNode({
14232
+ // move FROM the MRU node, not event-related node (which will be the node that is
14233
+ // outside the trap causing the focus escape we're trying to fix)
14234
+ target: state.mostRecentlyFocusedNode,
14235
+ isBackward: config.isKeyBackward(state.recentNavEvent)
14236
+ });
14237
+ }
14238
+ if (nextNode) {
14239
+ tryFocus(nextNode);
14240
+ } else {
14241
+ tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());
14242
+ }
14243
+ }
14244
+ state.recentNavEvent = undefined; // clear
14245
+ };
14246
+
14247
+ // Hijack key nav events on the first and last focusable nodes of the trap,
14248
+ // in order to prevent focus from escaping. If it escapes for even a
14249
+ // moment it can end up scrolling the page and causing confusion so we
14250
+ // kind of need to capture the action at the keydown phase.
14251
+ var checkKeyNav = function checkKeyNav(event) {
14252
+ var isBackward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
14253
+ state.recentNavEvent = event;
14254
+ var destinationNode = findNextNavNode({
14255
+ event: event,
14256
+ isBackward: isBackward
14257
+ });
13862
14258
  if (destinationNode) {
13863
14259
  if (isTabEvent(event)) {
13864
14260
  // since tab natively moves focus, we wouldn't have a destination node unless we
@@ -14749,7 +15145,7 @@ const SeamlyActivityMonitor = ({ children }) => {
14749
15145
  // It is important to use keyUp here as focus may be set from outside the
14750
15146
  // chat container via keyboard. In this case the keyDown handler would not
14751
15147
  // be fired inside the container on the initial focus event.
14752
- return ((0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('activity-monitor'), tabIndex: -1, onMouseDown: onActivityHandler, onKeyUp: onActivityHandler, onTouchStart: onActivityHandler, onMouseMove: onActivityHandler, onWheel: onActivityHandler, onPointerDown: onActivityHandler, onPointerMove: onActivityHandler }, { children: (0,jsx_runtime_.jsx)(seamly_activity_event_context/* default */.Z.Provider, Object.assign({ value: onActivityHandler }, { children: children })) })));
15148
+ return ((0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('activity-monitor'), tabIndex: -1, onMouseDown: onActivityHandler, onKeyUp: onActivityHandler, onTouchStart: onActivityHandler, onMouseMove: onActivityHandler, onWheel: onActivityHandler, onPointerDown: onActivityHandler, onPointerMove: onActivityHandler, children: (0,jsx_runtime_.jsx)(seamly_activity_event_context/* default */.Z.Provider, { value: onActivityHandler, children: children }) }));
14753
15149
  };
14754
15150
  /* harmony default export */ const seamly_activity_monitor = (SeamlyActivityMonitor);
14755
15151
 
@@ -14759,8 +15155,39 @@ var seamly_api_context = __webpack_require__(2871);
14759
15155
  var seamly_offline_error = __webpack_require__(3243);
14760
15156
  // EXTERNAL MODULE: ./src/javascripts/domains/interrupt/slice.ts
14761
15157
  var interrupt_slice = __webpack_require__(6160);
15158
+ // EXTERNAL MODULE: ./src/javascripts/domains/store/index.ts + 4 modules
15159
+ var domains_store = __webpack_require__(7271);
15160
+ // EXTERNAL MODULE: ./src/javascripts/domains/store/actions.ts
15161
+ var actions = __webpack_require__(2770);
14762
15162
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/core/seamly-event-subscriber.ts
14763
- var __rest = undefined && undefined.__rest || function (s, e) {
15163
+ var seamly_event_subscriber_awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) {
15164
+ function adopt(value) {
15165
+ return value instanceof P ? value : new P(function (resolve) {
15166
+ resolve(value);
15167
+ });
15168
+ }
15169
+ return new (P || (P = Promise))(function (resolve, reject) {
15170
+ function fulfilled(value) {
15171
+ try {
15172
+ step(generator.next(value));
15173
+ } catch (e) {
15174
+ reject(e);
15175
+ }
15176
+ }
15177
+ function rejected(value) {
15178
+ try {
15179
+ step(generator["throw"](value));
15180
+ } catch (e) {
15181
+ reject(e);
15182
+ }
15183
+ }
15184
+ function step(result) {
15185
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
15186
+ }
15187
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15188
+ });
15189
+ };
15190
+ var seamly_event_subscriber_rest = undefined && undefined.__rest || function (s, e) {
14764
15191
  var t = {};
14765
15192
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
14766
15193
  if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
@@ -14780,13 +15207,13 @@ var __rest = undefined && undefined.__rest || function (s, e) {
14780
15207
 
14781
15208
 
14782
15209
 
15210
+
14783
15211
  const EMITTABLE_MESSAGE_TYPES = ['text', 'choice_prompt', 'image', 'video'];
14784
15212
  const SeamlyEventSubscriber = () => {
14785
15213
  const api = (0,seamly_hooks/* useSeamlyApiContext */.jM)();
14786
15214
  const syncChannelRef = (0,hooks_.useRef)();
14787
15215
  const messageChannelRef = (0,hooks_.useRef)();
14788
- const dispatch = (0,es/* useDispatch */.I0)();
14789
- const events = (0,seamly_hooks/* useEvents */.hI)();
15216
+ const dispatch = (0,domains_store/* useAppDispatch */.T)();
14790
15217
  const eventBus = (0,hooks_.useContext)(seamly_api_context/* SeamlyEventBusContext */.T);
14791
15218
  const prevEmittedEventId = (0,hooks_.useRef)(null);
14792
15219
  const {
@@ -14934,7 +15361,7 @@ const SeamlyEventSubscriber = () => {
14934
15361
  const {
14935
15362
  serviceSettings
14936
15363
  } = payload,
14937
- eventPayload = __rest(payload, ["serviceSettings"]);
15364
+ eventPayload = seamly_event_subscriber_rest(payload, ["serviceSettings"]);
14938
15365
  const {
14939
15366
  entry,
14940
15367
  proactiveMessages
@@ -15031,31 +15458,19 @@ const SeamlyEventSubscriber = () => {
15031
15458
  if (syncChannelRef.current) {
15032
15459
  (_a = api.conversation.channel) === null || _a === void 0 ? void 0 : _a.off('sync', syncChannelRef.current);
15033
15460
  }
15034
- syncChannelRef.current = api.conversation.channel.on('sync', payload => {
15035
- var _a;
15036
- const lastEvent = events[events.length - 1];
15037
- const payloadLastEventId = (_a = payload === null || payload === void 0 ? void 0 : payload.lastEvent) === null || _a === void 0 ? void 0 : _a.id;
15038
- if (lastEvent && payloadLastEventId === lastEvent.payload.id) {
15039
- return payload;
15040
- }
15041
- return api.getConversation().then(history => {
15461
+ syncChannelRef.current = api.conversation.channel.on('sync', payload => seamly_event_subscriber_awaiter(void 0, void 0, void 0, function* () {
15462
+ try {
15463
+ const history = yield dispatch((0,actions/* getConversation */.c)(payload)).unwrap();
15042
15464
  if (!history) return;
15043
15465
  dispatch((0,store_slice/* setHistory */.JB)(history));
15044
- }).catch(error => {
15045
- dispatch((0,interrupt_slice/* setInterrupt */.uc)({
15046
- name: error === null || error === void 0 ? void 0 : error.name,
15047
- message: error === null || error === void 0 ? void 0 : error.message,
15048
- langKey: error === null || error === void 0 ? void 0 : error.langKey,
15049
- action: error === null || error === void 0 ? void 0 : error.action,
15050
- originalEvent: error === null || error === void 0 ? void 0 : error.originalEvent,
15051
- originalError: error === null || error === void 0 ? void 0 : error.originalError
15052
- }));
15053
- });
15054
- });
15466
+ } catch (_e) {
15467
+ // nothing to do, the error is handled in the thunk
15468
+ }
15469
+ }));
15055
15470
  return true;
15056
15471
  });
15057
15472
  }
15058
- }, [api, api.connectionInfo, api.conversation.channel, events, dispatch]);
15473
+ }, [api, api.connectionInfo, api.conversation.channel, dispatch]);
15059
15474
  return null;
15060
15475
  };
15061
15476
  /* harmony default export */ const seamly_event_subscriber = (SeamlyEventSubscriber);
@@ -15164,7 +15579,7 @@ const SeamlyFileUpload = ({ children }) => {
15164
15579
  uploadHandle,
15165
15580
  }));
15166
15581
  }, [addImageToSessionStorage, addUploadBubble, api, dispatch, t]);
15167
- return ((0,jsx_runtime_.jsx)(seamly_file_upload_context/* default */.Z.Provider, Object.assign({ value: onUploadFileHandler }, { children: children })));
15582
+ return ((0,jsx_runtime_.jsx)(seamly_file_upload_context/* default */.Z.Provider, { value: onUploadFileHandler, children: children }));
15168
15583
  };
15169
15584
  /* harmony default export */ const seamly_file_upload = (SeamlyFileUpload);
15170
15585
 
@@ -15565,7 +15980,7 @@ const SeamlyCore = ({ store, children, eventBus, api }) => {
15565
15980
  (0,hooks_.useErrorBoundary)((error) => {
15566
15981
  store.dispatch((0,errors/* catchError */.K)(error));
15567
15982
  });
15568
- return ((0,jsx_runtime_.jsx)(es/* Provider */.zt, Object.assign({ store: store }, { children: (0,jsx_runtime_.jsx)(seamly_api_context/* SeamlyEventBusContext */.T.Provider, Object.assign({ value: eventBus }, { children: (0,jsx_runtime_.jsx)(seamly_api_context/* SeamlyApiContext */.a.Provider, Object.assign({ value: api }, { children: (0,jsx_runtime_.jsx)(seamly_live_region, { children: (0,jsx_runtime_.jsx)(seamly_chat, { children: (0,jsx_runtime_.jsxs)(component_filter, { children: [(0,jsx_runtime_.jsx)(seamly_initializer, {}), (0,jsx_runtime_.jsx)(seamly_event_subscriber, {}), (0,jsx_runtime_.jsx)(seamly_read_state, {}), (0,jsx_runtime_.jsx)(seamly_new_notifications, {}), (0,jsx_runtime_.jsx)(seamly_idle_detach_counter, {}), (0,jsx_runtime_.jsxs)(seamly_activity_monitor, { children: [(0,jsx_runtime_.jsx)(seamly_instance_functions_loader, {}), (0,jsx_runtime_.jsx)(seamly_file_upload, { children: children })] })] }) }) }) })) })) })));
15983
+ return ((0,jsx_runtime_.jsx)(es/* Provider */.zt, { store: store, children: (0,jsx_runtime_.jsx)(seamly_api_context/* SeamlyEventBusContext */.T.Provider, { value: eventBus, children: (0,jsx_runtime_.jsx)(seamly_api_context/* SeamlyApiContext */.a.Provider, { value: api, children: (0,jsx_runtime_.jsx)(seamly_live_region, { children: (0,jsx_runtime_.jsx)(seamly_chat, { children: (0,jsx_runtime_.jsxs)(component_filter, { children: [(0,jsx_runtime_.jsx)(seamly_initializer, {}), (0,jsx_runtime_.jsx)(seamly_event_subscriber, {}), (0,jsx_runtime_.jsx)(seamly_read_state, {}), (0,jsx_runtime_.jsx)(seamly_new_notifications, {}), (0,jsx_runtime_.jsx)(seamly_idle_detach_counter, {}), (0,jsx_runtime_.jsxs)(seamly_activity_monitor, { children: [(0,jsx_runtime_.jsx)(seamly_instance_functions_loader, {}), (0,jsx_runtime_.jsx)(seamly_file_upload, { children: children })] })] }) }) }) }) }) }));
15569
15984
  };
15570
15985
  /* harmony default export */ const seamly_core = (SeamlyCore);
15571
15986
 
@@ -15624,9 +16039,9 @@ var reselect_es = __webpack_require__(573);
15624
16039
  const getState = ({
15625
16040
  forms
15626
16041
  }) => forms;
15627
- const getFormById = (0,reselect_es/* createSelector */.P1)(getState, (_, {
16042
+ const getFormById = (0,reselect_es/* createSelector */.P1)([getState, (_, {
15628
16043
  formId
15629
- }) => formId, (forms, formId) => forms[formId]);
16044
+ }) => formId], (forms, formId) => forms[formId]);
15630
16045
  const getFormControlsByFormId = (0,reselect_es/* createSelector */.P1)(getFormById, form => (form === null || form === void 0 ? void 0 : form.controls) || {});
15631
16046
  const getFormValuesByFormId = (0,reselect_es/* createSelector */.P1)(getFormControlsByFormId, controls => {
15632
16047
  const valuesObj = {};
@@ -15637,15 +16052,15 @@ const getFormValuesByFormId = (0,reselect_es/* createSelector */.P1)(getFormCont
15637
16052
  });
15638
16053
  return valuesObj;
15639
16054
  });
15640
- const getControlValueByName = (0,reselect_es/* createSelector */.P1)(getFormControlsByFormId, (_, {
16055
+ const getControlValueByName = (0,reselect_es/* createSelector */.P1)([getFormControlsByFormId, (_, {
15641
16056
  name
15642
- }) => name, (controls, name) => {
16057
+ }) => name], (controls, name) => {
15643
16058
  var _a;
15644
16059
  return (_a = controls[name]) === null || _a === void 0 ? void 0 : _a.value;
15645
16060
  });
15646
- const getControlTouchedByName = (0,reselect_es/* createSelector */.P1)(getFormControlsByFormId, (_, {
16061
+ const getControlTouchedByName = (0,reselect_es/* createSelector */.P1)([getFormControlsByFormId, (_, {
15647
16062
  name
15648
- }) => name, (controls, name) => {
16063
+ }) => name], (controls, name) => {
15649
16064
  var _a;
15650
16065
  return (_a = controls[name]) === null || _a === void 0 ? void 0 : _a.touched;
15651
16066
  });
@@ -15842,7 +16257,7 @@ const useEntryTextTranslation = controlName => {
15842
16257
  text: (text === null || text === void 0 ? void 0 : text.label) || t('input.inputLabelText'),
15843
16258
  limit: !(text === null || text === void 0 ? void 0 : text.label) && hasCharacterLimit ? characterLimit : null
15844
16259
  }), [t, hasCharacterLimit, characterLimit, text === null || text === void 0 ? void 0 : text.label]);
15845
- const labelClass = (0,hooks_.useMemo)(() => (text === null || text === void 0 ? void 0 : text.label) ? 'input__label' : 'visually-hidden', [text === null || text === void 0 ? void 0 : text.label]);
16260
+ const labelClass = (0,hooks_.useMemo)(() => (text === null || text === void 0 ? void 0 : text.label) ? 'label' : 'visually-hidden', [text === null || text === void 0 ? void 0 : text.label]);
15846
16261
  return {
15847
16262
  placeholder,
15848
16263
  label,
@@ -15887,14 +16302,14 @@ function AbortTransactionButton() {
15887
16302
  });
15888
16303
  clearEntryAbortTransaction();
15889
16304
  };
15890
- return ((0,jsx_runtime_.jsx)("li", Object.assign({ className: (0,css/* className */.o)([
16305
+ return ((0,jsx_runtime_.jsx)("li", { className: (0,css/* className */.o)([
15891
16306
  'cvco-conversation__item',
15892
16307
  'cvco-conversation__item--abort-transaction',
15893
- ]) }, { children: (0,jsx_runtime_.jsx)("button", Object.assign({ className: (0,css/* className */.o)([
16308
+ ]), children: (0,jsx_runtime_.jsx)("button", { className: (0,css/* className */.o)([
15894
16309
  'button',
15895
16310
  'button--secondary',
15896
16311
  'abort-transaction__button',
15897
- ]), type: "button", onClick: handleAbortTransaction }, { children: abortTransaction.label })) })));
16312
+ ]), type: "button", onClick: handleAbortTransaction, children: abortTransaction.label }) }));
15898
16313
  }
15899
16314
 
15900
16315
  ;// CONCATENATED MODULE: external "preact/compat"
@@ -15969,7 +16384,7 @@ const Event = ({ event, newParticipant }) => {
15969
16384
  if (newParticipant) {
15970
16385
  classNames.push('conversation__item--new-participant');
15971
16386
  }
15972
- return ((0,jsx_runtime_.jsxs)("li", Object.assign({ className: (0,css/* className */.o)(classNames), ref: containerRef }, { children: [event.timeIndicator && (0,jsx_runtime_.jsx)(time_indicator, { event: event }), (0,jsx_runtime_.jsx)(Component, Object.assign({ event: event }, { children: (0,jsx_runtime_.jsx)(SubComponent, { event: event }) }))] })));
16387
+ return ((0,jsx_runtime_.jsxs)("li", { className: (0,css/* className */.o)(classNames), ref: containerRef, children: [event.timeIndicator && (0,jsx_runtime_.jsx)(time_indicator, { event: event }), (0,jsx_runtime_.jsx)(Component, { event: event, children: (0,jsx_runtime_.jsx)(SubComponent, { event: event }) })] }));
15973
16388
  };
15974
16389
  /* harmony default export */ const event_event = (Event);
15975
16390
 
@@ -16056,7 +16471,7 @@ const Conversation = () => {
16056
16471
  e.preventDefault();
16057
16472
  focusSkiplinkTarget();
16058
16473
  };
16059
- return ((0,jsx_runtime_.jsxs)(jsx_runtime_.Fragment, { children: [isOpen && ((0,jsx_runtime_.jsx)("a", Object.assign({ className: (0,css/* className */.o)('skip-link'), href: `#${skiplinkTargetId}`, onClick: onClickHandler }, { children: t('skiplinkText') }))), (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('chat__body') }, { children: (0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)('conversation__container') }, { children: [(0,jsx_runtime_.jsx)(privacy_disclaimer, {}), (0,jsx_runtime_.jsxs)("ol", Object.assign({ className: (0,css/* className */.o)('conversation') }, { children: [(0,jsx_runtime_.jsx)(component_filter, { children: (0,jsx_runtime_.jsx)(Events, {}) }), debouncedIsLoading ? (0,jsx_runtime_.jsx)(loader, {}) : null, (0,jsx_runtime_.jsx)(AbortTransactionButton, {})] }))] })) }))] }));
16474
+ return ((0,jsx_runtime_.jsxs)(jsx_runtime_.Fragment, { children: [isOpen && ((0,jsx_runtime_.jsx)("a", { className: (0,css/* className */.o)('skip-link'), href: `#${skiplinkTargetId}`, onClick: onClickHandler, children: t('skiplinkText') })), (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('chat__body'), children: (0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('conversation__container'), children: [(0,jsx_runtime_.jsx)(privacy_disclaimer, {}), (0,jsx_runtime_.jsxs)("ol", { className: (0,css/* className */.o)('conversation'), children: [(0,jsx_runtime_.jsx)(component_filter, { children: (0,jsx_runtime_.jsx)(Events, {}) }), debouncedIsLoading ? (0,jsx_runtime_.jsx)(loader, {}) : null, (0,jsx_runtime_.jsx)(AbortTransactionButton, {})] })] }) })] }));
16060
16475
  };
16061
16476
  /* harmony default export */ const conversation = (Conversation);
16062
16477
 
@@ -16459,16 +16874,16 @@ const OptionsFrame = ({ className: givenClassName, children, onCancel, headingTe
16459
16874
  (0,hooks_.useEffect)(() => {
16460
16875
  (0,general_utils/* focusElement */.C5)(container.current);
16461
16876
  }, [container]);
16462
- return ((0,jsx_runtime_.jsx)("section", Object.assign({ className: (0,css/* className */.o)('options', {
16877
+ return ((0,jsx_runtime_.jsx)("section", { className: (0,css/* className */.o)('options', {
16463
16878
  'options--right': position.horizontal === 'right',
16464
16879
  'options--left': position.horizontal === 'left',
16465
16880
  'options--top': position.vertical === 'top',
16466
16881
  'options--bottom': position.vertical === 'bottom',
16467
- }, givenClassName), "aria-labelledby": mainHeadingId, tabIndex: -1, ref: container }, { children: (0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)('options__body') }, { children: [(0,jsx_runtime_.jsx)("h2", Object.assign({ id: mainHeadingId, className: (0,css/* className */.o)('options__title') }, { children: headingText })), (0,jsx_runtime_.jsxs)("button", Object.assign({ type: "button", onClick: onCancelHandler, "aria-describedby": mainHeadingId, className: (0,css/* className */.o)('button', 'options__close'), ref: (btn) => {
16882
+ }, givenClassName), "aria-labelledby": mainHeadingId, tabIndex: -1, ref: container, children: (0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('options__body'), children: [(0,jsx_runtime_.jsx)("h2", { id: mainHeadingId, className: (0,css/* className */.o)('options__title'), children: headingText }), (0,jsx_runtime_.jsxs)("button", { type: "button", onClick: onCancelHandler, "aria-describedby": mainHeadingId, className: (0,css/* className */.o)('button', 'options__close'), ref: (btn) => {
16468
16883
  if (cancelButtonRef) {
16469
16884
  cancelButtonRef.current = btn;
16470
16885
  }
16471
- } }, { children: [(0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "close", size: "16", alt: "" }), (0,jsx_runtime_.jsx)("span", { children: cancelButtonText })] })), description ? ((0,jsx_runtime_.jsx)("p", Object.assign({ className: (0,css/* className */.o)('options__description'), id: descriptionId }, { children: description }))) : null, (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('options__wrapper') }, { children: children }))] })) })));
16886
+ }, children: [(0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "close", size: "16", alt: "" }), (0,jsx_runtime_.jsx)("span", { children: cancelButtonText })] }), description ? ((0,jsx_runtime_.jsx)("p", { className: (0,css/* className */.o)('options__description'), id: descriptionId, children: description })) : null, (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('options__wrapper'), children: children })] }) }));
16472
16887
  };
16473
16888
  /* harmony default export */ const options_frame = (OptionsFrame);
16474
16889
 
@@ -16605,7 +17020,7 @@ function FormProvider(_a) {
16605
17020
  console.error('"onSubmit" is required.');
16606
17021
  return null;
16607
17022
  }
16608
- return ((0,jsx_runtime_.jsx)(Provider, Object.assign({}, props, { value: contextValue }, { children: children })));
17023
+ return ((0,jsx_runtime_.jsx)(Provider, Object.assign({}, props, { value: contextValue, children: children })));
16609
17024
  }
16610
17025
 
16611
17026
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/form-controls/form.js
@@ -16671,8 +17086,8 @@ function error_Error({
16671
17086
 
16672
17087
 
16673
17088
 
16674
- const FormControlWrapper = ({ contentHint, id, labelText, labelClass = (0,css/* className */.o)('label'), validity, errorText, children, }) => {
16675
- return ((0,jsx_runtime_.jsxs)(jsx_runtime_.Fragment, { children: [contentHint && ((0,jsx_runtime_.jsx)("span", Object.assign({ id: `${id}-content-hint`, className: (0,css/* className */.o)('input__content-hint') }, { children: contentHint }))), (0,jsx_runtime_.jsx)(error_Error, { id: `${id}-error`, error: !validity && errorText }), (0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)('form-control__wrapper') }, { children: [(0,jsx_runtime_.jsx)("label", Object.assign({ htmlFor: id, className: labelClass }, { children: labelText })), children] }))] }));
17089
+ const FormControlWrapper = ({ contentHint, id, labelText, labelClass, validity, errorText, children, }) => {
17090
+ return ((0,jsx_runtime_.jsxs)(jsx_runtime_.Fragment, { children: [contentHint && ((0,jsx_runtime_.jsx)("span", { id: `${id}-content-hint`, className: (0,css/* className */.o)('input__content-hint'), children: contentHint })), (0,jsx_runtime_.jsx)(error_Error, { id: `${id}-error`, error: !validity && errorText }), (0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('form-control__wrapper'), children: [(0,jsx_runtime_.jsx)("label", { htmlFor: id, className: (0,css/* className */.o)(labelClass), children: labelText }), children] })] }));
16676
17091
  };
16677
17092
  /* harmony default export */ const wrapper = (FormControlWrapper);
16678
17093
 
@@ -16707,7 +17122,7 @@ function Input(_a) {
16707
17122
  describedByIds.push(`${id}-error`);
16708
17123
  }
16709
17124
  // todo: destructure Field
16710
- return ((0,jsx_runtime_.jsx)(wrapper, Object.assign({ id: id, contentHint: contentHint, validity: !hasError, errorText: error, labelText: labelText, labelClass: labelClass }, { children: (0,jsx_runtime_.jsx)("input", Object.assign({ id: id, name: name, type: type, "aria-invalid": hasError ? 'true' : 'false', "aria-describedby": describedByIds.join(' ') || null }, field, props)) })));
17125
+ return ((0,jsx_runtime_.jsx)(wrapper, { id: id, contentHint: contentHint, validity: !hasError, errorText: error, labelText: labelText, labelClass: labelClass, children: (0,jsx_runtime_.jsx)("input", Object.assign({ id: id, name: name, type: type, "aria-invalid": hasError ? 'true' : 'false', "aria-describedby": describedByIds.join(' ') || null }, field, props)) }));
16711
17126
  }
16712
17127
  /* harmony default export */ const input = (Input);
16713
17128
 
@@ -17055,14 +17470,14 @@ const OptionsButton = () => {
17055
17470
 
17056
17471
 
17057
17472
 
17058
- const TranslationOption = ({ label, checked, description, onChange, id, }) => {
17473
+ const TranslationOption = ({ label, checked, description, onChange, id, itemClassName, }) => {
17059
17474
  const onKeyDown = (e) => {
17060
17475
  if (e.code === 'Space' || e.code === 'Enter') {
17061
17476
  e.preventDefault();
17062
17477
  onChange();
17063
17478
  }
17064
17479
  };
17065
- return ((0,jsx_runtime_.jsxs)("li", Object.assign({ className: (0,css/* className */.o)('translation-options__item'), "aria-selected": checked, role: "option", tabIndex: 0, onClick: onChange, onKeyDown: onKeyDown, id: id }, { children: [(0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { alt: "", name: "check", size: "16" }), label, " ", description && (0,jsx_runtime_.jsxs)("span", { children: ["(", description, ")"] })] })));
17480
+ return ((0,jsx_runtime_.jsxs)("li", { className: (0,css/* className */.o)([itemClassName, 'translation-options__item']), "aria-selected": checked, role: "option", tabIndex: 0, onClick: onChange, onKeyDown: onKeyDown, id: id, children: [(0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { alt: "", name: "check", size: "16" }), label, " ", description && (0,jsx_runtime_.jsxs)("span", { children: ["(", description, ")"] })] }));
17066
17481
  };
17067
17482
  /* harmony default export */ const translation_option = (TranslationOption);
17068
17483
 
@@ -17074,12 +17489,13 @@ const TranslationOption = ({ label, checked, description, onChange, id, }) => {
17074
17489
 
17075
17490
 
17076
17491
 
17492
+ const isChecked = (language, currentLocale, isOriginal) => currentLocale === language.locale || (!currentLocale && isOriginal);
17077
17493
  const TranslationOptions = ({ onChange, describedById, }) => {
17078
17494
  const { context: { locale: defaultLocale }, } = (0,hooks/* useConfig */.ZR)();
17079
17495
  const { t } = (0,i18n_hooks/* useI18n */.Q)();
17080
17496
  const { focusContainer } = (0,translations_hooks/* useTranslationsContainer */.a5)();
17081
17497
  const { languages, currentLocale, enableTranslations, disableTranslations } = (0,translations_hooks/* useTranslations */.T_)();
17082
- const handleChange = ({ locale }) => () => {
17498
+ const handleChange = (locale) => () => {
17083
17499
  if (locale === currentLocale || defaultLocale === locale) {
17084
17500
  disableTranslations();
17085
17501
  }
@@ -17089,22 +17505,25 @@ const TranslationOptions = ({ onChange, describedById, }) => {
17089
17505
  onChange();
17090
17506
  focusContainer();
17091
17507
  };
17092
- const sortedLanguages = (0,hooks_.useMemo)(() => {
17093
- return [...languages].sort((a, b) => {
17094
- if (a.locale === defaultLocale)
17095
- return -1;
17096
- if (b.locale === defaultLocale)
17097
- return 1;
17098
- return a.nativeName.localeCompare(b.nativeName, undefined, {
17099
- sensitivity: 'base',
17100
- });
17101
- });
17102
- }, [languages, defaultLocale]);
17103
- return ((0,jsx_runtime_.jsx)("ul", Object.assign({ "aria-describedby": describedById, role: "listbox", tabIndex: -1, className: (0,css/* className */.o)('translation-options') }, { children: sortedLanguages.map((language, idx) => {
17104
- const isOriginal = idx === 0;
17105
- const checked = currentLocale === language.locale || (!currentLocale && isOriginal);
17106
- return ((0,jsx_runtime_.jsx)(translation_option, { id: language.locale, label: language.nativeName, checked: checked, description: isOriginal && t('translations.settings.original'), onChange: handleChange(language) }, language.locale));
17107
- }) })));
17508
+ const { primaryLanguages, remainingLanguages } = (0,compat_namespaceObject.useMemo)(() => languages.reduce((acc, language) => {
17509
+ const isOriginal = language.locale === defaultLocale;
17510
+ const checked = isChecked(language, currentLocale, isOriginal);
17511
+ if (language.locale !== defaultLocale) {
17512
+ acc.remainingLanguages.push(Object.assign(Object.assign({}, language), { checked, isOriginal }));
17513
+ }
17514
+ const selectedIdx = acc.remainingLanguages.findIndex((l) => l.locale === currentLocale);
17515
+ if (isOriginal || (checked && selectedIdx > 4)) {
17516
+ acc.primaryLanguages.push(Object.assign(Object.assign({}, language), { checked, isOriginal }));
17517
+ }
17518
+ return acc;
17519
+ }, {
17520
+ primaryLanguages: [],
17521
+ remainingLanguages: [],
17522
+ }), [currentLocale, defaultLocale, languages]);
17523
+ return ((0,jsx_runtime_.jsxs)("ul", { "aria-describedby": describedById, role: "listbox", tabIndex: -1, className: (0,css/* className */.o)('translation-options'), children: [primaryLanguages.map(({ locale, nativeName, checked, isOriginal }, idx) => ((0,jsx_runtime_.jsx)(translation_option, { id: locale, label: nativeName, checked: checked, description: isOriginal && t('translations.settings.original'), onChange: handleChange(locale), itemClassName: (0,css/* className */.o)({
17524
+ 'translation-options__item--original': isOriginal,
17525
+ 'translation-options__item--selected': checked && idx !== 0,
17526
+ }) }, locale))), remainingLanguages.map(({ locale, nativeName, checked, isOriginal }) => ((0,jsx_runtime_.jsx)(translation_option, { id: locale, label: nativeName, checked: checked, description: isOriginal && t('translations.settings.original'), onChange: handleChange(locale) }, locale)))] }));
17108
17527
  };
17109
17528
  /* harmony default export */ const translation_options = (TranslationOptions);
17110
17529
 
@@ -17117,7 +17536,7 @@ const TranslationOptions = ({ onChange, describedById, }) => {
17117
17536
  function TranslationsOptionsDialog({ onClose, position, }) {
17118
17537
  const { t } = (0,i18n_hooks/* useI18n */.Q)();
17119
17538
  const descriptionId = (0,seamly_hooks/* useGeneratedId */.I8)();
17120
- return ((0,jsx_runtime_.jsx)(options_frame, Object.assign({ onCancel: onClose, headingText: t('translations.menu.title'), cancelButtonText: t('translations.settings.cancelButtonText'), description: t('translations.menu.description'), descriptionId: descriptionId, position: position, disableButtonFocusing: true }, { children: (0,jsx_runtime_.jsx)(translation_options, { describedById: descriptionId, onChange: onClose }) })));
17539
+ return ((0,jsx_runtime_.jsx)(options_frame, { onCancel: onClose, headingText: t('translations.menu.title'), cancelButtonText: t('translations.settings.cancelButtonText'), description: t('translations.menu.description'), descriptionId: descriptionId, position: position, disableButtonFocusing: true, children: (0,jsx_runtime_.jsx)(translation_options, { describedById: descriptionId, onChange: onClose }) }));
17121
17540
  }
17122
17541
  /* harmony default export */ const options_dialog = (TranslationsOptionsDialog);
17123
17542
 
@@ -17157,11 +17576,11 @@ function TranslationsOptionsButton({ children, position = {
17157
17576
  e.preventDefault();
17158
17577
  }
17159
17578
  };
17160
- return ((0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)('translations__container'), onKeyDown: onMainKeyDownHandler }, { children: [(0,jsx_runtime_.jsx)(in_out_transition, Object.assign({ transitionStartState: transitionStartStates.notRendered, isActive: menuIsOpen }, { children: (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('options__dialog'), role: "dialog" }, { children: (0,jsx_runtime_.jsx)(options_dialog, { onClose: handleDialogClose, position: position }) })) })), (0,jsx_runtime_.jsx)("button", Object.assign({ type: "button", className: (0,css/* className */.o)([
17579
+ return ((0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('translations__container'), onKeyDown: onMainKeyDownHandler, children: [(0,jsx_runtime_.jsx)(in_out_transition, { transitionStartState: transitionStartStates.notRendered, isActive: menuIsOpen, children: (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('options__dialog'), role: "dialog", children: (0,jsx_runtime_.jsx)(options_dialog, { onClose: handleDialogClose, position: position }) }) }), (0,jsx_runtime_.jsx)("button", { type: "button", className: (0,css/* className */.o)([
17161
17580
  'button',
17162
17581
  'chat__options__button',
17163
17582
  ...classNames,
17164
- ]), id: toggleButtonId, onClick: handleToggleClick, onKeyDown: handleToggleKeyDown, ref: toggleButton, "aria-haspopup": "dialog", "aria-expanded": menuIsOpen }, { children: children }))] })));
17583
+ ]), id: toggleButtonId, onClick: handleToggleClick, onKeyDown: handleToggleKeyDown, ref: toggleButton, "aria-haspopup": "dialog", "aria-expanded": menuIsOpen, children: children })] }));
17165
17584
  }
17166
17585
 
17167
17586
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/app-options/index.js
@@ -17231,7 +17650,7 @@ const UnreadMessagesButton = () => {
17231
17650
  const { scrollToRef, unreadIds } = (0,hooks_.useContext)(chat_scroll_context);
17232
17651
  const { isMinimized } = (0,visibility_hooks/* useVisibility */.iJ)();
17233
17652
  const { t } = (0,i18n_hooks/* useI18n */.Q)();
17234
- return ((0,jsx_runtime_.jsx)(in_out_transition, Object.assign({ isActive: !!unreadIds.length && !isMinimized }, { children: (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('unread-messages') }, { children: (0,jsx_runtime_.jsxs)("button", Object.assign({ type: "button", className: (0,css/* className */.o)('button', 'button--primary'), onClick: scrollToRef }, { children: [t('message.unreadMessagesCount', { unreadCount: unreadIds.length }), (0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "chevronDown", size: "32", alt: "" })] })) })) })));
17653
+ return ((0,jsx_runtime_.jsx)(in_out_transition, { isActive: !!unreadIds.length && !isMinimized, children: (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('unread-messages'), children: (0,jsx_runtime_.jsxs)("button", { type: "button", className: (0,css/* className */.o)('button', 'button--primary'), onClick: scrollToRef, children: [t('message.unreadMessagesCount', { unreadCount: unreadIds.length }), (0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "chevronDown", size: "32", alt: "" })] }) }) }));
17235
17654
  };
17236
17655
  /* harmony default export */ const unread_messages_button = (UnreadMessagesButton);
17237
17656
 
@@ -17379,13 +17798,13 @@ const ChatScrollProvider = ({ children }) => {
17379
17798
  return acc;
17380
17799
  }, {}), [events]);
17381
17800
  const { scrollToRef, scrollToBottom, containerRef, unreadIds } = use_chat_scroll(eventRefs);
17382
- return ((0,jsx_runtime_.jsx)(chat_scroll_context.Provider, Object.assign({ value: {
17801
+ return ((0,jsx_runtime_.jsx)(chat_scroll_context.Provider, { value: {
17383
17802
  eventRefs,
17384
17803
  unreadIds,
17385
17804
  scrollToRef,
17386
17805
  scrollToBottom,
17387
17806
  containerRef,
17388
- } }, { children: (0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)('chat__container') }, { children: [(0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('chat__container__scroll-area'), ref: containerRef }, { children: children })), (0,jsx_runtime_.jsx)(unread_messages_button, {})] })) })));
17807
+ }, children: (0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('chat__container'), children: [(0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('chat__container__scroll-area'), ref: containerRef, children: children }), (0,jsx_runtime_.jsx)(unread_messages_button, {})] }) }));
17389
17808
  };
17390
17809
  /* harmony default export */ const chat_scroll_provider = (ChatScrollProvider);
17391
17810
 
@@ -17678,13 +18097,13 @@ function TextEntryForm({ controlName, skipLinkId }) {
17678
18097
  // When a message is submitted, the keyboard should be prevented from closing on mobile devices
17679
18098
  event.preventDefault();
17680
18099
  };
17681
- return ((0,jsx_runtime_.jsxs)(form_controls_form, Object.assign({ className: (0,css/* className */.o)('entry-form'), disableValidationClasses: true, noValidate: "true" }, { children: [(0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)([
18100
+ return ((0,jsx_runtime_.jsxs)(form_controls_form, { className: (0,css/* className */.o)('entry-form'), disableValidationClasses: true, noValidate: "true", children: [(0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)([
17682
18101
  'input--text__container',
17683
18102
  ...(reachedCharacterWarning && !reachedCharacterLimit
17684
18103
  ? ['character-warning']
17685
18104
  : []),
17686
18105
  ...(reachedCharacterLimit ? ['character-exceeded'] : []),
17687
- ]) }, { children: [(0,jsx_runtime_.jsx)(input, { id: skipLinkId, type: "text", name: controlName, className: (0,css/* className */.o)('input__text'), autocomplete: "off", placeholder: placeholder, labelText: label, labelClass: (0,css/* className */.o)(labelClass), "aria-invalid": hasCharacterLimit ? reachedCharacterLimit : null, onKeyUp: handleKeyUp, onFocus: handleFocus }), (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('character-count') }, { children: reachedCharacterWarning && (0,jsx_runtime_.jsx)("span", { children: remainingChars }) }))] })), (0,jsx_runtime_.jsx)("button", Object.assign({ className: (0,css/* className */.o)('button', 'input__submit'), type: "submit", onPointerDown: handlePointerDown, "aria-disabled": !hasValue || reachedCharacterLimit ? 'true' : null }, { children: (0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "send", size: "32", alt: t('input.sendMessage') }) }))] })));
18106
+ ]), children: [(0,jsx_runtime_.jsx)(input, { id: skipLinkId, type: "text", name: controlName, className: (0,css/* className */.o)('input__text'), autocomplete: "off", placeholder: placeholder, labelText: label, labelClass: (0,css/* className */.o)(labelClass), "aria-invalid": hasCharacterLimit ? reachedCharacterLimit : null, onKeyUp: handleKeyUp, onFocus: handleFocus }), (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('character-count'), children: reachedCharacterWarning && (0,jsx_runtime_.jsx)("span", { children: remainingChars }) })] }), (0,jsx_runtime_.jsx)("button", { className: (0,css/* className */.o)('button', 'input__submit'), type: "submit", onPointerDown: handlePointerDown, "aria-disabled": !hasValue || reachedCharacterLimit ? 'true' : null, children: (0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "send", size: "32", alt: t('input.sendMessage') }) })] }));
17688
18107
  }
17689
18108
 
17690
18109
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/entry/text-entry/index.js
@@ -18342,7 +18761,7 @@ const CollapseButton = () => {
18342
18761
 
18343
18762
  const ChatStatus = ({ children, handleClose, title, closeButtonText, srCloseButtonText, id, }) => {
18344
18763
  const headingId = (0,utility_hooks/* useGeneratedId */.I8)();
18345
- return ((0,jsx_runtime_.jsxs)("section", Object.assign({ tabIndex: -1, id: id, "aria-labelledby": title ? headingId : undefined, className: (0,css/* className */.o)('chat-status', !title && 'chat-status--condensed') }, { children: [(0,jsx_runtime_.jsxs)("div", Object.assign({ className: (0,css/* className */.o)('chat-status__body') }, { children: [title ? ((0,jsx_runtime_.jsx)("h2", Object.assign({ className: (0,css/* className */.o)('chat-status__title'), id: headingId }, { children: title }))) : null, children] })), typeof handleClose === 'function' && ((0,jsx_runtime_.jsxs)("button", Object.assign({ type: "button", onClick: handleClose, className: (0,css/* className */.o)('button', 'button--tertiary', 'chat-status__close') }, { children: [closeButtonText || (0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "close", size: "16", alt: "" }), srCloseButtonText && ((0,jsx_runtime_.jsx)("span", Object.assign({ className: (0,css/* className */.o)('visually-hidden') }, { children: srCloseButtonText })))] })))] })));
18764
+ return ((0,jsx_runtime_.jsxs)("section", { tabIndex: -1, id: id, "aria-labelledby": title ? headingId : undefined, className: (0,css/* className */.o)('chat-status', !title && 'chat-status--condensed'), children: [(0,jsx_runtime_.jsxs)("div", { className: (0,css/* className */.o)('chat-status__body'), children: [title ? ((0,jsx_runtime_.jsx)("h2", { className: (0,css/* className */.o)('chat-status__title'), id: headingId, children: title })) : null, children] }), typeof handleClose === 'function' && ((0,jsx_runtime_.jsxs)("button", { type: "button", onClick: handleClose, className: (0,css/* className */.o)('button', 'button--tertiary', 'chat-status__close'), children: [closeButtonText || (0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: "close", size: "16", alt: "" }), srCloseButtonText && ((0,jsx_runtime_.jsx)("span", { className: (0,css/* className */.o)('visually-hidden'), children: srCloseButtonText }))] }))] }));
18346
18765
  };
18347
18766
  /* harmony default export */ const chat_status = (ChatStatus);
18348
18767
 
@@ -18377,7 +18796,7 @@ function TranslationChatStatus() {
18377
18796
 
18378
18797
 
18379
18798
 
18380
- const ChatStatusAction = ({ handleClick, icon, title, srButtonText, }) => ((0,jsx_runtime_.jsxs)("button", Object.assign({ type: "button", onClick: handleClick, className: (0,css/* className */.o)('button', 'button--primary', 'chat-status__button') }, { children: [(0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: icon, size: "16", alt: "" }), title, srButtonText && ((0,jsx_runtime_.jsx)("span", Object.assign({ className: (0,css/* className */.o)('visually-hidden') }, { children: srButtonText })))] })));
18799
+ const ChatStatusAction = ({ handleClick, icon, title, srButtonText, }) => ((0,jsx_runtime_.jsxs)("button", { type: "button", onClick: handleClick, className: (0,css/* className */.o)('button', 'button--primary', 'chat-status__button'), children: [(0,jsx_runtime_.jsx)(layout_icon/* default */.Z, { name: icon, size: "16", alt: "" }), title, srButtonText && ((0,jsx_runtime_.jsx)("span", { className: (0,css/* className */.o)('visually-hidden'), children: srButtonText }))] }));
18381
18800
  /* harmony default export */ const chat_status_action = (ChatStatusAction);
18382
18801
 
18383
18802
  ;// CONCATENATED MODULE: ./src/javascripts/ui/components/translation-proposal/index.tsx
@@ -18391,7 +18810,7 @@ function TranslationProposal() {
18391
18810
  if (!showProposal) {
18392
18811
  return null;
18393
18812
  }
18394
- return ((0,jsx_runtime_.jsx)(chat_status, Object.assign({ handleClose: dismissTranslationProposal, srCloseButtonText: translationProposal.srDismissButtonText, id: id, title: translationProposal.titleLabel }, { children: (0,jsx_runtime_.jsx)(chat_status_action, { handleClick: activateTranslationProposal, icon: "newTranslation", title: translationProposal.buttonLabel }) })));
18813
+ return ((0,jsx_runtime_.jsx)(chat_status, { handleClose: dismissTranslationProposal, srCloseButtonText: translationProposal.srDismissButtonText, id: id, title: translationProposal.titleLabel, children: (0,jsx_runtime_.jsx)(chat_status_action, { handleClick: activateTranslationProposal, icon: "newTranslation", title: translationProposal.buttonLabel }) }));
18395
18814
  }
18396
18815
 
18397
18816
  ;// CONCATENATED MODULE: ./src/javascripts/domains/translations/components/translation-status.tsx
@@ -18660,10 +19079,14 @@ const WindowOpenButton = ({
18660
19079
  "aria-label": ariaLabel,
18661
19080
  "aria-hidden": isOpen,
18662
19081
  onClick: handleClick,
18663
- children: [(0,jsx_runtime_.jsx)("span", {
18664
- className: (0,css/* className */.o)('message-count'),
18665
- "aria-hidden": "true",
18666
- children: !!count && count
19082
+ children: [(0,jsx_runtime_.jsx)(in_out_transition, {
19083
+ isActive: !!count,
19084
+ transitionStartState: transitionStartStates.notRendered,
19085
+ children: (0,jsx_runtime_.jsx)("span", {
19086
+ className: (0,css/* className */.o)('message-count'),
19087
+ "aria-hidden": "true",
19088
+ children: count
19089
+ })
18667
19090
  }), (0,jsx_runtime_.jsx)(ButtonIcon, {})]
18668
19091
  })
18669
19092
  });
@@ -18698,7 +19121,7 @@ const WindowView = () => {
18698
19121
  },
18699
19122
  },
18700
19123
  }), [continueChatText]);
18701
- return ((0,jsx_runtime_.jsxs)(jsx_runtime_.Fragment, { children: [(0,jsx_runtime_.jsx)(window_open_button, { onClick: openChat }), (0,jsx_runtime_.jsx)(in_out_transition, Object.assign({ isActive: preChat && !isOpen && !userHasResponded, exitAfter: getDelay(preChat, 'exitAfter'), enterDelay: getDelay(preChat, 'enterDelay'), transitionStartState: transitionStartStates.rendered }, { children: (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('unstarted-wrapper', 'unstarted-wrapper--window') }, { children: (0,jsx_runtime_.jsx)(PreChatMessages, {}) })) })), (0,jsx_runtime_.jsx)(in_out_transition, Object.assign({ isActive: continueChat && !isOpen && userHasResponded, exitAfter: getDelay(continueChat, 'exitAfter'), enterDelay: getDelay(continueChat, 'enterDelay'), transitionStartState: transitionStartStates.notRendered }, { children: (0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)('unstarted-wrapper', 'unstarted-wrapper--window', 'unstarted-wrapper--continue') }, { children: (0,jsx_runtime_.jsx)(event_text, { event: continueChatEvent }) })) })), (0,jsx_runtime_.jsx)(in_out_transition, Object.assign({ isActive: isOpen, transitionStartState: transitionStartStates.notRendered }, { children: (0,jsx_runtime_.jsx)(chat, { children: (0,jsx_runtime_.jsx)(chat_frame, { children: (0,jsx_runtime_.jsx)(conversation, {}) }) }) }))] }));
19124
+ return ((0,jsx_runtime_.jsxs)(jsx_runtime_.Fragment, { children: [(0,jsx_runtime_.jsx)(window_open_button, { onClick: openChat }), (0,jsx_runtime_.jsx)(in_out_transition, { isActive: preChat && !isOpen && !userHasResponded, exitAfter: getDelay(preChat, 'exitAfter'), enterDelay: getDelay(preChat, 'enterDelay'), transitionStartState: transitionStartStates.rendered, children: (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('unstarted-wrapper', 'unstarted-wrapper--window'), children: (0,jsx_runtime_.jsx)(PreChatMessages, {}) }) }), (0,jsx_runtime_.jsx)(in_out_transition, { isActive: continueChat && !isOpen && userHasResponded, exitAfter: getDelay(continueChat, 'exitAfter'), enterDelay: getDelay(continueChat, 'enterDelay'), transitionStartState: transitionStartStates.notRendered, children: (0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)('unstarted-wrapper', 'unstarted-wrapper--window', 'unstarted-wrapper--continue'), children: (0,jsx_runtime_.jsx)(event_text, { event: continueChatEvent }) }) }), (0,jsx_runtime_.jsx)(in_out_transition, { isActive: isOpen, transitionStartState: transitionStartStates.notRendered, children: (0,jsx_runtime_.jsx)(chat, { children: (0,jsx_runtime_.jsx)(chat_frame, { children: (0,jsx_runtime_.jsx)(conversation, {}) }) }) })] }));
18702
19125
  };
18703
19126
  /* harmony default export */ const window_view = (WindowView);
18704
19127
 
@@ -18913,7 +19336,7 @@ const View = ({ children }) => {
18913
19336
  if (userHasResponded) {
18914
19337
  classNames.push('app--user-responded');
18915
19338
  }
18916
- return (isVisible && ((0,jsx_runtime_.jsx)("div", Object.assign({ className: (0,css/* className */.o)(classNames), lang: blockLang, tabIndex: -1, "data-nosnippet": true, style: { zIndex }, ref: containerElementRef }, { children: children || (0,jsx_runtime_.jsx)(ViewComponent, {}) }))));
19339
+ return (isVisible && ((0,jsx_runtime_.jsx)("div", { className: (0,css/* className */.o)(classNames), lang: blockLang, tabIndex: -1, "data-nosnippet": true, style: { zIndex }, ref: containerElementRef, children: children || (0,jsx_runtime_.jsx)(ViewComponent, {}) })));
18917
19340
  };
18918
19341
  /* harmony default export */ const view = (View);
18919
19342
 
@@ -18928,14 +19351,12 @@ const ChatApp = props => {
18928
19351
  });
18929
19352
  };
18930
19353
  /* harmony default export */ const chat_app = (ChatApp);
18931
- // EXTERNAL MODULE: ./src/javascripts/domains/app/actions.ts
18932
- var actions = __webpack_require__(9201);
19354
+ // EXTERNAL MODULE: ./src/javascripts/domains/app/actions.ts + 1 modules
19355
+ var app_actions = __webpack_require__(526);
18933
19356
  // EXTERNAL MODULE: ./src/javascripts/domains/config/actions.ts
18934
19357
  var config_actions = __webpack_require__(257);
18935
19358
  // EXTERNAL MODULE: ./src/javascripts/domains/i18n/actions.ts
18936
19359
  var i18n_actions = __webpack_require__(5409);
18937
- // EXTERNAL MODULE: ./src/javascripts/domains/store/index.ts + 4 modules
18938
- var domains_store = __webpack_require__(7271);
18939
19360
  // EXTERNAL MODULE: ./src/javascripts/domains/visibility/actions.ts
18940
19361
  var visibility_actions = __webpack_require__(9586);
18941
19362
  ;// CONCATENATED MODULE: ./src/javascripts/lib/engine/index.tsx
@@ -19012,15 +19433,17 @@ class Engine {
19012
19433
  store.dispatch((0,config_slice/* setConfig */.v6)(renderConfig));
19013
19434
  yield store.dispatch((0,config_actions/* initializeConfig */.t)());
19014
19435
  try {
19015
- const { locale } = yield store.dispatch((0,actions/* initializeApp */.Z)()).unwrap();
19016
- yield store.dispatch((0,i18n_actions/* setLocale */.i)(locale));
19436
+ const { locale } = yield store.dispatch((0,app_actions/* initializeApp */.Z)()).unwrap();
19437
+ if (locale) {
19438
+ yield store.dispatch((0,i18n_actions/* setLocale */.i)(locale));
19439
+ }
19017
19440
  }
19018
19441
  catch (rejectedValueOrSerializedError) {
19019
19442
  // nothing to do
19020
19443
  }
19021
19444
  store.dispatch((0,visibility_actions/* initializeVisibility */.Z)());
19022
19445
  if (View) {
19023
- (0,external_preact_.render)((0,jsx_runtime_.jsx)(seamly_core, Object.assign({ eventBus: this.eventBus, store: store, api: this.api }, { children: (0,jsx_runtime_.jsx)(View, {}) })), this.parentElement);
19446
+ (0,external_preact_.render)((0,jsx_runtime_.jsx)(seamly_core, { eventBus: this.eventBus, store: store, api: this.api, children: (0,jsx_runtime_.jsx)(View, {}) }), this.parentElement);
19024
19447
  }
19025
19448
  else {
19026
19449
  (0,external_preact_.render)((0,jsx_runtime_.jsx)(chat_app, { config: renderConfig, eventBus: this.eventBus, store: store, api: this.api }), this.parentElement);