@hellotext/hellotext 2.4.2 → 2.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hellotext.js +1 -1
- package/lib/controllers/message_controller.cjs +144 -25
- package/lib/controllers/message_controller.js +145 -25
- package/lib/controllers/mixins/usePopover.cjs +2 -0
- package/lib/controllers/mixins/usePopover.js +2 -0
- package/lib/controllers/webchat/useTeaser.cjs +3 -1
- package/lib/controllers/webchat/useTeaser.js +3 -1
- package/lib/controllers/webchat_controller.cjs +219 -25
- package/lib/controllers/webchat_controller.js +233 -25
- package/lib/core/configuration.cjs +19 -0
- package/lib/core/configuration.js +19 -0
- package/lib/models/business.cjs +86 -5
- package/lib/models/business.js +82 -5
- package/lib/models/webchat.cjs +18 -3
- package/lib/models/webchat.js +27 -6
- package/package.json +1 -1
- package/src/controllers/message_controller.js +145 -22
- package/src/controllers/mixins/usePopover.js +1 -0
- package/src/controllers/webchat/useTeaser.js +4 -1
- package/src/controllers/webchat_controller.js +255 -27
- package/src/core/configuration.js +25 -0
- package/src/models/business.js +86 -5
- package/src/models/webchat.js +22 -3
|
@@ -30,6 +30,15 @@ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "
|
|
|
30
30
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
31
31
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
32
32
|
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
33
|
+
const POPOVER_ANIMATION_DURATION = 120;
|
|
34
|
+
const MESSAGE_TIMESTAMP_FORMAT_OPTIONS = {
|
|
35
|
+
hour: 'numeric',
|
|
36
|
+
minute: '2-digit'
|
|
37
|
+
};
|
|
38
|
+
const SCROLL_ISOLATION_EVENT_OPTIONS = {
|
|
39
|
+
capture: true,
|
|
40
|
+
passive: true
|
|
41
|
+
};
|
|
33
42
|
let _default = /*#__PURE__*/function (_Controller) {
|
|
34
43
|
_inherits(_default, _Controller);
|
|
35
44
|
var _super = _createSuper(_default);
|
|
@@ -49,6 +58,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
49
58
|
this.onTypingStart = this.onTypingStart.bind(this);
|
|
50
59
|
this.onScroll = this.onScroll.bind(this);
|
|
51
60
|
this.onOutboundMessageSent = this.onOutboundMessageSent.bind(this);
|
|
61
|
+
this.closePopoverOnEscape = this.closePopoverOnEscape.bind(this);
|
|
52
62
|
this.broadcastChannel = new BroadcastChannel(`hellotext--webchat--${this.idValue}`);
|
|
53
63
|
_get(_getPrototypeOf(_default.prototype), "initialize", this).call(this);
|
|
54
64
|
}
|
|
@@ -72,15 +82,20 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
72
82
|
}
|
|
73
83
|
this.setupTeaser();
|
|
74
84
|
this.setupOpeningSequence();
|
|
85
|
+
this.localizeMessageTimestamps();
|
|
75
86
|
this.webChatChannel.onMessage(this.onMessageReceived);
|
|
76
87
|
this.webChatChannel.onTypingStart(this.onTypingStart);
|
|
77
88
|
this.webChatChannel.onReaction(this.onMessageReaction);
|
|
89
|
+
this.setupMessagesContainerScrollIsolation();
|
|
78
90
|
this.messagesContainerTarget.addEventListener('scroll', this.onScroll);
|
|
91
|
+
this.messagesContainerTarget.addEventListener('wheel', this.stopHostScrollPropagation, SCROLL_ISOLATION_EVENT_OPTIONS);
|
|
92
|
+
this.messagesContainerTarget.addEventListener('touchmove', this.stopHostScrollPropagation, SCROLL_ISOLATION_EVENT_OPTIONS);
|
|
79
93
|
if (this.shouldOpenOnMount) {
|
|
80
94
|
this.openValue = true;
|
|
81
95
|
}
|
|
82
96
|
_hellotext.default.eventEmitter.dispatch('webchat:mounted');
|
|
83
97
|
this.broadcastChannel.addEventListener('message', this.onOutboundMessageSent);
|
|
98
|
+
window.addEventListener('keydown', this.closePopoverOnEscape, true);
|
|
84
99
|
this.scheduleBehaviourOpen();
|
|
85
100
|
_get(_getPrototypeOf(_default.prototype), "connect", this).call(this);
|
|
86
101
|
}
|
|
@@ -88,10 +103,14 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
88
103
|
key: "disconnect",
|
|
89
104
|
value: function disconnect() {
|
|
90
105
|
this.cancelBehaviourOpen();
|
|
106
|
+
this.clearPopoverOpenAnimation();
|
|
91
107
|
this.teardownTeaser();
|
|
92
108
|
this.teardownOpeningSequence();
|
|
93
109
|
this.broadcastChannel.removeEventListener('message', this.onOutboundMessageSent);
|
|
94
110
|
this.messagesContainerTarget.removeEventListener('scroll', this.onScroll);
|
|
111
|
+
this.messagesContainerTarget.removeEventListener('wheel', this.stopHostScrollPropagation, SCROLL_ISOLATION_EVENT_OPTIONS);
|
|
112
|
+
this.messagesContainerTarget.removeEventListener('touchmove', this.stopHostScrollPropagation, SCROLL_ISOLATION_EVENT_OPTIONS);
|
|
113
|
+
window.removeEventListener('keydown', this.closePopoverOnEscape, true);
|
|
95
114
|
|
|
96
115
|
// Clean up typing indicator timeouts
|
|
97
116
|
this.clearTypingIndicator();
|
|
@@ -99,6 +118,21 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
99
118
|
this.floatingUICleanup();
|
|
100
119
|
_get(_getPrototypeOf(_default.prototype), "disconnect", this).call(this);
|
|
101
120
|
}
|
|
121
|
+
}, {
|
|
122
|
+
key: "setupMessagesContainerScrollIsolation",
|
|
123
|
+
value: function setupMessagesContainerScrollIsolation() {
|
|
124
|
+
this.messagesContainerTarget.style.overscrollBehavior = 'contain';
|
|
125
|
+
this.messagesContainerTarget.style.webkitOverflowScrolling = 'touch';
|
|
126
|
+
this.messagesContainerTarget.style.touchAction = 'pan-y';
|
|
127
|
+
this.messagesContainerTarget.setAttribute('data-lenis-prevent', '');
|
|
128
|
+
this.messagesContainerTarget.setAttribute('data-lenis-prevent-wheel', '');
|
|
129
|
+
this.messagesContainerTarget.setAttribute('data-lenis-prevent-touch', '');
|
|
130
|
+
}
|
|
131
|
+
}, {
|
|
132
|
+
key: "stopHostScrollPropagation",
|
|
133
|
+
value: function stopHostScrollPropagation(event) {
|
|
134
|
+
event.stopPropagation();
|
|
135
|
+
}
|
|
102
136
|
}, {
|
|
103
137
|
key: "onTypingStart",
|
|
104
138
|
value: function onTypingStart() {
|
|
@@ -180,6 +214,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
180
214
|
const callbacks = {
|
|
181
215
|
'message:sent': data => {
|
|
182
216
|
const element = new DOMParser().parseFromString(data.element, 'text/html').body.firstElementChild;
|
|
217
|
+
this.localizeMessageTimestamps(element);
|
|
183
218
|
|
|
184
219
|
// Insert message before typing indicator if one exists
|
|
185
220
|
if (this.typingIndicatorVisible && this.hasTypingIndicatorTarget) {
|
|
@@ -192,8 +227,8 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
192
227
|
});
|
|
193
228
|
},
|
|
194
229
|
'message:failed': data => {
|
|
195
|
-
|
|
196
|
-
|
|
230
|
+
const element = this.messagesContainerTarget.querySelector(`#${data.id}`);
|
|
231
|
+
this.markMessageFailed(element, data.reason);
|
|
197
232
|
}
|
|
198
233
|
};
|
|
199
234
|
if (callbacks[data.type]) {
|
|
@@ -222,6 +257,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
222
257
|
body,
|
|
223
258
|
attachments
|
|
224
259
|
} = message;
|
|
260
|
+
const createdAt = message.created_at || message.createdAt;
|
|
225
261
|
const div = document.createElement('div');
|
|
226
262
|
div.innerHTML = body;
|
|
227
263
|
const element = this.messageTemplateTarget.cloneNode(true);
|
|
@@ -244,6 +280,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
244
280
|
});
|
|
245
281
|
}
|
|
246
282
|
element.setAttribute('data-body', body);
|
|
283
|
+
this.localizeMessageTimestamp(element.querySelector('[data-message-timestamp]'), createdAt);
|
|
247
284
|
this.messagesContainerTarget.prepend(element);
|
|
248
285
|
});
|
|
249
286
|
this.messagesContainerTarget.scroll({
|
|
@@ -262,10 +299,30 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
262
299
|
}, {
|
|
263
300
|
key: "closePopover",
|
|
264
301
|
value: function closePopover() {
|
|
265
|
-
this.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
302
|
+
this.clearPopoverOpenAnimation();
|
|
303
|
+
this.popoverTarget.classList.remove(...this.fadeOutClasses);
|
|
304
|
+
this.openValue = false;
|
|
305
|
+
}
|
|
306
|
+
}, {
|
|
307
|
+
key: "preparePopoverOpenAnimation",
|
|
308
|
+
value: function preparePopoverOpenAnimation() {
|
|
309
|
+
this.clearPopoverOpenAnimation();
|
|
310
|
+
this.popoverTarget.classList.remove(...this.fadeOutClasses);
|
|
311
|
+
this.popoverTarget.classList.add('hellotext--webchat-popover-opening');
|
|
312
|
+
this.popoverOpenAnimationTimeout = setTimeout(() => {
|
|
313
|
+
this.popoverTarget.classList.remove('hellotext--webchat-popover-opening');
|
|
314
|
+
this.popoverOpenAnimationTimeout = null;
|
|
315
|
+
}, POPOVER_ANIMATION_DURATION);
|
|
316
|
+
}
|
|
317
|
+
}, {
|
|
318
|
+
key: "clearPopoverOpenAnimation",
|
|
319
|
+
value: function clearPopoverOpenAnimation() {
|
|
320
|
+
var _this$popoverTarget;
|
|
321
|
+
if (this.popoverOpenAnimationTimeout) {
|
|
322
|
+
clearTimeout(this.popoverOpenAnimationTimeout);
|
|
323
|
+
this.popoverOpenAnimationTimeout = null;
|
|
324
|
+
}
|
|
325
|
+
(_this$popoverTarget = this.popoverTarget) === null || _this$popoverTarget === void 0 ? void 0 : _this$popoverTarget.classList.remove('hellotext--webchat-popover-opening');
|
|
269
326
|
}
|
|
270
327
|
}, {
|
|
271
328
|
key: "onPopoverOpened",
|
|
@@ -299,6 +356,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
299
356
|
}, {
|
|
300
357
|
key: "onPopoverClosed",
|
|
301
358
|
value: function onPopoverClosed() {
|
|
359
|
+
this.clearPopoverOpenAnimation();
|
|
302
360
|
_hellotext.default.eventEmitter.dispatch('webchat:closed');
|
|
303
361
|
localStorage.setItem(`hellotext--webchat--${this.idValue}`, 'closed');
|
|
304
362
|
}
|
|
@@ -336,6 +394,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
336
394
|
attachments,
|
|
337
395
|
teaser
|
|
338
396
|
} = message;
|
|
397
|
+
const createdAt = message.created_at || message.createdAt;
|
|
339
398
|
if (!this.claimMessageId(id)) return;
|
|
340
399
|
(_this$hideTeaser = this.hideTeaser) === null || _this$hideTeaser === void 0 ? void 0 : _this$hideTeaser.call(this);
|
|
341
400
|
if (message.carousel) {
|
|
@@ -348,6 +407,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
348
407
|
element.querySelector('[data-body]').innerHTML = div.innerHTML;
|
|
349
408
|
element.setAttribute('data-id', id);
|
|
350
409
|
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
410
|
+
this.localizeMessageTimestamp(element.querySelector('[data-message-timestamp]'), createdAt);
|
|
351
411
|
if (attachments) {
|
|
352
412
|
attachments.forEach(attachmentUrl => {
|
|
353
413
|
var _this$messageAttachme2;
|
|
@@ -405,6 +465,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
405
465
|
const element = new DOMParser().parseFromString(html, 'text/html').body.firstElementChild;
|
|
406
466
|
element.setAttribute('data-id', message.id);
|
|
407
467
|
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
468
|
+
this.localizeMessageTimestamps(element);
|
|
408
469
|
this.clearTypingIndicator();
|
|
409
470
|
this.messagesContainerTarget.appendChild(element);
|
|
410
471
|
element.scrollIntoView({
|
|
@@ -449,14 +510,14 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
449
510
|
(_this$dismissTeaserFo2 = this.dismissTeaserForSession) === null || _this$dismissTeaserFo2 === void 0 ? void 0 : _this$dismissTeaserFo2.call(this);
|
|
450
511
|
const formData = new FormData();
|
|
451
512
|
formData.append('message[body]', body);
|
|
452
|
-
formData.append('message[replied_to]', id);
|
|
453
|
-
formData.append('message[product]', product);
|
|
454
|
-
formData.append('message[button]', buttonId);
|
|
513
|
+
if (id) formData.append('message[replied_to]', id);
|
|
514
|
+
if (product) formData.append('message[product]', product);
|
|
515
|
+
if (buttonId) formData.append('message[button]', buttonId);
|
|
455
516
|
formData.append('session', _hellotext.default.session);
|
|
456
517
|
formData.append('locale', _core.Locale.toString());
|
|
457
518
|
this.appendOpeningSequenceMessageIds(formData);
|
|
458
519
|
const element = this.buildMessageElement();
|
|
459
|
-
const attachment = (_cardElement$querySel = cardElement.querySelector('img')) === null || _cardElement$querySel === void 0 ? void 0 : _cardElement$querySel.cloneNode(true);
|
|
520
|
+
const attachment = cardElement === null || cardElement === void 0 ? void 0 : (_cardElement$querySel = cardElement.querySelector('img')) === null || _cardElement$querySel === void 0 ? void 0 : _cardElement$querySel.cloneNode(true);
|
|
460
521
|
element.querySelector('[data-body]').innerText = body;
|
|
461
522
|
if (attachment) {
|
|
462
523
|
var _this$messageAttachme3;
|
|
@@ -480,17 +541,14 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
480
541
|
if (response.failed) {
|
|
481
542
|
// Clear the optimistic typing indicator on failure
|
|
482
543
|
clearTimeout(this.optimisticTypingTimeout);
|
|
483
|
-
this.
|
|
484
|
-
type: 'message:failed',
|
|
485
|
-
id: element.id
|
|
486
|
-
});
|
|
487
|
-
return element.classList.add('failed');
|
|
544
|
+
return this.markMessageFailedFromResponse(response, element);
|
|
488
545
|
}
|
|
489
546
|
const data = await response.json();
|
|
490
547
|
this.dispatch('set:id', {
|
|
491
548
|
target: element,
|
|
492
549
|
detail: data.id
|
|
493
550
|
});
|
|
551
|
+
this.localizeMessageTimestamp(element.querySelector('[data-message-timestamp]'), data.created_at || data.createdAt);
|
|
494
552
|
this.clearRevealedOpeningSequenceMessageIds();
|
|
495
553
|
const message = {
|
|
496
554
|
id: data.id,
|
|
@@ -545,14 +603,11 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
545
603
|
const response = await this.messagesAPI.create(formData);
|
|
546
604
|
if (response.failed) {
|
|
547
605
|
clearTimeout(this.optimisticTypingTimeout);
|
|
548
|
-
this.
|
|
549
|
-
type: 'message:failed',
|
|
550
|
-
id: element.id
|
|
551
|
-
});
|
|
552
|
-
return element.classList.add('failed');
|
|
606
|
+
return this.markMessageFailedFromResponse(response, element);
|
|
553
607
|
}
|
|
554
608
|
const data = await response.json();
|
|
555
609
|
element.setAttribute('data-id', data.id);
|
|
610
|
+
this.localizeMessageTimestamp(element.querySelector('[data-message-timestamp]'), data.created_at || data.createdAt);
|
|
556
611
|
this.clearRevealedOpeningSequenceMessageIds();
|
|
557
612
|
_hellotext.default.eventEmitter.dispatch('webchat:message:sent', {
|
|
558
613
|
id: data.id,
|
|
@@ -648,15 +703,12 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
648
703
|
if (response.failed) {
|
|
649
704
|
// Clear the optimistic typing indicator on failure
|
|
650
705
|
clearTimeout(this.optimisticTypingTimeout);
|
|
651
|
-
this.
|
|
652
|
-
type: 'message:failed',
|
|
653
|
-
id: element.id
|
|
654
|
-
});
|
|
655
|
-
return element.classList.add('failed');
|
|
706
|
+
return this.markMessageFailedFromResponse(response, element);
|
|
656
707
|
}
|
|
657
708
|
const data = await response.json();
|
|
658
709
|
element.setAttribute('data-id', data.id);
|
|
659
710
|
message.id = data.id;
|
|
711
|
+
this.localizeMessageTimestamp(element.querySelector('[data-message-timestamp]'), data.created_at || data.createdAt);
|
|
660
712
|
this.clearRevealedOpeningSequenceMessageIds();
|
|
661
713
|
_hellotext.default.eventEmitter.dispatch('webchat:message:sent', message);
|
|
662
714
|
if (data.conversation !== this.conversationIdValue) {
|
|
@@ -679,8 +731,131 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
679
731
|
element.style.removeProperty('display');
|
|
680
732
|
element.setAttribute('data-controller', 'hellotext--message');
|
|
681
733
|
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
734
|
+
this.localizeMessageTimestamp(element.querySelector('[data-message-timestamp]'), new Date());
|
|
682
735
|
return element;
|
|
683
736
|
}
|
|
737
|
+
}, {
|
|
738
|
+
key: "focusCompose",
|
|
739
|
+
value: function focusCompose(event) {
|
|
740
|
+
const {
|
|
741
|
+
target
|
|
742
|
+
} = event;
|
|
743
|
+
const ignoredSelector = ['button', 'a', 'input', 'textarea', 'select', 'label', '[role="button"]', 'em-emoji-picker', '[data-hellotext--webchat--emoji-target~="popover"]', '[data-controller~="hellotext--webchat--emoji"]'].join(', ');
|
|
744
|
+
if (!this.hasInputTarget || target.closest(ignoredSelector)) return;
|
|
745
|
+
event.preventDefault();
|
|
746
|
+
this.inputTarget.focus();
|
|
747
|
+
if (typeof this.inputTarget.selectionStart === 'number') {
|
|
748
|
+
const position = this.inputTarget.value.length;
|
|
749
|
+
this.inputTarget.setSelectionRange(position, position);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}, {
|
|
753
|
+
key: "closePopoverFromHeader",
|
|
754
|
+
value: function closePopoverFromHeader(event) {
|
|
755
|
+
const {
|
|
756
|
+
target
|
|
757
|
+
} = event;
|
|
758
|
+
if (target.closest('.hellotext--webchat-header-channel-button, .hellotext--webchat-close-button')) return;
|
|
759
|
+
event.preventDefault();
|
|
760
|
+
this.closePopover();
|
|
761
|
+
}
|
|
762
|
+
}, {
|
|
763
|
+
key: "closePopoverOnEscape",
|
|
764
|
+
value: function closePopoverOnEscape(event) {
|
|
765
|
+
var _this$triggerTarget, _this$triggerTarget$f;
|
|
766
|
+
if (event.key !== 'Escape' || !this.openValue) return;
|
|
767
|
+
event.preventDefault();
|
|
768
|
+
event.stopPropagation();
|
|
769
|
+
this.closePopover();
|
|
770
|
+
(_this$triggerTarget = this.triggerTarget) === null || _this$triggerTarget === void 0 ? void 0 : (_this$triggerTarget$f = _this$triggerTarget.focus) === null || _this$triggerTarget$f === void 0 ? void 0 : _this$triggerTarget$f.call(_this$triggerTarget);
|
|
771
|
+
}
|
|
772
|
+
}, {
|
|
773
|
+
key: "markMessageFailedFromResponse",
|
|
774
|
+
value: async function markMessageFailedFromResponse(response, element) {
|
|
775
|
+
const reason = await this.messageFailureReason(response);
|
|
776
|
+
this.markMessageFailed(element, reason);
|
|
777
|
+
this.broadcastChannel.postMessage({
|
|
778
|
+
type: 'message:failed',
|
|
779
|
+
id: element.id,
|
|
780
|
+
reason
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
}, {
|
|
784
|
+
key: "markMessageFailed",
|
|
785
|
+
value: function markMessageFailed(element, reason) {
|
|
786
|
+
if (!element) return;
|
|
787
|
+
element.classList.add('failed');
|
|
788
|
+
if (!reason) return;
|
|
789
|
+
const timestamp = element.querySelector('[data-message-timestamp]');
|
|
790
|
+
if (timestamp) {
|
|
791
|
+
timestamp.textContent = reason;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}, {
|
|
795
|
+
key: "localizeMessageTimestamps",
|
|
796
|
+
value: function localizeMessageTimestamps(root = this.element) {
|
|
797
|
+
var _root$matches, _root$querySelectorAl;
|
|
798
|
+
if (!root) return;
|
|
799
|
+
const timestamps = (_root$matches = root.matches) !== null && _root$matches !== void 0 && _root$matches.call(root, 'time[datetime][data-message-timestamp]') ? [root] : Array.from(((_root$querySelectorAl = root.querySelectorAll) === null || _root$querySelectorAl === void 0 ? void 0 : _root$querySelectorAl.call(root, 'time[datetime][data-message-timestamp]')) || []);
|
|
800
|
+
timestamps.forEach(timestamp => this.localizeMessageTimestamp(timestamp));
|
|
801
|
+
}
|
|
802
|
+
}, {
|
|
803
|
+
key: "localizeMessageTimestamp",
|
|
804
|
+
value: function localizeMessageTimestamp(timestamp, value = timestamp === null || timestamp === void 0 ? void 0 : timestamp.getAttribute('datetime')) {
|
|
805
|
+
if (!timestamp || !value) return;
|
|
806
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
807
|
+
if (Number.isNaN(date.getTime())) return;
|
|
808
|
+
timestamp.setAttribute('datetime', date.toISOString());
|
|
809
|
+
timestamp.textContent = this.formatMessageTimestamp(date);
|
|
810
|
+
}
|
|
811
|
+
}, {
|
|
812
|
+
key: "formatMessageTimestamp",
|
|
813
|
+
value: function formatMessageTimestamp(date) {
|
|
814
|
+
return this.constructor.messageTimestampFormatterFor(_core.Locale.toString()).format(date);
|
|
815
|
+
}
|
|
816
|
+
}, {
|
|
817
|
+
key: "messageFailureReason",
|
|
818
|
+
value: async function messageFailureReason(response) {
|
|
819
|
+
const nativeResponse = (response === null || response === void 0 ? void 0 : response.data) || (response === null || response === void 0 ? void 0 : response.response);
|
|
820
|
+
const fallback = (nativeResponse === null || nativeResponse === void 0 ? void 0 : nativeResponse.statusText) || 'Message failed';
|
|
821
|
+
try {
|
|
822
|
+
var _jsonResponse$json;
|
|
823
|
+
const jsonResponse = nativeResponse !== null && nativeResponse !== void 0 && nativeResponse.clone ? nativeResponse.clone() : nativeResponse;
|
|
824
|
+
const payload = await (jsonResponse === null || jsonResponse === void 0 ? void 0 : (_jsonResponse$json = jsonResponse.json) === null || _jsonResponse$json === void 0 ? void 0 : _jsonResponse$json.call(jsonResponse));
|
|
825
|
+
const reason = this.messageFailureReasonFromPayload(payload);
|
|
826
|
+
if (reason) return reason;
|
|
827
|
+
} catch (_) {
|
|
828
|
+
// Fall through to text parsing/fallback. Some stores strip content-type or
|
|
829
|
+
// return non-JSON failures, so the timestamp still needs a useful reason.
|
|
830
|
+
}
|
|
831
|
+
try {
|
|
832
|
+
var _textResponse$text;
|
|
833
|
+
const textResponse = nativeResponse !== null && nativeResponse !== void 0 && nativeResponse.clone ? nativeResponse.clone() : nativeResponse;
|
|
834
|
+
const text = await (textResponse === null || textResponse === void 0 ? void 0 : (_textResponse$text = textResponse.text) === null || _textResponse$text === void 0 ? void 0 : _textResponse$text.call(textResponse));
|
|
835
|
+
return this.messageFailureReasonFromText(text) || fallback;
|
|
836
|
+
} catch (_) {
|
|
837
|
+
return fallback;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}, {
|
|
841
|
+
key: "messageFailureReasonFromText",
|
|
842
|
+
value: function messageFailureReasonFromText(text) {
|
|
843
|
+
if (typeof text !== 'string') return null;
|
|
844
|
+
const value = text.trim();
|
|
845
|
+
if (!value || value.startsWith('<')) return null;
|
|
846
|
+
try {
|
|
847
|
+
return this.messageFailureReasonFromPayload(JSON.parse(value)) || value;
|
|
848
|
+
} catch (_) {
|
|
849
|
+
return value;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}, {
|
|
853
|
+
key: "messageFailureReasonFromPayload",
|
|
854
|
+
value: function messageFailureReasonFromPayload(payload) {
|
|
855
|
+
var _payload$error, _payload$errors, _payload$errors2, _payload$errors2$, _payload$errors3, _payload$errors3$;
|
|
856
|
+
if (!payload) return null;
|
|
857
|
+
return [(_payload$error = payload.error) === null || _payload$error === void 0 ? void 0 : _payload$error.message, payload.message, (_payload$errors = payload.errors) === null || _payload$errors === void 0 ? void 0 : _payload$errors.message, (_payload$errors2 = payload.errors) === null || _payload$errors2 === void 0 ? void 0 : (_payload$errors2$ = _payload$errors2[0]) === null || _payload$errors2$ === void 0 ? void 0 : _payload$errors2$.message, (_payload$errors3 = payload.errors) === null || _payload$errors3 === void 0 ? void 0 : (_payload$errors3$ = _payload$errors3[0]) === null || _payload$errors3$ === void 0 ? void 0 : _payload$errors3$.description].find(reason => typeof reason === 'string' && reason.trim().length > 0);
|
|
858
|
+
}
|
|
684
859
|
}, {
|
|
685
860
|
key: "messageAttachmentsContainer",
|
|
686
861
|
value: function messageAttachmentsContainer(element) {
|
|
@@ -809,10 +984,29 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
809
984
|
get: function () {
|
|
810
985
|
return window.matchMedia(`(max-width: ${this.fullScreenThresholdValue}px)`).matches;
|
|
811
986
|
}
|
|
987
|
+
}], [{
|
|
988
|
+
key: "messageTimestampFormatterFor",
|
|
989
|
+
value: function messageTimestampFormatterFor(locale) {
|
|
990
|
+
const key = locale || 'default';
|
|
991
|
+
if (!this.messageTimestampFormatters[key]) {
|
|
992
|
+
this.messageTimestampFormatters[key] = this.buildMessageTimestampFormatter(locale);
|
|
993
|
+
}
|
|
994
|
+
return this.messageTimestampFormatters[key];
|
|
995
|
+
}
|
|
996
|
+
}, {
|
|
997
|
+
key: "buildMessageTimestampFormatter",
|
|
998
|
+
value: function buildMessageTimestampFormatter(locale) {
|
|
999
|
+
try {
|
|
1000
|
+
return new Intl.DateTimeFormat(locale || undefined, MESSAGE_TIMESTAMP_FORMAT_OPTIONS);
|
|
1001
|
+
} catch (_) {
|
|
1002
|
+
return new Intl.DateTimeFormat(undefined, MESSAGE_TIMESTAMP_FORMAT_OPTIONS);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
812
1005
|
}]);
|
|
813
1006
|
return _default;
|
|
814
1007
|
}(_stimulus.Controller);
|
|
815
1008
|
exports.default = _default;
|
|
1009
|
+
_default.messageTimestampFormatters = {};
|
|
816
1010
|
_default.values = {
|
|
817
1011
|
id: String,
|
|
818
1012
|
conversationId: String,
|