@nyaruka/temba-components 0.86.0 → 0.87.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/.eslintrc.js +3 -3
- package/.prettierrc +6 -0
- package/.storybook/main.js +3 -3
- package/.storybook/preview.js +2 -2
- package/CHANGELOG.md +14 -0
- package/CreateIncludesPlugin.js +2 -2
- package/demo/index.html +1 -0
- package/dist/locales/es.js +1 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +1 -1
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/pt.js +1 -1
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +296 -277
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/RapidElement.js +3 -3
- package/out-tsc/src/RapidElement.js.map +1 -1
- package/out-tsc/src/ResizeElement.js +2 -2
- package/out-tsc/src/ResizeElement.js.map +1 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js +1 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
- package/out-tsc/src/button/Button.js +1 -1
- package/out-tsc/src/button/Button.js.map +1 -1
- package/out-tsc/src/charcount/helpers.js +1 -1
- package/out-tsc/src/charcount/helpers.js.map +1 -1
- package/out-tsc/src/colorpicker/ColorPicker.js +4 -4
- package/out-tsc/src/colorpicker/ColorPicker.js.map +1 -1
- package/out-tsc/src/completion/Completion.js +2 -2
- package/out-tsc/src/completion/Completion.js.map +1 -1
- package/out-tsc/src/completion/ExcellentParser.js +1 -1
- package/out-tsc/src/completion/ExcellentParser.js.map +1 -1
- package/out-tsc/src/completion/helpers.js +8 -8
- package/out-tsc/src/completion/helpers.js.map +1 -1
- package/out-tsc/src/compose/Compose.js +14 -14
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactBadges.js +2 -2
- package/out-tsc/src/contacts/ContactBadges.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +4 -4
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactDetails.js +4 -4
- package/out-tsc/src/contacts/ContactDetails.js.map +1 -1
- package/out-tsc/src/contacts/ContactFieldEditor.js +3 -3
- package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/contacts/ContactFields.js +2 -2
- package/out-tsc/src/contacts/ContactFields.js.map +1 -1
- package/out-tsc/src/contacts/ContactHistory.js +21 -19
- package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
- package/out-tsc/src/contacts/ContactPending.js +4 -4
- package/out-tsc/src/contacts/ContactPending.js.map +1 -1
- package/out-tsc/src/contacts/ContactTickets.js +8 -8
- package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
- package/out-tsc/src/contacts/events.js +2 -2
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/contacts/helpers.js +2 -2
- package/out-tsc/src/contacts/helpers.js.map +1 -1
- package/out-tsc/src/contactsearch/ContactSearch.js +7 -7
- package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
- package/out-tsc/src/date/TembaDate.js +1 -1
- package/out-tsc/src/date/TembaDate.js.map +1 -1
- package/out-tsc/src/datepicker/DatePicker.js +1 -1
- package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
- package/out-tsc/src/dialog/Dialog.js +5 -5
- package/out-tsc/src/dialog/Dialog.js.map +1 -1
- package/out-tsc/src/dialog/Modax.js +8 -8
- package/out-tsc/src/dialog/Modax.js.map +1 -1
- package/out-tsc/src/dropdown/Dropdown.js +1 -1
- package/out-tsc/src/dropdown/Dropdown.js.map +1 -1
- package/out-tsc/src/fields/FieldManager.js +6 -6
- package/out-tsc/src/fields/FieldManager.js.map +1 -1
- package/out-tsc/src/imagepicker/ImagePicker.js +4 -4
- package/out-tsc/src/imagepicker/ImagePicker.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/label/Label.js +1 -1
- package/out-tsc/src/label/Label.js.map +1 -1
- package/out-tsc/src/leafletmap/LeafletMap.js +6 -6
- package/out-tsc/src/leafletmap/LeafletMap.js.map +1 -1
- package/out-tsc/src/leafletmap/helpers.js +2 -2
- package/out-tsc/src/leafletmap/helpers.js.map +1 -1
- package/out-tsc/src/lightbox/Lightbox.js +2 -2
- package/out-tsc/src/lightbox/Lightbox.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +8 -8
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/NotificationList.js +7 -3
- package/out-tsc/src/list/NotificationList.js.map +1 -1
- package/out-tsc/src/list/RunList.js +1 -1
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +6 -6
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/list/TembaList.js +5 -5
- package/out-tsc/src/list/TembaList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +22 -22
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/loading/Loading.js +1 -1
- package/out-tsc/src/loading/Loading.js.map +1 -1
- package/out-tsc/src/locales/es.js +1 -1
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +1 -1
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/pt.js +1 -1
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/omnibox/Omnibox.js +1 -1
- package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
- package/out-tsc/src/options/Options.js +9 -9
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/remote/Remote.js +1 -1
- package/out-tsc/src/remote/Remote.js.map +1 -1
- package/out-tsc/src/select/Select.js +18 -18
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/sms/gsmsplitter.js +8 -8
- package/out-tsc/src/sms/gsmsplitter.js.map +1 -1
- package/out-tsc/src/sms/gsmvalidator.js +1 -1
- package/out-tsc/src/sms/gsmvalidator.js.map +1 -1
- package/out-tsc/src/sms/index.js +2 -2
- package/out-tsc/src/sms/index.js.map +1 -1
- package/out-tsc/src/sms/unicodesplitter.js +8 -8
- package/out-tsc/src/sms/unicodesplitter.js.map +1 -1
- package/out-tsc/src/store/Store.js +10 -10
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/store/StoreElement.js +2 -2
- package/out-tsc/src/store/StoreElement.js.map +1 -1
- package/out-tsc/src/tabpane/TabPane.js +4 -4
- package/out-tsc/src/tabpane/TabPane.js.map +1 -1
- package/out-tsc/src/templates/TemplateEditor.js +9 -9
- package/out-tsc/src/templates/TemplateEditor.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +1 -1
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/thumbnail/Thumbnail.js +5 -5
- package/out-tsc/src/thumbnail/Thumbnail.js.map +1 -1
- package/out-tsc/src/tip/Tip.js +3 -3
- package/out-tsc/src/tip/Tip.js.map +1 -1
- package/out-tsc/src/utils/index.js +21 -21
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/vectoricon/VectorIcon.js +2 -2
- package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +2 -0
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +234 -81
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/src/webchat/assets.js +2 -0
- package/out-tsc/src/webchat/assets.js.map +1 -0
- package/out-tsc/src/webchat/index.js.map +1 -1
- package/out-tsc/test/temba-alert.test.js +1 -1
- package/out-tsc/test/temba-alert.test.js.map +1 -1
- package/out-tsc/test/temba-checkbox.test.js.map +1 -1
- package/out-tsc/test/temba-color-picker.test.js +4 -4
- package/out-tsc/test/temba-color-picker.test.js.map +1 -1
- package/out-tsc/test/temba-compose.test.js +50 -54
- package/out-tsc/test/temba-compose.test.js.map +1 -1
- package/out-tsc/test/temba-contact-badges.test.js +2 -2
- package/out-tsc/test/temba-contact-badges.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +25 -38
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-contact-details.test.js +2 -2
- package/out-tsc/test/temba-contact-details.test.js.map +1 -1
- package/out-tsc/test/temba-contact-fields.test.js +4 -4
- package/out-tsc/test/temba-contact-fields.test.js.map +1 -1
- package/out-tsc/test/temba-contact-history.test.js +3 -3
- package/out-tsc/test/temba-contact-history.test.js.map +1 -1
- package/out-tsc/test/temba-contact-search.test.js +7 -7
- package/out-tsc/test/temba-contact-search.test.js.map +1 -1
- package/out-tsc/test/temba-contact-tickets.test.js +3 -3
- package/out-tsc/test/temba-contact-tickets.test.js.map +1 -1
- package/out-tsc/test/temba-content-menu.test.js +7 -7
- package/out-tsc/test/temba-content-menu.test.js.map +1 -1
- package/out-tsc/test/temba-date.test.js +3 -3
- package/out-tsc/test/temba-date.test.js.map +1 -1
- package/out-tsc/test/temba-datepicker.test.js +1 -1
- package/out-tsc/test/temba-datepicker.test.js.map +1 -1
- package/out-tsc/test/temba-field-manager.test.js +1 -3
- package/out-tsc/test/temba-field-manager.test.js.map +1 -1
- package/out-tsc/test/temba-label.test.js +6 -6
- package/out-tsc/test/temba-label.test.js.map +1 -1
- package/out-tsc/test/temba-lightbox.test.js +2 -2
- package/out-tsc/test/temba-lightbox.test.js.map +1 -1
- package/out-tsc/test/temba-list.test.js +6 -6
- package/out-tsc/test/temba-list.test.js.map +1 -1
- package/out-tsc/test/temba-menu.test.js +4 -5
- package/out-tsc/test/temba-menu.test.js.map +1 -1
- package/out-tsc/test/temba-modax.test.js +3 -3
- package/out-tsc/test/temba-modax.test.js.map +1 -1
- package/out-tsc/test/temba-options.test.js +1 -1
- package/out-tsc/test/temba-options.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +17 -17
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-sortable-list.test.js +1 -1
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/out-tsc/test/temba-textinput.test.js +2 -2
- package/out-tsc/test/temba-textinput.test.js.map +1 -1
- package/out-tsc/test/temba-tip.test.js +4 -4
- package/out-tsc/test/temba-tip.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +8 -8
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +6 -15
- package/src/RapidElement.ts +3 -3
- package/src/ResizeElement.ts +2 -2
- package/src/aliaseditor/AliasEditor.ts +1 -2
- package/src/button/Button.ts +1 -1
- package/src/charcount/helpers.ts +1 -1
- package/src/colorpicker/ColorPicker.ts +4 -4
- package/src/completion/Completion.ts +2 -2
- package/src/completion/ExcellentParser.ts +1 -1
- package/src/completion/helpers.ts +9 -9
- package/src/compose/Compose.ts +18 -16
- package/src/contacts/ContactBadges.ts +2 -2
- package/src/contacts/ContactChat.ts +4 -4
- package/src/contacts/ContactDetails.ts +4 -4
- package/src/contacts/ContactFieldEditor.ts +4 -4
- package/src/contacts/ContactFields.ts +2 -2
- package/src/contacts/ContactHistory.ts +25 -22
- package/src/contacts/ContactPending.ts +4 -4
- package/src/contacts/ContactTickets.ts +9 -9
- package/src/contacts/events.ts +3 -3
- package/src/contacts/helpers.ts +2 -2
- package/src/contactsearch/ContactSearch.ts +9 -9
- package/src/date/TembaDate.ts +1 -1
- package/src/datepicker/DatePicker.ts +1 -1
- package/src/dialog/Dialog.ts +6 -6
- package/src/dialog/Modax.ts +8 -8
- package/src/dropdown/Dropdown.ts +1 -2
- package/src/emojis.json +1882 -1
- package/src/fields/FieldManager.ts +6 -7
- package/src/imagepicker/ImagePicker.ts +4 -4
- package/src/interfaces.ts +4 -4
- package/src/label/Label.ts +1 -1
- package/src/leafletmap/LeafletMap.ts +6 -6
- package/src/leafletmap/helpers.ts +2 -2
- package/src/lightbox/Lightbox.ts +2 -2
- package/src/list/ContentMenu.ts +9 -9
- package/src/list/NotificationList.ts +7 -3
- package/src/list/RunList.ts +1 -1
- package/src/list/SortableList.ts +6 -6
- package/src/list/TembaList.ts +5 -5
- package/src/list/TembaMenu.ts +23 -23
- package/src/loading/Loading.ts +1 -1
- package/src/locales/es.ts +1 -1
- package/src/locales/fr.ts +1 -1
- package/src/locales/pt.ts +1 -1
- package/src/omnibox/Omnibox.ts +2 -2
- package/src/options/Options.ts +9 -9
- package/src/remote/Remote.ts +1 -1
- package/src/select/Select.ts +19 -19
- package/src/sms/gsmsplitter.ts +8 -8
- package/src/sms/gsmvalidator.ts +1 -1
- package/src/sms/index.ts +2 -2
- package/src/sms/unicodesplitter.ts +8 -8
- package/src/store/Store.ts +10 -10
- package/src/store/StoreElement.ts +2 -2
- package/src/tabpane/TabPane.ts +4 -4
- package/src/templates/TemplateEditor.ts +9 -9
- package/src/textinput/TextInput.ts +2 -2
- package/src/thumbnail/Thumbnail.ts +5 -5
- package/src/tip/Tip.ts +3 -3
- package/src/utils/index.ts +24 -24
- package/src/vectoricon/VectorIcon.ts +2 -2
- package/src/vectoricon/index.ts +3 -1
- package/src/webchat/WebChat.ts +272 -87
- package/src/webchat/assets.ts +2 -0
- package/src/webchat/index.ts +1 -1
- package/svg.js +28 -29
- package/test/temba-alert.test.ts +1 -1
- package/test/temba-checkbox.test.ts +1 -1
- package/test/temba-color-picker.test.ts +4 -4
- package/test/temba-compose.test.ts +50 -55
- package/test/temba-contact-badges.test.ts +2 -2
- package/test/temba-contact-chat.test.ts +26 -46
- package/test/temba-contact-details.test.ts +2 -8
- package/test/temba-contact-fields.test.ts +4 -11
- package/test/temba-contact-history.test.ts +3 -3
- package/test/temba-contact-search.test.ts +7 -13
- package/test/temba-contact-tickets.test.ts +3 -3
- package/test/temba-content-menu.test.ts +7 -7
- package/test/temba-date.test.ts +3 -3
- package/test/temba-datepicker.test.ts +1 -1
- package/test/temba-field-manager.test.ts +1 -4
- package/test/temba-label.test.ts +6 -6
- package/test/temba-lightbox.test.ts +2 -2
- package/test/temba-list.test.ts +6 -6
- package/test/temba-menu.test.ts +4 -5
- package/test/temba-modax.test.ts +3 -3
- package/test/temba-options.test.ts +1 -1
- package/test/temba-select.test.ts +17 -17
- package/test/temba-sortable-list.test.ts +1 -1
- package/test/temba-textinput.test.ts +2 -2
- package/test/temba-tip.test.ts +5 -5
- package/test/utils.test.ts +8 -9
package/src/webchat/WebChat.ts
CHANGED
|
@@ -1,38 +1,53 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
2
2
|
import { LitElement, TemplateResult, html, css, PropertyValueMap } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
|
+
import { getCookie, setCookie } from '../utils';
|
|
5
|
+
import { DEFAULT_AVATAR } from './assets';
|
|
6
|
+
|
|
7
|
+
interface User {
|
|
8
|
+
avatar?: string;
|
|
9
|
+
email: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
4
12
|
|
|
5
13
|
interface Message {
|
|
6
|
-
text: string;
|
|
7
14
|
type: string;
|
|
15
|
+
msg_id?: string;
|
|
16
|
+
text?: string;
|
|
8
17
|
chat_id?: string;
|
|
9
18
|
origin?: string;
|
|
10
|
-
|
|
19
|
+
time?: string;
|
|
20
|
+
before?: string;
|
|
21
|
+
history?: Message[];
|
|
22
|
+
timeAsDate?: Date;
|
|
23
|
+
user?: User;
|
|
11
24
|
}
|
|
12
25
|
|
|
13
26
|
enum ChatStatus {
|
|
14
27
|
DISCONNECTED = 'disconnected',
|
|
15
28
|
CONNECTING = 'connecting',
|
|
16
|
-
CONNECTED = 'connected'
|
|
29
|
+
CONNECTED = 'connected'
|
|
17
30
|
}
|
|
18
31
|
|
|
19
32
|
// how long of a window to show time between batches
|
|
20
33
|
const BATCH_TIME_WINDOW = 30 * 60 * 1000;
|
|
34
|
+
const SCROLL_FETCH_BUFFER = 0.05;
|
|
35
|
+
const MIN_FETCH_TIME = 250;
|
|
21
36
|
|
|
22
37
|
const TIME_FORMAT = { hour: 'numeric', minute: '2-digit' } as any;
|
|
23
38
|
const DAY_FORMAT = {
|
|
24
39
|
weekday: undefined,
|
|
25
40
|
year: 'numeric',
|
|
26
41
|
month: 'short',
|
|
27
|
-
day: 'numeric'
|
|
42
|
+
day: 'numeric'
|
|
28
43
|
} as any;
|
|
29
44
|
const VERBOSE_FORMAT = {
|
|
30
45
|
weekday: undefined,
|
|
31
|
-
year:
|
|
46
|
+
year: undefined,
|
|
32
47
|
month: 'short',
|
|
33
48
|
day: 'numeric',
|
|
34
49
|
hour: 'numeric',
|
|
35
|
-
minute: '2-digit'
|
|
50
|
+
minute: '2-digit'
|
|
36
51
|
} as any;
|
|
37
52
|
|
|
38
53
|
export class WebChat extends LitElement {
|
|
@@ -46,12 +61,11 @@ export class WebChat extends LitElement {
|
|
|
46
61
|
--color-primary: hsla(208, 70%, 55%, 1);
|
|
47
62
|
font-family: 'Roboto', 'Helvetica Neue', sans-serif;
|
|
48
63
|
font-weight: 400;
|
|
49
|
-
font-size: 1.1em;
|
|
50
64
|
--toggle-speed: 80ms;
|
|
51
|
-
position:
|
|
65
|
+
position: fixed;
|
|
52
66
|
right: 0;
|
|
53
67
|
bottom: 0;
|
|
54
|
-
z-index:
|
|
68
|
+
z-index: 10000;
|
|
55
69
|
}
|
|
56
70
|
|
|
57
71
|
.header {
|
|
@@ -60,6 +74,8 @@ export class WebChat extends LitElement {
|
|
|
60
74
|
display: flex;
|
|
61
75
|
align-items: center;
|
|
62
76
|
width: 100%;
|
|
77
|
+
color: rgba(255, 255, 255, 0.8);
|
|
78
|
+
font-size: 0.8em;
|
|
63
79
|
}
|
|
64
80
|
|
|
65
81
|
.header slot {
|
|
@@ -138,7 +154,7 @@ export class WebChat extends LitElement {
|
|
|
138
154
|
cursor: pointer;
|
|
139
155
|
transition: box-shadow var(--toggle-speed) ease-out;
|
|
140
156
|
position: absolute;
|
|
141
|
-
bottom:
|
|
157
|
+
bottom: 1em;
|
|
142
158
|
right: 1em;
|
|
143
159
|
}
|
|
144
160
|
|
|
@@ -185,7 +201,6 @@ export class WebChat extends LitElement {
|
|
|
185
201
|
}
|
|
186
202
|
|
|
187
203
|
.chat {
|
|
188
|
-
max-width: 50vw;
|
|
189
204
|
width: 28rem;
|
|
190
205
|
border-radius: var(--curvature);
|
|
191
206
|
overflow: hidden;
|
|
@@ -201,7 +216,7 @@ export class WebChat extends LitElement {
|
|
|
201
216
|
}
|
|
202
217
|
|
|
203
218
|
.chat.open {
|
|
204
|
-
bottom:
|
|
219
|
+
bottom: 6em;
|
|
205
220
|
opacity: 1;
|
|
206
221
|
transform: scale(1);
|
|
207
222
|
pointer-events: initial;
|
|
@@ -218,6 +233,8 @@ export class WebChat extends LitElement {
|
|
|
218
233
|
-webkit-overflow-scrolling: touch;
|
|
219
234
|
overflow-scrolling: touch;
|
|
220
235
|
padding: 1em 1em 0 1em;
|
|
236
|
+
display: flex;
|
|
237
|
+
flex-direction: column-reverse;
|
|
221
238
|
}
|
|
222
239
|
|
|
223
240
|
.messages:before {
|
|
@@ -231,7 +248,6 @@ export class WebChat extends LitElement {
|
|
|
231
248
|
height: 10px;
|
|
232
249
|
display: block;
|
|
233
250
|
position: absolute;
|
|
234
|
-
max-width: 50vw;
|
|
235
251
|
width: 28rem;
|
|
236
252
|
transition: opacity var(--toggle-speed) ease-out;
|
|
237
253
|
}
|
|
@@ -248,7 +264,6 @@ export class WebChat extends LitElement {
|
|
|
248
264
|
display: block;
|
|
249
265
|
position: absolute;
|
|
250
266
|
margin-top: -10px;
|
|
251
|
-
max-width: 50vw;
|
|
252
267
|
width: 28rem;
|
|
253
268
|
margin-right: 5em;
|
|
254
269
|
transition: opacity var(--toggle-speed) ease-out;
|
|
@@ -324,6 +339,16 @@ export class WebChat extends LitElement {
|
|
|
324
339
|
.input:disabled {
|
|
325
340
|
background: transparent !important;
|
|
326
341
|
}
|
|
342
|
+
|
|
343
|
+
temba-loading {
|
|
344
|
+
justify-content: center;
|
|
345
|
+
margin: 0.5em auto;
|
|
346
|
+
margin-bottom: 2em;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
temba-loading.hidden {
|
|
350
|
+
display: none;
|
|
351
|
+
}
|
|
327
352
|
`;
|
|
328
353
|
}
|
|
329
354
|
|
|
@@ -334,7 +359,7 @@ export class WebChat extends LitElement {
|
|
|
334
359
|
urn: string;
|
|
335
360
|
|
|
336
361
|
@property({ type: Array })
|
|
337
|
-
|
|
362
|
+
messageGroups: string[][] = [];
|
|
338
363
|
|
|
339
364
|
// is our socket connection established
|
|
340
365
|
@property({ type: String })
|
|
@@ -344,6 +369,9 @@ export class WebChat extends LitElement {
|
|
|
344
369
|
@property({ type: Boolean })
|
|
345
370
|
open = false;
|
|
346
371
|
|
|
372
|
+
@property({ type: Boolean })
|
|
373
|
+
fetching = false;
|
|
374
|
+
|
|
347
375
|
@property({ type: Boolean })
|
|
348
376
|
hasPendingText = false;
|
|
349
377
|
|
|
@@ -353,10 +381,20 @@ export class WebChat extends LitElement {
|
|
|
353
381
|
@property({ type: Boolean, attribute: false })
|
|
354
382
|
hideBottomScroll = true;
|
|
355
383
|
|
|
384
|
+
@property({ type: Boolean, attribute: false })
|
|
385
|
+
blockHistoryFetching = false;
|
|
386
|
+
|
|
356
387
|
@property({ type: String })
|
|
357
388
|
host: string;
|
|
358
389
|
|
|
390
|
+
@property({ type: String })
|
|
391
|
+
activeUserAvatar: string;
|
|
392
|
+
|
|
393
|
+
private msgMap = new Map<string, Message>();
|
|
359
394
|
private sock: WebSocket;
|
|
395
|
+
private newMessageCount = 0;
|
|
396
|
+
private oldestMessageDate: Date;
|
|
397
|
+
private fetchRequested: Date;
|
|
360
398
|
|
|
361
399
|
public constructor() {
|
|
362
400
|
super();
|
|
@@ -366,6 +404,11 @@ export class WebChat extends LitElement {
|
|
|
366
404
|
this.openSocket();
|
|
367
405
|
}
|
|
368
406
|
|
|
407
|
+
private sendSockMessage(message: Message) {
|
|
408
|
+
console.log('MO', message);
|
|
409
|
+
this.sock.send(JSON.stringify(message));
|
|
410
|
+
}
|
|
411
|
+
|
|
369
412
|
private openSocket(): void {
|
|
370
413
|
if (this.status !== ChatStatus.DISCONNECTED) {
|
|
371
414
|
return;
|
|
@@ -373,7 +416,7 @@ export class WebChat extends LitElement {
|
|
|
373
416
|
|
|
374
417
|
this.status = ChatStatus.CONNECTING;
|
|
375
418
|
const webChat = this;
|
|
376
|
-
let url = `
|
|
419
|
+
let url = `wss://localhost.textit.com/connect/${this.channel}/`;
|
|
377
420
|
if (this.urn) {
|
|
378
421
|
url = `${url}?chat_id=${this.urn}`;
|
|
379
422
|
}
|
|
@@ -387,44 +430,152 @@ export class WebChat extends LitElement {
|
|
|
387
430
|
this.sock.onopen = function (event: Event) {
|
|
388
431
|
console.log('Socket opened', event);
|
|
389
432
|
webChat.status = ChatStatus.CONNECTED;
|
|
390
|
-
|
|
433
|
+
webChat.urn = getCookie('temba-chat-urn');
|
|
434
|
+
const startChat = { type: 'start_chat' };
|
|
435
|
+
if (webChat.urn) {
|
|
436
|
+
startChat['chat_id'] = webChat.urn;
|
|
437
|
+
}
|
|
438
|
+
webChat.sendSockMessage(startChat);
|
|
391
439
|
};
|
|
440
|
+
|
|
392
441
|
this.sock.onmessage = function (event: MessageEvent) {
|
|
393
|
-
console.log(event);
|
|
394
442
|
webChat.status = ChatStatus.CONNECTED;
|
|
395
443
|
const msg = JSON.parse(event.data) as Message;
|
|
444
|
+
console.log('MT', msg);
|
|
445
|
+
|
|
396
446
|
if (msg.type === 'chat_started') {
|
|
397
447
|
if (webChat.urn !== msg.chat_id) {
|
|
398
|
-
webChat.
|
|
448
|
+
webChat.messageGroups = [];
|
|
399
449
|
}
|
|
400
450
|
webChat.urn = msg.chat_id;
|
|
401
|
-
|
|
451
|
+
setCookie('temba-chat-urn', msg.chat_id);
|
|
452
|
+
webChat.requestUpdate('messageGroups');
|
|
402
453
|
} else if (msg.type === 'chat_resumed') {
|
|
454
|
+
webChat.oldestMessageDate = new Date(msg.time);
|
|
403
455
|
webChat.urn = msg.chat_id;
|
|
404
|
-
|
|
405
|
-
|
|
456
|
+
webChat.fetchPreviousMessages();
|
|
457
|
+
} else if (msg.type === 'msg_out') {
|
|
406
458
|
webChat.addMessage(msg);
|
|
407
|
-
webChat.
|
|
459
|
+
webChat.insertGroups(webChat.groupMessages([msg.msg_id]), true);
|
|
460
|
+
} else if (msg.type === 'history') {
|
|
461
|
+
webChat.handleHistoryResponse(msg);
|
|
408
462
|
}
|
|
409
463
|
};
|
|
410
464
|
}
|
|
411
465
|
|
|
412
|
-
private
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
466
|
+
private isSameGroup(msg1: Message, msg2: Message): boolean {
|
|
467
|
+
if (msg1 && msg2) {
|
|
468
|
+
return (
|
|
469
|
+
msg1.origin === msg2.origin &&
|
|
470
|
+
msg1.user?.name === msg2.user?.name &&
|
|
471
|
+
Math.abs(msg1.timeAsDate.getTime() - msg2.timeAsDate.getTime()) <
|
|
472
|
+
BATCH_TIME_WINDOW
|
|
473
|
+
);
|
|
419
474
|
}
|
|
475
|
+
return false;
|
|
420
476
|
}
|
|
421
477
|
|
|
422
|
-
private
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
478
|
+
private insertGroups(newGroups: string[][], append = false) {
|
|
479
|
+
newGroups.reverse();
|
|
480
|
+
for (const newGroup of newGroups) {
|
|
481
|
+
// see if our new group belongs to the most recent group
|
|
482
|
+
const group =
|
|
483
|
+
this.messageGroups[append ? 0 : this.messageGroups.length - 1];
|
|
484
|
+
|
|
485
|
+
if (group) {
|
|
486
|
+
const lastMsgId = group[group.length - 1];
|
|
487
|
+
const lastMsg = this.msgMap.get(lastMsgId);
|
|
488
|
+
const newMsg = this.msgMap.get(newGroup[0]);
|
|
489
|
+
// if our message belongs to the previous group, in we go
|
|
490
|
+
if (this.isSameGroup(lastMsg, newMsg)) {
|
|
491
|
+
group.push(...newGroup);
|
|
492
|
+
} else {
|
|
493
|
+
// otherwise, just add our entire group as a new one
|
|
494
|
+
if (append) {
|
|
495
|
+
this.messageGroups.splice(0, 0, newGroup);
|
|
496
|
+
} else {
|
|
497
|
+
this.messageGroups.push(newGroup);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
} else {
|
|
501
|
+
if (append) {
|
|
502
|
+
this.messageGroups.splice(0, 0, newGroup);
|
|
503
|
+
} else {
|
|
504
|
+
this.messageGroups.push(newGroup);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
this.requestUpdate('messageGroups');
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private groupMessages(msgIds: string[]): string[][] {
|
|
513
|
+
// group our messages by origin and user
|
|
514
|
+
const groups = [];
|
|
515
|
+
let lastGroup = [];
|
|
516
|
+
let lastMsg = null;
|
|
517
|
+
for (const msgId of msgIds) {
|
|
518
|
+
const msg = this.msgMap.get(msgId);
|
|
519
|
+
if (!this.isSameGroup(msg, lastMsg)) {
|
|
520
|
+
lastGroup = [];
|
|
521
|
+
groups.push(lastGroup);
|
|
522
|
+
}
|
|
523
|
+
lastGroup.push(msgId);
|
|
524
|
+
lastMsg = msg;
|
|
427
525
|
}
|
|
526
|
+
return groups;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
private fetchPreviousMessages() {
|
|
530
|
+
if (!this.blockHistoryFetching) {
|
|
531
|
+
this.blockHistoryFetching = true;
|
|
532
|
+
this.fetching = true;
|
|
533
|
+
|
|
534
|
+
const getHistoryMsg = { type: 'get_history' };
|
|
535
|
+
if (this.oldestMessageDate) {
|
|
536
|
+
getHistoryMsg['before'] = this.oldestMessageDate.toISOString();
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
this.fetchRequested = new Date();
|
|
540
|
+
this.sendSockMessage(getHistoryMsg);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
private handleHistoryResponse(msg: Message) {
|
|
545
|
+
const elapsed = new Date().getTime() - this.fetchRequested.getTime();
|
|
546
|
+
window.setTimeout(
|
|
547
|
+
() => {
|
|
548
|
+
this.fetching = false;
|
|
549
|
+
// block of historical messages
|
|
550
|
+
const msgs = msg.history.reverse();
|
|
551
|
+
|
|
552
|
+
// first add messages to the map
|
|
553
|
+
const newMessages = [];
|
|
554
|
+
for (const m of msgs) {
|
|
555
|
+
if (this.addMessage(m)) {
|
|
556
|
+
newMessages.push(m.msg_id);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (newMessages.length === 0) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
this.insertGroups(this.groupMessages(newMessages));
|
|
565
|
+
|
|
566
|
+
const ele = this.shadowRoot.querySelector('.scroll');
|
|
567
|
+
const prevTop = ele.scrollTop;
|
|
568
|
+
|
|
569
|
+
window.setTimeout(() => {
|
|
570
|
+
ele.scrollTop = prevTop;
|
|
571
|
+
this.blockHistoryFetching = false;
|
|
572
|
+
}, 100);
|
|
573
|
+
},
|
|
574
|
+
// if it's the first load don't wait, otherwise wait a minimum amount of time
|
|
575
|
+
this.messageGroups.length === 0
|
|
576
|
+
? 0
|
|
577
|
+
: Math.max(0, MIN_FETCH_TIME - elapsed)
|
|
578
|
+
);
|
|
428
579
|
}
|
|
429
580
|
|
|
430
581
|
public firstUpdated(
|
|
@@ -462,30 +613,27 @@ export class WebChat extends LitElement {
|
|
|
462
613
|
this.focusInput();
|
|
463
614
|
}
|
|
464
615
|
}
|
|
616
|
+
}
|
|
465
617
|
|
|
466
|
-
|
|
467
|
-
|
|
618
|
+
private addMessage(msg: Message): boolean {
|
|
619
|
+
if (msg.time && !msg.timeAsDate) {
|
|
620
|
+
msg.timeAsDate = new Date(msg.time);
|
|
468
621
|
}
|
|
469
622
|
|
|
470
|
-
if (
|
|
471
|
-
|
|
472
|
-
this.
|
|
473
|
-
|
|
474
|
-
this.
|
|
623
|
+
if (
|
|
624
|
+
!this.oldestMessageDate ||
|
|
625
|
+
msg.timeAsDate.getTime() < this.oldestMessageDate.getTime()
|
|
626
|
+
) {
|
|
627
|
+
this.oldestMessageDate = msg.timeAsDate;
|
|
475
628
|
}
|
|
476
|
-
}
|
|
477
629
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
lastGroup = [];
|
|
484
|
-
}
|
|
485
|
-
if (lastGroup.length === 0) {
|
|
486
|
-
this.messages.push(lastGroup);
|
|
630
|
+
const isNew = !this.msgMap.has(msg.msg_id);
|
|
631
|
+
this.msgMap.set(msg.msg_id, msg);
|
|
632
|
+
|
|
633
|
+
if (msg.user?.avatar) {
|
|
634
|
+
this.activeUserAvatar = msg.user.avatar;
|
|
487
635
|
}
|
|
488
|
-
|
|
636
|
+
return isNew;
|
|
489
637
|
}
|
|
490
638
|
|
|
491
639
|
public openChat(): void {
|
|
@@ -507,13 +655,15 @@ export class WebChat extends LitElement {
|
|
|
507
655
|
input.value = '';
|
|
508
656
|
|
|
509
657
|
const msg = {
|
|
658
|
+
msg_id: `pending-${this.newMessageCount++}`,
|
|
510
659
|
type: 'send_msg',
|
|
511
660
|
text: text,
|
|
661
|
+
time: new Date().toISOString()
|
|
512
662
|
};
|
|
513
663
|
|
|
514
664
|
this.addMessage(msg);
|
|
515
|
-
this.
|
|
516
|
-
this.
|
|
665
|
+
this.insertGroups(this.groupMessages([msg.msg_id]), true);
|
|
666
|
+
this.sendSockMessage(msg);
|
|
517
667
|
this.hasPendingText = input.value.length > 0;
|
|
518
668
|
}
|
|
519
669
|
}
|
|
@@ -527,42 +677,52 @@ export class WebChat extends LitElement {
|
|
|
527
677
|
}
|
|
528
678
|
|
|
529
679
|
private renderMessageGroup(
|
|
530
|
-
|
|
680
|
+
msgIds: string[],
|
|
531
681
|
idx: number,
|
|
532
|
-
groups:
|
|
682
|
+
groups: string[][]
|
|
533
683
|
): TemplateResult {
|
|
534
|
-
|
|
684
|
+
const today = new Date();
|
|
685
|
+
let prevMsg;
|
|
535
686
|
if (idx > 0) {
|
|
536
687
|
const lastGroup = groups[idx - 1];
|
|
537
688
|
if (lastGroup && lastGroup.length > 0) {
|
|
538
|
-
|
|
689
|
+
prevMsg = this.msgMap.get(lastGroup[0]);
|
|
539
690
|
}
|
|
540
691
|
}
|
|
541
692
|
|
|
542
|
-
const
|
|
543
|
-
const showTime = newBatchTime - lastBatchTime > BATCH_TIME_WINDOW;
|
|
544
|
-
|
|
693
|
+
const currentMsg = this.msgMap.get(msgIds[msgIds.length - 1]);
|
|
545
694
|
let timeDisplay = null;
|
|
546
|
-
if (
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const showDay =
|
|
695
|
+
if (
|
|
696
|
+
prevMsg &&
|
|
697
|
+
!this.isSameGroup(prevMsg, currentMsg) &&
|
|
698
|
+
prevMsg.timeAsDate.getTime() - currentMsg.timeAsDate.getTime() >
|
|
699
|
+
BATCH_TIME_WINDOW
|
|
700
|
+
) {
|
|
701
|
+
const showDay =
|
|
702
|
+
!prevMsg ||
|
|
703
|
+
prevMsg.timeAsDate.getDate() !== currentMsg.timeAsDate.getDate();
|
|
553
704
|
if (showDay) {
|
|
554
705
|
timeDisplay = html`<div class="time">
|
|
555
|
-
${
|
|
706
|
+
${prevMsg.timeAsDate.toLocaleDateString(undefined, DAY_FORMAT)}
|
|
556
707
|
</div>`;
|
|
557
708
|
} else {
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
709
|
+
if (prevMsg.timeAsDate.getDate() !== today.getDate()) {
|
|
710
|
+
timeDisplay = html`<div class="time">
|
|
711
|
+
${prevMsg.timeAsDate.toLocaleTimeString(undefined, VERBOSE_FORMAT)}
|
|
712
|
+
</div>`;
|
|
713
|
+
} else {
|
|
714
|
+
timeDisplay = html`<div class="time">
|
|
715
|
+
${prevMsg.timeAsDate.toLocaleTimeString(undefined, TIME_FORMAT)}
|
|
716
|
+
</div>`;
|
|
717
|
+
}
|
|
561
718
|
}
|
|
562
719
|
}
|
|
563
720
|
|
|
564
|
-
const blockTime = new Date(
|
|
565
|
-
const
|
|
721
|
+
const blockTime = new Date(this.msgMap.get(msgIds[msgIds.length - 1]).time);
|
|
722
|
+
const message = this.msgMap.get(msgIds[0]);
|
|
723
|
+
const incoming = !message.origin;
|
|
724
|
+
const avatar = message.user?.avatar;
|
|
725
|
+
const name = message.user?.name;
|
|
566
726
|
|
|
567
727
|
return html` <div
|
|
568
728
|
class="block ${incoming ? 'incoming' : 'outgoing'} ${idx === 0
|
|
@@ -570,30 +730,50 @@ export class WebChat extends LitElement {
|
|
|
570
730
|
: ''}"
|
|
571
731
|
title="${blockTime.toLocaleTimeString(undefined, VERBOSE_FORMAT)}"
|
|
572
732
|
>
|
|
573
|
-
${timeDisplay}
|
|
574
733
|
<div class="row">
|
|
575
734
|
${!incoming
|
|
576
735
|
? html`
|
|
577
736
|
<div
|
|
578
737
|
class="avatar"
|
|
579
|
-
style="background: center / contain no-repeat url(
|
|
738
|
+
style="background: center / contain no-repeat url(${avatar ||
|
|
739
|
+
DEFAULT_AVATAR})"
|
|
580
740
|
></div>
|
|
581
741
|
`
|
|
582
742
|
: null}
|
|
583
743
|
|
|
584
744
|
<div class="bubble">
|
|
585
|
-
${!incoming ? html`<div class="name"
|
|
586
|
-
${
|
|
745
|
+
${!incoming ? html`<div class="name">${name}</div>` : null}
|
|
746
|
+
${msgIds.map(
|
|
747
|
+
(msgId) =>
|
|
748
|
+
html`<div class="message">${this.msgMap.get(msgId).text}</div>
|
|
749
|
+
<!--div style="font-size:10px">
|
|
750
|
+
${this.msgMap
|
|
751
|
+
.get(msgId)
|
|
752
|
+
.timeAsDate.toLocaleDateString(undefined, VERBOSE_FORMAT)}
|
|
753
|
+
</div-->`
|
|
754
|
+
)}
|
|
587
755
|
</div>
|
|
588
756
|
</div>
|
|
757
|
+
${timeDisplay}
|
|
589
758
|
</div>`;
|
|
590
759
|
}
|
|
591
760
|
|
|
592
761
|
private handleScroll(event: any) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
762
|
+
const ele = event.target;
|
|
763
|
+
const top = ele.scrollHeight - ele.clientHeight;
|
|
764
|
+
const scroll = Math.round(top + ele.scrollTop);
|
|
765
|
+
const scrollPct = scroll / top;
|
|
766
|
+
|
|
767
|
+
this.hideTopScroll = scrollPct <= 0.01;
|
|
768
|
+
this.hideBottomScroll = scrollPct >= 0.99;
|
|
769
|
+
|
|
770
|
+
if (this.blockHistoryFetching) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (scrollPct < SCROLL_FETCH_BUFFER) {
|
|
775
|
+
this.fetchPreviousMessages();
|
|
776
|
+
}
|
|
597
777
|
}
|
|
598
778
|
|
|
599
779
|
private handleClickInputPanel(event: MouseEvent) {
|
|
@@ -617,7 +797,7 @@ export class WebChat extends LitElement {
|
|
|
617
797
|
: ''}"
|
|
618
798
|
>
|
|
619
799
|
<div class="header">
|
|
620
|
-
<slot name="header"
|
|
800
|
+
<slot name="header">${this.urn ? this.urn : 'Chat'}</slot>
|
|
621
801
|
<temba-icon
|
|
622
802
|
name="close"
|
|
623
803
|
size="1.3"
|
|
@@ -627,12 +807,16 @@ export class WebChat extends LitElement {
|
|
|
627
807
|
</div>
|
|
628
808
|
<div class="messages">
|
|
629
809
|
<div class="scroll" @scroll=${this.handleScroll}>
|
|
630
|
-
${this.
|
|
631
|
-
? this.
|
|
810
|
+
${this.messageGroups
|
|
811
|
+
? this.messageGroups.map(
|
|
632
812
|
(msgGroup, idx, groups) =>
|
|
633
813
|
html`${this.renderMessageGroup(msgGroup, idx, groups)}`
|
|
634
814
|
)
|
|
635
815
|
: null}
|
|
816
|
+
|
|
817
|
+
<temba-loading
|
|
818
|
+
class="${!this.fetching ? 'hidden' : ''}"
|
|
819
|
+
></temba-loading>
|
|
636
820
|
</div>
|
|
637
821
|
</div>
|
|
638
822
|
|
|
@@ -680,7 +864,8 @@ export class WebChat extends LitElement {
|
|
|
680
864
|
<div @click=${this.toggleChat}>
|
|
681
865
|
<div
|
|
682
866
|
class="toggle"
|
|
683
|
-
style="background: center / contain no-repeat url(
|
|
867
|
+
style="background: center / contain no-repeat url(${this
|
|
868
|
+
.activeUserAvatar || DEFAULT_AVATAR})"
|
|
684
869
|
></div>
|
|
685
870
|
</div>
|
|
686
871
|
`;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export const DEFAULT_AVATAR =
|
|
2
|
+
'data:image/png;base64,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';
|
package/src/webchat/index.ts
CHANGED