@nyaruka/temba-components 0.133.0 → 0.134.1
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/CHANGELOG.md +17 -0
- package/demo/components/webchat/example.html +1 -1
- package/dist/locales/es.js +5 -5
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +5 -5
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/locale-codes.js +2 -11
- package/dist/locales/locale-codes.js.map +1 -1
- package/dist/locales/pt.js +5 -5
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +307 -259
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +223 -90
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/TembaUser.js +3 -3
- package/out-tsc/src/display/TembaUser.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +8 -0
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +117 -28
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/utils.js +141 -0
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +122 -170
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/locales/es.js +5 -5
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +5 -5
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/locale-codes.js +2 -11
- package/out-tsc/src/locales/locale-codes.js.map +1 -1
- package/out-tsc/src/locales/pt.js +5 -5
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/store/AppState.js +3 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/store/Store.js +5 -5
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +22 -9
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js +9 -4
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/temba-flow-collision.test.js +673 -0
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +128 -42
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
- package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
- package/src/display/Chat.ts +303 -129
- package/src/display/TembaUser.ts +3 -2
- package/src/events.ts +11 -8
- package/src/flow/CanvasNode.ts +10 -0
- package/src/flow/Editor.ts +156 -28
- package/src/flow/utils.ts +207 -1
- package/src/interfaces.ts +7 -0
- package/src/live/ContactChat.ts +129 -180
- package/src/locales/es.ts +13 -18
- package/src/locales/fr.ts +13 -18
- package/src/locales/locale-codes.ts +2 -11
- package/src/locales/pt.ts +13 -18
- package/src/store/AppState.ts +2 -0
- package/src/store/Store.ts +5 -5
- package/src/webchat/WebChat.ts +24 -10
- package/test/actions/send_broadcast.test.ts +2 -1
- package/test/temba-flow-collision.test.ts +833 -0
- package/test/temba-flow-editor-node.test.ts +142 -47
|
@@ -1,21 +1,49 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { html, css } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
4
5
|
import { RapidElement } from '../RapidElement';
|
|
5
6
|
import { CustomEventType } from '../interfaces';
|
|
6
7
|
import { DEFAULT_AVATAR } from '../webchat/assets';
|
|
7
|
-
import { hashCode } from '../utils';
|
|
8
8
|
const BATCH_TIME_WINDOW = 60 * 60 * 1000;
|
|
9
|
-
const SCROLL_FETCH_BUFFER =
|
|
9
|
+
const SCROLL_FETCH_BUFFER = 200; // pixels from top
|
|
10
10
|
const MIN_FETCH_TIME = 250;
|
|
11
|
+
const getUnsendableReasonMessage = (reason) => {
|
|
12
|
+
switch (reason) {
|
|
13
|
+
case 'no_route':
|
|
14
|
+
return 'No channel available to send message';
|
|
15
|
+
case 'contact_blocked':
|
|
16
|
+
return 'Contact has been blocked';
|
|
17
|
+
case 'contact_stopped':
|
|
18
|
+
return 'Contact has been stopped';
|
|
19
|
+
case 'contact_archived':
|
|
20
|
+
return 'Contact is archived';
|
|
21
|
+
case 'org_suspended':
|
|
22
|
+
return 'Workspace is suspended';
|
|
23
|
+
case 'looping':
|
|
24
|
+
return 'Message loop detected';
|
|
25
|
+
default:
|
|
26
|
+
return 'Unable to send message';
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const getStatusReasonMessage = (reason) => {
|
|
30
|
+
switch (reason) {
|
|
31
|
+
case 'error_limit':
|
|
32
|
+
return 'Error limit reached';
|
|
33
|
+
case 'too_old':
|
|
34
|
+
return 'Message is too old to send';
|
|
35
|
+
case 'channel_removed':
|
|
36
|
+
return 'Channel was removed';
|
|
37
|
+
default:
|
|
38
|
+
return 'Message failed to send';
|
|
39
|
+
}
|
|
40
|
+
};
|
|
11
41
|
export var MessageType;
|
|
12
42
|
(function (MessageType) {
|
|
13
43
|
MessageType["Inline"] = "inline";
|
|
14
44
|
MessageType["Error"] = "error";
|
|
15
45
|
MessageType["Collapse"] = "collapse";
|
|
16
46
|
MessageType["Note"] = "note";
|
|
17
|
-
MessageType["MsgIn"] = "msg_in";
|
|
18
|
-
MessageType["MsgOut"] = "msg_out";
|
|
19
47
|
})(MessageType || (MessageType = {}));
|
|
20
48
|
const TIME_FORMAT = { hour: 'numeric', minute: '2-digit' };
|
|
21
49
|
const VERBOSE_FORMAT = {
|
|
@@ -37,7 +65,10 @@ export class Chat extends RapidElement {
|
|
|
37
65
|
this.agent = false;
|
|
38
66
|
this.endOfHistory = false;
|
|
39
67
|
this.oldestEventDate = null;
|
|
68
|
+
this.showNewMessageNotification = false;
|
|
69
|
+
this.hasFooter = false;
|
|
40
70
|
this.msgMap = new Map();
|
|
71
|
+
this.metadataCache = new Map();
|
|
41
72
|
}
|
|
42
73
|
static get styles() {
|
|
43
74
|
return css `
|
|
@@ -207,16 +238,24 @@ export class Chat extends RapidElement {
|
|
|
207
238
|
color: rgba(0, 0, 0, 0.5);
|
|
208
239
|
}
|
|
209
240
|
|
|
241
|
+
.failed .bubble,
|
|
242
|
+
.error .bubble {
|
|
243
|
+
border: 1px solid var(--color-error);
|
|
244
|
+
background: #ffe6e6;
|
|
245
|
+
color: #ad4747ff;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.error .bubble .name,
|
|
249
|
+
.failed .bubble .name {
|
|
250
|
+
color: #ad47479a;
|
|
251
|
+
}
|
|
252
|
+
|
|
210
253
|
.message {
|
|
211
254
|
margin-bottom: 0.5em;
|
|
212
255
|
line-height: 1.2em;
|
|
213
256
|
word-break: break-word;
|
|
214
257
|
}
|
|
215
258
|
|
|
216
|
-
.message-text {
|
|
217
|
-
white-space: pre-line;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
259
|
.chat {
|
|
221
260
|
width: 28rem;
|
|
222
261
|
border-radius: var(--curvature);
|
|
@@ -427,19 +466,12 @@ export class Chat extends RapidElement {
|
|
|
427
466
|
border-radius: var(--curvature);
|
|
428
467
|
}
|
|
429
468
|
|
|
430
|
-
.
|
|
431
|
-
border: 1px solid var(--color-error);
|
|
432
|
-
background: white;
|
|
433
|
-
color: #333;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
.error .bubble .name {
|
|
437
|
-
color: #999;
|
|
438
|
-
}
|
|
439
|
-
|
|
469
|
+
.failed temba-thumbnail,
|
|
440
470
|
.error temba-thumbnail {
|
|
441
|
-
--thumb-background:
|
|
442
|
-
--thumb-
|
|
471
|
+
--thumb-background: #ffe6e6;
|
|
472
|
+
--thumb-border: var(--color-error);
|
|
473
|
+
border: 1px solid var(--color-error);
|
|
474
|
+
color: #ad4747a8;
|
|
443
475
|
}
|
|
444
476
|
|
|
445
477
|
.outgoing .popup {
|
|
@@ -483,6 +515,37 @@ export class Chat extends RapidElement {
|
|
|
483
515
|
opacity: 1;
|
|
484
516
|
transition-delay: 1s;
|
|
485
517
|
}
|
|
518
|
+
|
|
519
|
+
.new-message-notification {
|
|
520
|
+
position: absolute;
|
|
521
|
+
bottom: 1em;
|
|
522
|
+
left: 50%;
|
|
523
|
+
transform: translateX(-50%) translateY(100px);
|
|
524
|
+
background: var(--color-primary-dark, #3c92dd);
|
|
525
|
+
color: white;
|
|
526
|
+
padding: 0.75em 1.5em;
|
|
527
|
+
border-radius: var(--curvature);
|
|
528
|
+
box-shadow: rgba(0, 0, 0, 0.2) 0px 3px 7px 0px,
|
|
529
|
+
rgba(0, 0, 0, 0.3) 0px 1px 2px 0px;
|
|
530
|
+
cursor: pointer;
|
|
531
|
+
opacity: 0;
|
|
532
|
+
transition: all 0.3s ease-out;
|
|
533
|
+
z-index: 100;
|
|
534
|
+
font-weight: 500;
|
|
535
|
+
pointer-events: none;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.new-message-notification.visible {
|
|
539
|
+
transform: translateX(-50%) translateY(0);
|
|
540
|
+
opacity: 1;
|
|
541
|
+
pointer-events: auto;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.new-message-notification:hover {
|
|
545
|
+
background: var(--color-primary-darker, #2b7ac4);
|
|
546
|
+
box-shadow: rgba(0, 0, 0, 0.3) 0px 4px 10px 0px,
|
|
547
|
+
rgba(0, 0, 0, 0.4) 0px 2px 4px 0px;
|
|
548
|
+
}
|
|
486
549
|
`;
|
|
487
550
|
}
|
|
488
551
|
firstUpdated(changed) {
|
|
@@ -493,15 +556,6 @@ export class Chat extends RapidElement {
|
|
|
493
556
|
this.hideTopScroll = !hasScroll;
|
|
494
557
|
}
|
|
495
558
|
addMessages(messages, startTime = null, append = false) {
|
|
496
|
-
// make sure our messages have ids
|
|
497
|
-
messages.forEach((m) => {
|
|
498
|
-
if (!m.id) {
|
|
499
|
-
m.id =
|
|
500
|
-
hashCode((m.text.strings || []).join('')) +
|
|
501
|
-
'_' +
|
|
502
|
-
m.date.toISOString();
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
559
|
if (!startTime) {
|
|
506
560
|
startTime = new Date();
|
|
507
561
|
}
|
|
@@ -511,8 +565,16 @@ export class Chat extends RapidElement {
|
|
|
511
565
|
// first add messages to the map
|
|
512
566
|
const newMessages = [];
|
|
513
567
|
for (const m of messages) {
|
|
568
|
+
// filter out metadata events - they aren't rendered but cached for later reference
|
|
569
|
+
if (m.type === 'msg_deleted' || m.type === 'msg_status_changed') {
|
|
570
|
+
const msgUuid = m.msg_uuid;
|
|
571
|
+
if (msgUuid) {
|
|
572
|
+
this.metadataCache.set(msgUuid, m);
|
|
573
|
+
}
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
514
576
|
if (this.addMessage(m)) {
|
|
515
|
-
newMessages.push(m.
|
|
577
|
+
newMessages.push(m.uuid);
|
|
516
578
|
}
|
|
517
579
|
}
|
|
518
580
|
if (newMessages.length === 0) {
|
|
@@ -520,10 +582,25 @@ export class Chat extends RapidElement {
|
|
|
520
582
|
}
|
|
521
583
|
const ele = this.shadowRoot.querySelector('.scroll');
|
|
522
584
|
const prevTop = ele.scrollTop;
|
|
585
|
+
const prevScrollHeight = ele.scrollHeight;
|
|
586
|
+
const scrollableHeight = ele.scrollHeight - ele.clientHeight;
|
|
587
|
+
const isScrolledAway = scrollableHeight > 0 && Math.abs(ele.scrollTop) > 50;
|
|
523
588
|
const grouped = this.groupMessages(newMessages);
|
|
524
589
|
this.insertGroups(grouped, append);
|
|
590
|
+
// show notification if new messages are appended and user is scrolled away from bottom
|
|
591
|
+
if (append && isScrolledAway && newMessages.length > 0) {
|
|
592
|
+
this.showNewMessageNotification = true;
|
|
593
|
+
}
|
|
525
594
|
window.setTimeout(() => {
|
|
526
|
-
|
|
595
|
+
// when appending (new messages at bottom), adjust scroll to maintain visible content
|
|
596
|
+
// with column-reverse, new content at bottom increases scrollHeight
|
|
597
|
+
if (append && isScrolledAway) {
|
|
598
|
+
const heightDiff = ele.scrollHeight - prevScrollHeight;
|
|
599
|
+
ele.scrollTop = prevTop - heightDiff;
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
ele.scrollTop = prevTop;
|
|
603
|
+
}
|
|
527
604
|
this.fireCustomEvent(CustomEventType.FetchComplete);
|
|
528
605
|
}, 100);
|
|
529
606
|
},
|
|
@@ -534,18 +611,19 @@ export class Chat extends RapidElement {
|
|
|
534
611
|
}
|
|
535
612
|
addMessage(msg) {
|
|
536
613
|
const isNew = !this.messageExists(msg);
|
|
537
|
-
this.msgMap.set(msg.
|
|
614
|
+
this.msgMap.set(msg.uuid, msg);
|
|
538
615
|
return isNew;
|
|
539
616
|
}
|
|
540
617
|
messageExists(msg) {
|
|
541
|
-
return this.msgMap.has(msg.
|
|
618
|
+
return this.msgMap.has(msg.uuid);
|
|
542
619
|
}
|
|
543
620
|
isSameGroup(msg1, msg2) {
|
|
544
621
|
var _a, _b;
|
|
545
622
|
if (msg1 && msg2) {
|
|
546
623
|
const sameGroup = msg1.type === msg2.type &&
|
|
547
|
-
((_a = msg1.
|
|
548
|
-
Math.abs(msg1.
|
|
624
|
+
((_a = msg1._user) === null || _a === void 0 ? void 0 : _a.name) === ((_b = msg2._user) === null || _b === void 0 ? void 0 : _b.name) &&
|
|
625
|
+
Math.abs(msg1.created_on.getTime() - msg2.created_on.getTime()) <
|
|
626
|
+
BATCH_TIME_WINDOW;
|
|
549
627
|
return sameGroup;
|
|
550
628
|
}
|
|
551
629
|
return false;
|
|
@@ -604,24 +682,39 @@ export class Chat extends RapidElement {
|
|
|
604
682
|
}
|
|
605
683
|
handleScroll(event) {
|
|
606
684
|
const ele = event.target;
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
if (
|
|
685
|
+
const scrollableHeight = ele.scrollHeight - ele.clientHeight;
|
|
686
|
+
if (scrollableHeight <= 0) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
689
|
+
// with column-reverse, scrollTop behavior depends on the browser
|
|
690
|
+
// check if scrollTop is negative (some browsers) or positive (others)
|
|
691
|
+
const absScrollTop = Math.abs(ele.scrollTop);
|
|
692
|
+
// when scrolling up to older messages, absScrollTop increases
|
|
693
|
+
// trigger when we're close to the maximum scroll (oldest messages)
|
|
694
|
+
const shouldFetch = absScrollTop >= scrollableHeight - SCROLL_FETCH_BUFFER;
|
|
695
|
+
this.hideTopScroll = absScrollTop >= scrollableHeight - 1;
|
|
696
|
+
this.hideBottomScroll = absScrollTop <= 1;
|
|
697
|
+
// hide notification when scrolled to bottom
|
|
698
|
+
if (absScrollTop <= 10) {
|
|
699
|
+
this.showNewMessageNotification = false;
|
|
700
|
+
}
|
|
701
|
+
if (shouldFetch) {
|
|
613
702
|
this.fireCustomEvent(CustomEventType.ScrollThreshold);
|
|
614
703
|
}
|
|
615
704
|
}
|
|
616
705
|
scrollToBottom() {
|
|
617
706
|
const scroll = this.shadowRoot.querySelector('.scroll');
|
|
618
707
|
if (scroll) {
|
|
619
|
-
scroll.scrollTop =
|
|
708
|
+
scroll.scrollTop = 0;
|
|
620
709
|
this.hideBottomScroll = true;
|
|
710
|
+
this.showNewMessageNotification = false;
|
|
621
711
|
}
|
|
622
712
|
}
|
|
713
|
+
handleNewMessageClick() {
|
|
714
|
+
this.scrollToBottom();
|
|
715
|
+
}
|
|
623
716
|
renderMessageGroup(msgIds, idx, groups) {
|
|
624
|
-
var _a, _b, _c;
|
|
717
|
+
var _a, _b, _c, _d;
|
|
625
718
|
const today = new Date();
|
|
626
719
|
const firstGroup = idx === groups.length - 1;
|
|
627
720
|
let prevMsg;
|
|
@@ -636,51 +729,58 @@ export class Chat extends RapidElement {
|
|
|
636
729
|
let timeDisplay = null;
|
|
637
730
|
if (prevMsg &&
|
|
638
731
|
!this.isSameGroup(prevMsg, currentMsg) &&
|
|
639
|
-
(Math.abs(currentMsg.
|
|
640
|
-
BATCH_TIME_WINDOW ||
|
|
732
|
+
(Math.abs(currentMsg.created_on.getTime() - prevMsg.created_on.getTime()) > BATCH_TIME_WINDOW ||
|
|
641
733
|
idx === groups.length - 1)) {
|
|
642
|
-
if (today.getDate() !== prevMsg.
|
|
643
|
-
prevMsg.
|
|
734
|
+
if (today.getDate() !== prevMsg.created_on.getDate() ||
|
|
735
|
+
prevMsg.created_on.getDate() !== currentMsg.created_on.getDate()) {
|
|
644
736
|
timeDisplay = html `<div class="time ${firstGroup ? 'first' : ''}">
|
|
645
|
-
${prevMsg.
|
|
737
|
+
${prevMsg.created_on.toLocaleTimeString(undefined, VERBOSE_FORMAT)}
|
|
646
738
|
</div>`;
|
|
647
739
|
}
|
|
648
740
|
else {
|
|
649
741
|
timeDisplay = html `<div class="time ${firstGroup ? 'first' : ''}">
|
|
650
|
-
${prevMsg.
|
|
742
|
+
${prevMsg.created_on.toLocaleTimeString(undefined, TIME_FORMAT)}
|
|
651
743
|
</div>`;
|
|
652
744
|
}
|
|
653
745
|
}
|
|
654
746
|
const incoming = this.agent
|
|
655
|
-
? currentMsg.type !== '
|
|
656
|
-
: currentMsg.type === '
|
|
657
|
-
const name = (_a = currentMsg.
|
|
658
|
-
const
|
|
659
|
-
|
|
660
|
-
currentMsg.type === 'msg_in' ||
|
|
661
|
-
currentMsg.type === 'msg_out') &&
|
|
747
|
+
? currentMsg.type !== 'msg_received'
|
|
748
|
+
: currentMsg.type === 'msg_received';
|
|
749
|
+
const name = (_a = currentMsg._user) === null || _a === void 0 ? void 0 : _a.name;
|
|
750
|
+
const showAvatar = ((currentMsg.type === 'msg_received' ||
|
|
751
|
+
currentMsg.type === 'msg_created') &&
|
|
662
752
|
this.agent) ||
|
|
663
753
|
!incoming;
|
|
754
|
+
const isSystem = !((_b = currentMsg._user) === null || _b === void 0 ? void 0 : _b.uuid);
|
|
664
755
|
return html `
|
|
665
756
|
${timeDisplay}
|
|
666
|
-
<div
|
|
667
|
-
class="block ${incoming ? 'incoming' : 'outgoing'} ${currentMsg.type}"
|
|
668
|
-
>
|
|
757
|
+
<div class="block ${incoming ? 'incoming' : 'outgoing'}">
|
|
669
758
|
<div class="group-messages" style="flex-grow:1">
|
|
670
|
-
${msgIds
|
|
759
|
+
${repeat(msgIds, (msgId) => msgId, (msgId, index) => {
|
|
760
|
+
var _a, _b;
|
|
671
761
|
const msg = this.msgMap.get(msgId);
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
762
|
+
const msgEvent = msg;
|
|
763
|
+
const statusClass = msg._status
|
|
764
|
+
? msg._status.status
|
|
765
|
+
: '';
|
|
766
|
+
const hasError = ((_a = msgEvent.msg) === null || _a === void 0 ? void 0 : _a.unsendable_reason) ||
|
|
767
|
+
(((_b = msgEvent._status) === null || _b === void 0 ? void 0 : _b.reason) &&
|
|
768
|
+
(statusClass === 'failed' || statusClass === 'errored'));
|
|
769
|
+
const unsendableClass = hasError ? 'error' : '';
|
|
770
|
+
return html `<div
|
|
771
|
+
class="row message ${statusClass} ${unsendableClass}"
|
|
772
|
+
>
|
|
773
|
+
${this.renderMessage(msg, index == 0 ? name : null)}
|
|
774
|
+
</div>`;
|
|
675
775
|
})}
|
|
676
776
|
</div>
|
|
677
777
|
${showAvatar
|
|
678
778
|
? html `<div class="avatar" style="align-self:flex-end">
|
|
679
779
|
<temba-user
|
|
680
|
-
|
|
780
|
+
uuid=${(_c = currentMsg._user) === null || _c === void 0 ? void 0 : _c.uuid}
|
|
681
781
|
name=${name}
|
|
682
|
-
avatar=${(
|
|
683
|
-
?system=${
|
|
782
|
+
avatar=${(_d = currentMsg._user) === null || _d === void 0 ? void 0 : _d.avatar}
|
|
783
|
+
?system=${isSystem}
|
|
684
784
|
>
|
|
685
785
|
</temba-user>
|
|
686
786
|
</div>`
|
|
@@ -689,36 +789,53 @@ export class Chat extends RapidElement {
|
|
|
689
789
|
`;
|
|
690
790
|
}
|
|
691
791
|
renderMessage(event, name = null) {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
return html `<div class="event">${event.text}</div>`;
|
|
792
|
+
var _a, _b;
|
|
793
|
+
if (event._rendered) {
|
|
794
|
+
return html `<div class="event">${event._rendered.html}</div>`;
|
|
696
795
|
}
|
|
697
796
|
const message = event;
|
|
797
|
+
const unsendableReason = (_a = message.msg) === null || _a === void 0 ? void 0 : _a.unsendable_reason;
|
|
798
|
+
const statusReason = (_b = message._status) === null || _b === void 0 ? void 0 : _b.reason;
|
|
799
|
+
const errorMessage = unsendableReason
|
|
800
|
+
? getUnsendableReasonMessage(unsendableReason)
|
|
801
|
+
: statusReason
|
|
802
|
+
? getStatusReasonMessage(statusReason)
|
|
803
|
+
: null;
|
|
698
804
|
return html `
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
805
|
+
<div class="bubble-wrap">
|
|
806
|
+
<div class="popup" style="white-space: nowrap;">
|
|
807
|
+
${errorMessage
|
|
808
|
+
? html `<div style="color: var(--color-error); margin-right: 1em;">
|
|
809
|
+
${errorMessage}
|
|
704
810
|
</div>`
|
|
705
811
|
: null}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
812
|
+
<temba-date
|
|
813
|
+
value="${message.created_on.toISOString()}"
|
|
814
|
+
display="relative"
|
|
815
|
+
></temba-date>
|
|
816
|
+
${message._logs_url
|
|
817
|
+
? html `<a
|
|
818
|
+
style="margin-left: 1em; color: var(--color-primary-dark);"
|
|
819
|
+
href="${message._logs_url}"
|
|
820
|
+
target="_blank"
|
|
821
|
+
rel="noopener noreferrer"
|
|
822
|
+
><temba-icon name="log"></temba-icon
|
|
823
|
+
></a>`
|
|
824
|
+
: null}
|
|
825
|
+
|
|
826
|
+
<div class="arrow">▼</div>
|
|
827
|
+
</div>
|
|
828
|
+
${message.msg.text
|
|
829
|
+
? html `<div class="bubble">
|
|
830
|
+
${name ? html `<div class="name">${name}</div>` : null}
|
|
831
|
+
<div class="message message-text">${message.msg.text}</div>
|
|
832
|
+
</div>`
|
|
715
833
|
: null}
|
|
716
834
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
</div>
|
|
835
|
+
<div class="attachments">
|
|
836
|
+
${(message.msg.attachments || []).map((attachment) => html `<temba-thumbnail
|
|
837
|
+
attachment="${attachment}"
|
|
838
|
+
></temba-thumbnail>`)}
|
|
722
839
|
</div>
|
|
723
840
|
</div>
|
|
724
841
|
`;
|
|
@@ -744,7 +861,7 @@ export class Chat extends RapidElement {
|
|
|
744
861
|
>
|
|
745
862
|
<div class="scroll" @scroll=${this.handleScroll}>
|
|
746
863
|
${this.messageGroups
|
|
747
|
-
? this.messageGroups.
|
|
864
|
+
? repeat(this.messageGroups, (msgGroup) => msgGroup.join(','), (msgGroup, idx) => html `${this.renderMessageGroup(msgGroup, idx, this.messageGroups)}`)
|
|
748
865
|
: null}
|
|
749
866
|
|
|
750
867
|
<temba-loading
|
|
@@ -757,6 +874,16 @@ export class Chat extends RapidElement {
|
|
|
757
874
|
</div>`
|
|
758
875
|
: null}
|
|
759
876
|
</div>
|
|
877
|
+
${!this.hasFooter
|
|
878
|
+
? html `<div
|
|
879
|
+
class="new-message-notification ${this.showNewMessageNotification
|
|
880
|
+
? 'visible'
|
|
881
|
+
: ''}"
|
|
882
|
+
@click=${this.handleNewMessageClick}
|
|
883
|
+
>
|
|
884
|
+
New Messages
|
|
885
|
+
</div>`
|
|
886
|
+
: null}
|
|
760
887
|
<slot class="header" name="header"></slot>
|
|
761
888
|
<slot class="footer" name="footer"></slot>
|
|
762
889
|
</div>`;
|
|
@@ -786,4 +913,10 @@ __decorate([
|
|
|
786
913
|
__decorate([
|
|
787
914
|
property({ type: Object, attribute: false })
|
|
788
915
|
], Chat.prototype, "oldestEventDate", void 0);
|
|
916
|
+
__decorate([
|
|
917
|
+
property({ type: Boolean, attribute: false })
|
|
918
|
+
], Chat.prototype, "showNewMessageNotification", void 0);
|
|
919
|
+
__decorate([
|
|
920
|
+
property({ type: Boolean })
|
|
921
|
+
], Chat.prototype, "hasFooter", void 0);
|
|
789
922
|
//# sourceMappingURL=Chat.js.map
|