@meetelise/chat 1.20.97 → 1.20.99

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.
@@ -0,0 +1,401 @@
1
+ import { css } from "lit";
2
+
3
+ // the entire tourScheduler needs a complete rework - it's a mess
4
+ export const tourSchedulerStyles = css`
5
+ * {
6
+ box-sizing: border-box;
7
+ }
8
+
9
+ h1,
10
+ h2,
11
+ h3,
12
+ h4,
13
+ h5,
14
+ h6 {
15
+ margin: 0;
16
+ padding: 0;
17
+ }
18
+
19
+ .tour-scheduler-full,
20
+ .tour-scheduler-compact,
21
+ .tour-scheduler-mobile {
22
+ background: #ffffff;
23
+ box-shadow: 0px 16px 18px 10px rgba(21, 21, 21, 0.4);
24
+ border-radius: 10px;
25
+ font-family: "Helvetica Neue", Arial;
26
+ color: #202020;
27
+
28
+ max-width: 1000px;
29
+ }
30
+ .tour-scheduler-full {
31
+ position: fixed;
32
+ left: 50%;
33
+ top: 50%;
34
+ transform: translate(-50%, -50%);
35
+ width: 100%;
36
+ max-width: 1018px;
37
+ }
38
+ .tour-scheduler-compact {
39
+ position: fixed;
40
+ left: 5%;
41
+ top: 50%;
42
+ transform: translate(0%, -50%);
43
+ width: 100%;
44
+ max-width: calc(90% - 340px); /* 340px is width of chat popup */
45
+ }
46
+ .tour-scheduler-mobile {
47
+ position: fixed;
48
+ left: 6px;
49
+ right: 0;
50
+ bottom: 0;
51
+ top: 6px;
52
+ height: calc(100% - 12px);
53
+ width: calc(100% - 12px);
54
+ box-sizing: border-box;
55
+
56
+ display: flex;
57
+ flex-direction: column;
58
+ overflow: hidden;
59
+ }
60
+ #mobile-body-container {
61
+ flex: 1;
62
+ box-sizing: border-box;
63
+ padding: 24px;
64
+ }
65
+
66
+ #mobile-next-bttn {
67
+ height: 50px;
68
+ padding: 13px 22px 14px 22px;
69
+ float: right;
70
+ background: #202020;
71
+ border: 1px solid #ffffff;
72
+ border-radius: 10px;
73
+ font-family: "Helvetica Neue", Arial;
74
+ font-weight: 700;
75
+ font-size: 14px;
76
+ color: #ffffff;
77
+ box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.5);
78
+ margin-top: 22px;
79
+ cursor: pointer;
80
+ }
81
+ #mobile-next-bttn:disabled {
82
+ background: #e7e7e7;
83
+ box-shadow: none;
84
+ }
85
+ #schedule-bttn {
86
+ float: right;
87
+ margin-top: 4px;
88
+ margin-bottom: 4px;
89
+ cursor: pointer;
90
+ }
91
+ #top-header {
92
+ position: sticky;
93
+ top: 0;
94
+ left: 0;
95
+ width: 100%;
96
+ height: 64px;
97
+
98
+ box-sizing: border-box;
99
+ padding-left: 24px;
100
+ padding-right: 24px;
101
+ display: flex;
102
+ justify-content: space-between;
103
+ align-items: center;
104
+
105
+ border-bottom: 1px solid #e7e7e7;
106
+ }
107
+ #tour-header-title {
108
+ font-size: 14px;
109
+ font-weight: 600;
110
+ }
111
+ #close-button {
112
+ background: none;
113
+ border: none;
114
+ cursor: pointer;
115
+ padding: 0;
116
+ margin: 0;
117
+ }
118
+ #scheduler-container {
119
+ padding: 24px;
120
+ height: 500px;
121
+ overflow-y: auto;
122
+ position: relative;
123
+ }
124
+
125
+ #book-tour-journey-items {
126
+ display: flex;
127
+ justify-content: space-between;
128
+ gap: 24px;
129
+ }
130
+ .journey-header {
131
+ font-size: 14px;
132
+ font-weight: 600;
133
+ padding-bottom: 12px;
134
+ }
135
+
136
+ #tour-type-menu-outer-container {
137
+ width: 220px;
138
+ }
139
+ #date-and-time-menu-outer-container {
140
+ width: calc(70% - 220px);
141
+ }
142
+ #user-info-and-layout-menu-outer-container {
143
+ width: 30%;
144
+ }
145
+
146
+ #tour-type-menu {
147
+ align-self: start;
148
+ display: flex;
149
+ flex-direction: column;
150
+ gap: 6px;
151
+ }
152
+
153
+ @media screen and (max-width: 1200px) {
154
+ #book-tour-journey-items {
155
+ display: flex;
156
+ flex-direction: column;
157
+ align-items: center;
158
+ }
159
+ #tour-type-menu-outer-container {
160
+ width: 320px;
161
+ padding-bottom: 24px;
162
+ border-bottom: 1px solid #e7e7e7;
163
+ }
164
+ #date-and-time-menu-outer-container {
165
+ width: 320px;
166
+ padding-bottom: 24px;
167
+ border-bottom: 1px solid #e7e7e7;
168
+ }
169
+ #user-info-and-layout-menu-outer-container {
170
+ width: 320px;
171
+ padding-bottom: 64px;
172
+ }
173
+
174
+ #datePicker {
175
+ display: flex;
176
+ flex-direction: column;
177
+ justify-content: center;
178
+ align-items: center;
179
+ width: 100%;
180
+ }
181
+ }
182
+
183
+ /*
184
+ makes button fit size of SVG:
185
+ https://stackoverflow.com/questions/45423874/button-height-is-greater-than-the-nested-contents-height
186
+ otherwise there's some empty space at the bottom of the button, which interferes with vertical centering
187
+ */
188
+ button#closeButton > svg {
189
+ vertical-align: middle;
190
+ }
191
+
192
+ h2 {
193
+ font-weight: 600;
194
+ font-size: 14px;
195
+ grid-row: label-row;
196
+ }
197
+
198
+ h2#tourType {
199
+ grid-column: 1;
200
+ grid-row: 2;
201
+ }
202
+
203
+ h2#dateAndTime {
204
+ grid-column: 2;
205
+ grid-row: 2;
206
+ }
207
+
208
+ h2#yourInformation {
209
+ grid-column: 3;
210
+ grid-row: 2;
211
+ }
212
+
213
+ #datePicker {
214
+ display: flex;
215
+ gap: 8px;
216
+ }
217
+
218
+ #dateAndTimeMenu {
219
+ grid-row: 4 / 5;
220
+ grid-column: 2;
221
+ align-self: start;
222
+ display: flex;
223
+ flex-direction: column;
224
+ }
225
+
226
+ #yourInformationMenu {
227
+ grid-row: 4 / 5;
228
+ grid-column: 3;
229
+ display: flex;
230
+ flex-direction: column;
231
+ gap: 12px;
232
+ }
233
+
234
+ #yourInformationMenu input {
235
+ width: 100%;
236
+ height: 49px;
237
+ }
238
+
239
+ .unitLayoutChoices {
240
+ grid-row: 5 / 6;
241
+ grid-column: 3;
242
+ align-self: start;
243
+ display: flex;
244
+ flex-direction: column;
245
+ }
246
+ .unitLayoutChoicesDropdowns {
247
+ display: flex;
248
+ justify-content: space-between;
249
+ gap: 6px;
250
+ }
251
+
252
+ .what-to-view-subheader {
253
+ font-size: 12px;
254
+ padding-top: 4px;
255
+ padding-bottom: 4px;
256
+ }
257
+ .unitLayoutChoice {
258
+ width: -webkit-fill-available;
259
+ }
260
+
261
+ h2.unitLayoutChoice {
262
+ margin-bottom: 7px;
263
+ }
264
+
265
+ .unitLayoutOptions {
266
+ display: flex;
267
+ flex-direction: column;
268
+ gap: 8px;
269
+ }
270
+
271
+ hr {
272
+ grid-row: 6;
273
+ grid-column: 1 / 5;
274
+ /* remove side margins because of this
275
+ * (https://stackoverflow.com/questions/34365271/hr-inside-container-with-display-flex-become-corrupted)
276
+ * and top/bottom margins to position the line exactly at the gridline
277
+ */
278
+ margin: 0;
279
+ }
280
+
281
+ #tour-scheduler-footer {
282
+ height: 100px;
283
+ display: flex;
284
+ justify-content: space-between;
285
+ align-items: center;
286
+ border-top: 1px solid #e7e7e7;
287
+
288
+ padding-left: 24px;
289
+ padding-right: 24px;
290
+ box-sizing: border-box;
291
+ }
292
+
293
+ .explanation {
294
+ font-weight: 400;
295
+ font-size: 12px;
296
+ padding-right: 24px;
297
+ }
298
+ #schedule {
299
+ width: 145px;
300
+ height: 50px;
301
+ justify-self: end;
302
+ }
303
+
304
+ #confirmationMessage {
305
+ display: flex;
306
+ flex-direction: column;
307
+ justify-content: center;
308
+ align-items: center;
309
+ padding: 24px;
310
+ box-sizing: border-box;
311
+ gap: 12px;
312
+ }
313
+
314
+ #confirmationMessage > p {
315
+ font-size: 18px;
316
+ }
317
+
318
+ /* Loading styles: pulsing gray overlay on all the form elements */
319
+
320
+ @keyframes spin {
321
+ 0% {
322
+ transform: none;
323
+ }
324
+ 50% {
325
+ transform: rotateZ(180deg);
326
+ }
327
+ 100% {
328
+ transform: rotateZ(360deg);
329
+ }
330
+ }
331
+
332
+ svg#loadingIcon {
333
+ animation: spin 2s infinite linear;
334
+ }
335
+
336
+ .tour-scheduler.loading #scheduleATour {
337
+ display: flex;
338
+ gap: 10px;
339
+ }
340
+
341
+ @keyframes loadingPulse {
342
+ 0% {
343
+ background-color: #e7e7e7;
344
+ }
345
+ 50% {
346
+ background-color: white;
347
+ }
348
+ 100% {
349
+ background-color: #e7e7e7;
350
+ }
351
+ }
352
+
353
+ tour-type-option,
354
+ date-picker,
355
+ #yourInformationMenu .inputContainer {
356
+ position: relative;
357
+ }
358
+
359
+ .tour-scheduler.loading
360
+ :is(tour-type-option, date-picker, #yourInformationMenu
361
+ .inputContainer)::after {
362
+ content: "";
363
+ position: absolute;
364
+ top: 0;
365
+ left: 0;
366
+ height: 100%;
367
+ z-index: 1;
368
+ animation: loadingPulse 2s infinite;
369
+ }
370
+
371
+ .tour-scheduler.loading tour-type-option::after {
372
+ border-radius: 10px;
373
+ width: 200px;
374
+ }
375
+
376
+ .tour-scheduler.loading date-picker::after {
377
+ border-radius: 10px;
378
+ width: 205px;
379
+ }
380
+
381
+ .tour-scheduler.loading #yourInformationMenu .inputContainer input {
382
+ visibility: hidden;
383
+ }
384
+
385
+ .tour-scheduler.loading time-picker {
386
+ display: none;
387
+ }
388
+
389
+ #namesWrapper {
390
+ display: flex;
391
+ justify-content: space-between;
392
+ }
393
+
394
+ .nameContainer {
395
+ width: 48%;
396
+ }
397
+
398
+ .nameInput {
399
+ width: 100%;
400
+ }
401
+ `;
@@ -101,6 +101,10 @@ export class Launcher extends LitElement {
101
101
  unitOptions: UnitV2[] = [];
102
102
  @property({ attribute: false })
103
103
  tourTypeOptions: LabeledOption[] = [];
104
+
105
+ @property({ attribute: true })
106
+ showTourNextToChat = false;
107
+
104
108
  @property({ attribute: false })
105
109
  onChatTapped: () => void = () => {
106
110
  return;
@@ -161,6 +165,14 @@ export class Launcher extends LitElement {
161
165
  this.hasSSTEnabled = true;
162
166
  }
163
167
  }
168
+
169
+ // If we have the SST tour popup open next to the chat widget, we want to close it
170
+ if (
171
+ (this.isEmailWindowOpen || this.isCallUsWindowOpen) &&
172
+ this.isSSTWindowOpen
173
+ ) {
174
+ this.onCloseSSTWindow();
175
+ }
164
176
  };
