@hellotext/hellotext 2.1.3 → 2.1.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/channels/application_channel.cjs +9 -6
- package/lib/channels/application_channel.js +9 -6
- package/lib/channels/webchat_channel.cjs +42 -17
- package/lib/channels/webchat_channel.js +42 -17
- package/lib/controllers/webchat_controller.cjs +141 -42
- package/lib/controllers/webchat_controller.js +142 -43
- package/lib/core/configuration.cjs +1 -0
- package/lib/core/configuration.js +1 -0
- package/lib/models/query.cjs +1 -2
- package/lib/models/query.js +1 -2
- package/lib/models/session.cjs +1 -1
- package/lib/models/session.js +1 -1
- package/package.json +1 -1
- package/src/channels/application_channel.js +12 -9
- package/src/channels/webchat_channel.js +33 -19
- package/src/controllers/webchat_controller.js +133 -34
- package/src/core/configuration.js +1 -0
- package/src/models/query.js +1 -3
- package/src/models/session.js +1 -1
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
+
var _core = require("../core");
|
|
7
8
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
8
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); } }
|
|
9
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; }
|
|
@@ -17,17 +18,19 @@ let ApplicationChannel = /*#__PURE__*/function () {
|
|
|
17
18
|
key: "send",
|
|
18
19
|
value: function send({
|
|
19
20
|
command,
|
|
20
|
-
identifier
|
|
21
|
+
identifier,
|
|
22
|
+
data
|
|
21
23
|
}) {
|
|
22
|
-
const
|
|
24
|
+
const payload = {
|
|
23
25
|
command,
|
|
24
|
-
identifier: JSON.stringify(identifier)
|
|
26
|
+
identifier: JSON.stringify(identifier),
|
|
27
|
+
data: JSON.stringify(data || {})
|
|
25
28
|
};
|
|
26
29
|
if (this.webSocket.readyState === WebSocket.OPEN) {
|
|
27
|
-
this.webSocket.send(JSON.stringify(
|
|
30
|
+
this.webSocket.send(JSON.stringify(payload));
|
|
28
31
|
} else {
|
|
29
32
|
this.webSocket.addEventListener('open', () => {
|
|
30
|
-
this.webSocket.send(JSON.stringify(
|
|
33
|
+
this.webSocket.send(JSON.stringify(payload));
|
|
31
34
|
});
|
|
32
35
|
}
|
|
33
36
|
}
|
|
@@ -50,7 +53,7 @@ let ApplicationChannel = /*#__PURE__*/function () {
|
|
|
50
53
|
key: "webSocket",
|
|
51
54
|
get: function () {
|
|
52
55
|
if (!ApplicationChannel.webSocket) {
|
|
53
|
-
return ApplicationChannel.webSocket = new WebSocket(
|
|
56
|
+
return ApplicationChannel.webSocket = new WebSocket(_core.Configuration.actionCableUrl);
|
|
54
57
|
}
|
|
55
58
|
return ApplicationChannel.webSocket;
|
|
56
59
|
}
|
|
@@ -3,6 +3,7 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
|
|
|
3
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
4
|
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
5
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
|
+
import { Configuration } from '../core';
|
|
6
7
|
var ApplicationChannel = /*#__PURE__*/function () {
|
|
7
8
|
function ApplicationChannel() {
|
|
8
9
|
_classCallCheck(this, ApplicationChannel);
|
|
@@ -12,17 +13,19 @@ var ApplicationChannel = /*#__PURE__*/function () {
|
|
|
12
13
|
value: function send(_ref) {
|
|
13
14
|
var {
|
|
14
15
|
command,
|
|
15
|
-
identifier
|
|
16
|
+
identifier,
|
|
17
|
+
data
|
|
16
18
|
} = _ref;
|
|
17
|
-
var
|
|
19
|
+
var payload = {
|
|
18
20
|
command,
|
|
19
|
-
identifier: JSON.stringify(identifier)
|
|
21
|
+
identifier: JSON.stringify(identifier),
|
|
22
|
+
data: JSON.stringify(data || {})
|
|
20
23
|
};
|
|
21
24
|
if (this.webSocket.readyState === WebSocket.OPEN) {
|
|
22
|
-
this.webSocket.send(JSON.stringify(
|
|
25
|
+
this.webSocket.send(JSON.stringify(payload));
|
|
23
26
|
} else {
|
|
24
27
|
this.webSocket.addEventListener('open', () => {
|
|
25
|
-
this.webSocket.send(JSON.stringify(
|
|
28
|
+
this.webSocket.send(JSON.stringify(payload));
|
|
26
29
|
});
|
|
27
30
|
}
|
|
28
31
|
}
|
|
@@ -45,7 +48,7 @@ var ApplicationChannel = /*#__PURE__*/function () {
|
|
|
45
48
|
key: "webSocket",
|
|
46
49
|
get: function get() {
|
|
47
50
|
if (!ApplicationChannel.webSocket) {
|
|
48
|
-
return ApplicationChannel.webSocket = new WebSocket(
|
|
51
|
+
return ApplicationChannel.webSocket = new WebSocket(Configuration.actionCableUrl);
|
|
49
52
|
}
|
|
50
53
|
return ApplicationChannel.webSocket;
|
|
51
54
|
}
|
|
@@ -37,7 +37,7 @@ let WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
37
37
|
key: "subscribe",
|
|
38
38
|
value: function subscribe() {
|
|
39
39
|
const params = {
|
|
40
|
-
channel:
|
|
40
|
+
channel: 'WebchatChannel',
|
|
41
41
|
id: this.id,
|
|
42
42
|
session: this.session,
|
|
43
43
|
conversation: this.conversation
|
|
@@ -51,7 +51,7 @@ let WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
51
51
|
key: "unsubscribe",
|
|
52
52
|
value: function unsubscribe() {
|
|
53
53
|
const params = {
|
|
54
|
-
channel:
|
|
54
|
+
channel: 'WebchatChannel',
|
|
55
55
|
id: this.id,
|
|
56
56
|
session: this.session,
|
|
57
57
|
conversation: this.conversation
|
|
@@ -62,29 +62,45 @@ let WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
}, {
|
|
65
|
-
key: "
|
|
66
|
-
value: function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
key: "startTypingIndicator",
|
|
66
|
+
value: function startTypingIndicator() {
|
|
67
|
+
const params = {
|
|
68
|
+
channel: 'WebchatChannel',
|
|
69
|
+
id: this.id,
|
|
70
|
+
session: this.session,
|
|
71
|
+
conversation: this.conversation
|
|
72
|
+
};
|
|
73
|
+
this.send({
|
|
74
|
+
command: 'message',
|
|
75
|
+
identifier: params,
|
|
76
|
+
data: {
|
|
77
|
+
action: 'started_typing'
|
|
78
|
+
}
|
|
70
79
|
});
|
|
71
80
|
}
|
|
72
81
|
}, {
|
|
73
|
-
key: "
|
|
74
|
-
value: function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
key: "stopTypingIndicator",
|
|
83
|
+
value: function stopTypingIndicator() {
|
|
84
|
+
const params = {
|
|
85
|
+
channel: 'WebchatChannel',
|
|
86
|
+
id: this.id,
|
|
87
|
+
session: this.session,
|
|
88
|
+
conversation: this.conversation
|
|
89
|
+
};
|
|
90
|
+
this.send({
|
|
91
|
+
command: 'typing:stop',
|
|
92
|
+
identifier: params,
|
|
93
|
+
data: {
|
|
94
|
+
action: 'stopped_typing'
|
|
78
95
|
}
|
|
79
96
|
});
|
|
80
97
|
}
|
|
81
98
|
}, {
|
|
82
|
-
key: "
|
|
83
|
-
value: function
|
|
99
|
+
key: "onMessage",
|
|
100
|
+
value: function onMessage(callback) {
|
|
84
101
|
_get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
|
|
85
|
-
if (message.type
|
|
86
|
-
|
|
87
|
-
}
|
|
102
|
+
if (message.type !== 'message') return;
|
|
103
|
+
callback(message);
|
|
88
104
|
});
|
|
89
105
|
}
|
|
90
106
|
}, {
|
|
@@ -96,6 +112,15 @@ let WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
96
112
|
}
|
|
97
113
|
});
|
|
98
114
|
}
|
|
115
|
+
}, {
|
|
116
|
+
key: "onTypingStart",
|
|
117
|
+
value: function onTypingStart(callback) {
|
|
118
|
+
_get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
|
|
119
|
+
if (message.type === 'started_typing') {
|
|
120
|
+
callback(message);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
99
124
|
}, {
|
|
100
125
|
key: "updateSubscriptionWith",
|
|
101
126
|
value: function updateSubscriptionWith(conversation) {
|
|
@@ -30,7 +30,7 @@ var WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
30
30
|
key: "subscribe",
|
|
31
31
|
value: function subscribe() {
|
|
32
32
|
var params = {
|
|
33
|
-
channel:
|
|
33
|
+
channel: 'WebchatChannel',
|
|
34
34
|
id: this.id,
|
|
35
35
|
session: this.session,
|
|
36
36
|
conversation: this.conversation
|
|
@@ -44,7 +44,7 @@ var WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
44
44
|
key: "unsubscribe",
|
|
45
45
|
value: function unsubscribe() {
|
|
46
46
|
var params = {
|
|
47
|
-
channel:
|
|
47
|
+
channel: 'WebchatChannel',
|
|
48
48
|
id: this.id,
|
|
49
49
|
session: this.session,
|
|
50
50
|
conversation: this.conversation
|
|
@@ -55,29 +55,45 @@ var WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
}, {
|
|
58
|
-
key: "
|
|
59
|
-
value: function
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
key: "startTypingIndicator",
|
|
59
|
+
value: function startTypingIndicator() {
|
|
60
|
+
var params = {
|
|
61
|
+
channel: 'WebchatChannel',
|
|
62
|
+
id: this.id,
|
|
63
|
+
session: this.session,
|
|
64
|
+
conversation: this.conversation
|
|
65
|
+
};
|
|
66
|
+
this.send({
|
|
67
|
+
command: 'message',
|
|
68
|
+
identifier: params,
|
|
69
|
+
data: {
|
|
70
|
+
action: 'started_typing'
|
|
71
|
+
}
|
|
63
72
|
});
|
|
64
73
|
}
|
|
65
74
|
}, {
|
|
66
|
-
key: "
|
|
67
|
-
value: function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
key: "stopTypingIndicator",
|
|
76
|
+
value: function stopTypingIndicator() {
|
|
77
|
+
var params = {
|
|
78
|
+
channel: 'WebchatChannel',
|
|
79
|
+
id: this.id,
|
|
80
|
+
session: this.session,
|
|
81
|
+
conversation: this.conversation
|
|
82
|
+
};
|
|
83
|
+
this.send({
|
|
84
|
+
command: 'typing:stop',
|
|
85
|
+
identifier: params,
|
|
86
|
+
data: {
|
|
87
|
+
action: 'stopped_typing'
|
|
71
88
|
}
|
|
72
89
|
});
|
|
73
90
|
}
|
|
74
91
|
}, {
|
|
75
|
-
key: "
|
|
76
|
-
value: function
|
|
92
|
+
key: "onMessage",
|
|
93
|
+
value: function onMessage(callback) {
|
|
77
94
|
_get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
|
|
78
|
-
if (message.type
|
|
79
|
-
|
|
80
|
-
}
|
|
95
|
+
if (message.type !== 'message') return;
|
|
96
|
+
callback(message);
|
|
81
97
|
});
|
|
82
98
|
}
|
|
83
99
|
}, {
|
|
@@ -89,6 +105,15 @@ var WebchatChannel = /*#__PURE__*/function (_ApplicationChannel) {
|
|
|
89
105
|
}
|
|
90
106
|
});
|
|
91
107
|
}
|
|
108
|
+
}, {
|
|
109
|
+
key: "onTypingStart",
|
|
110
|
+
value: function onTypingStart(callback) {
|
|
111
|
+
_get(_getPrototypeOf(WebchatChannel.prototype), "onMessage", this).call(this, message => {
|
|
112
|
+
if (message.type === 'started_typing') {
|
|
113
|
+
callback(message);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
92
117
|
}, {
|
|
93
118
|
key: "updateSubscriptionWith",
|
|
94
119
|
value: function updateSubscriptionWith(conversation) {
|
|
@@ -42,9 +42,8 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
42
42
|
this.webChatChannel = new _webchat_channel.default(this.idValue, _hellotext.default.session, this.conversationIdValue);
|
|
43
43
|
this.files = [];
|
|
44
44
|
this.onMessageReceived = this.onMessageReceived.bind(this);
|
|
45
|
-
this.onConversationAssignment = this.onConversationAssignment.bind(this);
|
|
46
|
-
this.onAgentOnline = this.onAgentOnline.bind(this);
|
|
47
45
|
this.onMessageReaction = this.onMessageReaction.bind(this);
|
|
46
|
+
this.onTypingStart = this.onTypingStart.bind(this);
|
|
48
47
|
this.onScroll = this.onScroll.bind(this);
|
|
49
48
|
this.onOutboundMessageSent = this.onOutboundMessageSent.bind(this);
|
|
50
49
|
this.broadcastChannel = new BroadcastChannel(`hellotext--webchat--${this.idValue}`);
|
|
@@ -61,8 +60,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
61
60
|
popover: this.popoverTarget
|
|
62
61
|
});
|
|
63
62
|
this.webChatChannel.onMessage(this.onMessageReceived);
|
|
64
|
-
this.webChatChannel.
|
|
65
|
-
this.webChatChannel.onAgentOnline(this.onAgentOnline);
|
|
63
|
+
this.webChatChannel.onTypingStart(this.onTypingStart);
|
|
66
64
|
this.webChatChannel.onReaction(this.onMessageReaction);
|
|
67
65
|
this.messagesContainerTarget.addEventListener('scroll', this.onScroll);
|
|
68
66
|
if (!_hellotext.default.business.features.white_label) {
|
|
@@ -80,10 +78,85 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
80
78
|
value: function disconnect() {
|
|
81
79
|
this.broadcastChannel.removeEventListener('message', this.onOutboundMessageSent);
|
|
82
80
|
this.messagesContainerTarget.removeEventListener('scroll', this.onScroll);
|
|
81
|
+
|
|
82
|
+
// Clean up typing indicator timeouts
|
|
83
|
+
this.clearTypingIndicator();
|
|
83
84
|
this.broadcastChannel.close();
|
|
84
85
|
this.floatingUICleanup();
|
|
85
86
|
_get(_getPrototypeOf(_default.prototype), "disconnect", this).call(this);
|
|
86
87
|
}
|
|
88
|
+
}, {
|
|
89
|
+
key: "onTypingStart",
|
|
90
|
+
value: function onTypingStart() {
|
|
91
|
+
if (this.typingIndicatorVisible) {
|
|
92
|
+
return this.resetTypingIndicatorTimer();
|
|
93
|
+
}
|
|
94
|
+
this.showTypingIndicator();
|
|
95
|
+
}
|
|
96
|
+
}, {
|
|
97
|
+
key: "showOptimisticTypingIndicator",
|
|
98
|
+
value: function showOptimisticTypingIndicator() {
|
|
99
|
+
if (this.typingIndicatorVisible) return;
|
|
100
|
+
this.showTypingIndicator();
|
|
101
|
+
}
|
|
102
|
+
}, {
|
|
103
|
+
key: "showTypingIndicator",
|
|
104
|
+
value: function showTypingIndicator() {
|
|
105
|
+
this.clearTypingIndicator();
|
|
106
|
+
this.typingIndicatorVisible = true;
|
|
107
|
+
const indicator = this.typingIndicatorTemplateTarget.cloneNode(true);
|
|
108
|
+
indicator.setAttribute('data-hellotext--webchat-target', 'typingIndicator');
|
|
109
|
+
indicator.style.display = 'flex';
|
|
110
|
+
this.messagesContainerTarget.appendChild(indicator);
|
|
111
|
+
requestAnimationFrame(() => {
|
|
112
|
+
this.messagesContainerTarget.scroll({
|
|
113
|
+
top: this.messagesContainerTarget.scrollHeight,
|
|
114
|
+
behavior: 'instant'
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
const timeout = this.typingIndicatorKeepAliveValue;
|
|
118
|
+
this.incomingTypingIndicatorTimeout = setTimeout(() => {
|
|
119
|
+
this.clearTypingIndicator();
|
|
120
|
+
}, timeout);
|
|
121
|
+
}
|
|
122
|
+
}, {
|
|
123
|
+
key: "resetTypingIndicatorTimer",
|
|
124
|
+
value: function resetTypingIndicatorTimer() {
|
|
125
|
+
if (!this.typingIndicatorVisible) return;
|
|
126
|
+
|
|
127
|
+
// Clear existing timeout
|
|
128
|
+
clearTimeout(this.incomingTypingIndicatorTimeout);
|
|
129
|
+
clearTimeout(this.optimisticTypingTimeout);
|
|
130
|
+
|
|
131
|
+
// Use unified timeout for all typing indicators
|
|
132
|
+
const timeout = this.typingIndicatorKeepAliveValue;
|
|
133
|
+
this.incomingTypingIndicatorTimeout = setTimeout(() => {
|
|
134
|
+
this.clearTypingIndicator();
|
|
135
|
+
}, timeout);
|
|
136
|
+
}
|
|
137
|
+
}, {
|
|
138
|
+
key: "clearTypingIndicator",
|
|
139
|
+
value: function clearTypingIndicator() {
|
|
140
|
+
if (this.hasTypingIndicatorTarget) {
|
|
141
|
+
this.typingIndicatorTarget.remove();
|
|
142
|
+
}
|
|
143
|
+
this.typingIndicatorVisible = false;
|
|
144
|
+
clearTimeout(this.incomingTypingIndicatorTimeout);
|
|
145
|
+
clearTimeout(this.optimisticTypingTimeout);
|
|
146
|
+
}
|
|
147
|
+
}, {
|
|
148
|
+
key: "onMessageInputChange",
|
|
149
|
+
value: function onMessageInputChange() {
|
|
150
|
+
this.resizeInput();
|
|
151
|
+
clearTimeout(this.typingIndicatorTimeout);
|
|
152
|
+
if (!this.hasSentTypingIndicator) {
|
|
153
|
+
this.webChatChannel.startTypingIndicator();
|
|
154
|
+
this.hasSentTypingIndicator = true;
|
|
155
|
+
}
|
|
156
|
+
this.typingIndicatorTimeout = setTimeout(() => {
|
|
157
|
+
this.hasSentTypingIndicator = false;
|
|
158
|
+
}, 3000);
|
|
159
|
+
}
|
|
87
160
|
}, {
|
|
88
161
|
key: "onOutboundMessageSent",
|
|
89
162
|
value: function onOutboundMessageSent(event) {
|
|
@@ -93,7 +166,13 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
93
166
|
const callbacks = {
|
|
94
167
|
'message:sent': data => {
|
|
95
168
|
const element = new DOMParser().parseFromString(data.element, 'text/html').body.firstElementChild;
|
|
96
|
-
|
|
169
|
+
|
|
170
|
+
// Insert message before typing indicator if one exists
|
|
171
|
+
if (this.typingIndicatorVisible && this.hasTypingIndicatorTarget) {
|
|
172
|
+
this.messagesContainerTarget.insertBefore(element, this.typingIndicatorTarget);
|
|
173
|
+
} else {
|
|
174
|
+
this.messagesContainerTarget.appendChild(element);
|
|
175
|
+
}
|
|
97
176
|
element.scrollIntoView({
|
|
98
177
|
behavior: 'instant'
|
|
99
178
|
});
|
|
@@ -247,6 +326,11 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
247
326
|
element.querySelector('[data-attachment-container]').appendChild(image);
|
|
248
327
|
});
|
|
249
328
|
}
|
|
329
|
+
|
|
330
|
+
// Clear any typing indicator when message is received
|
|
331
|
+
if (this.typingIndicatorVisible) {
|
|
332
|
+
this.clearTypingIndicator();
|
|
333
|
+
}
|
|
250
334
|
this.messagesContainerTarget.appendChild(element);
|
|
251
335
|
_hellotext.default.eventEmitter.dispatch('webchat:message:received', {
|
|
252
336
|
...message,
|
|
@@ -255,7 +339,6 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
255
339
|
element.scrollIntoView({
|
|
256
340
|
behavior: 'smooth'
|
|
257
341
|
});
|
|
258
|
-
this.setOfflineTimeout();
|
|
259
342
|
if (this.openValue) {
|
|
260
343
|
this.messagesAPI.markAsSeen(id);
|
|
261
344
|
return;
|
|
@@ -265,33 +348,30 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
265
348
|
this.unreadCounterTarget.innerText = unreadCount > 99 ? '99+' : unreadCount;
|
|
266
349
|
}
|
|
267
350
|
}, {
|
|
268
|
-
key: "
|
|
269
|
-
value: function
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
this.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}, {
|
|
281
|
-
key: "onAgentOnline",
|
|
282
|
-
value: function onAgentOnline() {
|
|
283
|
-
this.onlineStatusTarget.style.display = 'flex';
|
|
284
|
-
this.setOfflineTimeout();
|
|
351
|
+
key: "resizeInput",
|
|
352
|
+
value: function resizeInput() {
|
|
353
|
+
const maxHeight = 96;
|
|
354
|
+
|
|
355
|
+
// Temporarily reset height to its natural content size
|
|
356
|
+
this.inputTarget.style.height = 'auto';
|
|
357
|
+
|
|
358
|
+
// Set the height to the scrollHeight, which is the minimum height
|
|
359
|
+
// the element needs to fit its content without a scrollbar.
|
|
360
|
+
const scrollHeight = this.inputTarget.scrollHeight;
|
|
361
|
+
this.inputTarget.style.height = `${Math.min(scrollHeight, maxHeight)}px`;
|
|
285
362
|
}
|
|
286
363
|
}, {
|
|
287
364
|
key: "sendMessage",
|
|
288
|
-
value: async function sendMessage() {
|
|
365
|
+
value: async function sendMessage(e) {
|
|
289
366
|
const formData = new FormData();
|
|
290
367
|
const message = {
|
|
291
368
|
body: this.inputTarget.value,
|
|
292
369
|
attachments: this.files
|
|
293
370
|
};
|
|
294
371
|
if (this.inputTarget.value.trim().length === 0 && this.files.length === 0) {
|
|
372
|
+
if (e && e.target) {
|
|
373
|
+
e.preventDefault();
|
|
374
|
+
}
|
|
295
375
|
return;
|
|
296
376
|
}
|
|
297
377
|
if (this.inputTarget.value.trim().length > 0) {
|
|
@@ -320,7 +400,13 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
320
400
|
element.querySelector('[data-attachment-container]').appendChild(attachment);
|
|
321
401
|
});
|
|
322
402
|
}
|
|
323
|
-
|
|
403
|
+
|
|
404
|
+
// Insert message before typing indicator if one exists
|
|
405
|
+
if (this.typingIndicatorVisible && this.hasTypingIndicatorTarget) {
|
|
406
|
+
this.messagesContainerTarget.insertBefore(element, this.typingIndicatorTarget);
|
|
407
|
+
} else {
|
|
408
|
+
this.messagesContainerTarget.appendChild(element);
|
|
409
|
+
}
|
|
324
410
|
element.scrollIntoView({
|
|
325
411
|
behavior: 'smooth'
|
|
326
412
|
});
|
|
@@ -329,6 +415,7 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
329
415
|
element: element.outerHTML
|
|
330
416
|
});
|
|
331
417
|
this.inputTarget.value = '';
|
|
418
|
+
this.resizeInput();
|
|
332
419
|
this.files = [];
|
|
333
420
|
this.attachmentInputTarget.value = '';
|
|
334
421
|
this.attachmentContainerTarget.innerHTML = '';
|
|
@@ -351,6 +438,14 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
351
438
|
this.conversationIdValue = data.conversation;
|
|
352
439
|
this.webChatChannel.updateSubscriptionWith(this.conversationIdValue);
|
|
353
440
|
}
|
|
441
|
+
if (this.typingIndicatorVisible) {
|
|
442
|
+
this.resetTypingIndicatorTimer();
|
|
443
|
+
} else {
|
|
444
|
+
clearTimeout(this.optimisticTypingTimeout);
|
|
445
|
+
this.optimisticTypingTimeout = setTimeout(() => {
|
|
446
|
+
this.showOptimisticTypingIndicator();
|
|
447
|
+
}, this.optimisticTypingIndicatorWaitValue);
|
|
448
|
+
}
|
|
354
449
|
this.attachmentContainerTarget.style.display = '';
|
|
355
450
|
}
|
|
356
451
|
}, {
|
|
@@ -447,29 +542,16 @@ let _default = /*#__PURE__*/function (_Controller) {
|
|
|
447
542
|
this.inputTarget.selectionStart = this.inputTarget.selectionEnd = start + emoji.length;
|
|
448
543
|
this.inputTarget.focus();
|
|
449
544
|
}
|
|
450
|
-
}, {
|
|
451
|
-
key: "setOfflineTimeout",
|
|
452
|
-
value: function setOfflineTimeout() {
|
|
453
|
-
clearTimeout(this.offlineTimeout);
|
|
454
|
-
this.offlineTimeout = setTimeout(() => {
|
|
455
|
-
this.onlineStatusTarget.style.display = 'none';
|
|
456
|
-
}, this.fiveMinutes);
|
|
457
|
-
}
|
|
458
545
|
}, {
|
|
459
546
|
key: "byteToMegabyte",
|
|
460
547
|
value: function byteToMegabyte(bytes) {
|
|
461
548
|
return Math.ceil(bytes / 1024 / 1024);
|
|
462
549
|
}
|
|
463
|
-
}, {
|
|
464
|
-
key: "fiveMinutes",
|
|
465
|
-
get: function () {
|
|
466
|
-
return 300000;
|
|
467
|
-
}
|
|
468
550
|
}, {
|
|
469
551
|
key: "middlewares",
|
|
470
552
|
get: function () {
|
|
471
|
-
return [(0, _dom.offset)(
|
|
472
|
-
padding:
|
|
553
|
+
return [(0, _dom.offset)(this.offsetValue), (0, _dom.shift)({
|
|
554
|
+
padding: this.paddingValue
|
|
473
555
|
}), (0, _dom.flip)()];
|
|
474
556
|
}
|
|
475
557
|
}, {
|
|
@@ -514,7 +596,24 @@ _default.values = {
|
|
|
514
596
|
fullScreenThreshold: {
|
|
515
597
|
type: Number,
|
|
516
598
|
default: 1024
|
|
517
|
-
}
|
|
599
|
+
},
|
|
600
|
+
typingIndicatorKeepAlive: {
|
|
601
|
+
type: Number,
|
|
602
|
+
default: 30000
|
|
603
|
+
},
|
|
604
|
+
// 30 seconds
|
|
605
|
+
offset: {
|
|
606
|
+
type: Number,
|
|
607
|
+
default: 24
|
|
608
|
+
},
|
|
609
|
+
padding: {
|
|
610
|
+
type: Number,
|
|
611
|
+
default: 24
|
|
612
|
+
},
|
|
613
|
+
optimisticTypingIndicatorWait: {
|
|
614
|
+
type: Number,
|
|
615
|
+
default: 1000
|
|
616
|
+
} // 1 second
|
|
518
617
|
};
|
|
519
618
|
_default.classes = ['fadeOut'];
|
|
520
|
-
_default.targets = ['trigger', 'popover', 'input', 'attachmentInput', 'attachmentButton', 'errorMessageContainer', 'attachmentTemplate', 'attachmentContainer', 'attachment', 'messageTemplate', 'messagesContainer', 'title', '
|
|
619
|
+
_default.targets = ['trigger', 'popover', 'input', 'attachmentInput', 'attachmentButton', 'errorMessageContainer', 'attachmentTemplate', 'attachmentContainer', 'attachment', 'messageTemplate', 'messagesContainer', 'title', 'attachmentImage', 'footer', 'toolbar', 'message', 'unreadCounter', 'typingIndicator', 'typingIndicatorTemplate'];
|