@telia-ace/widget-conversation 1.0.11 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/{lib-esm → dist}/agent.d.ts +0 -0
  2. package/{lib-esm → dist}/conversation-controller.d.ts +0 -0
  3. package/{lib-esm → dist}/conversation-form-adapter.d.ts +0 -0
  4. package/{lib-esm → dist}/conversation-platform.d.ts +0 -0
  5. package/{lib-esm → dist}/conversation-provider.d.ts +0 -0
  6. package/dist/conversation.js +1357 -0
  7. package/dist/conversation.js.map +1 -0
  8. package/{lib-esm → dist}/index.d.ts +0 -0
  9. package/dist/index.js +867 -0
  10. package/dist/index.js.map +1 -0
  11. package/{lib-esm → dist}/resolve-entity-value.d.ts +0 -0
  12. package/dist/return-button.js +174 -0
  13. package/dist/return-button.js.map +1 -0
  14. package/{lib-esm → dist}/types.d.ts +0 -0
  15. package/{lib-esm → dist}/ui/conversation/conversation-component.d.ts +0 -0
  16. package/{lib-esm → dist}/ui/conversation/conversation-content.d.ts +0 -0
  17. package/{lib-esm → dist}/ui/conversation/conversation-input.d.ts +0 -0
  18. package/{lib-esm → dist}/ui/conversation/conversation-loader.d.ts +0 -0
  19. package/{lib-esm → dist}/ui/conversation/conversation-message.d.ts +0 -0
  20. package/{lib-esm → dist}/ui/conversation/conversation-styles.d.ts +0 -0
  21. package/{lib-esm → dist}/ui/conversation/conversation.d.ts +0 -0
  22. package/{lib-esm → dist}/ui/conversation/index.d.ts +0 -0
  23. package/{lib-esm → dist}/ui/conversation/message-types/agent.d.ts +0 -0
  24. package/{lib-esm → dist}/ui/conversation/message-types/custom-message-list-item.d.ts +0 -0
  25. package/{lib-esm → dist}/ui/conversation/message-types/custom.d.ts +0 -0
  26. package/{lib-esm → dist}/ui/conversation/message-types/index.d.ts +0 -0
  27. package/{lib-esm → dist}/ui/conversation/message-types/system.d.ts +0 -0
  28. package/{lib-esm → dist}/ui/conversation/message-types/timestamp.d.ts +0 -0
  29. package/{lib-esm → dist}/ui/conversation/message-types/user.d.ts +0 -0
  30. package/{lib-esm → dist}/ui/index.d.ts +0 -0
  31. package/{lib-esm → dist}/ui/return-button/index.d.ts +0 -0
  32. package/{lib-esm → dist}/ui/return-button/return-button-component.d.ts +0 -0
  33. package/{lib-esm → dist}/ui/return-button/return-button.d.ts +0 -0
  34. package/{lib-esm → dist}/user.d.ts +0 -0
  35. package/{lib-esm → dist}/utils/custom-message.d.ts +0 -0
  36. package/{lib-esm → dist}/utils/index.d.ts +0 -0
  37. package/{lib-esm → dist}/utils/open-chat-widget.d.ts +0 -0
  38. package/package.json +15 -16
  39. package/lib/agent.d.ts +0 -17
  40. package/lib/agent.js +0 -37
  41. package/lib/conversation-controller.d.ts +0 -88
  42. package/lib/conversation-controller.js +0 -318
  43. package/lib/conversation-form-adapter.d.ts +0 -7
  44. package/lib/conversation-form-adapter.js +0 -88
  45. package/lib/conversation-platform.d.ts +0 -49
  46. package/lib/conversation-platform.js +0 -295
  47. package/lib/conversation-provider.d.ts +0 -22
  48. package/lib/conversation-provider.js +0 -73
  49. package/lib/index.d.ts +0 -9
  50. package/lib/index.js +0 -17
  51. package/lib/resolve-entity-value.d.ts +0 -10
  52. package/lib/resolve-entity-value.js +0 -22
  53. package/lib/types.d.ts +0 -110
  54. package/lib/types.js +0 -19
  55. package/lib/ui/conversation/conversation-component.d.ts +0 -37
  56. package/lib/ui/conversation/conversation-component.js +0 -152
  57. package/lib/ui/conversation/conversation-content.d.ts +0 -11
  58. package/lib/ui/conversation/conversation-content.js +0 -240
  59. package/lib/ui/conversation/conversation-input.d.ts +0 -6
  60. package/lib/ui/conversation/conversation-input.js +0 -163
  61. package/lib/ui/conversation/conversation-loader.d.ts +0 -8
  62. package/lib/ui/conversation/conversation-loader.js +0 -18
  63. package/lib/ui/conversation/conversation-message.d.ts +0 -7
  64. package/lib/ui/conversation/conversation-message.js +0 -141
  65. package/lib/ui/conversation/conversation-styles.d.ts +0 -11
  66. package/lib/ui/conversation/conversation-styles.js +0 -65
  67. package/lib/ui/conversation/conversation.d.ts +0 -6
  68. package/lib/ui/conversation/conversation.js +0 -139
  69. package/lib/ui/conversation/index.d.ts +0 -2
  70. package/lib/ui/conversation/index.js +0 -7
  71. package/lib/ui/conversation/message-types/agent.d.ts +0 -11
  72. package/lib/ui/conversation/message-types/agent.js +0 -54
  73. package/lib/ui/conversation/message-types/custom-message-list-item.d.ts +0 -9
  74. package/lib/ui/conversation/message-types/custom-message-list-item.js +0 -27
  75. package/lib/ui/conversation/message-types/custom.d.ts +0 -9
  76. package/lib/ui/conversation/message-types/custom.js +0 -50
  77. package/lib/ui/conversation/message-types/index.d.ts +0 -5
  78. package/lib/ui/conversation/message-types/index.js +0 -16
  79. package/lib/ui/conversation/message-types/system.d.ts +0 -12
  80. package/lib/ui/conversation/message-types/system.js +0 -26
  81. package/lib/ui/conversation/message-types/timestamp.d.ts +0 -8
  82. package/lib/ui/conversation/message-types/timestamp.js +0 -36
  83. package/lib/ui/conversation/message-types/user.d.ts +0 -8
  84. package/lib/ui/conversation/message-types/user.js +0 -24
  85. package/lib/ui/index.d.ts +0 -2
  86. package/lib/ui/index.js +0 -10
  87. package/lib/ui/return-button/index.d.ts +0 -2
  88. package/lib/ui/return-button/index.js +0 -7
  89. package/lib/ui/return-button/return-button-component.d.ts +0 -19
  90. package/lib/ui/return-button/return-button-component.js +0 -70
  91. package/lib/ui/return-button/return-button.d.ts +0 -6
  92. package/lib/ui/return-button/return-button.js +0 -82
  93. package/lib/user.d.ts +0 -7
  94. package/lib/user.js +0 -16
  95. package/lib/utils/custom-message.d.ts +0 -3
  96. package/lib/utils/custom-message.js +0 -56
  97. package/lib/utils/index.d.ts +0 -1
  98. package/lib/utils/index.js +0 -7
  99. package/lib/utils/open-chat-widget.d.ts +0 -4
  100. package/lib/utils/open-chat-widget.js +0 -148
  101. package/lib-esm/agent.js +0 -34
  102. package/lib-esm/conversation-controller.js +0 -314
  103. package/lib-esm/conversation-form-adapter.js +0 -85
  104. package/lib-esm/conversation-platform.js +0 -292
  105. package/lib-esm/conversation-provider.js +0 -70
  106. package/lib-esm/index.js +0 -6
  107. package/lib-esm/resolve-entity-value.js +0 -18
  108. package/lib-esm/types.js +0 -16
  109. package/lib-esm/ui/conversation/conversation-component.js +0 -127
  110. package/lib-esm/ui/conversation/conversation-content.js +0 -212
  111. package/lib-esm/ui/conversation/conversation-input.js +0 -138
  112. package/lib-esm/ui/conversation/conversation-loader.js +0 -13
  113. package/lib-esm/ui/conversation/conversation-message.js +0 -113
  114. package/lib-esm/ui/conversation/conversation-styles.js +0 -39
  115. package/lib-esm/ui/conversation/conversation.js +0 -111
  116. package/lib-esm/ui/conversation/index.js +0 -2
  117. package/lib-esm/ui/conversation/message-types/agent.js +0 -25
  118. package/lib-esm/ui/conversation/message-types/custom-message-list-item.js +0 -22
  119. package/lib-esm/ui/conversation/message-types/custom.js +0 -25
  120. package/lib-esm/ui/conversation/message-types/index.js +0 -5
  121. package/lib-esm/ui/conversation/message-types/system.js +0 -20
  122. package/lib-esm/ui/conversation/message-types/timestamp.js +0 -31
  123. package/lib-esm/ui/conversation/message-types/user.js +0 -19
  124. package/lib-esm/ui/index.js +0 -2
  125. package/lib-esm/ui/return-button/index.js +0 -2
  126. package/lib-esm/ui/return-button/return-button-component.js +0 -44
  127. package/lib-esm/ui/return-button/return-button.js +0 -54
  128. package/lib-esm/user.js +0 -13
  129. package/lib-esm/utils/custom-message.js +0 -52
  130. package/lib-esm/utils/index.js +0 -1
  131. package/lib-esm/utils/open-chat-widget.js +0 -142
