@nyaruka/temba-components 0.80.1 → 0.81.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/CHANGELOG.md +6 -0
- package/dist/temba-components.js +61 -27
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/button/Button.js +0 -1
- package/out-tsc/src/button/Button.js.map +1 -1
- package/out-tsc/src/checkbox/Checkbox.js +0 -1
- package/out-tsc/src/checkbox/Checkbox.js.map +1 -1
- package/out-tsc/src/contacts/ContactName.js +1 -3
- package/out-tsc/src/contacts/ContactName.js.map +1 -1
- package/out-tsc/src/datepicker/DatePicker.js +0 -1
- package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
- package/out-tsc/src/dialog/Dialog.js +0 -1
- package/out-tsc/src/dialog/Dialog.js.map +1 -1
- package/out-tsc/src/dialog/Modax.js +0 -1
- package/out-tsc/src/dialog/Modax.js.map +1 -1
- package/out-tsc/src/list/NotificationList.js +2 -2
- package/out-tsc/src/list/NotificationList.js.map +1 -1
- package/out-tsc/src/list/RunList.js +2 -1
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/select/Select.js +0 -3
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +1 -3
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +64 -15
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/checkbox/checkbox-label-background-hover.png +0 -0
- package/screenshots/truth/checkbox/checked.png +0 -0
- package/screenshots/truth/checkbox/default.png +0 -0
- package/screenshots/truth/colorpicker/default.png +0 -0
- package/screenshots/truth/colorpicker/focused.png +0 -0
- package/screenshots/truth/colorpicker/initialized.png +0 -0
- package/screenshots/truth/colorpicker/selected.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-no-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-attachments-no-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-no-counter-and-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-no-counter-no-send-button.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-failure-files.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-spaces.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-and-url.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-no-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-failure-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-click-send.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-hit-enter.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text-no-spaces.png +0 -0
- package/screenshots/truth/compose/chatbox-with-text.png +0 -0
- package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
- package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
- package/screenshots/truth/contacts/contact-active-default.png +0 -0
- package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/history.png +0 -0
- package/screenshots/truth/datepicker/date-truncated-time.png +0 -0
- package/screenshots/truth/datepicker/date.png +0 -0
- package/screenshots/truth/datepicker/initial-timezone.png +0 -0
- package/screenshots/truth/datepicker/updated-keyboard-date.png +0 -0
- package/screenshots/truth/dialog/focused.png +0 -0
- package/screenshots/truth/list/fields-dragging.png +0 -0
- package/screenshots/truth/list/fields-filtered.png +0 -0
- package/screenshots/truth/list/fields-hovered.png +0 -0
- package/screenshots/truth/list/fields.png +0 -0
- package/screenshots/truth/menu/menu-focused-with items.png +0 -0
- package/screenshots/truth/menu/menu-refresh-1.png +0 -0
- package/screenshots/truth/menu/menu-refresh-2.png +0 -0
- package/screenshots/truth/menu/menu-submenu.png +0 -0
- package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
- package/screenshots/truth/menu/menu-tasks.png +0 -0
- package/screenshots/truth/modax/form.png +0 -0
- package/screenshots/truth/modax/simple.png +0 -0
- package/screenshots/truth/select/expressions.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/local-options.png +0 -0
- package/screenshots/truth/select/remote-options.png +0 -0
- package/screenshots/truth/select/search-enabled.png +0 -0
- package/screenshots/truth/select/search-multi-no-matches.png +0 -0
- package/screenshots/truth/select/search-selected-focus.png +0 -0
- package/screenshots/truth/select/search-with-selected.png +0 -0
- package/screenshots/truth/select/searching.png +0 -0
- package/screenshots/truth/select/with-placeholder.png +0 -0
- package/screenshots/truth/templates/default.png +0 -0
- package/screenshots/truth/templates/french.png +0 -0
- package/screenshots/truth/textinput/input-disabled.png +0 -0
- package/screenshots/truth/textinput/input-focused.png +0 -0
- package/screenshots/truth/textinput/input-form.png +0 -0
- package/screenshots/truth/textinput/input-inserted.png +0 -0
- package/screenshots/truth/textinput/input-placeholder.png +0 -0
- package/screenshots/truth/textinput/input-updated.png +0 -0
- package/screenshots/truth/textinput/input.png +0 -0
- package/screenshots/truth/textinput/textarea-focused.png +0 -0
- package/screenshots/truth/textinput/textarea.png +0 -0
- package/src/button/Button.ts +0 -1
- package/src/checkbox/Checkbox.ts +0 -1
- package/src/contacts/ContactName.ts +1 -3
- package/src/datepicker/DatePicker.ts +0 -1
- package/src/dialog/Dialog.ts +0 -2
- package/src/dialog/Modax.ts +0 -1
- package/src/list/NotificationList.ts +2 -3
- package/src/list/RunList.ts +2 -1
- package/src/select/Select.ts +0 -3
- package/src/textinput/TextInput.ts +1 -3
- package/src/webchat/WebChat.ts +68 -19
- package/static/css/temba-components.css +0 -5
- package/test-assets/style.css +1 -1
- package/screenshots/truth/datepicker/datetime.png +0 -0
- package/screenshots/truth/datepicker/initial-value.png +0 -0
- package/screenshots/truth/datepicker/updated-keyboard.png +0 -0
|
@@ -35,6 +35,36 @@ export class WebChat extends LitElement {
|
|
|
35
35
|
--curvature: 0.6em;
|
|
36
36
|
--color-primary: hsla(208, 70%, 55%, 1);
|
|
37
37
|
font-family: 'Roboto', 'Helvetica Neue', sans-serif;
|
|
38
|
+
font-weight: 400;
|
|
39
|
+
font-size: 1.1em;
|
|
40
|
+
--toggle-speed: 80ms;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.header {
|
|
44
|
+
background: var(--color-primary);
|
|
45
|
+
height: 3em;
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
width: 100%;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.header slot {
|
|
52
|
+
flex-grow: 1;
|
|
53
|
+
padding: 1em;
|
|
54
|
+
color: rgba(255, 255, 255, 0.9);
|
|
55
|
+
font-size: 1.2em;
|
|
56
|
+
display: block;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.header .close-button {
|
|
60
|
+
margin: 0.5em;
|
|
61
|
+
color: rgba(255, 255, 255, 0.5);
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.header .close-button:hover {
|
|
66
|
+
cursor: pointer;
|
|
67
|
+
color: rgba(255, 255, 255, 1);
|
|
38
68
|
}
|
|
39
69
|
|
|
40
70
|
.block {
|
|
@@ -92,9 +122,9 @@ export class WebChat extends LitElement {
|
|
|
92
122
|
rgba(0, 0, 0, 0.2) 0px 1px 2px 0px,
|
|
93
123
|
inset 0 0 0 0.25em rgba(0, 0, 0, 0.1);
|
|
94
124
|
cursor: pointer;
|
|
95
|
-
transition: box-shadow
|
|
125
|
+
transition: box-shadow var(--toggle-speed) ease-out;
|
|
96
126
|
position: absolute;
|
|
97
|
-
bottom:
|
|
127
|
+
bottom: 0.5em;
|
|
98
128
|
right: 1em;
|
|
99
129
|
}
|
|
100
130
|
|
|
@@ -114,12 +144,14 @@ export class WebChat extends LitElement {
|
|
|
114
144
|
padding-bottom: 0.5em;
|
|
115
145
|
background: #fafafa;
|
|
116
146
|
border-radius: var(--curvature);
|
|
147
|
+
max-width: 70%;
|
|
117
148
|
}
|
|
118
149
|
|
|
119
150
|
.bubble .name {
|
|
120
|
-
font-size: 0.
|
|
151
|
+
font-size: 0.95em;
|
|
121
152
|
font-weight: 400;
|
|
122
|
-
|
|
153
|
+
color: #888;
|
|
154
|
+
margin-bottom: 0.25em;
|
|
123
155
|
}
|
|
124
156
|
|
|
125
157
|
.outgoing .bubble {
|
|
@@ -130,10 +162,12 @@ export class WebChat extends LitElement {
|
|
|
130
162
|
background: var(--color-primary);
|
|
131
163
|
color: white;
|
|
132
164
|
border-top-right-radius: 0;
|
|
165
|
+
text-align: right;
|
|
133
166
|
}
|
|
134
167
|
|
|
135
168
|
.message {
|
|
136
169
|
margin-bottom: 0.5em;
|
|
170
|
+
line-height: 1.2em;
|
|
137
171
|
}
|
|
138
172
|
|
|
139
173
|
.chat {
|
|
@@ -144,16 +178,16 @@ export class WebChat extends LitElement {
|
|
|
144
178
|
box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,
|
|
145
179
|
rgba(0, 0, 0, 0.2) 0px 1px 2px 0px, rgba(0, 0, 0, 0.1) 5em 5em 5em 5em;
|
|
146
180
|
position: absolute;
|
|
147
|
-
bottom:
|
|
181
|
+
bottom: 3em;
|
|
148
182
|
right: 1em;
|
|
149
|
-
transition: all
|
|
183
|
+
transition: all var(--toggle-speed) ease-out;
|
|
150
184
|
transform: scale(0.9);
|
|
151
185
|
pointer-events: none;
|
|
152
186
|
opacity: 0;
|
|
153
187
|
}
|
|
154
188
|
|
|
155
189
|
.chat.open {
|
|
156
|
-
bottom:
|
|
190
|
+
bottom: 5em;
|
|
157
191
|
opacity: 1;
|
|
158
192
|
transform: scale(1);
|
|
159
193
|
pointer-events: initial;
|
|
@@ -185,7 +219,7 @@ export class WebChat extends LitElement {
|
|
|
185
219
|
position: absolute;
|
|
186
220
|
max-width: 50vw;
|
|
187
221
|
width: 28rem;
|
|
188
|
-
transition: opacity
|
|
222
|
+
transition: opacity var(--toggle-speed) ease-out;
|
|
189
223
|
}
|
|
190
224
|
|
|
191
225
|
.messages:after {
|
|
@@ -203,7 +237,7 @@ export class WebChat extends LitElement {
|
|
|
203
237
|
max-width: 50vw;
|
|
204
238
|
width: 28rem;
|
|
205
239
|
margin-right: 5em;
|
|
206
|
-
transition: opacity
|
|
240
|
+
transition: opacity var(--toggle-speed) ease-out;
|
|
207
241
|
}
|
|
208
242
|
|
|
209
243
|
.scroll-at-top .messages:before {
|
|
@@ -217,6 +251,8 @@ export class WebChat extends LitElement {
|
|
|
217
251
|
.input {
|
|
218
252
|
border: none;
|
|
219
253
|
flex-grow: 1;
|
|
254
|
+
color: #333;
|
|
255
|
+
font-size: 1em;
|
|
220
256
|
}
|
|
221
257
|
|
|
222
258
|
.input:focus {
|
|
@@ -302,20 +338,22 @@ export class WebChat extends LitElement {
|
|
|
302
338
|
}
|
|
303
339
|
this.sock = new WebSocket(url);
|
|
304
340
|
this.sock.onclose = function (event) {
|
|
341
|
+
console.log('Socket closed', event);
|
|
305
342
|
webChat.status = ChatStatus.DISCONNECTED;
|
|
306
343
|
};
|
|
307
344
|
this.sock.onmessage = function (event) {
|
|
345
|
+
console.log(event);
|
|
308
346
|
webChat.status = ChatStatus.CONNECTED;
|
|
309
347
|
const msg = JSON.parse(event.data);
|
|
310
348
|
if (msg.type === 'chat_started') {
|
|
311
|
-
if (webChat.urn !== msg.
|
|
349
|
+
if (webChat.urn !== msg.chat_id) {
|
|
312
350
|
webChat.messages = [];
|
|
313
351
|
}
|
|
314
|
-
webChat.urn = msg.
|
|
352
|
+
webChat.urn = msg.chat_id;
|
|
315
353
|
webChat.requestUpdate('messages');
|
|
316
354
|
}
|
|
317
355
|
else if (msg.type === 'chat_resumed') {
|
|
318
|
-
webChat.urn = msg.
|
|
356
|
+
webChat.urn = msg.chat_id;
|
|
319
357
|
}
|
|
320
358
|
else if (msg.type === 'msg_out') {
|
|
321
359
|
msg['timestamp'] = new Date().getTime();
|
|
@@ -334,7 +372,7 @@ export class WebChat extends LitElement {
|
|
|
334
372
|
}
|
|
335
373
|
}
|
|
336
374
|
writeToLocal() {
|
|
337
|
-
console.log('Writing to localStorage..');
|
|
375
|
+
// console.log('Writing to localStorage..');
|
|
338
376
|
if (this.urn) {
|
|
339
377
|
const data = { urn: this.urn, messages: this.messages, version: 1 };
|
|
340
378
|
localStorage.setItem('temba-chat', JSON.stringify(data));
|
|
@@ -370,9 +408,9 @@ export class WebChat extends LitElement {
|
|
|
370
408
|
this.restoreFromLocal();
|
|
371
409
|
}
|
|
372
410
|
if (changed.has('messages')) {
|
|
373
|
-
console.log('messages changed', this.messages);
|
|
411
|
+
// console.log('messages changed', this.messages);
|
|
374
412
|
this.writeToLocal();
|
|
375
|
-
console.log(this.messages);
|
|
413
|
+
// console.log(this.messages);
|
|
376
414
|
this.scrollToBottom();
|
|
377
415
|
}
|
|
378
416
|
}
|
|
@@ -481,6 +519,8 @@ export class WebChat extends LitElement {
|
|
|
481
519
|
this.hideTopScroll = event.target.scrollTop === 0;
|
|
482
520
|
}
|
|
483
521
|
handleClickInputPanel(event) {
|
|
522
|
+
event.preventDefault();
|
|
523
|
+
event.stopPropagation();
|
|
484
524
|
const input = this.shadowRoot.querySelector('.input');
|
|
485
525
|
input.focus();
|
|
486
526
|
}
|
|
@@ -496,6 +536,15 @@ export class WebChat extends LitElement {
|
|
|
496
536
|
? 'open'
|
|
497
537
|
: ''}"
|
|
498
538
|
>
|
|
539
|
+
<div class="header">
|
|
540
|
+
<slot name="header"></slot>
|
|
541
|
+
<temba-icon
|
|
542
|
+
name="close"
|
|
543
|
+
size="1.3"
|
|
544
|
+
class="close-button"
|
|
545
|
+
@click=${this.toggleChat}
|
|
546
|
+
></temba-icon>
|
|
547
|
+
</div>
|
|
499
548
|
<div class="messages">
|
|
500
549
|
<div class="scroll" @scroll=${this.handleScroll}>
|
|
501
550
|
${this.messages
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebChat.js","sourceRoot":"","sources":["../../../src/webchat/WebChat.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-this-alias */\nimport { LitElement, TemplateResult, html, css, PropertyValueMap } from 'lit';\nimport { property } from 'lit/decorators.js';\n\ninterface Message {\n text: string;\n type: string;\n identifier?: string;\n origin?: string;\n timestamp: number;\n}\n\nenum ChatStatus {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n}\n\n// how long of a window to show time between batches\nconst BATCH_TIME_WINDOW = 30 * 60 * 1000;\n\nconst TIME_FORMAT = { hour: 'numeric', minute: '2-digit' } as any;\nconst DAY_FORMAT = {\n weekday: undefined,\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n} as any;\nconst VERBOSE_FORMAT = {\n weekday: undefined,\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n} as any;\n\nexport class WebChat extends LitElement {\n static get styles() {\n return css`\n :host {\n display: flex-inline;\n align-items: center;\n align-self: center;\n --curvature: 0.6em;\n --color-primary: hsla(208, 70%, 55%, 1);\n font-family: 'Roboto', 'Helvetica Neue', sans-serif;\n }\n\n .block {\n margin-bottom: 1em;\n }\n\n .time {\n text-align: center;\n font-size: 0.8em;\n color: #999;\n margin-top: 2em;\n border-top: 1px solid #f8f8f8;\n padding: 1em;\n margin-left: 4em;\n margin-right: 4em;\n }\n\n .first .time {\n margin-top: 0;\n border-top: none;\n padding-top: 0;\n }\n\n .row {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n }\n\n .input-panel {\n padding: 1em;\n background: #fff;\n }\n\n .avatar {\n margin-top: 0.6em;\n margin-right: 0.6em;\n flex-shrink: 0;\n width: 2em;\n height: 2em;\n overflow: hidden;\n border-radius: 100%;\n box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,\n rgba(0, 0, 0, 0.2) 0px 1px 2px 0px,\n inset 0 0 0 0.15em rgba(0, 0, 0, 0.1);\n }\n\n .toggle {\n flex-shrink: 0;\n width: 4em;\n height: 4em;\n overflow: hidden;\n border-radius: 100%;\n box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 1em 0.7em,\n rgba(0, 0, 0, 0.2) 0px 1px 2px 0px,\n inset 0 0 0 0.25em rgba(0, 0, 0, 0.1);\n cursor: pointer;\n transition: box-shadow 0.2s ease-out;\n position: absolute;\n bottom: 1em;\n right: 1em;\n }\n\n .toggle:hover {\n box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 1em 0.7em,\n rgba(0, 0, 0, 0.4) 0px 1px 2px 0px,\n inset 0 0 0 0.25em rgba(0, 0, 0, 0.2);\n }\n\n .incoming .row {\n flex-direction: row-reverse;\n margin-left: 1em;\n }\n\n .bubble {\n padding: 1em;\n padding-bottom: 0.5em;\n background: #fafafa;\n border-radius: var(--curvature);\n }\n\n .bubble .name {\n font-size: 0.9em;\n font-weight: 400;\n margin-bottom: 0.5em;\n }\n\n .outgoing .bubble {\n border-top-left-radius: 0;\n }\n\n .incoming .bubble {\n background: var(--color-primary);\n color: white;\n border-top-right-radius: 0;\n }\n\n .message {\n margin-bottom: 0.5em;\n }\n\n .chat {\n max-width: 50vw;\n width: 28rem;\n border-radius: var(--curvature);\n overflow: hidden;\n box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,\n rgba(0, 0, 0, 0.2) 0px 1px 2px 0px, rgba(0, 0, 0, 0.1) 5em 5em 5em 5em;\n position: absolute;\n bottom: 2em;\n right: 1em;\n transition: all 0.2s ease-out;\n transform: scale(0.9);\n pointer-events: none;\n opacity: 0;\n }\n\n .chat.open {\n bottom: 6em;\n opacity: 1;\n transform: scale(1);\n pointer-events: initial;\n }\n\n .messages {\n background: #fff;\n }\n\n .scroll {\n height: 40rem;\n max-height: 60vh;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n overflow-scrolling: touch;\n padding: 1em 1em 0 1em;\n }\n\n .messages:before {\n content: '';\n background: /* Shadow TOP */ radial-gradient(\n farthest-side at 50% 0,\n rgba(0, 0, 0, 0.2),\n rgba(0, 0, 0, 0)\n )\n center top;\n height: 10px;\n display: block;\n position: absolute;\n max-width: 50vw;\n width: 28rem;\n transition: opacity 0.1s ease-out;\n }\n\n .messages:after {\n content: '';\n background: /* Shadow BOTTOM */ radial-gradient(\n farthest-side at 50% 100%,\n rgba(0, 0, 0, 0.2),\n rgba(0, 0, 0, 0)\n )\n center bottom;\n height: 10px;\n display: block;\n position: absolute;\n margin-top: -10px;\n max-width: 50vw;\n width: 28rem;\n margin-right: 5em;\n transition: opacity 0.1s ease-out;\n }\n\n .scroll-at-top .messages:before {\n opacity: 0;\n }\n\n .scroll-at-bottom .messages:after {\n opacity: 0;\n }\n\n .input {\n border: none;\n flex-grow: 1;\n }\n\n .input:focus {\n outline: none;\n }\n\n input::placeholder {\n opacity: 0.3;\n }\n\n .input.inactive {\n // pointer-events: none;\n // opacity: 0.3;\n }\n\n .active {\n }\n\n .send-icon {\n color: #eee;\n pointer-events: none;\n transform: rotate(-45deg);\n transition: transform 0.2s ease-out;\n }\n\n .pending .send-icon {\n color: var(--color-primary);\n pointer-events: initial;\n transform: rotate(0deg);\n }\n\n .notice {\n padding: 1em;\n background: #f8f8f8;\n color: #666;\n text-align: center;\n cursor: pointer;\n }\n\n .connecting .notice {\n display: flex;\n justify-content: center;\n }\n\n .connecting .notice temba-icon {\n margin-left: 0.5em;\n }\n\n .reconnect {\n color: var(--color-primary);\n text-decoration: underline;\n font-size: 0.9em;\n }\n\n .input:disabled {\n background: transparent !important;\n }\n `;\n }\n\n @property({ type: String })\n channel: string;\n\n @property({ type: String })\n urn: string;\n\n @property({ type: Array })\n messages: Message[][] = [];\n\n // is our socket connection established\n @property({ type: String })\n status: ChatStatus = ChatStatus.DISCONNECTED;\n\n // is the chat widget open\n @property({ type: Boolean })\n open = false;\n\n @property({ type: Boolean })\n hasPendingText = false;\n\n @property({ type: Boolean, attribute: false })\n hideTopScroll = true;\n\n @property({ type: Boolean, attribute: false })\n hideBottomScroll = true;\n\n @property({ type: String })\n host: string;\n\n private sock: WebSocket;\n\n public constructor() {\n super();\n }\n\n private handleReconnect() {\n this.openSocket();\n }\n\n private openSocket(): void {\n if (this.status !== ChatStatus.DISCONNECTED) {\n return;\n }\n\n this.status = ChatStatus.CONNECTING;\n const webChat = this;\n let url = `ws://localhost:8070/start/${this.channel}/`;\n if (this.urn) {\n url = `${url}?chat_id=${this.urn}`;\n }\n this.sock = new WebSocket(url);\n this.sock.onclose = function (event) {\n webChat.status = ChatStatus.DISCONNECTED;\n };\n this.sock.onmessage = function (event) {\n webChat.status = ChatStatus.CONNECTED;\n const msg = JSON.parse(event.data) as Message;\n if (msg.type === 'chat_started') {\n if (webChat.urn !== msg.identifier) {\n webChat.messages = [];\n }\n webChat.urn = msg.identifier;\n webChat.requestUpdate('messages');\n } else if (msg.type === 'chat_resumed') {\n webChat.urn = msg.identifier;\n } else if (msg.type === 'msg_out') {\n msg['timestamp'] = new Date().getTime();\n webChat.addMessage(msg);\n webChat.requestUpdate('messages');\n }\n };\n }\n\n private restoreFromLocal(): void {\n const data = JSON.parse(localStorage.getItem('temba-chat') || '{}');\n const urn = 'urn' in data ? data['urn'] : null;\n if (urn && !this.urn) {\n this.urn = urn;\n const messages = 'messages' in data ? data['messages'] : [];\n this.messages.push(...messages);\n }\n }\n\n private writeToLocal(): void {\n console.log('Writing to localStorage..');\n if (this.urn) {\n const data = { urn: this.urn, messages: this.messages, version: 1 };\n localStorage.setItem('temba-chat', JSON.stringify(data));\n }\n }\n\n public firstUpdated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changed);\n }\n\n private focusInput() {\n const input = this.shadowRoot.querySelector('.input') as any;\n if (input) {\n input.focus();\n }\n }\n\n public updated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changed);\n\n if (this.open && changed.has('open') && changed.get('open') !== undefined) {\n const scroll = this.shadowRoot.querySelector('.scroll');\n const hasScroll = scroll.scrollHeight > scroll.clientHeight;\n this.hideBottomScroll = true;\n this.hideTopScroll = !hasScroll;\n this.scrollToBottom();\n\n if (this.status === ChatStatus.DISCONNECTED) {\n this.openSocket();\n }\n }\n\n if (changed.has('status')) {\n if (this.status === ChatStatus.CONNECTED) {\n this.focusInput();\n }\n }\n\n if (changed.has('channel')) {\n this.restoreFromLocal();\n }\n\n if (changed.has('messages')) {\n console.log('messages changed', this.messages);\n this.writeToLocal();\n console.log(this.messages);\n this.scrollToBottom();\n }\n }\n\n private addMessage(msg: Message) {\n let lastGroup =\n this.messages.length > 0 ? this.messages[this.messages.length - 1] : [];\n const isSame = lastGroup.length === 0 || lastGroup[0].origin === msg.origin;\n if (!isSame) {\n lastGroup = [];\n }\n if (lastGroup.length === 0) {\n this.messages.push(lastGroup);\n }\n lastGroup.push(msg);\n }\n\n public openChat(): void {\n this.open = true;\n }\n\n public handleKeyUp(event: any) {\n if (this.hasPendingText && event.key === 'Enter') {\n this.sendPendingMessage();\n }\n\n this.hasPendingText = event.target.value.length > 0;\n }\n\n private sendPendingMessage() {\n if (this.status === ChatStatus.CONNECTED) {\n const input = this.shadowRoot.querySelector('.input') as any;\n const text = input.value;\n input.value = '';\n\n const msg = {\n type: 'msg_in',\n text: text,\n timestamp: new Date().getTime(),\n };\n\n this.addMessage(msg);\n this.sock.send(JSON.stringify(msg));\n this.requestUpdate('messages');\n this.hasPendingText = input.value.length > 0;\n }\n }\n\n private scrollToBottom() {\n const scroll = this.shadowRoot.querySelector('.scroll');\n if (scroll) {\n scroll.scrollTop = scroll.scrollHeight;\n this.hideBottomScroll = true;\n }\n }\n\n private renderMessageGroup(\n messages: Message[],\n idx: number,\n groups: Message[][]\n ): TemplateResult {\n let lastBatchTime = null;\n if (idx > 0) {\n const lastGroup = groups[idx - 1];\n if (lastGroup && lastGroup.length > 0) {\n lastBatchTime = lastGroup[lastGroup.length - 1].timestamp;\n }\n }\n\n const newBatchTime = messages[0].timestamp;\n const showTime = newBatchTime - lastBatchTime > BATCH_TIME_WINDOW;\n\n let timeDisplay = null;\n if (showTime) {\n let lastTime = null;\n const newTime = new Date(newBatchTime);\n if (lastBatchTime) {\n lastTime = new Date(lastBatchTime);\n }\n const showDay = !lastTime || newTime.getDate() !== lastTime.getDate();\n if (showDay) {\n timeDisplay = html`<div class=\"time\">\n ${newTime.toLocaleDateString(undefined, DAY_FORMAT)}\n </div>`;\n } else {\n timeDisplay = html`<div class=\"time\">\n ${newTime.toLocaleTimeString(undefined, TIME_FORMAT)}\n </div>`;\n }\n }\n\n const blockTime = new Date(messages[messages.length - 1].timestamp);\n const incoming = !messages[0].origin;\n\n return html` <div\n class=\"block ${incoming ? 'incoming' : 'outgoing'} ${idx === 0\n ? 'first'\n : ''}\"\n title=\"${blockTime.toLocaleTimeString(undefined, VERBOSE_FORMAT)}\"\n >\n ${timeDisplay}\n <div class=\"row\">\n ${!incoming\n ? html`\n <div\n class=\"avatar\"\n style=\"background: center / contain no-repeat url(https://dl-textit.s3.amazonaws.com/orgs/6418/media/5e81/5e814c83-bf33-43ea-b6c1-ee46f8acaf34/avatar.jpg)\"\n ></div>\n `\n : null}\n\n <div class=\"bubble\">\n ${!incoming ? html`<div class=\"name\">Henry McHelper</div>` : null}\n ${messages.map(msg => html`<div class=\"message\">${msg.text}</div>`)}\n </div>\n </div>\n </div>`;\n }\n\n private handleScroll(event: any) {\n this.hideBottomScroll =\n Math.round(event.target.scrollTop + event.target.clientHeight) >=\n event.target.scrollHeight;\n this.hideTopScroll = event.target.scrollTop === 0;\n }\n\n private handleClickInputPanel(event: any) {\n const input = this.shadowRoot.querySelector('.input') as any;\n input.focus();\n }\n\n private toggleChat() {\n this.open = !this.open;\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=\"chat ${this.status} ${this.hideTopScroll\n ? 'scroll-at-top'\n : ''} ${this.hideBottomScroll ? 'scroll-at-bottom' : ''} ${this.open\n ? 'open'\n : ''}\"\n >\n <div class=\"messages\">\n <div class=\"scroll\" @scroll=${this.handleScroll}>\n ${this.messages\n ? this.messages.map(\n (msgGroup, idx, groups) =>\n html`${this.renderMessageGroup(msgGroup, idx, groups)}`\n )\n : null}\n </div>\n </div>\n\n ${this.status === ChatStatus.DISCONNECTED\n ? html`<div class=\"notice\">\n <div>This chat is not currently connected.</div>\n <div class=\"reconnect\" @click=${this.handleReconnect}>\n Click here to reconnect\n <div></div>\n </div>\n </div>`\n : null}\n ${this.status === ChatStatus.CONNECTING\n ? html`<div class=\"notice\">\n <div>Connecting</div>\n <temba-icon name=\"progress_spinner\" spin></temba-icon>\n </div>`\n : null}\n ${this.status === ChatStatus.CONNECTED\n ? html` <div\n class=\"row input-panel ${this.hasPendingText ? 'pending' : ''}\"\n @click=${this.handleClickInputPanel}\n >\n <input\n class=\"input ${this.status === ChatStatus.CONNECTED\n ? 'active'\n : 'inactive'}\"\n type=\"text\"\n placeholder=\"Message..\"\n ?disabled=${this.status !== ChatStatus.CONNECTED}\n @keydown=${this.handleKeyUp}\n />\n <temba-icon\n tabindex=\"1\"\n class=\"send-icon\"\n name=\"send\"\n size=\"1\"\n clickable\n @click=${this.sendPendingMessage}\n ></temba-icon>\n </div>`\n : null}\n </div>\n\n <div @click=${this.toggleChat}>\n <div\n class=\"toggle\"\n style=\"background: center / contain no-repeat url(https://dl-textit.s3.amazonaws.com/orgs/6418/media/5e81/5e814c83-bf33-43ea-b6c1-ee46f8acaf34/avatar.jpg)\"\n ></div>\n </div>\n `;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WebChat.js","sourceRoot":"","sources":["../../../src/webchat/WebChat.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-this-alias */\nimport { LitElement, TemplateResult, html, css, PropertyValueMap } from 'lit';\nimport { property } from 'lit/decorators.js';\n\ninterface Message {\n text: string;\n type: string;\n chat_id?: string;\n origin?: string;\n timestamp: number;\n}\n\nenum ChatStatus {\n DISCONNECTED = 'disconnected',\n CONNECTING = 'connecting',\n CONNECTED = 'connected',\n}\n\n// how long of a window to show time between batches\nconst BATCH_TIME_WINDOW = 30 * 60 * 1000;\n\nconst TIME_FORMAT = { hour: 'numeric', minute: '2-digit' } as any;\nconst DAY_FORMAT = {\n weekday: undefined,\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n} as any;\nconst VERBOSE_FORMAT = {\n weekday: undefined,\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n} as any;\n\nexport class WebChat extends LitElement {\n static get styles() {\n return css`\n :host {\n display: flex-inline;\n align-items: center;\n align-self: center;\n --curvature: 0.6em;\n --color-primary: hsla(208, 70%, 55%, 1);\n font-family: 'Roboto', 'Helvetica Neue', sans-serif;\n font-weight: 400;\n font-size: 1.1em;\n --toggle-speed: 80ms;\n }\n\n .header {\n background: var(--color-primary);\n height: 3em;\n display: flex;\n align-items: center;\n width: 100%;\n }\n\n .header slot {\n flex-grow: 1;\n padding: 1em;\n color: rgba(255, 255, 255, 0.9);\n font-size: 1.2em;\n display: block;\n }\n\n .header .close-button {\n margin: 0.5em;\n color: rgba(255, 255, 255, 0.5);\n cursor: pointer;\n }\n\n .header .close-button:hover {\n cursor: pointer;\n color: rgba(255, 255, 255, 1);\n }\n\n .block {\n margin-bottom: 1em;\n }\n\n .time {\n text-align: center;\n font-size: 0.8em;\n color: #999;\n margin-top: 2em;\n border-top: 1px solid #f8f8f8;\n padding: 1em;\n margin-left: 4em;\n margin-right: 4em;\n }\n\n .first .time {\n margin-top: 0;\n border-top: none;\n padding-top: 0;\n }\n\n .row {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n }\n\n .input-panel {\n padding: 1em;\n background: #fff;\n }\n\n .avatar {\n margin-top: 0.6em;\n margin-right: 0.6em;\n flex-shrink: 0;\n width: 2em;\n height: 2em;\n overflow: hidden;\n border-radius: 100%;\n box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,\n rgba(0, 0, 0, 0.2) 0px 1px 2px 0px,\n inset 0 0 0 0.15em rgba(0, 0, 0, 0.1);\n }\n\n .toggle {\n flex-shrink: 0;\n width: 4em;\n height: 4em;\n overflow: hidden;\n border-radius: 100%;\n box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 1em 0.7em,\n rgba(0, 0, 0, 0.2) 0px 1px 2px 0px,\n inset 0 0 0 0.25em rgba(0, 0, 0, 0.1);\n cursor: pointer;\n transition: box-shadow var(--toggle-speed) ease-out;\n position: absolute;\n bottom: 0.5em;\n right: 1em;\n }\n\n .toggle:hover {\n box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 1em 0.7em,\n rgba(0, 0, 0, 0.4) 0px 1px 2px 0px,\n inset 0 0 0 0.25em rgba(0, 0, 0, 0.2);\n }\n\n .incoming .row {\n flex-direction: row-reverse;\n margin-left: 1em;\n }\n\n .bubble {\n padding: 1em;\n padding-bottom: 0.5em;\n background: #fafafa;\n border-radius: var(--curvature);\n max-width: 70%;\n }\n\n .bubble .name {\n font-size: 0.95em;\n font-weight: 400;\n color: #888;\n margin-bottom: 0.25em;\n }\n\n .outgoing .bubble {\n border-top-left-radius: 0;\n }\n\n .incoming .bubble {\n background: var(--color-primary);\n color: white;\n border-top-right-radius: 0;\n text-align: right;\n }\n\n .message {\n margin-bottom: 0.5em;\n line-height: 1.2em;\n }\n\n .chat {\n max-width: 50vw;\n width: 28rem;\n border-radius: var(--curvature);\n overflow: hidden;\n box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,\n rgba(0, 0, 0, 0.2) 0px 1px 2px 0px, rgba(0, 0, 0, 0.1) 5em 5em 5em 5em;\n position: absolute;\n bottom: 3em;\n right: 1em;\n transition: all var(--toggle-speed) ease-out;\n transform: scale(0.9);\n pointer-events: none;\n opacity: 0;\n }\n\n .chat.open {\n bottom: 5em;\n opacity: 1;\n transform: scale(1);\n pointer-events: initial;\n }\n\n .messages {\n background: #fff;\n }\n\n .scroll {\n height: 40rem;\n max-height: 60vh;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n overflow-scrolling: touch;\n padding: 1em 1em 0 1em;\n }\n\n .messages:before {\n content: '';\n background: /* Shadow TOP */ radial-gradient(\n farthest-side at 50% 0,\n rgba(0, 0, 0, 0.2),\n rgba(0, 0, 0, 0)\n )\n center top;\n height: 10px;\n display: block;\n position: absolute;\n max-width: 50vw;\n width: 28rem;\n transition: opacity var(--toggle-speed) ease-out;\n }\n\n .messages:after {\n content: '';\n background: /* Shadow BOTTOM */ radial-gradient(\n farthest-side at 50% 100%,\n rgba(0, 0, 0, 0.2),\n rgba(0, 0, 0, 0)\n )\n center bottom;\n height: 10px;\n display: block;\n position: absolute;\n margin-top: -10px;\n max-width: 50vw;\n width: 28rem;\n margin-right: 5em;\n transition: opacity var(--toggle-speed) ease-out;\n }\n\n .scroll-at-top .messages:before {\n opacity: 0;\n }\n\n .scroll-at-bottom .messages:after {\n opacity: 0;\n }\n\n .input {\n border: none;\n flex-grow: 1;\n color: #333;\n font-size: 1em;\n }\n\n .input:focus {\n outline: none;\n }\n\n input::placeholder {\n opacity: 0.3;\n }\n\n .input.inactive {\n // pointer-events: none;\n // opacity: 0.3;\n }\n\n .active {\n }\n\n .send-icon {\n color: #eee;\n pointer-events: none;\n transform: rotate(-45deg);\n transition: transform 0.2s ease-out;\n }\n\n .pending .send-icon {\n color: var(--color-primary);\n pointer-events: initial;\n transform: rotate(0deg);\n }\n\n .notice {\n padding: 1em;\n background: #f8f8f8;\n color: #666;\n text-align: center;\n cursor: pointer;\n }\n\n .connecting .notice {\n display: flex;\n justify-content: center;\n }\n\n .connecting .notice temba-icon {\n margin-left: 0.5em;\n }\n\n .reconnect {\n color: var(--color-primary);\n text-decoration: underline;\n font-size: 0.9em;\n }\n\n .input:disabled {\n background: transparent !important;\n }\n `;\n }\n\n @property({ type: String })\n channel: string;\n\n @property({ type: String })\n urn: string;\n\n @property({ type: Array })\n messages: Message[][] = [];\n\n // is our socket connection established\n @property({ type: String })\n status: ChatStatus = ChatStatus.DISCONNECTED;\n\n // is the chat widget open\n @property({ type: Boolean })\n open = false;\n\n @property({ type: Boolean })\n hasPendingText = false;\n\n @property({ type: Boolean, attribute: false })\n hideTopScroll = true;\n\n @property({ type: Boolean, attribute: false })\n hideBottomScroll = true;\n\n @property({ type: String })\n host: string;\n\n private sock: WebSocket;\n\n public constructor() {\n super();\n }\n\n private handleReconnect() {\n this.openSocket();\n }\n\n private openSocket(): void {\n if (this.status !== ChatStatus.DISCONNECTED) {\n return;\n }\n\n this.status = ChatStatus.CONNECTING;\n const webChat = this;\n let url = `ws://localhost:8070/start/${this.channel}/`;\n if (this.urn) {\n url = `${url}?chat_id=${this.urn}`;\n }\n this.sock = new WebSocket(url);\n this.sock.onclose = function (event: CloseEvent) {\n console.log('Socket closed', event);\n webChat.status = ChatStatus.DISCONNECTED;\n };\n this.sock.onmessage = function (event: MessageEvent) {\n console.log(event);\n webChat.status = ChatStatus.CONNECTED;\n const msg = JSON.parse(event.data) as Message;\n if (msg.type === 'chat_started') {\n if (webChat.urn !== msg.chat_id) {\n webChat.messages = [];\n }\n webChat.urn = msg.chat_id;\n webChat.requestUpdate('messages');\n } else if (msg.type === 'chat_resumed') {\n webChat.urn = msg.chat_id;\n } else if (msg.type === 'msg_out') {\n msg['timestamp'] = new Date().getTime();\n webChat.addMessage(msg);\n webChat.requestUpdate('messages');\n }\n };\n }\n\n private restoreFromLocal(): void {\n const data = JSON.parse(localStorage.getItem('temba-chat') || '{}');\n const urn = 'urn' in data ? data['urn'] : null;\n if (urn && !this.urn) {\n this.urn = urn;\n const messages = 'messages' in data ? data['messages'] : [];\n this.messages.push(...messages);\n }\n }\n\n private writeToLocal(): void {\n // console.log('Writing to localStorage..');\n if (this.urn) {\n const data = { urn: this.urn, messages: this.messages, version: 1 };\n localStorage.setItem('temba-chat', JSON.stringify(data));\n }\n }\n\n public firstUpdated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changed);\n }\n\n private focusInput() {\n const input = this.shadowRoot.querySelector('.input') as any;\n if (input) {\n input.focus();\n }\n }\n\n public updated(\n changed: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changed);\n\n if (this.open && changed.has('open') && changed.get('open') !== undefined) {\n const scroll = this.shadowRoot.querySelector('.scroll');\n const hasScroll = scroll.scrollHeight > scroll.clientHeight;\n this.hideBottomScroll = true;\n this.hideTopScroll = !hasScroll;\n this.scrollToBottom();\n\n if (this.status === ChatStatus.DISCONNECTED) {\n this.openSocket();\n }\n }\n\n if (changed.has('status')) {\n if (this.status === ChatStatus.CONNECTED) {\n this.focusInput();\n }\n }\n\n if (changed.has('channel')) {\n this.restoreFromLocal();\n }\n\n if (changed.has('messages')) {\n // console.log('messages changed', this.messages);\n this.writeToLocal();\n // console.log(this.messages);\n this.scrollToBottom();\n }\n }\n\n private addMessage(msg: Message) {\n let lastGroup =\n this.messages.length > 0 ? this.messages[this.messages.length - 1] : [];\n const isSame = lastGroup.length === 0 || lastGroup[0].origin === msg.origin;\n if (!isSame) {\n lastGroup = [];\n }\n if (lastGroup.length === 0) {\n this.messages.push(lastGroup);\n }\n lastGroup.push(msg);\n }\n\n public openChat(): void {\n this.open = true;\n }\n\n public handleKeyUp(event: any) {\n if (this.hasPendingText && event.key === 'Enter') {\n this.sendPendingMessage();\n }\n\n this.hasPendingText = event.target.value.length > 0;\n }\n\n private sendPendingMessage() {\n if (this.status === ChatStatus.CONNECTED) {\n const input = this.shadowRoot.querySelector('.input') as any;\n const text = input.value;\n input.value = '';\n\n const msg = {\n type: 'msg_in',\n text: text,\n timestamp: new Date().getTime(),\n };\n\n this.addMessage(msg);\n this.sock.send(JSON.stringify(msg));\n this.requestUpdate('messages');\n this.hasPendingText = input.value.length > 0;\n }\n }\n\n private scrollToBottom() {\n const scroll = this.shadowRoot.querySelector('.scroll');\n if (scroll) {\n scroll.scrollTop = scroll.scrollHeight;\n this.hideBottomScroll = true;\n }\n }\n\n private renderMessageGroup(\n messages: Message[],\n idx: number,\n groups: Message[][]\n ): TemplateResult {\n let lastBatchTime = null;\n if (idx > 0) {\n const lastGroup = groups[idx - 1];\n if (lastGroup && lastGroup.length > 0) {\n lastBatchTime = lastGroup[lastGroup.length - 1].timestamp;\n }\n }\n\n const newBatchTime = messages[0].timestamp;\n const showTime = newBatchTime - lastBatchTime > BATCH_TIME_WINDOW;\n\n let timeDisplay = null;\n if (showTime) {\n let lastTime = null;\n const newTime = new Date(newBatchTime);\n if (lastBatchTime) {\n lastTime = new Date(lastBatchTime);\n }\n const showDay = !lastTime || newTime.getDate() !== lastTime.getDate();\n if (showDay) {\n timeDisplay = html`<div class=\"time\">\n ${newTime.toLocaleDateString(undefined, DAY_FORMAT)}\n </div>`;\n } else {\n timeDisplay = html`<div class=\"time\">\n ${newTime.toLocaleTimeString(undefined, TIME_FORMAT)}\n </div>`;\n }\n }\n\n const blockTime = new Date(messages[messages.length - 1].timestamp);\n const incoming = !messages[0].origin;\n\n return html` <div\n class=\"block ${incoming ? 'incoming' : 'outgoing'} ${idx === 0\n ? 'first'\n : ''}\"\n title=\"${blockTime.toLocaleTimeString(undefined, VERBOSE_FORMAT)}\"\n >\n ${timeDisplay}\n <div class=\"row\">\n ${!incoming\n ? html`\n <div\n class=\"avatar\"\n style=\"background: center / contain no-repeat url(https://dl-textit.s3.amazonaws.com/orgs/6418/media/5e81/5e814c83-bf33-43ea-b6c1-ee46f8acaf34/avatar.jpg)\"\n ></div>\n `\n : null}\n\n <div class=\"bubble\">\n ${!incoming ? html`<div class=\"name\">Henry McHelper</div>` : null}\n ${messages.map(msg => html`<div class=\"message\">${msg.text}</div>`)}\n </div>\n </div>\n </div>`;\n }\n\n private handleScroll(event: any) {\n this.hideBottomScroll =\n Math.round(event.target.scrollTop + event.target.clientHeight) >=\n event.target.scrollHeight;\n this.hideTopScroll = event.target.scrollTop === 0;\n }\n\n private handleClickInputPanel(event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n const input = this.shadowRoot.querySelector('.input') as any;\n input.focus();\n }\n\n private toggleChat() {\n this.open = !this.open;\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=\"chat ${this.status} ${this.hideTopScroll\n ? 'scroll-at-top'\n : ''} ${this.hideBottomScroll ? 'scroll-at-bottom' : ''} ${this.open\n ? 'open'\n : ''}\"\n >\n <div class=\"header\">\n <slot name=\"header\"></slot>\n <temba-icon\n name=\"close\"\n size=\"1.3\"\n class=\"close-button\"\n @click=${this.toggleChat}\n ></temba-icon>\n </div>\n <div class=\"messages\">\n <div class=\"scroll\" @scroll=${this.handleScroll}>\n ${this.messages\n ? this.messages.map(\n (msgGroup, idx, groups) =>\n html`${this.renderMessageGroup(msgGroup, idx, groups)}`\n )\n : null}\n </div>\n </div>\n\n ${this.status === ChatStatus.DISCONNECTED\n ? html`<div class=\"notice\">\n <div>This chat is not currently connected.</div>\n <div class=\"reconnect\" @click=${this.handleReconnect}>\n Click here to reconnect\n <div></div>\n </div>\n </div>`\n : null}\n ${this.status === ChatStatus.CONNECTING\n ? html`<div class=\"notice\">\n <div>Connecting</div>\n <temba-icon name=\"progress_spinner\" spin></temba-icon>\n </div>`\n : null}\n ${this.status === ChatStatus.CONNECTED\n ? html` <div\n class=\"row input-panel ${this.hasPendingText ? 'pending' : ''}\"\n @click=${this.handleClickInputPanel}\n >\n <input\n class=\"input ${this.status === ChatStatus.CONNECTED\n ? 'active'\n : 'inactive'}\"\n type=\"text\"\n placeholder=\"Message..\"\n ?disabled=${this.status !== ChatStatus.CONNECTED}\n @keydown=${this.handleKeyUp}\n />\n <temba-icon\n tabindex=\"1\"\n class=\"send-icon\"\n name=\"send\"\n size=\"1\"\n clickable\n @click=${this.sendPendingMessage}\n ></temba-icon>\n </div>`\n : null}\n </div>\n\n <div @click=${this.toggleChat}>\n <div\n class=\"toggle\"\n style=\"background: center / contain no-repeat url(https://dl-textit.s3.amazonaws.com/orgs/6418/media/5e81/5e814c83-bf33-43ea-b6c1-ee46f8acaf34/avatar.jpg)\"\n ></div>\n </div>\n `;\n }\n}\n"]}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files-and-click-send.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files-and-click-send.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-click-send.png
CHANGED
|
Binary file
|
package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-hit-enter.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-hit-enter.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/button/Button.ts
CHANGED
package/src/checkbox/Checkbox.ts
CHANGED
|
@@ -24,15 +24,13 @@ export class ContactName extends RapidElement {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.name {
|
|
27
|
-
font-size: 1.5rem;
|
|
27
|
+
font-size: var(--contact-name-font-size, 1.5rem);
|
|
28
28
|
overflow: hidden;
|
|
29
29
|
max-height: 2rem;
|
|
30
30
|
line-height: 2rem;
|
|
31
31
|
-webkit-box-orient: vertical;
|
|
32
32
|
-webkit-line-clamp: 1;
|
|
33
33
|
text-overflow: ellipsis;
|
|
34
|
-
display: -webkit-box;
|
|
35
|
-
margin: auto;
|
|
36
34
|
}
|
|
37
35
|
`;
|
|
38
36
|
}
|