@hellotext/hellotext 1.8.7 → 2.0.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/api/businesses.cjs +37 -0
- package/lib/api/businesses.js +3 -9
- package/lib/api/events.cjs +45 -0
- package/lib/api/events.js +8 -14
- package/lib/api/forms.cjs +51 -0
- package/lib/api/forms.js +10 -17
- package/lib/api/index.cjs +51 -0
- package/lib/api/index.js +10 -23
- package/lib/api/response.cjs +76 -0
- package/lib/api/response.js +1 -7
- package/lib/api/submissions.cjs +47 -0
- package/lib/api/submissions.js +9 -17
- package/lib/api/webchat/messages.cjs +70 -0
- package/lib/api/webchat/messages.js +10 -18
- package/lib/api/webchats.cjs +44 -0
- package/lib/api/webchats.js +8 -16
- package/lib/builders/input_builder.cjs +61 -0
- package/lib/builders/input_builder.js +4 -11
- package/lib/builders/logo_builder.cjs +50 -0
- package/lib/builders/logo_builder.js +5 -12
- package/lib/channels/application_channel.cjs +67 -0
- package/lib/channels/application_channel.js +1 -8
- package/lib/channels/{web_chat_channel.js → webchat_channel.cjs} +35 -20
- package/lib/channels/webchat_channel.js +3 -11
- package/lib/controllers/form_controller.cjs +141 -0
- package/lib/controllers/form_controller.js +15 -22
- package/lib/controllers/mixins/usePopover.cjs +59 -0
- package/lib/controllers/mixins/usePopover.js +6 -14
- package/lib/controllers/{web_chat/pagination_controller.js → webchat/emoji_picker_controller.cjs} +74 -29
- package/lib/controllers/webchat/emoji_picker_controller.js +11 -17
- package/lib/controllers/webchat_controller.cjs +433 -0
- package/lib/controllers/webchat_controller.js +49 -51
- package/lib/core/configuration/forms.cjs +49 -0
- package/lib/core/configuration/forms.js +2 -8
- package/lib/core/configuration/{web_chat.js → webchat.cjs} +53 -38
- package/lib/core/configuration/webchat.js +2 -9
- package/lib/core/configuration.cjs +65 -0
- package/lib/core/configuration.js +8 -13
- package/lib/core/event.cjs +71 -0
- package/lib/core/event.js +5 -11
- package/lib/core/index.cjs +20 -0
- package/lib/core/index.js +2 -20
- package/lib/errors/index.cjs +19 -0
- package/lib/errors/index.js +2 -19
- package/lib/errors/invalid_event.cjs +34 -0
- package/lib/errors/invalid_event.js +1 -7
- package/lib/errors/not_initialized_error.cjs +34 -0
- package/lib/errors/not_initialized_error.js +1 -7
- package/lib/hellotext.cjs +152 -0
- package/lib/hellotext.js +18 -27
- package/lib/index.cjs +20 -0
- package/lib/index.js +12 -20
- package/lib/locales/en.cjs +22 -0
- package/lib/locales/en.js +2 -9
- package/lib/locales/es.cjs +22 -0
- package/lib/locales/es.js +2 -9
- package/lib/locales/index.cjs +14 -0
- package/lib/locales/index.js +6 -14
- package/lib/models/business.cjs +65 -0
- package/lib/models/business.js +5 -12
- package/lib/models/cookies.cjs +40 -0
- package/lib/models/cookies.js +3 -10
- package/lib/models/form.cjs +166 -0
- package/lib/models/form.js +10 -17
- package/lib/models/form_collection.cjs +119 -0
- package/lib/models/form_collection.js +15 -22
- package/lib/models/index.cjs +54 -0
- package/lib/models/index.js +7 -54
- package/lib/models/query.cjs +51 -0
- package/lib/models/query.js +3 -9
- package/lib/models/session.cjs +58 -0
- package/lib/models/session.js +12 -17
- package/lib/models/{web_chat.js → webchat.cjs} +14 -22
- package/lib/models/webchat.js +6 -13
- package/lib/vanilla.cjs +13 -0
- package/lib/vanilla.js +1 -13
- package/package.json +34 -7
- package/src/controllers/webchat_controller.js +72 -47
- package/src/hellotext.js +3 -4
- package/src/models/session.js +4 -3
- package/.babelrc +0 -24
- package/.github/workflows/ci.yml +0 -24
- package/.prettierignore +0 -3
- package/.prettierrc.json +0 -18
- package/MIT-LICENSE +0 -20
- package/__tests__/builders/input_builder_test.js +0 -117
- package/__tests__/core/configuration/forms_test.js +0 -30
- package/__tests__/core/configuration/webchat_test.js +0 -163
- package/__tests__/core/configuration_test.js +0 -28
- package/__tests__/core/event_test.js +0 -56
- package/__tests__/hellotext_test.js +0 -197
- package/__tests__/models/business_test.js +0 -26
- package/__tests__/models/cookies_test.js +0 -25
- package/__tests__/models/form_collection_test.js +0 -103
- package/__tests__/models/form_test.js +0 -131
- package/__tests__/models/query_test.js +0 -97
- package/docs/forms.md +0 -176
- package/docs/tracking.md +0 -203
- package/docs/webchat.md +0 -101
- package/jest.config.js +0 -4
- package/jest.setup.js +0 -16
- package/lib/api/web_chat/messages.js +0 -74
- package/lib/api/web_chats.js +0 -53
- package/styles/index.css +0 -38
- package/webpack.config.js +0 -24
|
@@ -1,13 +1,3 @@
|
|
|
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
|
-
var _dom = require("@floating-ui/dom");
|
|
9
|
-
var _emojiMart = require("emoji-mart");
|
|
10
|
-
var _usePopover = require("../mixins/usePopover");
|
|
11
1
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
12
2
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
13
3
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
@@ -24,6 +14,10 @@ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "
|
|
|
24
14
|
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
25
15
|
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; } }
|
|
26
16
|
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
17
|
+
import { Controller } from '@hotwired/stimulus';
|
|
18
|
+
import { computePosition, autoUpdate, shift, autoPlacement, offset } from '@floating-ui/dom';
|
|
19
|
+
import { Picker } from 'emoji-mart';
|
|
20
|
+
import { usePopover } from '../mixins/usePopover';
|
|
27
21
|
var _default = /*#__PURE__*/function (_Controller) {
|
|
28
22
|
_inherits(_default, _Controller);
|
|
29
23
|
var _super = _createSuper(_default);
|
|
@@ -40,7 +34,7 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
40
34
|
}, {
|
|
41
35
|
key: "connect",
|
|
42
36
|
value: function connect() {
|
|
43
|
-
|
|
37
|
+
usePopover(this);
|
|
44
38
|
this.setupFloatingUI({
|
|
45
39
|
trigger: this.buttonTarget,
|
|
46
40
|
popover: this.popoverTarget
|
|
@@ -72,7 +66,7 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
72
66
|
}, {
|
|
73
67
|
key: "pickerObject",
|
|
74
68
|
get: function get() {
|
|
75
|
-
return new
|
|
69
|
+
return new Picker({
|
|
76
70
|
onEmojiSelect: this.onEmojiSelect,
|
|
77
71
|
theme: 'light',
|
|
78
72
|
dynamicWidth: true,
|
|
@@ -95,16 +89,15 @@ var _default = /*#__PURE__*/function (_Controller) {
|
|
|
95
89
|
}, {
|
|
96
90
|
key: "middlewares",
|
|
97
91
|
get: function get() {
|
|
98
|
-
return [
|
|
92
|
+
return [offset(5), shift({
|
|
99
93
|
padding: 24
|
|
100
|
-
}),
|
|
94
|
+
}), autoPlacement({
|
|
101
95
|
allowedPlacements: ['top', 'bottom']
|
|
102
96
|
})];
|
|
103
97
|
}
|
|
104
98
|
}]);
|
|
105
99
|
return _default;
|
|
106
|
-
}(
|
|
107
|
-
exports.default = _default;
|
|
100
|
+
}(Controller);
|
|
108
101
|
_default.targets = ['button', 'popover'];
|
|
109
102
|
_default.values = {
|
|
110
103
|
placement: {
|
|
@@ -131,4 +124,5 @@ _default.values = {
|
|
|
131
124
|
type: Number,
|
|
132
125
|
default: 9
|
|
133
126
|
}
|
|
134
|
-
};
|
|
127
|
+
};
|
|
128
|
+
export { _default as default };
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _dom = require("@floating-ui/dom");
|
|
8
|
+
var _stimulus = require("@hotwired/stimulus");
|
|
9
|
+
var _messages = _interopRequireDefault(require("../api/webchat/messages"));
|
|
10
|
+
var _webchat_channel = _interopRequireDefault(require("../channels/webchat_channel"));
|
|
11
|
+
var _hellotext = _interopRequireDefault(require("../hellotext"));
|
|
12
|
+
var _webchat = require("../core/configuration/webchat");
|
|
13
|
+
var _logo_builder = require("../builders/logo_builder");
|
|
14
|
+
var _usePopover = require("./mixins/usePopover");
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
17
|
+
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); } }
|
|
18
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
19
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
20
|
+
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); }
|
|
21
|
+
function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
|
|
22
|
+
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
|
|
23
|
+
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); }
|
|
24
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
25
|
+
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); }; }
|
|
26
|
+
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); }
|
|
27
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
28
|
+
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; } }
|
|
29
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
30
|
+
let _default = /*#__PURE__*/function (_Controller) {
|
|
31
|
+
_inherits(_default, _Controller);
|
|
32
|
+
var _super = _createSuper(_default);
|
|
33
|
+
function _default() {
|
|
34
|
+
_classCallCheck(this, _default);
|
|
35
|
+
return _super.apply(this, arguments);
|
|
36
|
+
}
|
|
37
|
+
_createClass(_default, [{
|
|
38
|
+
key: "initialize",
|
|
39
|
+
value: function initialize() {
|
|
40
|
+
this.messagesAPI = new _messages.default(this.idValue);
|
|
41
|
+
this.webChatChannel = new _webchat_channel.default(this.idValue, _hellotext.default.session, this.conversationIdValue);
|
|
42
|
+
this.files = [];
|
|
43
|
+
this.onMessageReceived = this.onMessageReceived.bind(this);
|
|
44
|
+
this.onConversationAssignment = this.onConversationAssignment.bind(this);
|
|
45
|
+
this.onAgentOnline = this.onAgentOnline.bind(this);
|
|
46
|
+
this.onMessageReaction = this.onMessageReaction.bind(this);
|
|
47
|
+
this.onScroll = this.onScroll.bind(this);
|
|
48
|
+
_get(_getPrototypeOf(_default.prototype), "initialize", this).call(this);
|
|
49
|
+
}
|
|
50
|
+
}, {
|
|
51
|
+
key: "connect",
|
|
52
|
+
value: function connect() {
|
|
53
|
+
(0, _usePopover.usePopover)(this);
|
|
54
|
+
this.popoverTarget.classList.add(..._webchat.Webchat.classes);
|
|
55
|
+
this.triggerTarget.classList.add(..._webchat.Webchat.triggerClasses);
|
|
56
|
+
this.setupFloatingUI({
|
|
57
|
+
trigger: this.triggerTarget,
|
|
58
|
+
popover: this.popoverTarget
|
|
59
|
+
});
|
|
60
|
+
this.webChatChannel.onMessage(this.onMessageReceived);
|
|
61
|
+
this.webChatChannel.onConversationAssignment(this.onConversationAssignment);
|
|
62
|
+
this.webChatChannel.onAgentOnline(this.onAgentOnline);
|
|
63
|
+
this.webChatChannel.onReaction(this.onMessageReaction);
|
|
64
|
+
this.messagesContainerTarget.addEventListener('scroll', this.onScroll);
|
|
65
|
+
if (!_hellotext.default.business.features.white_label) {
|
|
66
|
+
this.toolbarTarget.appendChild(_logo_builder.LogoBuilder.build());
|
|
67
|
+
}
|
|
68
|
+
if (localStorage.getItem(`hellotext--webchat--${this.idValue}`) === 'opened') {
|
|
69
|
+
this.openValue = true;
|
|
70
|
+
}
|
|
71
|
+
_hellotext.default.eventEmitter.dispatch('webchat:mounted');
|
|
72
|
+
_get(_getPrototypeOf(_default.prototype), "connect", this).call(this);
|
|
73
|
+
}
|
|
74
|
+
}, {
|
|
75
|
+
key: "disconnect",
|
|
76
|
+
value: function disconnect() {
|
|
77
|
+
this.messagesContainerTarget.removeEventListener('scroll', this.onScroll);
|
|
78
|
+
this.floatingUICleanup();
|
|
79
|
+
_get(_getPrototypeOf(_default.prototype), "disconnect", this).call(this);
|
|
80
|
+
}
|
|
81
|
+
}, {
|
|
82
|
+
key: "onScroll",
|
|
83
|
+
value: async function onScroll() {
|
|
84
|
+
if (this.messagesContainerTarget.scrollTop > 300 || !this.nextPageValue || this.fetchingNextPage) return;
|
|
85
|
+
this.fetchingNextPage = true;
|
|
86
|
+
const response = await this.messagesAPI.index({
|
|
87
|
+
page: this.nextPageValue,
|
|
88
|
+
session: _hellotext.default.session
|
|
89
|
+
});
|
|
90
|
+
const {
|
|
91
|
+
next: nextPage,
|
|
92
|
+
messages
|
|
93
|
+
} = await response.json();
|
|
94
|
+
this.nextPageValue = nextPage;
|
|
95
|
+
this.oldScrollHeight = this.messagesContainerTarget.scrollHeight;
|
|
96
|
+
messages.forEach(message => {
|
|
97
|
+
const {
|
|
98
|
+
body,
|
|
99
|
+
attachments
|
|
100
|
+
} = message;
|
|
101
|
+
const div = document.createElement('div');
|
|
102
|
+
div.innerHTML = body;
|
|
103
|
+
const element = this.messageTemplateTarget.cloneNode(true);
|
|
104
|
+
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
105
|
+
element.style.removeProperty('display');
|
|
106
|
+
element.querySelector('[data-body]').innerHTML = div.innerHTML;
|
|
107
|
+
if (message.state === 'received') {
|
|
108
|
+
element.classList.add('received');
|
|
109
|
+
} else {
|
|
110
|
+
element.classList.remove('received');
|
|
111
|
+
}
|
|
112
|
+
if (attachments) {
|
|
113
|
+
attachments.forEach(attachmentUrl => {
|
|
114
|
+
const image = this.attachmentImageTarget.cloneNode(true);
|
|
115
|
+
image.removeAttribute('data-hellotext--webchat-target');
|
|
116
|
+
image.src = attachmentUrl;
|
|
117
|
+
image.style.display = 'block';
|
|
118
|
+
element.querySelector('[data-attachment-container]').appendChild(image);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
element.setAttribute('data-body', body);
|
|
122
|
+
this.messagesContainerTarget.prepend(element);
|
|
123
|
+
});
|
|
124
|
+
this.messagesContainerTarget.scroll({
|
|
125
|
+
top: this.messagesContainerTarget.scrollHeight - this.oldScrollHeight,
|
|
126
|
+
behavior: 'instant'
|
|
127
|
+
});
|
|
128
|
+
this.fetchingNextPage = false;
|
|
129
|
+
}
|
|
130
|
+
}, {
|
|
131
|
+
key: "onClickOutside",
|
|
132
|
+
value: function onClickOutside(event) {
|
|
133
|
+
if (_webchat.Webchat.behaviour === _webchat.behaviors.POPOVER && this.openValue && event.target.nodeType && this.element.contains(event.target) === false) {
|
|
134
|
+
this.openValue = false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}, {
|
|
138
|
+
key: "onPopoverOpened",
|
|
139
|
+
value: function onPopoverOpened() {
|
|
140
|
+
this.inputTarget.focus();
|
|
141
|
+
if (!this.scrolled) {
|
|
142
|
+
this.messagesContainerTarget.scroll({
|
|
143
|
+
top: this.messagesContainerTarget.scrollHeight,
|
|
144
|
+
behavior: 'instant'
|
|
145
|
+
});
|
|
146
|
+
this.scrolled = true;
|
|
147
|
+
}
|
|
148
|
+
_hellotext.default.eventEmitter.dispatch('webchat:opened');
|
|
149
|
+
localStorage.setItem(`hellotext--webchat--${this.idValue}`, 'opened');
|
|
150
|
+
if (this.unreadCounterTarget.style.display === 'none') return;
|
|
151
|
+
this.unreadCounterTarget.style.display = 'none';
|
|
152
|
+
this.unreadCounterTarget.innerText = '0';
|
|
153
|
+
this.messagesAPI.markAsSeen();
|
|
154
|
+
}
|
|
155
|
+
}, {
|
|
156
|
+
key: "onPopoverClosed",
|
|
157
|
+
value: function onPopoverClosed() {
|
|
158
|
+
_hellotext.default.eventEmitter.dispatch('webchat:closed');
|
|
159
|
+
setTimeout(() => {
|
|
160
|
+
this.inputTarget.value = '';
|
|
161
|
+
});
|
|
162
|
+
localStorage.setItem(`hellotext--webchat--${this.idValue}`, 'closed');
|
|
163
|
+
}
|
|
164
|
+
}, {
|
|
165
|
+
key: "onMessageReaction",
|
|
166
|
+
value: function onMessageReaction(message) {
|
|
167
|
+
const {
|
|
168
|
+
message: messageId,
|
|
169
|
+
reaction,
|
|
170
|
+
type
|
|
171
|
+
} = message;
|
|
172
|
+
const messageElement = this.messageTargets.find(element => element.dataset.id === messageId);
|
|
173
|
+
const reactionsContainer = messageElement.querySelector('[data-reactions]');
|
|
174
|
+
if (type === 'reaction.destroy') {
|
|
175
|
+
const reactionElement = reactionsContainer.querySelector(`[data-id="${reaction.id}"]`);
|
|
176
|
+
return reactionElement.remove();
|
|
177
|
+
}
|
|
178
|
+
if (reactionsContainer.querySelector(`[data-id="${reaction.id}"]`)) {
|
|
179
|
+
const reactionElement = reactionsContainer.querySelector(`[data-id="${reaction.id}"]`);
|
|
180
|
+
reactionElement.innerText = reaction.emoji;
|
|
181
|
+
} else {
|
|
182
|
+
const reactionElement = document.createElement('span');
|
|
183
|
+
reactionElement.innerText = reaction.emoji;
|
|
184
|
+
reactionElement.setAttribute('data-id', reaction.id);
|
|
185
|
+
reactionsContainer.appendChild(reactionElement);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}, {
|
|
189
|
+
key: "onMessageReceived",
|
|
190
|
+
value: function onMessageReceived(message) {
|
|
191
|
+
const {
|
|
192
|
+
body,
|
|
193
|
+
attachments
|
|
194
|
+
} = message;
|
|
195
|
+
const div = document.createElement('div');
|
|
196
|
+
div.innerHTML = body;
|
|
197
|
+
const element = this.messageTemplateTarget.cloneNode(true);
|
|
198
|
+
element.style.display = 'flex';
|
|
199
|
+
element.querySelector('[data-body]').innerHTML = div.innerHTML;
|
|
200
|
+
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
201
|
+
if (attachments) {
|
|
202
|
+
attachments.forEach(attachmentUrl => {
|
|
203
|
+
const image = this.attachmentImageTarget.cloneNode(true);
|
|
204
|
+
image.src = attachmentUrl;
|
|
205
|
+
image.style.display = 'block';
|
|
206
|
+
element.querySelector('[data-attachment-container]').appendChild(image);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
this.messagesContainerTarget.appendChild(element);
|
|
210
|
+
_hellotext.default.eventEmitter.dispatch('webchat:message:received', {
|
|
211
|
+
...message,
|
|
212
|
+
body: element.querySelector('[data-body]').innerText
|
|
213
|
+
});
|
|
214
|
+
element.scrollIntoView({
|
|
215
|
+
behavior: 'smooth'
|
|
216
|
+
});
|
|
217
|
+
this.setOfflineTimeout();
|
|
218
|
+
if (this.openValue) return;
|
|
219
|
+
this.unreadCounterTarget.style.display = 'flex';
|
|
220
|
+
const unreadCount = (parseInt(this.unreadCounterTarget.innerText) || 0) + 1;
|
|
221
|
+
this.unreadCounterTarget.innerText = unreadCount > 99 ? '99+' : unreadCount;
|
|
222
|
+
}
|
|
223
|
+
}, {
|
|
224
|
+
key: "onConversationAssignment",
|
|
225
|
+
value: function onConversationAssignment(conversation) {
|
|
226
|
+
const {
|
|
227
|
+
to: user
|
|
228
|
+
} = conversation;
|
|
229
|
+
this.titleTarget.innerText = user.name;
|
|
230
|
+
if (user.online) {
|
|
231
|
+
this.onlineStatusTarget.style.display = 'flex';
|
|
232
|
+
} else {
|
|
233
|
+
this.onlineStatusTarget.style.display = 'none';
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}, {
|
|
237
|
+
key: "onAgentOnline",
|
|
238
|
+
value: function onAgentOnline() {
|
|
239
|
+
this.onlineStatusTarget.style.display = 'flex';
|
|
240
|
+
this.setOfflineTimeout();
|
|
241
|
+
}
|
|
242
|
+
}, {
|
|
243
|
+
key: "sendMessage",
|
|
244
|
+
value: async function sendMessage() {
|
|
245
|
+
const formData = new FormData();
|
|
246
|
+
const message = {
|
|
247
|
+
body: this.inputTarget.value,
|
|
248
|
+
attachments: this.files
|
|
249
|
+
};
|
|
250
|
+
formData.append('message[body]', this.inputTarget.value);
|
|
251
|
+
this.files.forEach(file => {
|
|
252
|
+
formData.append('message[attachments][]', file);
|
|
253
|
+
});
|
|
254
|
+
formData.append('session', _hellotext.default.session);
|
|
255
|
+
const element = this.messageTemplateTarget.cloneNode(true);
|
|
256
|
+
element.classList.add('received');
|
|
257
|
+
element.style.removeProperty('display');
|
|
258
|
+
element.setAttribute('data-hellotext--webchat-target', 'message');
|
|
259
|
+
element.querySelector('[data-body]').innerText = this.inputTarget.value;
|
|
260
|
+
const attachments = this.attachmentContainerTarget.querySelectorAll('img');
|
|
261
|
+
if (attachments.length > 0) {
|
|
262
|
+
attachments.forEach(attachment => {
|
|
263
|
+
element.querySelector('[data-attachment-container]').appendChild(attachment);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
this.messagesContainerTarget.appendChild(element);
|
|
267
|
+
element.scrollIntoView({
|
|
268
|
+
behavior: 'smooth'
|
|
269
|
+
});
|
|
270
|
+
this.inputTarget.value = '';
|
|
271
|
+
this.files = [];
|
|
272
|
+
this.attachmentContainerTarget.style.display = 'none';
|
|
273
|
+
this.errorMessageContainerTarget.style.display = 'none';
|
|
274
|
+
this.inputTarget.focus();
|
|
275
|
+
const response = await this.messagesAPI.create(formData);
|
|
276
|
+
if (response.failed) {
|
|
277
|
+
return element.classList.add('failed');
|
|
278
|
+
}
|
|
279
|
+
const data = await response.json();
|
|
280
|
+
element.setAttribute('data-id', data.id);
|
|
281
|
+
message.id = data.id;
|
|
282
|
+
_hellotext.default.eventEmitter.dispatch('webchat:message:sent', message);
|
|
283
|
+
if (data.conversation !== this.conversationIdValue) {
|
|
284
|
+
this.conversationIdValue = data.conversation;
|
|
285
|
+
this.webChatChannel.updateSubscriptionWith(this.conversationIdValue);
|
|
286
|
+
}
|
|
287
|
+
this.attachmentContainerTarget.style.display = '';
|
|
288
|
+
}
|
|
289
|
+
}, {
|
|
290
|
+
key: "openAttachment",
|
|
291
|
+
value: function openAttachment() {
|
|
292
|
+
this.attachmentInputTarget.click();
|
|
293
|
+
}
|
|
294
|
+
}, {
|
|
295
|
+
key: "onFileInputChange",
|
|
296
|
+
value: function onFileInputChange() {
|
|
297
|
+
this.errorMessageContainerTarget.style.display = 'none';
|
|
298
|
+
this.files = Array.from(this.attachmentInputTarget.files);
|
|
299
|
+
const fileMaxSizeTooMuch = this.files.find(file => {
|
|
300
|
+
const type = file.type.split('/')[0];
|
|
301
|
+
if (['image', 'video', 'audio'].includes(type)) {
|
|
302
|
+
return this.mediaValue[type].max_size < file.size;
|
|
303
|
+
} else {
|
|
304
|
+
return this.mediaValue.document.max_size < file.size;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
if (fileMaxSizeTooMuch) {
|
|
308
|
+
const type = fileMaxSizeTooMuch.type.split('/')[0];
|
|
309
|
+
const mediaType = ['image', 'audio', 'video'].includes(type) ? type : 'document';
|
|
310
|
+
this.errorMessageContainerTarget.innerText = this.fileSizeErrorMessageValue.replace('%{limit}', this.byteToMegabyte(this.mediaValue[mediaType].max_size));
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
this.errorMessageContainerTarget.innerText = '';
|
|
314
|
+
this.files.forEach(file => this.createAttachmentElement(file));
|
|
315
|
+
this.inputTarget.focus();
|
|
316
|
+
}
|
|
317
|
+
}, {
|
|
318
|
+
key: "createAttachmentElement",
|
|
319
|
+
value: function createAttachmentElement(file) {
|
|
320
|
+
const element = this.attachmentElement();
|
|
321
|
+
this.attachmentContainerTarget.style.display = '';
|
|
322
|
+
element.setAttribute('data-name', file.name);
|
|
323
|
+
if (file.type.startsWith('image/')) {
|
|
324
|
+
const thumbnail = this.attachmentImageTarget.cloneNode(true);
|
|
325
|
+
thumbnail.src = URL.createObjectURL(file);
|
|
326
|
+
thumbnail.style.display = 'block';
|
|
327
|
+
element.appendChild(thumbnail);
|
|
328
|
+
this.attachmentContainerTarget.appendChild(element);
|
|
329
|
+
this.attachmentContainerTarget.style.display = 'flex';
|
|
330
|
+
} else {
|
|
331
|
+
const main = element.querySelector('main');
|
|
332
|
+
main.style.height = '5rem';
|
|
333
|
+
main.style.borderRadius = '0.375rem';
|
|
334
|
+
main.style.backgroundColor = '#e5e7eb';
|
|
335
|
+
main.style.padding = '0.25rem';
|
|
336
|
+
element.querySelector('p[data-attachment-name]').innerText = file.name;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}, {
|
|
340
|
+
key: "removeAttachment",
|
|
341
|
+
value: function removeAttachment({
|
|
342
|
+
currentTarget
|
|
343
|
+
}) {
|
|
344
|
+
const attachment = currentTarget.closest("[data-hellotext--webchat-target='attachment']");
|
|
345
|
+
this.files = this.files.filter(file => file.name !== attachment.dataset.name);
|
|
346
|
+
attachment.remove();
|
|
347
|
+
this.inputTarget.focus();
|
|
348
|
+
}
|
|
349
|
+
}, {
|
|
350
|
+
key: "attachmentTargetDisconnected",
|
|
351
|
+
value: function attachmentTargetDisconnected() {
|
|
352
|
+
if (this.attachmentTargets.length === 0) {
|
|
353
|
+
this.attachmentContainerTarget.innerHTML = '';
|
|
354
|
+
this.attachmentContainerTarget.style.display = 'none';
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}, {
|
|
358
|
+
key: "attachmentElement",
|
|
359
|
+
value: function attachmentElement() {
|
|
360
|
+
const element = this.attachmentTemplateTarget.cloneNode(true);
|
|
361
|
+
element.removeAttribute('hidden');
|
|
362
|
+
element.style.display = 'flex';
|
|
363
|
+
element.setAttribute('data-hellotext--webchat-target', 'attachment');
|
|
364
|
+
return element;
|
|
365
|
+
}
|
|
366
|
+
}, {
|
|
367
|
+
key: "onEmojiSelect",
|
|
368
|
+
value: function onEmojiSelect({
|
|
369
|
+
detail: emoji
|
|
370
|
+
}) {
|
|
371
|
+
const value = this.inputTarget.value;
|
|
372
|
+
const start = this.inputTarget.selectionStart;
|
|
373
|
+
const end = this.inputTarget.selectionEnd;
|
|
374
|
+
this.inputTarget.value = value.slice(0, start) + emoji + value.slice(end);
|
|
375
|
+
this.inputTarget.selectionStart = this.inputTarget.selectionEnd = start + emoji.length;
|
|
376
|
+
this.inputTarget.focus();
|
|
377
|
+
}
|
|
378
|
+
}, {
|
|
379
|
+
key: "setOfflineTimeout",
|
|
380
|
+
value: function setOfflineTimeout() {
|
|
381
|
+
clearTimeout(this.offlineTimeout);
|
|
382
|
+
this.offlineTimeout = setTimeout(() => {
|
|
383
|
+
this.onlineStatusTarget.style.display = 'none';
|
|
384
|
+
}, this.fiveMinutes);
|
|
385
|
+
}
|
|
386
|
+
}, {
|
|
387
|
+
key: "byteToMegabyte",
|
|
388
|
+
value: function byteToMegabyte(bytes) {
|
|
389
|
+
return Math.ceil(bytes / 1024 / 1024);
|
|
390
|
+
}
|
|
391
|
+
}, {
|
|
392
|
+
key: "fiveMinutes",
|
|
393
|
+
get: function () {
|
|
394
|
+
return 300000;
|
|
395
|
+
}
|
|
396
|
+
}, {
|
|
397
|
+
key: "middlewares",
|
|
398
|
+
get: function () {
|
|
399
|
+
return [(0, _dom.offset)(5), (0, _dom.shift)({
|
|
400
|
+
padding: 24
|
|
401
|
+
}), (0, _dom.flip)()];
|
|
402
|
+
}
|
|
403
|
+
}]);
|
|
404
|
+
return _default;
|
|
405
|
+
}(_stimulus.Controller);
|
|
406
|
+
exports.default = _default;
|
|
407
|
+
_default.values = {
|
|
408
|
+
id: String,
|
|
409
|
+
conversationId: String,
|
|
410
|
+
media: Object,
|
|
411
|
+
fileSizeErrorMessage: String,
|
|
412
|
+
placement: {
|
|
413
|
+
type: String,
|
|
414
|
+
default: 'bottom-end'
|
|
415
|
+
},
|
|
416
|
+
open: {
|
|
417
|
+
type: Boolean,
|
|
418
|
+
default: false
|
|
419
|
+
},
|
|
420
|
+
autoPlacement: {
|
|
421
|
+
type: Boolean,
|
|
422
|
+
default: false
|
|
423
|
+
},
|
|
424
|
+
disabled: {
|
|
425
|
+
type: Boolean,
|
|
426
|
+
default: false
|
|
427
|
+
},
|
|
428
|
+
nextPage: {
|
|
429
|
+
type: Number,
|
|
430
|
+
default: undefined
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
_default.targets = ['trigger', 'popover', 'input', 'attachmentInput', 'attachmentButton', 'errorMessageContainer', 'attachmentTemplate', 'attachmentContainer', 'attachment', 'messageTemplate', 'messagesContainer', 'title', 'onlineStatus', 'attachmentImage', 'footer', 'toolbar', 'message', 'unreadCounter'];
|