package/dist/index.js ADDED
@@ -0,0 +1,867 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __objRest = (source, exclude) => {
21
+ var target = {};
22
+ for (var prop in source)
23
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
24
+ target[prop] = source[prop];
25
+ if (source != null && __getOwnPropSymbols)
26
+ for (var prop of __getOwnPropSymbols(source)) {
27
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
28
+ target[prop] = source[prop];
29
+ }
30
+ return target;
31
+ };
32
+ var __async = (__this, __arguments, generator) => {
33
+ return new Promise((resolve, reject) => {
34
+ var fulfilled = (value) => {
35
+ try {
36
+ step(generator.next(value));
37
+ } catch (e) {
38
+ reject(e);
39
+ }
40
+ };
41
+ var rejected = (value) => {
42
+ try {
43
+ step(generator.throw(value));
44
+ } catch (e) {
45
+ reject(e);
46
+ }
47
+ };
48
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
49
+ step((generator = generator.apply(__this, __arguments)).next());
50
+ });
51
+ };
52
+ import { ComponentPlatform } from "@telia-ace/widget-core";
53
+ import { createStorageWriter, StorageCategory, StorageMedium, StorageScope, readStorage } from "@telia-ace/widget-services";
54
+ import { uuid, lock } from "@telia-ace/widget-utilities";
55
+ import { FormBuilder } from "@telia-ace/widget-forms";
56
+ import { closeAllModals } from "@telia-ace/widget-plugins";
57
+ import { createReactComponent } from "@telia-ace/widget-ui";
58
+ import { lazy } from "react";
59
+ class Agent {
60
+ constructor(provider, settings) {
61
+ this.provider = provider;
62
+ this.print = (settings2) => {
63
+ const sender = { name: this.name, avatar: this.avatar };
64
+ const normalized = getNormalizedMessageSettings(settings2);
65
+ return this.provider.createEntry(normalized.key, normalized.content, ConversationMessageType.Agent, sender, normalized.timestamp);
66
+ };
67
+ this.typing = () => {
68
+ return this.provider.setTypingState({ name: this.name, avatar: this.avatar });
69
+ };
70
+ this.name = settings.name;
71
+ this.avatar = settings.avatar;
72
+ }
73
+ update(settings) {
74
+ const { name, avatar } = settings;
75
+ if (avatar === null) {
76
+ this.avatar = void 0;
77
+ } else if (avatar) {
78
+ this.avatar = avatar;
79
+ }
80
+ if (name === null) {
81
+ this.name = void 0;
82
+ } else if (name) {
83
+ this.name = name;
84
+ }
85
+ }
86
+ }
87
+ class ConversationProvider {
88
+ constructor(name, container, controller) {
89
+ this.name = name;
90
+ this.container = container;
91
+ this.controller = controller;
92
+ this.subscriptions = [];
93
+ this.user = controller == null ? void 0 : controller.user;
94
+ }
95
+ static create(name, container, controller) {
96
+ return new ConversationProvider(name, container, controller);
97
+ }
98
+ createAgent(settings = {}) {
99
+ if (this.controller) {
100
+ return new Agent(this, settings);
101
+ }
102
+ }
103
+ print(settings) {
104
+ var _a;
105
+ return (_a = this.controller) == null ? void 0 : _a.print(settings);
106
+ }
107
+ setTypingState(sender, type) {
108
+ var _a;
109
+ return (_a = this.controller) == null ? void 0 : _a.setTypingState(sender, type);
110
+ }
111
+ loading() {
112
+ if (!this.controller) {
113
+ return () => () => {
114
+ };
115
+ }
116
+ return this.controller.loader();
117
+ }
118
+ createEntry(key, content, type, sender, timestamp) {
119
+ var _a;
120
+ return (_a = this.controller) == null ? void 0 : _a.createEntry(key, content, type, sender, timestamp);
121
+ }
122
+ dispose() {
123
+ var _a;
124
+ (_a = this.controller) == null ? void 0 : _a.disposeProvider(this);
125
+ this.controller = null;
126
+ this.subscriptions.forEach((unsub) => unsub());
127
+ }
128
+ onUnreadMessage(fn) {
129
+ var _a;
130
+ if (this.controller) {
131
+ const unsubscribe = (_a = this.controller) == null ? void 0 : _a.onUnreadMessage(fn);
132
+ this.subscriptions.push(unsubscribe);
133
+ return () => {
134
+ unsubscribe();
135
+ };
136
+ }
137
+ }
138
+ onMounted(fn) {
139
+ var _a;
140
+ if (this.controller) {
141
+ const unsubscribe = (_a = this.controller) == null ? void 0 : _a.events.subscribe("conversation:component-mount-changed", fn);
142
+ this.subscriptions.push(unsubscribe);
143
+ fn({}, this.controller.getComponentMountedState());
144
+ return () => {
145
+ unsubscribe();
146
+ };
147
+ }
148
+ }
149
+ }
150
+ class User {
151
+ constructor(controller) {
152
+ this.controller = controller;
153
+ this.print = (settings) => {
154
+ const normalized = getNormalizedMessageSettings(settings);
155
+ return this.controller.createEntry(normalized.key, normalized.content, ConversationMessageType.User, void 0, normalized.timestamp);
156
+ };
157
+ }
158
+ }
159
+ class ConversationEntry {
160
+ constructor(writer) {
161
+ this.writer = writer;
162
+ }
163
+ update(content) {
164
+ const normalized = this.getNormalizedSettings(content);
165
+ this.writer(normalized);
166
+ }
167
+ remove() {
168
+ this.writer(null);
169
+ }
170
+ getNormalizedSettings(content) {
171
+ if (typeof content === "string")
172
+ return { body: content };
173
+ else if (content.length > -1 && typeof content === "object")
174
+ return { items: content };
175
+ else
176
+ return content;
177
+ }
178
+ }
179
+ var ConversationMessageType = /* @__PURE__ */ ((ConversationMessageType2) => {
180
+ ConversationMessageType2["User"] = "user";
181
+ ConversationMessageType2["Agent"] = "agent";
182
+ ConversationMessageType2["System"] = "system";
183
+ return ConversationMessageType2;
184
+ })(ConversationMessageType || {});
185
+ const getNormalizedMessageSettings = (settings) => {
186
+ let content;
187
+ let key = uuid();
188
+ let timestamp = Date.now();
189
+ if (Array.isArray(settings) && settings.length > -1) {
190
+ if (typeof settings[0] === "string") {
191
+ content = { items: [settings] };
192
+ } else {
193
+ content = { items: settings };
194
+ }
195
+ } else if (typeof settings === "string") {
196
+ content = { body: settings };
197
+ } else {
198
+ settings = settings || {};
199
+ if (settings.type) {
200
+ content = __spreadValues({}, settings);
201
+ } else {
202
+ content = {
203
+ body: settings.body,
204
+ actions: settings.actions,
205
+ title: settings.title
206
+ };
207
+ if (settings.key) {
208
+ key = settings.key;
209
+ }
210
+ if (settings.timestamp) {
211
+ timestamp = settings.timestamp;
212
+ }
213
+ if (settings.form) {
214
+ const builder = FormBuilder.create(key);
215
+ settings.form(builder);
216
+ const builtForm = builder.get();
217
+ content.form = builtForm;
218
+ }
219
+ if (settings.timestamp === null) {
220
+ timestamp = null;
221
+ }
222
+ }
223
+ }
224
+ return { content, key, timestamp };
225
+ };
226
+ const removeTypingState = (typingActors, sender) => {
227
+ if (!sender) {
228
+ return;
229
+ }
230
+ const senderString = JSON.stringify(sender);
231
+ const indexToRemove = typingActors.findIndex((item) => {
232
+ return senderString === JSON.stringify(item);
233
+ });
234
+ if (indexToRemove > -1) {
235
+ return typingActors.splice(indexToRemove, 1);
236
+ }
237
+ };
238
+ class ConversationController {
239
+ constructor(container, id) {
240
+ this.container = container;
241
+ this.id = id;
242
+ this.formHandlers = {};
243
+ this.user = new User(this);
244
+ this.providers = [];
245
+ this.active = false;
246
+ this.registeredProviders = [];
247
+ this.loaders = 0;
248
+ this.componentMounted = false;
249
+ this.messages = [];
250
+ this.typingActors = [];
251
+ this.print = (settings) => {
252
+ const normalized = getNormalizedMessageSettings(settings);
253
+ return this.createEntry(normalized.key, normalized.content, "system", void 0, normalized.timestamp);
254
+ };
255
+ const widget = container.get("$widget");
256
+ this.events = widget.events.createChild(this);
257
+ }
258
+ setProviders(providers) {
259
+ const removed = [];
260
+ const added = [];
261
+ this.providers.reduce((acc, provider) => {
262
+ if (providers.indexOf(provider) === -1) {
263
+ acc.push(provider);
264
+ }
265
+ return acc;
266
+ }, []).forEach((providerToRemove) => {
267
+ const indexToRemove = this.providers.indexOf(providerToRemove);
268
+ if (indexToRemove > -1) {
269
+ removed.push(providerToRemove);
270
+ this.providers.splice(indexToRemove, 1);
271
+ }
272
+ });
273
+ providers.forEach((provider) => {
274
+ if (this.providers.indexOf(provider) === -1) {
275
+ added.push(provider);
276
+ this.providers.push(provider);
277
+ }
278
+ });
279
+ if (added.length || removed.length) {
280
+ this.events.dispatch("conversation:providers-changed", { added, removed });
281
+ }
282
+ }
283
+ createProvider(name) {
284
+ const index = this.providerIndex(name);
285
+ if (index > -1) {
286
+ return this.registeredProviders[index];
287
+ }
288
+ const provider = ConversationProvider.create(name, this.container, this);
289
+ this.registeredProviders.push(provider);
290
+ return provider;
291
+ }
292
+ providerIndex(name) {
293
+ return this.registeredProviders.findIndex((p) => p.name === name);
294
+ }
295
+ dispose() {
296
+ this.registeredProviders.forEach((provider) => provider.dispose());
297
+ this.messages = [];
298
+ this.events.dispatch("conversation:controller-disposed", this);
299
+ this.active = false;
300
+ }
301
+ onDispose(fn) {
302
+ return this.events.subscribe("conversation:controller-disposed", fn);
303
+ }
304
+ onStarted(fn) {
305
+ return this.events.subscribe("conversation:started", fn);
306
+ }
307
+ disposeProvider(target) {
308
+ const index = this.providerIndex(target.name);
309
+ index > -1 && this.registeredProviders.splice(index, 1);
310
+ this.events.dispatch("conversation:providers-changed", { removed: [target.name] });
311
+ if (!this.registeredProviders.length) {
312
+ this.dispose();
313
+ }
314
+ }
315
+ onProvidersChange(fn) {
316
+ return this.events.subscribe("conversation:providers-changed", fn);
317
+ }
318
+ setComponentMountedState(mounted) {
319
+ if (this.componentMounted === mounted) {
320
+ return;
321
+ }
322
+ this.componentMounted = mounted;
323
+ if (mounted) {
324
+ this.events.dispatch("conversation:unread-message", false);
325
+ this.events.dispatch("conversation:started", true);
326
+ this.active = true;
327
+ }
328
+ this.events.dispatch("conversation:component-mount-changed", mounted);
329
+ }
330
+ getComponentMountedState() {
331
+ return this.componentMounted;
332
+ }
333
+ onUnreadMessage(fn) {
334
+ return this.events.subscribe("conversation:unread-message", fn);
335
+ }
336
+ createEntry(key, content, type, sender, timestamp) {
337
+ const message = {
338
+ key,
339
+ content,
340
+ type,
341
+ sender: sender || null,
342
+ timestamp: timestamp || timestamp === null ? timestamp : Date.now()
343
+ };
344
+ this.messages.push(message);
345
+ message.type === "agent" && removeTypingState(this.typingActors, sender);
346
+ const entry = new ConversationEntry((updated) => {
347
+ if (updated !== null) {
348
+ const _a = updated, { timestamp: updatedTimestamp = void 0 } = _a, content2 = __objRest(_a, ["timestamp"]);
349
+ message.content = content2;
350
+ if (updatedTimestamp) {
351
+ message.timestamp = updatedTimestamp;
352
+ }
353
+ } else {
354
+ const indexToRemove = this.messages.indexOf(message);
355
+ message.content = null;
356
+ if (indexToRemove > -1) {
357
+ this.messages.splice(indexToRemove, 1);
358
+ }
359
+ }
360
+ this.events.dispatch("conversation:message-updated", { message });
361
+ this.update();
362
+ });
363
+ this.events.dispatch("conversation:message-created", { message });
364
+ this.update();
365
+ if (!this.componentMounted) {
366
+ this.events.dispatch("conversation:unread-message", true);
367
+ }
368
+ return entry;
369
+ }
370
+ update() {
371
+ this.events.dispatch("conversation:updated", {
372
+ messages: this.messages,
373
+ loading: this.loaders > 0,
374
+ typingActors: this.typingActors
375
+ });
376
+ }
377
+ getMessageStream() {
378
+ return {
379
+ messages: this.messages,
380
+ loading: this.loaders > 0,
381
+ typingActors: this.typingActors
382
+ };
383
+ }
384
+ setTypingState(sender, type) {
385
+ if (this.typingActors.indexOf(sender) === -1) {
386
+ this.typingActors.push(sender);
387
+ this.update();
388
+ }
389
+ return () => {
390
+ removeTypingState(this.typingActors, sender);
391
+ this.update();
392
+ };
393
+ }
394
+ loader() {
395
+ this.loaders = this.loaders + 1;
396
+ let dismissed = false;
397
+ if (this.loaders === 1) {
398
+ this.update();
399
+ }
400
+ return () => {
401
+ if (!dismissed) {
402
+ dismissed = true;
403
+ this.loaders = this.loaders - 1;
404
+ if (this.loaders === 0) {
405
+ this.update();
406
+ }
407
+ }
408
+ };
409
+ }
410
+ submitForm(key, handler) {
411
+ this.formHandlers[key] = __spreadProps(__spreadValues({}, this.formHandlers[key]), { submit: handler });
412
+ }
413
+ validateForm(key, handler) {
414
+ this.formHandlers[key] = __spreadProps(__spreadValues({}, this.formHandlers[key]), { validate: handler });
415
+ }
416
+ }
417
+ const getParentWidget = (widgetName, implementation) => {
418
+ const mainWidgetName = widgetName.split("_contact");
419
+ return implementation.widgets.get(mainWidgetName[0]);
420
+ };
421
+ const getSeparateWidget = (container) => {
422
+ const originWidget = container.get("$widget");
423
+ const { name, implementation } = container.get("$widget");
424
+ const mainWidget = name.indexOf("_contact") > -1 ? getParentWidget(name, implementation) : originWidget;
425
+ const { data } = container.get("$settings");
426
+ const { trigger } = mainWidget.container.get("$settings");
427
+ const chatWidgetName = `${name.replace("_contact-method", "").replace("_contact", "")}_contact-method`;
428
+ const chatWidget = implementation.widgets.get(chatWidgetName);
429
+ if (chatWidget && !trigger) {
430
+ return { chatWidget, mainWidget, data };
431
+ }
432
+ return { mainWidget, data };
433
+ };
434
+ const shouldPreventDefault = (container) => {
435
+ const { chatWidget } = getSeparateWidget(container);
436
+ return !!chatWidget;
437
+ };
438
+ const openChatWidget = (container, contactMethod, triggerDOMTarget) => {
439
+ const { mainWidget, data, chatWidget } = getSeparateWidget(container);
440
+ if (chatWidget) {
441
+ if (chatWidget.state === "activated") {
442
+ return chatWidget.invoke("open").then(() => {
443
+ chatWidget.container.getAsync("conversation").then((conversation) => {
444
+ conversation.navigateToConversationIfActive(contactMethod.id).then(() => closeAllModals(container));
445
+ });
446
+ });
447
+ }
448
+ return chatWidget.activate().then(() => {
449
+ const { trigger } = chatWidget.container.get("$settings");
450
+ trigger.action = "hide";
451
+ return chatWidget.invoke("setSettings", () => ({
452
+ data,
453
+ trigger,
454
+ activate: true
455
+ })).then(() => {
456
+ return chatWidget.container.getAsync("components").then((components) => {
457
+ const contactMethodsQuery = components.components().ofType("contact-method");
458
+ components.write({
459
+ key: "setContactMethodId",
460
+ attributes: {
461
+ properties: {
462
+ id: contactMethod.id,
463
+ guideId: contactMethod.guideId
464
+ }
465
+ },
466
+ target: contactMethodsQuery,
467
+ provider: "localStorage"
468
+ });
469
+ const conversationsQuery = components.components().ofType("conversation");
470
+ components.write({
471
+ key: "setConversationProvider",
472
+ attributes: {
473
+ properties: { providers: [contactMethod.clientName] }
474
+ },
475
+ target: conversationsQuery,
476
+ provider: "localStorage"
477
+ });
478
+ });
479
+ });
480
+ }).then(() => {
481
+ return chatWidget.invoke("attach", {
482
+ key: "contact-method",
483
+ triggerDOMElement: triggerDOMTarget,
484
+ withRenderState: "open"
485
+ });
486
+ }).then(() => {
487
+ createStorageWriter(chatWidget.container, "activeStickyWidget", StorageCategory.Necessary, {
488
+ medium: StorageMedium.Local,
489
+ scope: StorageScope.Implementation
490
+ }).then((write) => write(chatWidget.name));
491
+ return chatWidget.container.getAsync("conversation").then((platform) => {
492
+ platform.setConversationEndedBehavior(ConversationEndedBehavior.Deactivate);
493
+ }).then(() => closeAllModals(container)).then(() => false);
494
+ });
495
+ }
496
+ mainWidget.container.getAsync("conversation").then((platform) => {
497
+ return platform.navigateToConversationIfActive(contactMethod.id).then(() => platform.setConversationEndedBehavior(ConversationEndedBehavior.Navigate));
498
+ });
499
+ return chatWidget ? false : true;
500
+ };
501
+ const navigateToConversation = (container, contactMethod, routeName = "conversation") => {
502
+ const { mainWidget, chatWidget } = getSeparateWidget(container);
503
+ if (chatWidget) {
504
+ return chatWidget.container.getAsync("router").then((router) => {
505
+ router.navigate(routeName, { id: contactMethod.id });
506
+ });
507
+ }
508
+ return mainWidget.container.getAsync("conversation").then((platform) => {
509
+ var _a;
510
+ (_a = platform.setConversationEndedBehavior(ConversationEndedBehavior.Navigate)) == null ? void 0 : _a.then(() => {
511
+ mainWidget.container.getAsync("router").then((router) => {
512
+ mainWidget.container.getAsync("components").then((components) => {
513
+ const conversationQuery = components.components().ofType("conversation");
514
+ components.write({
515
+ key: "setConversationProvider",
516
+ attributes: { properties: { providers: [contactMethod.clientName] } },
517
+ target: conversationQuery,
518
+ provider: "localStorage"
519
+ });
520
+ }).then(() => {
521
+ router.navigate(routeName, { id: contactMethod.id });
522
+ });
523
+ });
524
+ });
525
+ });
526
+ };
527
+ const STORAGE_KEY = "conversations";
528
+ var ConversationEndedBehavior = /* @__PURE__ */ ((ConversationEndedBehavior2) => {
529
+ ConversationEndedBehavior2["Deactivate"] = "deactivate";
530
+ ConversationEndedBehavior2["Navigate"] = "navigate";
531
+ ConversationEndedBehavior2["None"] = "none";
532
+ return ConversationEndedBehavior2;
533
+ })(ConversationEndedBehavior || {});
534
+ class ConversationPlatform {
535
+ constructor(container, components) {
536
+ this.container = container;
537
+ this.components = components;
538
+ this.controllers = [];
539
+ this.providers = [];
540
+ this.disposeProviders = {};
541
+ this.subscriptions = [];
542
+ this.storageWriter = null;
543
+ this.router = null;
544
+ this.buttonQuery = null;
545
+ this.sessionInfo = null;
546
+ const widget = container.get("$widget");
547
+ this.events = widget.events.createChild(this);
548
+ }
549
+ initialize() {
550
+ createStorageWriter(this.container, STORAGE_KEY, StorageCategory.Necessary, {
551
+ medium: StorageMedium.Local
552
+ }).then((writer) => this.storageWriter = writer);
553
+ readStorage(this.container, STORAGE_KEY, StorageMedium.Local).then((storedSession) => {
554
+ this.buttonQuery = this.components.components().ofType("conversation-return-button");
555
+ if (storedSession) {
556
+ this.sessionInfo = storedSession;
557
+ if (storedSession.id && storedSession.route) {
558
+ this.writeToComponents({ active: true, alert: { show: false } });
559
+ }
560
+ }
561
+ });
562
+ this.container.getAsync("router").then((router) => this.router = router);
563
+ this.events.subscribe("conversation:ended", (event, data) => {
564
+ var _a, _b, _c;
565
+ switch ((_a = this.sessionInfo) == null ? void 0 : _a.conversationEndedBehavior) {
566
+ case "deactivate":
567
+ const widget = this.container.get("$widget");
568
+ widget.deactivate();
569
+ break;
570
+ case "navigate":
571
+ const initialRoute = (_b = this.router) == null ? void 0 : _b.getInitialRoute();
572
+ if (initialRoute) {
573
+ (_c = this.router) == null ? void 0 : _c.navigate(initialRoute.name);
574
+ }
575
+ break;
576
+ }
577
+ this.writeToComponents({ active: false });
578
+ this.sessionInfo = null;
579
+ this.storageWriter && this.storageWriter();
580
+ });
581
+ }
582
+ addSubscription(sub) {
583
+ this.subscriptions.push(sub);
584
+ }
585
+ static getInstance(container, key = "conversation") {
586
+ return lock(container)(() => {
587
+ return container.getAsync(key).then((value) => {
588
+ let conversation = value;
589
+ if (!conversation) {
590
+ return ComponentPlatform.getInstance(container).then((components) => {
591
+ conversation = new ConversationPlatform(container, components);
592
+ conversation.initialize();
593
+ container.registerAsync(key, () => conversation);
594
+ return conversation;
595
+ });
596
+ }
597
+ return conversation;
598
+ });
599
+ });
600
+ }
601
+ navigateToConversationIfActive(id) {
602
+ return readStorage(this.container, STORAGE_KEY, StorageMedium.Local).then((storedSession) => {
603
+ var _a;
604
+ if (storedSession && storedSession.id === id) {
605
+ if (storedSession.route) {
606
+ const { name, params } = storedSession.route;
607
+ (_a = this.router) == null ? void 0 : _a.navigate(name, params);
608
+ }
609
+ }
610
+ });
611
+ }
612
+ setConversationEndedBehavior(behavior) {
613
+ return readStorage(this.container, STORAGE_KEY, StorageMedium.Local).then((stored) => {
614
+ let storedSession = stored;
615
+ if (storedSession) {
616
+ storedSession.conversationEndedBehavior = behavior;
617
+ } else {
618
+ storedSession = { conversationEndedBehavior: behavior };
619
+ }
620
+ this.sessionInfo = storedSession;
621
+ return this.storageWriter && this.storageWriter(this.sessionInfo) || Promise.resolve();
622
+ });
623
+ }
624
+ createController(id) {
625
+ const index = this.controllers.findIndex((c) => c.conversation.id === id);
626
+ if (index > -1) {
627
+ return this.controllers[index].conversation;
628
+ }
629
+ return new ConversationController(this.container, id);
630
+ }
631
+ registerProvider(name, handler) {
632
+ const provider = {
633
+ name,
634
+ handler
635
+ };
636
+ this.providers.push(provider);
637
+ this.controllers.filter((controller) => controller.conversation.providers.indexOf(name) > -1).forEach((controller) => {
638
+ this.invokeHandler(provider, controller);
639
+ });
640
+ }
641
+ registerController(conversation, component) {
642
+ const index = this.controllers.findIndex((c) => c.conversation.id === conversation.id);
643
+ let controller;
644
+ if (index < 0) {
645
+ controller = { conversation, component };
646
+ this.controllers.push(controller);
647
+ const invokeHandlers = (providers) => {
648
+ if (providers) {
649
+ this.providers.filter((provider) => providers.indexOf(provider.name) > -1).forEach((provider) => {
650
+ this.invokeHandler(provider, controller);
651
+ });
652
+ }
653
+ };
654
+ this.subscriptions.push(conversation.onDispose((event, data) => {
655
+ const index2 = this.controllers.findIndex((c) => c.conversation === data);
656
+ index2 > -1 && this.controllers.splice(index2, 1);
657
+ this.components.components().ofType("conversation-return-button").select().writeProperties({ active: false });
658
+ this.events.dispatch("conversation:ended", {}, { bubbles: true });
659
+ }));
660
+ this.subscriptions.push(conversation.onProvidersChange((event, data) => {
661
+ const { added, removed } = data;
662
+ removed.forEach((removedProvider) => {
663
+ this.disposeProviders[removedProvider].forEach((dispose) => {
664
+ dispose();
665
+ });
666
+ });
667
+ invokeHandlers(added);
668
+ }));
669
+ this.subscriptions.push(conversation.onStarted((event, isActive) => {
670
+ var _a, _b;
671
+ const session = {
672
+ id: conversation.id,
673
+ route: (_a = this.router) == null ? void 0 : _a.getRouteData(),
674
+ conversationEndedBehavior: (_b = this.sessionInfo) == null ? void 0 : _b.conversationEndedBehavior
675
+ };
676
+ this.sessionInfo = session;
677
+ this.storageWriter && this.storageWriter(session);
678
+ this.writeToComponents({ active: isActive });
679
+ }));
680
+ this.subscriptions.push(conversation.onUnreadMessage((event, data) => {
681
+ this.events.dispatch("conversation:unread-message", data);
682
+ this.writeToComponents({ alert: { show: data } });
683
+ }));
684
+ invokeHandlers(conversation.providers);
685
+ return true;
686
+ }
687
+ controller = this.controllers[index];
688
+ return false;
689
+ }
690
+ writeToComponents(properties, key = "conversationReturnButtonState") {
691
+ if (this.buttonQuery) {
692
+ this.components.write({
693
+ key: "conversationReturnButtonState",
694
+ attributes: { properties },
695
+ target: this.buttonQuery,
696
+ provider: "localStorage"
697
+ });
698
+ }
699
+ }
700
+ invokeHandler(provider, controller) {
701
+ const dispose = provider.handler(controller.conversation.createProvider(provider.name), controller.component);
702
+ if (dispose) {
703
+ if (!this.disposeProviders[provider.name]) {
704
+ this.disposeProviders[provider.name] = [];
705
+ }
706
+ this.disposeProviders[provider.name].push(dispose);
707
+ }
708
+ }
709
+ getComponentRoute() {
710
+ return readStorage(this.container, STORAGE_KEY, StorageMedium.Local).then((stored) => stored == null ? void 0 : stored.route);
711
+ }
712
+ dispose() {
713
+ Object.keys(this.disposeProviders).forEach((key) => {
714
+ this.disposeProviders[key].forEach((dispose) => {
715
+ dispose();
716
+ });
717
+ });
718
+ this.subscriptions.forEach((unsubscribe) => {
719
+ unsubscribe();
720
+ });
721
+ this.controllers = [];
722
+ this.providers = [];
723
+ }
724
+ static handleContactMethodClick(event, container, contactMethod, callback) {
725
+ return __async(this, null, function* () {
726
+ if (shouldPreventDefault(container)) {
727
+ event.preventDefault();
728
+ let triggerEl = document.getElementById("humany-dynamic-anchor");
729
+ if (!triggerEl) {
730
+ triggerEl = document.createElement("a");
731
+ triggerEl.setAttribute("href", "#");
732
+ triggerEl.id = "humany-dynamic-anchor";
733
+ document.body.appendChild(triggerEl);
734
+ }
735
+ openChatWidget(container, contactMethod, triggerEl);
736
+ }
737
+ openChatWidget(container, contactMethod);
738
+ });
739
+ }
740
+ static handleContactMethodSubmit(container, contactMethod) {
741
+ return __async(this, null, function* () {
742
+ return navigateToConversation(container, contactMethod);
743
+ });
744
+ }
745
+ }
746
+ var ConversationMessageListItemType = /* @__PURE__ */ ((ConversationMessageListItemType2) => {
747
+ ConversationMessageListItemType2["Header"] = "header";
748
+ ConversationMessageListItemType2["LinkList"] = "link-list";
749
+ ConversationMessageListItemType2["Separator"] = "separator";
750
+ ConversationMessageListItemType2["NoGoodAlternative"] = "no-good-alternative";
751
+ ConversationMessageListItemType2["ButtonList"] = "button-list";
752
+ ConversationMessageListItemType2["Text"] = "text";
753
+ ConversationMessageListItemType2["HTML"] = "html";
754
+ ConversationMessageListItemType2["FeedbackList"] = "feedback-list";
755
+ return ConversationMessageListItemType2;
756
+ })(ConversationMessageListItemType || {});
757
+ const groupedMessages = (messages, timeout) => {
758
+ return messages.reduce((acc, current, index) => {
759
+ var _a, _b;
760
+ const newItem = __spreadProps(__spreadValues({}, current), {
761
+ content: [__spreadProps(__spreadValues({}, current.content), { key: current.key })]
762
+ });
763
+ if (acc.length > 0 && current.type !== ConversationMessageType.System) {
764
+ const previous = acc[acc.length - 1];
765
+ if (!timeout && timeout !== 0 || Math.abs(previous.timestamp - current.timestamp) < timeout) {
766
+ if (((_a = previous.sender) == null ? void 0 : _a.name) === ((_b = current.sender) == null ? void 0 : _b.name) && previous.type === current.type) {
767
+ previous.timestamp = current.timestamp;
768
+ previous.content.push(__spreadProps(__spreadValues({}, current.content), { key: current.key }));
769
+ return acc;
770
+ }
771
+ }
772
+ }
773
+ acc.push(newItem);
774
+ return acc;
775
+ }, []);
776
+ };
777
+ const ConversationComponent = (container) => {
778
+ return Promise.all([
779
+ ConversationPlatform.getInstance(container),
780
+ container.getAsync("router")
781
+ ]).then(([platform, router]) => {
782
+ return createReactComponent(container, "conversation", import("./conversation.js"), (component) => {
783
+ const routeData = router.getRouteData();
784
+ const name = routeData.params.id || component.node.name || "component";
785
+ const conversation = platform.createController(name);
786
+ const isNewController = platform.registerController(conversation, component);
787
+ const messageGroupingTimeout = 3 * 60 * 1e3;
788
+ const setProperties = (properties) => {
789
+ const { providers = [] } = properties;
790
+ if (providers) {
791
+ const providerKeys = Array.isArray(providers) ? providers : [providers];
792
+ conversation.setProviders(providerKeys);
793
+ return providerKeys;
794
+ }
795
+ };
796
+ setProperties(component.properties(setProperties));
797
+ conversation.setComponentMountedState(true);
798
+ const writeMessages = (messageStream) => {
799
+ const { loading, typingActors, messages } = messageStream;
800
+ component.writeProperties({
801
+ loading,
802
+ typingActors,
803
+ messages: groupedMessages(messages, messageGroupingTimeout)
804
+ });
805
+ };
806
+ writeMessages(conversation.getMessageStream());
807
+ if (isNewController) {
808
+ component.actions.create("user-submit", (data, options) => {
809
+ if (options) {
810
+ const { preventDefault, validationPromise } = options;
811
+ if (preventDefault) {
812
+ if (validationPromise) {
813
+ validationPromise().then((text) => {
814
+ if (text) {
815
+ conversation.user.print(text);
816
+ }
817
+ });
818
+ }
819
+ return;
820
+ }
821
+ }
822
+ conversation.user.print(data.text);
823
+ });
824
+ component.actions.create("user-typing", (data, options) => {
825
+ });
826
+ component.actions.create("form", (data, options) => {
827
+ });
828
+ component.actions.create("action", (data, options) => {
829
+ });
830
+ }
831
+ const unsubscribe = conversation.events.subscribe("conversation:updated", (e, conversationData) => {
832
+ writeMessages(conversationData);
833
+ });
834
+ return () => {
835
+ conversation.setComponentMountedState(false);
836
+ unsubscribe();
837
+ if (!conversation.active) {
838
+ writeMessages({ messages: [], typingActors: [], loading: false });
839
+ }
840
+ };
841
+ }, { reuseController: true });
842
+ });
843
+ };
844
+ const ConversationReturnButtonComponent = (container) => {
845
+ return Promise.all([
846
+ ComponentPlatform.getInstance(container),
847
+ ConversationPlatform.getInstance(container),
848
+ container.getAsync("router")
849
+ ]).then(([components, platform, router]) => {
850
+ return createReactComponent(container, "conversation-return-button", import("./return-button.js"), (component) => {
851
+ component.actions.create("toggle", (options = {}) => {
852
+ var _a;
853
+ (_a = platform.getComponentRoute()) == null ? void 0 : _a.then((route) => {
854
+ route && router.navigate(route.name, route.params);
855
+ });
856
+ });
857
+ });
858
+ });
859
+ };
860
+ const registerCustomMessageComponent = (container, type, component) => {
861
+ return container.getAsync("componentResolver").then((o) => __async(this, null, function* () {
862
+ const platform = yield ConversationPlatform.getInstance(container);
863
+ platform.addSubscription(o.registerComponent(type, lazy(() => component)));
864
+ }));
865
+ };
866
+ export { ConversationComponent, ConversationController, ConversationEndedBehavior, ConversationEntry, ConversationMessageListItemType, ConversationMessageType, ConversationPlatform, ConversationReturnButtonComponent, registerCustomMessageComponent };
867
+ //# sourceMappingURL=index.js.map