165
177
 
166
178
  attachOnClickToEmailUsWindow = (): void => {
@@ -233,6 +245,13 @@ export class Launcher extends LitElement {
233
245
 
234
246
  onCloseSSTWindow = (): void => {
235
247
  this.isSSTWindowOpen = false;
248
+ if (this.showTourNextToChat) {
249
+ this.dispatchEvent(
250
+ new CustomEvent("closeShowTourNextToChat", {
251
+ bubbles: true,
252
+ })
253
+ );
254
+ }
236
255
  };
237
256
 
238
257
  renderSSTOption = (): TemplateResult => {
@@ -563,6 +582,9 @@ export class Launcher extends LitElement {
563
582
  buildingId=${this.buildingId}
564
583
  featureFlagShowDropdown="${this.featureFlagShowDropdown}"
565
584
  .buildingName=${this.buildingName}
585
+ .compactDesign=${this.showTourNextToChat
586
+ ? this.showTourNextToChat
587
+ : ""}
566
588
  ${ref(this.tourSchedulerRef)}
567
589
  ></tour-scheduler>
568
590
  </div>`
@@ -581,7 +603,9 @@ export class Launcher extends LitElement {
581
603
  </div>
582
604
  `
583
605
  : ""}
584
- ${!this.isCallToActionWindowOpen() ? this.renderActionPills() : ""}
606
+ ${!this.isCallToActionWindowOpen() && !this.showTourNextToChat
607
+ ? this.renderActionPills()
608
+ : ""}
585
609
  </div>
586
610
  `;
587
611
  }
@@ -163,6 +163,9 @@ export class MEChat extends LitElement {
163
163
  @state()
164
164
  private chatProvider: ChatProviders = ChatProviders.TALKJS;
165
165
 
166
+ @state()
167
+ private showTourNextToChat = false;
168
+
166
169
  @state()
167
170
  private displayPubnubChat = false;
168
171
 
@@ -393,6 +396,7 @@ export class MEChat extends LitElement {
393
396
  await popup.mount({ show: false });
394
397
  popup.on("close", () => {
395
398
  this.hideLauncher = false;
399
+ this.showTourNextToChat = false;
396
400
  });
397
401
  const talkjsPopupElement = document.querySelector(".__talkjs_popup");
398
402
  this.talkjsPopupElement = talkjsPopupElement;
@@ -520,16 +524,26 @@ export class MEChat extends LitElement {
520
524
  this.displayPubnubChat = false;
521
525
  }
522
526
  this.hideLauncher = false;
527
+ this.showTourNextToChat = false;
523
528
 
524
529
  this.launcherRef.value?.onClickEmailOption(e);
525
530
  };
526
531
 
527
532
  handleTourClicked = (e: MouseEvent): void => {
528
- if (this.chatProvider === ChatProviders.TALKJS) {
529
- this.popup?.hide();
530
- } else if (this.chatProvider === ChatProviders.PUBNUB) {
531
- this.displayPubnubChat = false;
533
+ if (this.showTourNextToChat) {
534
+ this.launcherRef.value?.onClickSSTOption(e);
535
+ return;
532
536
  }
537
+ if (!this.hideLauncher) {
538
+ if (this.chatProvider === ChatProviders.TALKJS) {
539
+ this.popup?.hide();
540
+ } else if (this.chatProvider === ChatProviders.PUBNUB) {
541
+ this.displayPubnubChat = false;
542
+ }
543
+ } else {
544
+ this.showTourNextToChat = true;
545
+ }
546
+
533
547
  this.hideLauncher = false;
534
548
  this.launcherRef.value?.onClickSSTOption(e);
535
549
  };
@@ -540,8 +554,8 @@ export class MEChat extends LitElement {
540
554
  } else if (this.chatProvider === ChatProviders.PUBNUB) {
541
555
  this.displayPubnubChat = false;
542
556
  }
557
+ this.showTourNextToChat = false;
543
558
  this.hideLauncher = false;
544
-
545
559
  this.launcherRef.value?.onClickPhoneOption(e);
546
560
  };
547
561
 
@@ -587,6 +601,7 @@ export class MEChat extends LitElement {
587
601
  e.preventDefault();
588
602
  e.stopPropagation();
589
603
  this.isMinimized = !this.isMinimized;
604
+ this.showTourNextToChat = false;
590
605
  };
591
606
 
592
607
  render(): TemplateResult {
@@ -615,6 +630,7 @@ export class MEChat extends LitElement {
615
630
  .onClickExit=${() => {
616
631
  this.displayPubnubChat = false;
617
632
  this.hideLauncher = false;
633
+ this.showTourNextToChat = false;
618
634
  }}
619
635
  .onMount=${() => {
620
636
  this.adjustTopHeaderContactCoords();
@@ -623,7 +639,7 @@ export class MEChat extends LitElement {
623
639
  ></pubnub-chat>
624
640
  ${this.renderChatAdditionalActions(
625
641
  "chatAdditionalActionsPubnub",
626
- showChatAdditionalActions
642
+ showChatAdditionalActions || this.showTourNextToChat
627
643
  )}
628
644
  `
629
645
  : ""
@@ -673,6 +689,11 @@ export class MEChat extends LitElement {
673
689
  .leadSources="${this.leadSources ?? []}"
674
690
  escortedToursLink="${this.building?.escortedToursLink ?? ""}"
675
691
  virtualToursLink="${this.building?.virtualToursLink ?? ""}"
692
+ .showTourNextToChat="${this.showTourNextToChat ?? ""}"
693
+ @closeShowTourNextToChat=${() => {
694
+ this.showTourNextToChat = false;
695
+ this.hideLauncher = true;
696
+ }}
676
697
  ?hidden=${this.hideLauncher}
677
698
  ?hasCallUsEnabled=${!this.building?.chatWidgets
678
699
  ? true
@@ -699,7 +720,7 @@ export class MEChat extends LitElement {
699
720
  this.chatProvider === ChatProviders.TALKJS
700
721
  ? this.renderChatAdditionalActions(
701
722
  "chatAdditionalActionsTalkjs",
702
- showChatAdditionalActions
723
+ showChatAdditionalActions || this.showTourNextToChat
703
724
  )
704
725
  : ""
705
726
  }
@@ -748,6 +769,7 @@ export class MEChat extends LitElement {
748
769
  } else if (this.chatProvider === ChatProviders.TALKJS) {
749
770
  this.popup?.hide();
750
771
  }
772
+ this.showTourNextToChat = false;
751
773
  this.hideLauncher = false;
752
774
  }}
753
775
  ></minimize-expand-button>
@@ -93,7 +93,7 @@ export class MESelect extends LitElement {
93
93
  ul {
94
94
  padding-left: 0;
95
95
  margin-bottom: 0;
96
- max-height: 200px;
96
+ max-height: 140px;
97
97
  overflow-y: scroll;
98
98
  position: absolute;
99
99
  min-height: 40px;
@@ -113,6 +113,10 @@ export class MESelect extends LitElement {
113
113
  font-family: "Helvetica Neue", Arial;
114
114
  }
115
115
 
116
+ #outer-select-container {
117
+ position: relative;
118
+ }
119
+
116
120
  #select {
117
121
  width: -webkit-fill-available;
118
122
  display: flex;
@@ -170,7 +174,7 @@ export class MESelect extends LitElement {
170
174
  };
171
175
  render(): TemplateResult {
172
176
  return html`
173
- <div>
177
+ <div id="outer-select-container">
174
178
  <div
175
179
  id="select"
176
180
  class="webchat-input"
@@ -168,7 +168,8 @@ export const pubnubChatStyles = css`
168
168
  }
169
169
 
170
170
  #footer {
171
- height: 70px;
171
+ min-height: 70px;
172
+ max-height: 200px;
172
173
  width: 100%;
173
174
  background: black;
174
175
 
@@ -181,8 +182,13 @@ export const pubnubChatStyles = css`
181
182
  z-index: 100001;
182
183
  }
183
184
  #message-input {
184
- height: 40px;
185
185
  width: 100%;
186
+ height: auto;
187
+ max-height: 100%;
188
+
189
+ resize: none;
190
+
191
+ font-family: inherit;
186
192
  box-sizing: border-box;
187
193
  font-weight: 300;
188
194
  font-size: 14px;
@@ -190,6 +196,9 @@ export const pubnubChatStyles = css`
190
196
  border: none;
191
197
  color: white;
192
198
  background: none;
199
+
200
+ padding-right: 6px; /* width of the scrollbar */
201
+ box-sizing: border-box;
193
202
  z-index: 1000000000000000000000000001;
194
203
  }
195
204
  #message-input:focus {
@@ -36,7 +36,7 @@ export class PubnubChat extends LitElement {
36
36
  onMount: () => void = () => ({});
37
37
 
38
38
  @query("#message-input", true)
39
- messageInput!: HTMLInputElement;
39
+ messageInput!: HTMLTextAreaElement;
40
40
 
41
41
  @query("#conversation-body", true)
42
42
  messageBody!: HTMLDivElement;
@@ -63,6 +63,7 @@ export class PubnubChat extends LitElement {
63
63
 
64
64
  sendMessage = async (message: string): Promise<void> => {
65
65
  this.messageInput.value = "";
66
+ this.autoResizeMessageInput();
66
67
  await this.myPubnub?.sendMessage(message);
67
68
  };
68
69
  firstUpdated(): void {
@@ -87,6 +88,11 @@ export class PubnubChat extends LitElement {
87
88
  this.scrollToChatBottom();
88
89
  }
89
90
 
91
+ autoResizeMessageInput = (): void => {
92
+ this.messageInput.style.height = "auto";
93
+ this.messageInput.style.height = this.messageInput.scrollHeight + "px";
94
+ };
95
+
90
96
  render(): TemplateResult {
91
97
  if (!this.buildingSlug || !this.building) {
92
98
  return html``; // error here
@@ -167,13 +173,18 @@ export class PubnubChat extends LitElement {
167
173
  </ul>
168
174
  </div>
169
175
  <div id="footer">
170
- <input
176
+ <textarea
171
177
  id="message-input"
172
178
  placeholder="Ask a question..."
173
179
  @keydown=${(e: KeyboardEvent) => {
174
- if (e.key === "Enter") this.sendMessage(this.messageInput.value);
180
+ if (e.key === "Enter") {
181
+ e.preventDefault();
182
+ this.sendMessage(this.messageInput.value);
183
+ }
175
184
  }}
176
- />
185
+ @input=${() => this.autoResizeMessageInput()}
186
+ rows="1"
187
+ ></textarea>
177
188
  <button
178
189
  id="send-message-bttn"
179
190
  @click=${() => this.sendMessage(this.messageInput.value)}