@hellotext/hellotext 2.1.6 → 2.2.0
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 +124 -0
- package/lib/controllers/message_controller.js +120 -0
- package/lib/controllers/webchat_controller.cjs +105 -6
- package/lib/controllers/webchat_controller.js +116 -11
- package/lib/index.cjs +2 -0
- package/lib/index.js +2 -0
- package/package.json +1 -1
- package/src/controllers/message_controller.js +95 -0
- package/src/controllers/webchat_controller.js +113 -9
- package/src/index.js +2 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _stimulus = require("@hotwired/stimulus");
|
|
8
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
9
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
10
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
11
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
12
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
13
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
14
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
15
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
16
|
+
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
17
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
18
|
+
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; } }
|
|
19
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
20
|
+
let _default = /*#__PURE__*/function (_Controller) {
|
|
21
|
+
_inherits(_default, _Controller);
|
|
22
|
+
var _super = _createSuper(_default);
|
|
23
|
+
function _default() {
|
|
24
|
+
_classCallCheck(this, _default);
|
|
25
|
+
return _super.apply(this, arguments);
|
|
26
|
+
}
|
|
27
|
+
_createClass(_default, [{
|
|
28
|
+
key: "connect",
|
|
29
|
+
value: function connect() {
|
|
30
|
+
this.updateFades();
|
|
31
|
+
}
|
|
32
|
+
}, {
|
|
33
|
+
key: "setId",
|
|
34
|
+
value: function setId({
|
|
35
|
+
detail: id
|
|
36
|
+
}) {
|
|
37
|
+
this.idValue = id;
|
|
38
|
+
this.element.id = id;
|
|
39
|
+
}
|
|
40
|
+
}, {
|
|
41
|
+
key: "onScroll",
|
|
42
|
+
value: function onScroll() {
|
|
43
|
+
this.updateFades();
|
|
44
|
+
}
|
|
45
|
+
}, {
|
|
46
|
+
key: "quickReply",
|
|
47
|
+
value: function quickReply({
|
|
48
|
+
currentTarget
|
|
49
|
+
}) {
|
|
50
|
+
const card = currentTarget.closest('[data-hellotext--message-target="carouselCard"]');
|
|
51
|
+
this.dispatch('quickReply', {
|
|
52
|
+
detail: {
|
|
53
|
+
id: this.idValue,
|
|
54
|
+
product: card.dataset.id,
|
|
55
|
+
buttonId: currentTarget.dataset.id,
|
|
56
|
+
body: currentTarget.dataset.text,
|
|
57
|
+
cardElement: card
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}, {
|
|
62
|
+
key: "moveToLeft",
|
|
63
|
+
value: function moveToLeft() {
|
|
64
|
+
if (!this.hasCarouselContainerTarget) return;
|
|
65
|
+
const scrollAmount = this.getScrollAmount();
|
|
66
|
+
this.carouselContainerTarget.scrollBy({
|
|
67
|
+
left: -scrollAmount,
|
|
68
|
+
behavior: 'smooth'
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}, {
|
|
72
|
+
key: "moveToRight",
|
|
73
|
+
value: function moveToRight() {
|
|
74
|
+
if (!this.hasCarouselContainerTarget) return;
|
|
75
|
+
const scrollAmount = this.getScrollAmount();
|
|
76
|
+
this.carouselContainerTarget.scrollBy({
|
|
77
|
+
left: scrollAmount,
|
|
78
|
+
behavior: 'smooth'
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}, {
|
|
82
|
+
key: "getScrollAmount",
|
|
83
|
+
value: function getScrollAmount() {
|
|
84
|
+
// Get the actual card width from DOM
|
|
85
|
+
const firstCard = this.carouselContainerTarget.querySelector('.message__carousel_card');
|
|
86
|
+
if (!firstCard) {
|
|
87
|
+
return 280; // Fallback to default desktop card width
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const cardWidth = firstCard.offsetWidth;
|
|
91
|
+
const gap = 16; // gap-x-4 = 1rem = 16px
|
|
92
|
+
|
|
93
|
+
return cardWidth + gap;
|
|
94
|
+
}
|
|
95
|
+
}, {
|
|
96
|
+
key: "updateFades",
|
|
97
|
+
value: function updateFades() {
|
|
98
|
+
if (!this.hasCarouselContainerTarget) return;
|
|
99
|
+
const scrollLeft = this.carouselContainerTarget.scrollLeft;
|
|
100
|
+
const maxScroll = this.carouselContainerTarget.scrollWidth - this.carouselContainerTarget.clientWidth;
|
|
101
|
+
|
|
102
|
+
// Show left fade if scrolled past start
|
|
103
|
+
if (scrollLeft > 0) {
|
|
104
|
+
this.leftFadeTarget.classList.remove('hidden');
|
|
105
|
+
} else {
|
|
106
|
+
this.leftFadeTarget.classList.add('hidden');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Show right fade if not at end
|
|
110
|
+
if (scrollLeft < maxScroll - 1) {
|
|
111
|
+
// -1 for rounding errors
|
|
112
|
+
this.rightFadeTarget.classList.remove('hidden');
|
|
113
|
+
} else {
|
|
114
|
+
this.rightFadeTarget.classList.add('hidden');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}]);
|
|
118
|
+
return _default;
|
|
119
|
+
}(_stimulus.Controller);
|
|
120
|
+
exports.default = _default;
|
|
121
|
+
_default.values = {
|
|
122
|
+
id: String
|
|
123
|
+
};
|
|
124
|
+
_default.targets = ['carouselContainer', 'leftFade', 'rightFade', 'carouselCard'];
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
2
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
3
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
4
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
5
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
6
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
7
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
8
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
9
|
+
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
10
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
11
|
+
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; } }
|
|
12
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
13
|
+
import { Controller } from '@hotwired/stimulus';
|
|
14
|
+
var _default = /*#__PURE__*/function (_Controller) {
|
|
15
|
+
_inherits(_default, _Controller);
|
|
16
|
+
var _super = _createSuper(_default);
|
|
17
|
+
function _default() {
|
|
18
|
+
_classCallCheck(this, _default);
|
|
19
|
+
return _super.apply(this, arguments);
|
|
20
|
+
}
|
|
21
|
+
_createClass(_default, [{
|
|
22
|
+
key: "connect",
|
|
23
|
+
value: function connect() {
|
|
24
|
+
this.updateFades();
|
|
25
|
+
}
|
|
26
|
+
}, {
|
|
27
|
+
key: "setId",
|
|
28
|
+
value: function setId(_ref) {
|
|
29
|
+
var {
|
|
30
|
+
detail: id
|
|
31
|
+
} = _ref;
|
|
32
|
+
this.idValue = id;
|
|
33
|
+
this.element.id = id;
|
|
34
|
+
}
|
|
35
|
+
}, {
|
|
36
|
+
key: "onScroll",
|
|
37
|
+
value: function onScroll() {
|
|
38
|
+
this.updateFades();
|
|
39
|
+
}
|
|
40
|
+
}, {
|
|
41
|
+
key: "quickReply",
|
|
42
|
+
value: function quickReply(_ref2) {
|
|
43
|
+
var {
|
|
44
|
+
currentTarget
|
|
45
|
+
} = _ref2;
|
|
46
|
+
var card = currentTarget.closest('[data-hellotext--message-target="carouselCard"]');
|
|
47
|
+
this.dispatch('quickReply', {
|
|
48
|
+
detail: {
|
|
49
|
+
id: this.idValue,
|
|
50
|
+
product: card.dataset.id,
|
|
51
|
+
buttonId: currentTarget.dataset.id,
|
|
52
|
+
body: currentTarget.dataset.text,
|
|
53
|
+
cardElement: card
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}, {
|
|
58
|
+
key: "moveToLeft",
|
|
59
|
+
value: function moveToLeft() {
|
|
60
|
+
if (!this.hasCarouselContainerTarget) return;
|
|
61
|
+
var scrollAmount = this.getScrollAmount();
|
|
62
|
+
this.carouselContainerTarget.scrollBy({
|
|
63
|
+
left: -scrollAmount,
|
|
64
|
+
behavior: 'smooth'
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}, {
|
|
68
|
+
key: "moveToRight",
|
|
69
|
+
value: function moveToRight() {
|
|
70
|
+
if (!this.hasCarouselContainerTarget) return;
|
|
71
|
+
var scrollAmount = this.getScrollAmount();
|
|
72
|
+
this.carouselContainerTarget.scrollBy({
|
|
73
|
+
left: scrollAmount,
|
|
74
|
+
behavior: 'smooth'
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}, {
|
|
78
|
+
key: "getScrollAmount",
|
|
79
|
+
value: function getScrollAmount() {
|
|
80
|
+
// Get the actual card width from DOM
|
|
81
|
+
var firstCard = this.carouselContainerTarget.querySelector('.message__carousel_card');
|
|
82
|
+
if (!firstCard) {
|
|
83
|
+
return 280; // Fallback to default desktop card width
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
var cardWidth = firstCard.offsetWidth;
|
|
87
|
+
var gap = 16; // gap-x-4 = 1rem = 16px
|
|
88
|
+
|
|
89
|
+
return cardWidth + gap;
|
|
90
|
+
}
|
|
91
|
+
}, {
|
|
92
|
+
key: "updateFades",
|
|
93
|
+
value: function updateFades() {
|
|
94
|
+
if (!this.hasCarouselContainerTarget) return;
|
|
95
|
+
var scrollLeft = this.carouselContainerTarget.scrollLeft;
|
|
96
|
+
var maxScroll = this.carouselContainerTarget.scrollWidth - this.carouselContainerTarget.clientWidth;
|
|
97
|
+
|
|
98
|
+
// Show left fade if scrolled past start
|
|
99
|
+
if (scrollLeft > 0) {
|
|
100
|
+
this.leftFadeTarget.classList.remove('hidden');
|
|
101
|
+
} else {
|
|
102
|
+
this.leftFadeTarget.classList.add('hidden');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Show right fade if not at end
|
|
106
|
+
if (scrollLeft < maxScroll - 1) {
|
|
107
|
+
// -1 for rounding errors
|
|
108
|
+
this.rightFadeTarget.classList.remove('hidden');
|
|
109
|
+
} else {
|
|
110
|
+
this.rightFadeTarget.classList.add('hidden');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}]);
|
|
114
|
+
return _default;
|
|
115
|
+
}(Controller);
|
|
116
|
+
_default.values = {
|
|
117
|
+
id: String
|
|
118
|
+
};
|
|
119
|
+
_default.targets = ['carouselContainer', 'leftFade', 'rightFade', 'carouselCard'];
|
|
120
|
+
export { _default as default };
|
|
@@ -255,6 +255,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
255
255
|
}, {
|
|
256
256
|
key: "onPopoverOpened",
|
|
257
257
|
value: function onPopoverOpened() {
|
|
258
|
+
this.popoverTarget.classList.remove(...this.fadeOutClasses);
|
|
258
259
|
if (!this.onMobile) {
|
|
259
260
|
this.inputTarget.focus();
|
|
260
261
|
}
|
|
@@ -312,6 +313,9 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
312
313
|
body,
|
|
313
314
|
attachments
|
|
314
315
|
} = message;
|
|
316
|
+
if (message.carousel) {
|
|
317
|
+
return this.insertCarouselMessage(message);
|
|
318
|
+
}
|
|
315
319
|
const div = document.createElement('div');
|
|
316
320
|
div.innerHTML = body;
|
|
317
321
|
const element = this.messageTemplateTarget.cloneNode(true);
|
|
@@ -343,6 +347,29 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
343
347
|
const unreadCount = (parseInt(this.unreadCounterTarget.innerText) || 0) + 1;
|
|
344
348
|
this.unreadCounterTarget.innerText = unreadCount > 99 ? '99+' : unreadCount;
|
|
345
349
|
}
|
|
350
|
+
}, {
|
|
351
|
+
key: "insertCarouselMessage",
|
|
352
|
+
value: function insertCarouselMessage(message) {
|
|
353
|
+
var _element$querySelecto;
|
|
354
|
+
const html = message.html;
|
|
355
|
+
const element = new DOMParser().parseFromString(html, 'text/html').body.firstElementChild;
|
|
356
|
+
this.clearTypingIndicator();
|
|
357
|
+
this.messagesContainerTarget.appendChild(element);
|
|
358
|
+
element.scrollIntoView({
|
|
359
|
+
behavior: 'smooth'
|
|
360
|
+
});
|
|
361
|
+
_hellotext.default.eventEmitter.dispatch('webchat:message:received', {
|
|
362
|
+
...message,
|
|
363
|
+
body: ((_element$querySelecto = element.querySelector('[data-body]')) === null || _element$querySelecto === void 0 ? void 0 : _element$querySelecto.innerText) || ''
|
|
364
|
+
});
|
|
365
|
+
if (this.openValue) {
|
|
366
|
+
this.messagesAPI.markAsSeen(message.id);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
this.unreadCounterTarget.style.display = 'flex';
|
|
370
|
+
const unreadCount = (parseInt(this.unreadCounterTarget.innerText) || 0) + 1;
|
|
371
|
+
this.unreadCounterTarget.innerText = unreadCount > 99 ? '99+' : unreadCount;
|
|
372
|
+
}
|
|
346
373
|
}, {
|
|
347
374
|
key: "resizeInput",
|
|
348
375
|
value: function resizeInput() {
|
|
@@ -356,6 +383,71 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
356
383
|
const scrollHeight = this.inputTarget.scrollHeight;
|
|
357
384
|
this.inputTarget.style.height = `${Math.min(scrollHeight, maxHeight)}px`;
|
|
358
385
|
}
|
|
386
|
+
}, {
|
|
387
|
+
key: "sendQuickReplyMessage",
|
|
388
|
+
value: async function sendQuickReplyMessage({
|
|
389
|
+
detail: {
|
|
390
|
+
id,
|
|
391
|
+
product,
|
|
392
|
+
buttonId,
|
|
393
|
+
body,
|
|
394
|
+
cardElement
|
|
395
|
+
}
|
|
396
|
+
}) {
|
|
397
|
+
var _cardElement$querySel;
|
|
398
|
+
const formData = new FormData();
|
|
399
|
+
formData.append('message[body]', body);
|
|
400
|
+
formData.append('message[replied_to]', id);
|
|
401
|
+
formData.append('message[product]', product);
|
|
402
|
+
formData.append('message[button]', buttonId);
|
|
403
|
+
formData.append('session', _hellotext.default.session);
|
|
404
|
+
formData.append('locale', _core.Locale.toString());
|
|
405
|
+
const element = this.buildMessageElement();
|
|
406
|
+
const attachment = (_cardElement$querySel = cardElement.querySelector('img')) === null || _cardElement$querySel === void 0 ? void 0 : _cardElement$querySel.cloneNode(true);
|
|
407
|
+
element.querySelector('[data-body]').innerText = body;
|
|
408
|
+
if (attachment) {
|
|
409
|
+
attachment.removeAttribute('width');
|
|
410
|
+
attachment.removeAttribute('height');
|
|
411
|
+
element.querySelector('[data-attachment-container]').appendChild(attachment);
|
|
412
|
+
}
|
|
413
|
+
if (this.typingIndicatorVisible && this.hasTypingIndicatorTarget) {
|
|
414
|
+
this.messagesContainerTarget.insertBefore(element, this.typingIndicatorTarget);
|
|
415
|
+
} else {
|
|
416
|
+
this.messagesContainerTarget.appendChild(element);
|
|
417
|
+
}
|
|
418
|
+
element.scrollIntoView({
|
|
419
|
+
behavior: 'smooth'
|
|
420
|
+
});
|
|
421
|
+
this.broadcastChannel.postMessage({
|
|
422
|
+
type: 'message:sent',
|
|
423
|
+
element: element.outerHTML
|
|
424
|
+
});
|
|
425
|
+
const response = await this.messagesAPI.create(formData);
|
|
426
|
+
if (response.failed) {
|
|
427
|
+
// Clear the optimistic typing indicator on failure
|
|
428
|
+
clearTimeout(this.optimisticTypingTimeout);
|
|
429
|
+
this.broadcastChannel.postMessage({
|
|
430
|
+
type: 'message:failed',
|
|
431
|
+
id: element.id
|
|
432
|
+
});
|
|
433
|
+
return element.classList.add('failed');
|
|
434
|
+
}
|
|
435
|
+
const data = await response.json();
|
|
436
|
+
this.dispatch('set:id', {
|
|
437
|
+
target: element,
|
|
438
|
+
detail: data.id
|
|
439
|
+
});
|
|
440
|
+
const message = {
|
|
441
|
+
id: data.id,
|
|
442
|
+
body: body,
|
|
443
|
+
attachments: attachment ? [attachment.src] : [],
|
|
444
|
+
replied_to: id,
|
|
445
|
+
product: product,
|
|
446
|
+
button: buttonId,
|
|
447
|
+
type: 'quick_reply'
|
|
448
|
+
};
|
|
449
|
+
_hellotext.default.eventEmitter.dispatch('webchat:message:sent', message);
|
|
450
|
+
}
|
|
359
451
|
}, {
|
|
360
452
|
key: "sendMessage",
|
|
361
453
|
value: async function sendMessage(e) {
|
|
@@ -380,11 +472,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
380
472
|
});
|
|
381
473
|
formData.append('session', _hellotext.default.session);
|
|
382
474
|
formData.append('locale', _core.Locale.toString());
|
|
383
|
-
const element = this.
|
|
384
|
-
element.id = `hellotext--webchat--${this.idValue}--message--${Date.now()}`;
|
|
385
|
-
element.classList.add('received');
|
|
386
|
-
element.style.removeProperty('display');
|
|
387
|
-
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
475
|
+
const element = this.buildMessageElement();
|
|
388
476
|
if (this.inputTarget.value.trim().length > 0) {
|
|
389
477
|
element.querySelector('[data-body]').innerText = this.inputTarget.value;
|
|
390
478
|
} else {
|
|
@@ -393,7 +481,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
393
481
|
const attachments = this.attachmentContainerTarget.querySelectorAll('img');
|
|
394
482
|
if (attachments.length > 0) {
|
|
395
483
|
attachments.forEach(attachment => {
|
|
396
|
-
element.querySelector('[data-attachment-container]').appendChild(attachment);
|
|
484
|
+
element.querySelector('[data-attachment-container]').appendChild(attachment.cloneNode(true));
|
|
397
485
|
});
|
|
398
486
|
}
|
|
399
487
|
|
|
@@ -452,6 +540,17 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
452
540
|
}
|
|
453
541
|
this.attachmentContainerTarget.style.display = '';
|
|
454
542
|
}
|
|
543
|
+
}, {
|
|
544
|
+
key: "buildMessageElement",
|
|
545
|
+
value: function buildMessageElement() {
|
|
546
|
+
const element = this.messageTemplateTarget.cloneNode(true);
|
|
547
|
+
element.id = `hellotext--webchat--${this.idValue}--message--${Date.now()}`;
|
|
548
|
+
element.classList.add('received');
|
|
549
|
+
element.style.removeProperty('display');
|
|
550
|
+
element.setAttribute('data-controller', 'hellotext--message');
|
|
551
|
+
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
552
|
+
return element;
|
|
553
|
+
}
|
|
455
554
|
}, {
|
|
456
555
|
key: "openAttachment",
|
|
457
556
|
value: function openAttachment() {
|
|
@@ -259,6 +259,7 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
259
259
|
}, {
|
|
260
260
|
key: "onPopoverOpened",
|
|
261
261
|
value: function onPopoverOpened() {
|
|
262
|
+
this.popoverTarget.classList.remove(...this.fadeOutClasses);
|
|
262
263
|
if (!this.onMobile) {
|
|
263
264
|
this.inputTarget.focus();
|
|
264
265
|
}
|
|
@@ -316,6 +317,9 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
316
317
|
body,
|
|
317
318
|
attachments
|
|
318
319
|
} = message;
|
|
320
|
+
if (message.carousel) {
|
|
321
|
+
return this.insertCarouselMessage(message);
|
|
322
|
+
}
|
|
319
323
|
var div = document.createElement('div');
|
|
320
324
|
div.innerHTML = body;
|
|
321
325
|
var element = this.messageTemplateTarget.cloneNode(true);
|
|
@@ -346,6 +350,28 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
346
350
|
var unreadCount = (parseInt(this.unreadCounterTarget.innerText) || 0) + 1;
|
|
347
351
|
this.unreadCounterTarget.innerText = unreadCount > 99 ? '99+' : unreadCount;
|
|
348
352
|
}
|
|
353
|
+
}, {
|
|
354
|
+
key: "insertCarouselMessage",
|
|
355
|
+
value: function insertCarouselMessage(message) {
|
|
356
|
+
var _element$querySelecto;
|
|
357
|
+
var html = message.html;
|
|
358
|
+
var element = new DOMParser().parseFromString(html, 'text/html').body.firstElementChild;
|
|
359
|
+
this.clearTypingIndicator();
|
|
360
|
+
this.messagesContainerTarget.appendChild(element);
|
|
361
|
+
element.scrollIntoView({
|
|
362
|
+
behavior: 'smooth'
|
|
363
|
+
});
|
|
364
|
+
Hellotext.eventEmitter.dispatch('webchat:message:received', _objectSpread(_objectSpread({}, message), {}, {
|
|
365
|
+
body: ((_element$querySelecto = element.querySelector('[data-body]')) === null || _element$querySelecto === void 0 ? void 0 : _element$querySelecto.innerText) || ''
|
|
366
|
+
}));
|
|
367
|
+
if (this.openValue) {
|
|
368
|
+
this.messagesAPI.markAsSeen(message.id);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
this.unreadCounterTarget.style.display = 'flex';
|
|
372
|
+
var unreadCount = (parseInt(this.unreadCounterTarget.innerText) || 0) + 1;
|
|
373
|
+
this.unreadCounterTarget.innerText = unreadCount > 99 ? '99+' : unreadCount;
|
|
374
|
+
}
|
|
349
375
|
}, {
|
|
350
376
|
key: "resizeInput",
|
|
351
377
|
value: function resizeInput() {
|
|
@@ -359,6 +385,78 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
359
385
|
var scrollHeight = this.inputTarget.scrollHeight;
|
|
360
386
|
this.inputTarget.style.height = "".concat(Math.min(scrollHeight, maxHeight), "px");
|
|
361
387
|
}
|
|
388
|
+
}, {
|
|
389
|
+
key: "sendQuickReplyMessage",
|
|
390
|
+
value: function () {
|
|
391
|
+
var _sendQuickReplyMessage = _asyncToGenerator(function* (_ref) {
|
|
392
|
+
var _cardElement$querySel;
|
|
393
|
+
var {
|
|
394
|
+
detail: {
|
|
395
|
+
id,
|
|
396
|
+
product,
|
|
397
|
+
buttonId,
|
|
398
|
+
body,
|
|
399
|
+
cardElement
|
|
400
|
+
}
|
|
401
|
+
} = _ref;
|
|
402
|
+
var formData = new FormData();
|
|
403
|
+
formData.append('message[body]', body);
|
|
404
|
+
formData.append('message[replied_to]', id);
|
|
405
|
+
formData.append('message[product]', product);
|
|
406
|
+
formData.append('message[button]', buttonId);
|
|
407
|
+
formData.append('session', Hellotext.session);
|
|
408
|
+
formData.append('locale', Locale.toString());
|
|
409
|
+
var element = this.buildMessageElement();
|
|
410
|
+
var attachment = (_cardElement$querySel = cardElement.querySelector('img')) === null || _cardElement$querySel === void 0 ? void 0 : _cardElement$querySel.cloneNode(true);
|
|
411
|
+
element.querySelector('[data-body]').innerText = body;
|
|
412
|
+
if (attachment) {
|
|
413
|
+
attachment.removeAttribute('width');
|
|
414
|
+
attachment.removeAttribute('height');
|
|
415
|
+
element.querySelector('[data-attachment-container]').appendChild(attachment);
|
|
416
|
+
}
|
|
417
|
+
if (this.typingIndicatorVisible && this.hasTypingIndicatorTarget) {
|
|
418
|
+
this.messagesContainerTarget.insertBefore(element, this.typingIndicatorTarget);
|
|
419
|
+
} else {
|
|
420
|
+
this.messagesContainerTarget.appendChild(element);
|
|
421
|
+
}
|
|
422
|
+
element.scrollIntoView({
|
|
423
|
+
behavior: 'smooth'
|
|
424
|
+
});
|
|
425
|
+
this.broadcastChannel.postMessage({
|
|
426
|
+
type: 'message:sent',
|
|
427
|
+
element: element.outerHTML
|
|
428
|
+
});
|
|
429
|
+
var response = yield this.messagesAPI.create(formData);
|
|
430
|
+
if (response.failed) {
|
|
431
|
+
// Clear the optimistic typing indicator on failure
|
|
432
|
+
clearTimeout(this.optimisticTypingTimeout);
|
|
433
|
+
this.broadcastChannel.postMessage({
|
|
434
|
+
type: 'message:failed',
|
|
435
|
+
id: element.id
|
|
436
|
+
});
|
|
437
|
+
return element.classList.add('failed');
|
|
438
|
+
}
|
|
439
|
+
var data = yield response.json();
|
|
440
|
+
this.dispatch('set:id', {
|
|
441
|
+
target: element,
|
|
442
|
+
detail: data.id
|
|
443
|
+
});
|
|
444
|
+
var message = {
|
|
445
|
+
id: data.id,
|
|
446
|
+
body: body,
|
|
447
|
+
attachments: attachment ? [attachment.src] : [],
|
|
448
|
+
replied_to: id,
|
|
449
|
+
product: product,
|
|
450
|
+
button: buttonId,
|
|
451
|
+
type: 'quick_reply'
|
|
452
|
+
};
|
|
453
|
+
Hellotext.eventEmitter.dispatch('webchat:message:sent', message);
|
|
454
|
+
});
|
|
455
|
+
function sendQuickReplyMessage(_x) {
|
|
456
|
+
return _sendQuickReplyMessage.apply(this, arguments);
|
|
457
|
+
}
|
|
458
|
+
return sendQuickReplyMessage;
|
|
459
|
+
}()
|
|
362
460
|
}, {
|
|
363
461
|
key: "sendMessage",
|
|
364
462
|
value: function () {
|
|
@@ -384,11 +482,7 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
384
482
|
});
|
|
385
483
|
formData.append('session', Hellotext.session);
|
|
386
484
|
formData.append('locale', Locale.toString());
|
|
387
|
-
var element = this.
|
|
388
|
-
element.id = "hellotext--webchat--".concat(this.idValue, "--message--").concat(Date.now());
|
|
389
|
-
element.classList.add('received');
|
|
390
|
-
element.style.removeProperty('display');
|
|
391
|
-
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
485
|
+
var element = this.buildMessageElement();
|
|
392
486
|
if (this.inputTarget.value.trim().length > 0) {
|
|
393
487
|
element.querySelector('[data-body]').innerText = this.inputTarget.value;
|
|
394
488
|
} else {
|
|
@@ -397,7 +491,7 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
397
491
|
var attachments = this.attachmentContainerTarget.querySelectorAll('img');
|
|
398
492
|
if (attachments.length > 0) {
|
|
399
493
|
attachments.forEach(attachment => {
|
|
400
|
-
element.querySelector('[data-attachment-container]').appendChild(attachment);
|
|
494
|
+
element.querySelector('[data-attachment-container]').appendChild(attachment.cloneNode(true));
|
|
401
495
|
});
|
|
402
496
|
}
|
|
403
497
|
|
|
@@ -456,11 +550,22 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
456
550
|
}
|
|
457
551
|
this.attachmentContainerTarget.style.display = '';
|
|
458
552
|
});
|
|
459
|
-
function sendMessage(
|
|
553
|
+
function sendMessage(_x2) {
|
|
460
554
|
return _sendMessage.apply(this, arguments);
|
|
461
555
|
}
|
|
462
556
|
return sendMessage;
|
|
463
557
|
}()
|
|
558
|
+
}, {
|
|
559
|
+
key: "buildMessageElement",
|
|
560
|
+
value: function buildMessageElement() {
|
|
561
|
+
var element = this.messageTemplateTarget.cloneNode(true);
|
|
562
|
+
element.id = "hellotext--webchat--".concat(this.idValue, "--message--").concat(Date.now());
|
|
563
|
+
element.classList.add('received');
|
|
564
|
+
element.style.removeProperty('display');
|
|
565
|
+
element.setAttribute('data-controller', 'hellotext--message');
|
|
566
|
+
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
567
|
+
return element;
|
|
568
|
+
}
|
|
464
569
|
}, {
|
|
465
570
|
key: "openAttachment",
|
|
466
571
|
value: function openAttachment() {
|
|
@@ -517,10 +622,10 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
517
622
|
}
|
|
518
623
|
}, {
|
|
519
624
|
key: "removeAttachment",
|
|
520
|
-
value: function removeAttachment(
|
|
625
|
+
value: function removeAttachment(_ref2) {
|
|
521
626
|
var {
|
|
522
627
|
currentTarget
|
|
523
|
-
} =
|
|
628
|
+
} = _ref2;
|
|
524
629
|
var attachment = currentTarget.closest("[data-hellotext--webchat-target='attachment']");
|
|
525
630
|
this.files = this.files.filter(file => file.name !== attachment.dataset.name);
|
|
526
631
|
this.attachmentInputTarget.value = '';
|
|
@@ -546,10 +651,10 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
546
651
|
}
|
|
547
652
|
}, {
|
|
548
653
|
key: "onEmojiSelect",
|
|
549
|
-
value: function onEmojiSelect(
|
|
654
|
+
value: function onEmojiSelect(_ref3) {
|
|
550
655
|
var {
|
|
551
656
|
detail: emoji
|
|
552
|
-
} =
|
|
657
|
+
} = _ref3;
|
|
553
658
|
var value = this.inputTarget.value;
|
|
554
659
|
var start = this.inputTarget.selectionStart;
|
|
555
660
|
var end = this.inputTarget.selectionEnd;
|
package/lib/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ exports.default = void 0;
|
|
|
7
7
|
var _stimulus = require("@hotwired/stimulus");
|
|
8
8
|
var _hellotext = _interopRequireDefault(require("./hellotext"));
|
|
9
9
|
var _form_controller = _interopRequireDefault(require("./controllers/form_controller"));
|
|
10
|
+
var _message_controller = _interopRequireDefault(require("./controllers/message_controller"));
|
|
10
11
|
var _emoji_picker_controller = _interopRequireDefault(require("./controllers/webchat/emoji_picker_controller"));
|
|
11
12
|
var _webchat_controller = _interopRequireDefault(require("./controllers/webchat_controller"));
|
|
12
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -14,6 +15,7 @@ const application = _stimulus.Application.start();
|
|
|
14
15
|
application.register('hellotext--form', _form_controller.default);
|
|
15
16
|
application.register('hellotext--webchat', _webchat_controller.default);
|
|
16
17
|
application.register('hellotext--webchat--emoji', _emoji_picker_controller.default);
|
|
18
|
+
application.register('hellotext--message', _message_controller.default);
|
|
17
19
|
window.Hellotext = _hellotext.default;
|
|
18
20
|
var _default = _hellotext.default;
|
|
19
21
|
exports.default = _default;
|
package/lib/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Application } from '@hotwired/stimulus';
|
|
2
2
|
import Hellotext from './hellotext';
|
|
3
3
|
import FormController from './controllers/form_controller';
|
|
4
|
+
import MessageController from './controllers/message_controller';
|
|
4
5
|
import WebChatEmojiController from './controllers/webchat/emoji_picker_controller';
|
|
5
6
|
import WebchatController from './controllers/webchat_controller';
|
|
6
7
|
var application = Application.start();
|
|
7
8
|
application.register('hellotext--form', FormController);
|
|
8
9
|
application.register('hellotext--webchat', WebchatController);
|
|
9
10
|
application.register('hellotext--webchat--emoji', WebChatEmojiController);
|
|
11
|
+
application.register('hellotext--message', MessageController);
|
|
10
12
|
window.Hellotext = Hellotext;
|
|
11
13
|
export default Hellotext;
|