yelda-webchat 1.1.3 → 1.1.8
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/README.md +3 -1
- package/dist/css/yeldaWebchatInjector.css +60 -0
- package/dist/css/yeldaWebchatInjector.min.css +7 -0
- package/dist/css/yeldaWebchatInjector.min.css.map +1 -1
- package/dist/js/yeldaWebchatInjector.js +270 -57
- package/dist/js/yeldaWebchatInjector.js.map +1 -1
- package/dist/js/yeldaWebchatInjector.min.js +1 -1
- package/package.json +2 -2
- package/src/config/index.js +20 -0
- package/src/css/yeldaWebchatInjector.css +60 -0
- package/src/js/yeldaWebchatInjector.js +212 -44
- package/uploadBuildToS3.js +11 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yelda-webchat",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "Website Chat Plugin",
|
|
5
5
|
"main": "./dist/js/yeldaWebchatInjector.min.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"lint:check": "eslint --ext .js src",
|
|
22
22
|
"lint:fix": "eslint --fix --ext .js src",
|
|
23
23
|
"test": "mocha --require esm ./test/*.js",
|
|
24
|
-
"uploadBuildToS3": "npm run prepack && node uploadBuildToS3 build -s $npm_config_semver -d $npm_config_destinationPath"
|
|
24
|
+
"uploadBuildToS3": "npm run prepack && node uploadBuildToS3 build -s $npm_config_semver -d $npm_config_destinationPath -o $otp"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"autoprefixer-loader": "^3.2.0",
|
package/src/config/index.js
CHANGED
|
@@ -11,4 +11,24 @@ module.exports = {
|
|
|
11
11
|
PRODUCTION: 'app.yelda.ai',
|
|
12
12
|
STAGING: 'staging.yelda.ai',
|
|
13
13
|
},
|
|
14
|
+
FRAME_EVENT_TYPES: {
|
|
15
|
+
SENT: {
|
|
16
|
+
OPEN_CHAT: 'openChat',
|
|
17
|
+
LEAVE_VIEWPORT: 'leaveViewPort',
|
|
18
|
+
SEND_USER_MESSAGE: 'sendUserMessage',
|
|
19
|
+
URL_UPDATE: 'urlUpdate'
|
|
20
|
+
},
|
|
21
|
+
RECEIVED: {
|
|
22
|
+
OPEN_CHAT: 'openChat',
|
|
23
|
+
CLOSE_CHAT: 'closeChat',
|
|
24
|
+
ABSTAIN_LEAVE_VIEWPORT: 'abstainLeaveViewport',
|
|
25
|
+
OPEN_LIGHT_GALLERY: 'openLightGallery',
|
|
26
|
+
IS_SENDING_MESSAGE: 'isSendingMessage',
|
|
27
|
+
LISTEN_LEAVE_VIEWPORT: 'listenLeaveViewport',
|
|
28
|
+
LISTEN_URL_UPDATE: 'listenUrlUpdate',
|
|
29
|
+
ABSTAIN_URL_UPDATE: 'abstainUrlUpdate',
|
|
30
|
+
ADD_BUBBLE_TEXT: 'addBubbleText',
|
|
31
|
+
ADD_MINIMAL_NOTIFICATION_TEXT: 'addMinimalNotificationText'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
14
34
|
}
|
|
@@ -48,6 +48,12 @@
|
|
|
48
48
|
font-size: 35px !important;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
.yelda_container {
|
|
52
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,
|
|
53
|
+
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
|
|
54
|
+
font-weight: normal;
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
.yelda_container.inner {
|
|
52
58
|
position: absolute !important;
|
|
53
59
|
left: 45px;
|
|
@@ -138,7 +144,61 @@
|
|
|
138
144
|
overflow: hidden;
|
|
139
145
|
}
|
|
140
146
|
}
|
|
147
|
+
/** CSS for assistant bubble text */
|
|
148
|
+
#yelda_assistant_bubble_text {
|
|
149
|
+
animation: 1s ease-out 0s 1 fadeAndSlideInFromRight;
|
|
150
|
+
position: absolute;
|
|
151
|
+
padding: 7px 10px;
|
|
152
|
+
border-radius: 8px;
|
|
153
|
+
box-shadow: #00000030 0px 2px 8px 0px;
|
|
154
|
+
background-color: white;
|
|
155
|
+
cursor: pointer;
|
|
156
|
+
right: 0;
|
|
157
|
+
bottom: 76px;
|
|
158
|
+
max-width: 300px;
|
|
159
|
+
width: calc(66vw);
|
|
160
|
+
text-align: left;
|
|
161
|
+
font-size: 14px;
|
|
162
|
+
font-weight: normal;
|
|
163
|
+
}
|
|
141
164
|
|
|
165
|
+
#yelda_assistant_bubble_text.hidden {
|
|
166
|
+
display: none;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Close button for bubble text */
|
|
170
|
+
.bubbleCloseButton {
|
|
171
|
+
position: relative;
|
|
172
|
+
top: -17px;
|
|
173
|
+
left: 95%;
|
|
174
|
+
color: white;
|
|
175
|
+
background: grey;
|
|
176
|
+
border-radius: 50%;
|
|
177
|
+
padding: 1px 4px;
|
|
178
|
+
font-size: 16px;
|
|
179
|
+
visibility: hidden; /* Don't show the close button by default */
|
|
180
|
+
}
|
|
142
181
|
|
|
182
|
+
/* Show the close button on mouse hover */
|
|
183
|
+
#yelda_assistant_bubble_text:hover .bubbleCloseButton {
|
|
184
|
+
visibility: visible;
|
|
185
|
+
}
|
|
143
186
|
|
|
187
|
+
/* Show the close button always on mobile screen */
|
|
188
|
+
@media only screen and (max-width: 768px) {
|
|
189
|
+
.bubbleCloseButton {
|
|
190
|
+
visibility: visible !important;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
144
193
|
|
|
194
|
+
/** Animation for assistant bubble text */
|
|
195
|
+
@keyframes fadeAndSlideInFromRight {
|
|
196
|
+
0% {
|
|
197
|
+
transform: translateY(10%);
|
|
198
|
+
opacity: 0;
|
|
199
|
+
}
|
|
200
|
+
100% {
|
|
201
|
+
transform: translateY(0%);
|
|
202
|
+
opacity: 1;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -44,7 +44,7 @@ class YeldaChat {
|
|
|
44
44
|
* get Specific parameter from the url
|
|
45
45
|
* @param {*} parameter
|
|
46
46
|
* @param {*} defaultValue, default empty string
|
|
47
|
-
* @return {String}
|
|
47
|
+
* @return {String} urlParameter
|
|
48
48
|
*/
|
|
49
49
|
getUrlParam(parameter, defaultValue = '', url = window.location.href) {
|
|
50
50
|
let urlParameter = defaultValue
|
|
@@ -82,24 +82,54 @@ class YeldaChat {
|
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Create an assistantBubbleText component and add it to webChatContainer element
|
|
85
|
+
* @param {String} text - default null
|
|
85
86
|
*/
|
|
86
|
-
addAssistantBubbleText() {
|
|
87
|
-
|
|
87
|
+
addAssistantBubbleText(text = null) {
|
|
88
|
+
text = text || this.webchatSettings && this.webchatSettings.bubbleText
|
|
89
|
+
if (!this.webChatContainer || !text) {
|
|
88
90
|
return
|
|
89
91
|
}
|
|
90
92
|
|
|
93
|
+
// Remove the assistant bubble text element before adding a new one
|
|
94
|
+
this.removeElement('yelda_assistant_bubble_text')
|
|
91
95
|
// create assistantBubbleText element and set the text
|
|
92
96
|
this.assistantBubbleText = document.createElement('span')
|
|
93
97
|
this.assistantBubbleText.setAttribute('id', 'yelda_assistant_bubble_text')
|
|
94
|
-
this.assistantBubbleText.innerText =
|
|
98
|
+
this.assistantBubbleText.innerText = text
|
|
99
|
+
this.addCloseButtonForBubbleText()
|
|
95
100
|
|
|
96
101
|
// Add click event to assistant text
|
|
97
|
-
this.assistantBubbleText.addEventListener('click', this.openChat)
|
|
102
|
+
this.assistantBubbleText.addEventListener('click', this.openChat.bind(this))
|
|
98
103
|
|
|
99
104
|
// add assistant text to webChatContainer using the webchatSettings
|
|
100
105
|
this.webChatContainer.appendChild(this.assistantBubbleText)
|
|
101
106
|
}
|
|
102
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Add close button for bubble text
|
|
110
|
+
*/
|
|
111
|
+
addCloseButtonForBubbleText() {
|
|
112
|
+
// Create close button and add it to the bubble text container
|
|
113
|
+
const closeButton = document.createElement('a')
|
|
114
|
+
closeButton.setAttribute('class', 'bubbleCloseButton')
|
|
115
|
+
closeButton.setAttribute('id', 'yelda_assistant_bubble_text_close')
|
|
116
|
+
closeButton.setAttribute('href', '#')
|
|
117
|
+
closeButton.innerHTML = '×'
|
|
118
|
+
closeButton.onclick = this.closeBubbleText.bind(this)
|
|
119
|
+
this.assistantBubbleText.prepend(closeButton)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Callback function for bubble text close button
|
|
124
|
+
* @param {Event} event
|
|
125
|
+
*/
|
|
126
|
+
closeBubbleText(event) {
|
|
127
|
+
event.preventDefault()
|
|
128
|
+
event.stopPropagation()
|
|
129
|
+
this.removeElement('yelda_assistant_bubble_text')
|
|
130
|
+
this.assistantBubbleText = null
|
|
131
|
+
}
|
|
132
|
+
|
|
103
133
|
/**
|
|
104
134
|
* Create assistantImage element and add it to webChatContainer element
|
|
105
135
|
*/
|
|
@@ -131,7 +161,7 @@ class YeldaChat {
|
|
|
131
161
|
this.assistantImage.innerHTML = '<i class="fas fa-comment"></i>'
|
|
132
162
|
|
|
133
163
|
// Add click event to assistant image
|
|
134
|
-
this.assistantImage.addEventListener('click', this.openChat)
|
|
164
|
+
this.assistantImage.addEventListener('click', this.openChat.bind(this))
|
|
135
165
|
|
|
136
166
|
// add assistantImage to webChatContainer using the webchatSettings
|
|
137
167
|
this.updateAssistantImageWithAssistantSettings()
|
|
@@ -276,7 +306,7 @@ class YeldaChat {
|
|
|
276
306
|
/**
|
|
277
307
|
* add CSS class which controls the opacity of the frame container if the iframe:
|
|
278
308
|
* - should be opened on load OR has a start button
|
|
279
|
-
* - cannot be closed (canBeClosed
|
|
309
|
+
* - cannot be closed (canBeClosed explicitly set to false)
|
|
280
310
|
*
|
|
281
311
|
* If we are sure that the webchat should be opened and displayed all the time, we can add the y_active class right away
|
|
282
312
|
* Otherwise,
|
|
@@ -365,41 +395,83 @@ class YeldaChat {
|
|
|
365
395
|
}
|
|
366
396
|
|
|
367
397
|
/**
|
|
368
|
-
* Handles
|
|
398
|
+
* Handles communication between parent window and iframe, mainly for open and closing the chat
|
|
369
399
|
* handles also the chat bubble style
|
|
370
400
|
* @param {event} event
|
|
371
401
|
*/
|
|
372
402
|
messageListener(event) {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (event.data === 'openChat' || event.message === 'openChat') {
|
|
379
|
-
this.openChat()
|
|
403
|
+
// event.message is only there to support IE11.
|
|
404
|
+
const eventData = event.data || event.message
|
|
405
|
+
if (!eventData) {
|
|
380
406
|
return
|
|
381
407
|
}
|
|
382
408
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
409
|
+
/*
|
|
410
|
+
* Simple event management parent.postMessage('string message')
|
|
411
|
+
*/
|
|
412
|
+
if (!eventData.event) {
|
|
413
|
+
switch(eventData) {
|
|
414
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.OPEN_CHAT:
|
|
415
|
+
// 'openChat' event triggered from webchat
|
|
416
|
+
this.openChat()
|
|
417
|
+
break
|
|
418
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.CLOSE_CHAT:
|
|
419
|
+
// 'closeChat' event triggered from webchat
|
|
420
|
+
this.closeChat()
|
|
421
|
+
break
|
|
422
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ABSTAIN_LEAVE_VIEWPORT:
|
|
423
|
+
// 'abstainLeaveViewport' event triggered from webchat to stop listening to the leave viewport event
|
|
424
|
+
this.listenLeaveViewport(true)
|
|
425
|
+
break
|
|
426
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.LISTEN_LEAVE_VIEWPORT:
|
|
427
|
+
// Triggered from webchat to listen leave viewport event
|
|
428
|
+
this.listenLeaveViewport()
|
|
429
|
+
break
|
|
430
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.LISTEN_URL_UPDATE:
|
|
431
|
+
// Triggered from webchat to listen for url update
|
|
432
|
+
this.listenUrlUpdate()
|
|
433
|
+
break
|
|
434
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ABSTAIN_URL_UPDATE:
|
|
435
|
+
// Triggered form webchat to stop listening for url update
|
|
436
|
+
this.listenUrlUpdate(true)
|
|
437
|
+
break
|
|
438
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ADD_BUBBLE_TEXT:
|
|
439
|
+
// Triggered from webchat to add assistant bubble text if possible
|
|
440
|
+
if (!this.configurationData.hasOwnProperty('canBeClosed') || this.configurationData.canBeClosed) {
|
|
441
|
+
this.addAssistantBubbleText()
|
|
442
|
+
}
|
|
443
|
+
break;
|
|
386
444
|
}
|
|
387
|
-
|
|
388
|
-
this.handleLightGallery(event.data)
|
|
389
445
|
return
|
|
390
446
|
}
|
|
391
447
|
|
|
392
|
-
|
|
393
|
-
*
|
|
394
|
-
* If isSendingMessage data is true, it means that a user message has already been sent to the webchat and
|
|
395
|
-
* is still waiting for an answer
|
|
396
|
-
* If isSendingMessage data is false, the webchat is ready to receive new user messages
|
|
448
|
+
/*
|
|
449
|
+
* Complex event management parent.postMessage({ event: 'xxxx', data: yyyy })
|
|
397
450
|
*/
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
451
|
+
switch(eventData.event) {
|
|
452
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.OPEN_LIGHT_GALLERY:
|
|
453
|
+
if (!eventData.mediaSources || !eventData.mediaSources.length) {
|
|
454
|
+
return
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
this.handleLightGallery(eventData)
|
|
458
|
+
break
|
|
459
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.IS_SENDING_MESSAGE:
|
|
460
|
+
/**
|
|
461
|
+
* Custom event to send to Yelda to keep track of the webchat ability to receive a new message
|
|
462
|
+
* If isSendingMessage data is true, it means that a user message has already been sent to the webchat and
|
|
463
|
+
* is still waiting for an answer
|
|
464
|
+
* If isSendingMessage data is false, the webchat is ready to receive new user messages
|
|
465
|
+
*/
|
|
466
|
+
if (eventData.hasOwnProperty('data')) {
|
|
467
|
+
window.dispatchEvent(new CustomEvent('isSendingMessage', { detail: eventData.data }))
|
|
468
|
+
}
|
|
469
|
+
break
|
|
470
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ADD_MINIMAL_NOTIFICATION_TEXT:
|
|
471
|
+
if (!this.configurationData.hasOwnProperty('canBeClosed') || this.configurationData.canBeClosed) {
|
|
472
|
+
this.addAssistantBubbleText(eventData.text)
|
|
473
|
+
}
|
|
474
|
+
break;
|
|
403
475
|
}
|
|
404
476
|
}
|
|
405
477
|
|
|
@@ -483,8 +555,16 @@ class YeldaChat {
|
|
|
483
555
|
yeldaIframeContainerElement.classList.add('y_active')
|
|
484
556
|
}
|
|
485
557
|
|
|
558
|
+
// hide the assistant bubble text while opening the webchat window
|
|
559
|
+
if (this.assistantBubbleText) {
|
|
560
|
+
this.assistantBubbleText = null
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Remove assistant bubble text while opening the webchat window
|
|
564
|
+
this.removeElement('yelda_assistant_bubble_text')
|
|
565
|
+
|
|
486
566
|
// Propagate the event to the webchat
|
|
487
|
-
document.getElementById('web_chat_frame').contentWindow.postMessage(
|
|
567
|
+
document.getElementById('web_chat_frame').contentWindow.postMessage(config.FRAME_EVENT_TYPES.SENT.OPEN_CHAT, '*')
|
|
488
568
|
}
|
|
489
569
|
|
|
490
570
|
/**
|
|
@@ -509,7 +589,7 @@ class YeldaChat {
|
|
|
509
589
|
}
|
|
510
590
|
|
|
511
591
|
/**
|
|
512
|
-
* Load CSS
|
|
592
|
+
* Load CSS asynchronously
|
|
513
593
|
*/
|
|
514
594
|
loadCssAsync() {
|
|
515
595
|
const head = document.getElementsByTagName('head')[0]
|
|
@@ -523,7 +603,7 @@ class YeldaChat {
|
|
|
523
603
|
}
|
|
524
604
|
|
|
525
605
|
/**
|
|
526
|
-
*
|
|
606
|
+
* Generate webchatURL and create webchatIframe
|
|
527
607
|
* @param {Object} data { chatUrl, assistantId, assistantSlug, shouldBeOpened, isStartBtn, canBeClosed }
|
|
528
608
|
*/
|
|
529
609
|
setUpChatIFrame(data) {
|
|
@@ -674,7 +754,7 @@ class YeldaChat {
|
|
|
674
754
|
return isFound
|
|
675
755
|
}
|
|
676
756
|
|
|
677
|
-
|
|
757
|
+
/**
|
|
678
758
|
* return getAssistantSettings endpoint URL from data
|
|
679
759
|
* @param {Object} data { assistantUrl, assistantId, settingId }
|
|
680
760
|
* @return {String} url
|
|
@@ -754,7 +834,13 @@ class YeldaChat {
|
|
|
754
834
|
this.webchatSettings = null
|
|
755
835
|
}
|
|
756
836
|
|
|
837
|
+
// Remove event listeners when switching bots
|
|
838
|
+
this.listenLeaveViewport(true)
|
|
839
|
+
this.listenUrlUpdate(true)
|
|
840
|
+
|
|
757
841
|
this.loadChat(data)
|
|
842
|
+
|
|
843
|
+
this.configurationData = data
|
|
758
844
|
return resolve()
|
|
759
845
|
})
|
|
760
846
|
}
|
|
@@ -795,17 +881,17 @@ class YeldaChat {
|
|
|
795
881
|
|
|
796
882
|
/**
|
|
797
883
|
* Return if the webchat loadChat settings are different from the yeldaChat global assistant settings
|
|
798
|
-
*
|
|
799
|
-
* - yeldaChat can be init (and reset) either with the settingId parameter or the pair (assistantId, locale) that we store globally
|
|
800
|
-
* - Each new webchat loading request implies a "getAssistantSettings" async API call,
|
|
801
|
-
* => If multiple new webchat loading requests are done in a short amount of time,
|
|
802
|
-
* "getAssistantSettings" response can be subject to a race condition issue:
|
|
884
|
+
*
|
|
885
|
+
* - yeldaChat can be init (and reset) either with the settingId parameter or the pair (assistantId, locale) that we store globally
|
|
886
|
+
* - Each new webchat loading request implies a "getAssistantSettings" async API call,
|
|
887
|
+
* => If multiple new webchat loading requests are done in a short amount of time,
|
|
888
|
+
* "getAssistantSettings" response can be subject to a race condition issue:
|
|
803
889
|
* The latest requested answer received might not be the latest API call answer.
|
|
804
|
-
*
|
|
890
|
+
*
|
|
805
891
|
* isDataOutdated checks if one of the global parameter is different the ones from the webchat settings we got from the "getAssistantSettings" API call
|
|
806
892
|
* so the "loadChat" function can be informed that the latest request is not the one currently handled
|
|
807
893
|
* And can stop the current process to let the chat load with the global latest requested settings
|
|
808
|
-
*
|
|
894
|
+
*
|
|
809
895
|
* @param {Object} webchatSettings - current settings from the reset or init yeldaChat request
|
|
810
896
|
* @param {String} webchatSettings.settingId
|
|
811
897
|
* @param {String} webchatSettings.assistantId
|
|
@@ -861,7 +947,6 @@ class YeldaChat {
|
|
|
861
947
|
// because the assistant image containing the openChat event wouldn't have been created
|
|
862
948
|
if (!data.hasOwnProperty('canBeClosed') || data.canBeClosed) {
|
|
863
949
|
this.addAssistantImage()
|
|
864
|
-
this.addAssistantBubbleText()
|
|
865
950
|
}
|
|
866
951
|
|
|
867
952
|
// add the frame lister to receive message from iframe to the parent
|
|
@@ -879,7 +964,7 @@ class YeldaChat {
|
|
|
879
964
|
if (this.bubbleContainer) {
|
|
880
965
|
this.assistantImage.removeAttribute('id', 'yelda_assistant_img')
|
|
881
966
|
this.assistantImage.removeAttribute('class', 'yelda_assistant_img default')
|
|
882
|
-
this.assistantImage.removeEventListener('click', this.openChat)
|
|
967
|
+
this.assistantImage.removeEventListener('click', this.openChat.bind(this))
|
|
883
968
|
this.assistantImage.replaceWith(this.bubbleContainerClone)
|
|
884
969
|
} else {
|
|
885
970
|
this.removeElement('yelda_assistant_img')
|
|
@@ -946,8 +1031,91 @@ class YeldaChat {
|
|
|
946
1031
|
const webchatFrame = document.getElementById('web_chat_frame')
|
|
947
1032
|
if (webchatFrame) {
|
|
948
1033
|
this.openChat()
|
|
949
|
-
webchatFrame.contentWindow.postMessage({ event:
|
|
1034
|
+
webchatFrame.contentWindow.postMessage({ event: config.FRAME_EVENT_TYPES.SENT.SEND_USER_MESSAGE, data: message })
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Listen to url update on the page
|
|
1040
|
+
* @param {Boolean} shouldRemoveEvent
|
|
1041
|
+
*/
|
|
1042
|
+
listenUrlUpdate(shouldRemoveEvent = false) {
|
|
1043
|
+
if (shouldRemoveEvent && this.urlObserver) {
|
|
1044
|
+
this.urlObserver.disconnect()
|
|
1045
|
+
this.urlObserver = null
|
|
1046
|
+
return
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
try {
|
|
1050
|
+
this.previousUrl = ''
|
|
1051
|
+
this.urlObserver = new MutationObserver(() => {
|
|
1052
|
+
if (location.href === this.previousUrl) {
|
|
1053
|
+
return
|
|
1054
|
+
}
|
|
1055
|
+
this.previousUrl = location.href
|
|
1056
|
+
this.urlUpdateListener()
|
|
1057
|
+
})
|
|
1058
|
+
|
|
1059
|
+
this.urlObserver.observe(document, {childList: true, subtree: true})
|
|
1060
|
+
} catch(err) {
|
|
1061
|
+
console.warn('listenUrlUpdate error', err)
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Callback for url update listener
|
|
1067
|
+
*/
|
|
1068
|
+
urlUpdateListener() {
|
|
1069
|
+
const webchatFrame = document.getElementById('web_chat_frame')
|
|
1070
|
+
|
|
1071
|
+
if (!webchatFrame) {
|
|
1072
|
+
return
|
|
950
1073
|
}
|
|
1074
|
+
webchatFrame.contentWindow.postMessage({ event: config.FRAME_EVENT_TYPES.SENT.URL_UPDATE, data: window.location.href }, '*')
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Listen leave viewport event handling
|
|
1079
|
+
* @param {Boolean} shouldRemoveEvent - default false
|
|
1080
|
+
*/
|
|
1081
|
+
listenLeaveViewport(shouldRemoveEvent = false) {
|
|
1082
|
+
const md = new MobileDetect(navigator.userAgent)
|
|
1083
|
+
const isMobile = md.mobile() !== null
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* Not needed to listen on mobile since webchat covers the full page of the site
|
|
1087
|
+
* and we can't able to detect mouseout events
|
|
1088
|
+
*/
|
|
1089
|
+
if (isMobile) {
|
|
1090
|
+
return
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
const eventHandler = window[shouldRemoveEvent ? 'removeEventListener' : 'addEventListener']
|
|
1094
|
+
|
|
1095
|
+
if (!this.viewportListenerBind) {
|
|
1096
|
+
this.viewportListenerBind = this.viewportListener.bind(this)
|
|
1097
|
+
}
|
|
1098
|
+
// mouseout event is used to listen leave viewport
|
|
1099
|
+
eventHandler('mouseout', this.viewportListenerBind)
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
/**
|
|
1103
|
+
* Callback for leave viewport listener
|
|
1104
|
+
* @param {Event} event
|
|
1105
|
+
*/
|
|
1106
|
+
viewportListener(event) {
|
|
1107
|
+
/**
|
|
1108
|
+
* when mouse moves between dom elements mouseout event is trigged but we need to trigger
|
|
1109
|
+
* the event when mouse moves out of the viewport so toElement and relatedTarget is checked
|
|
1110
|
+
*/
|
|
1111
|
+
if (event.toElement || event.relatedTarget) {
|
|
1112
|
+
return
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
// When mouse leaves the viewport send 'leaveViewPort' to webchat
|
|
1116
|
+
document.getElementById('web_chat_frame').contentWindow.postMessage({
|
|
1117
|
+
event: config.FRAME_EVENT_TYPES.SENT.LEAVE_VIEWPORT
|
|
1118
|
+
}, '*')
|
|
951
1119
|
}
|
|
952
1120
|
}
|
|
953
1121
|
|
package/uploadBuildToS3.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* To copy dist folder to Yelda repo include the yelda repo static folder path in the command
|
|
8
8
|
* Like this
|
|
9
|
-
* npm run uploadBuildToS3 --destinationPath=/home/Documents/www/yelda/git/yelda/frontend/static --semver=patch
|
|
9
|
+
* npm run uploadBuildToS3 --destinationPath=/home/Documents/www/yelda/git/yelda/frontend/static --semver=patch -o <code>
|
|
10
10
|
* This command uploadBuildToS3 runs build, test, upload to s3, npm version update, push to git and move dist folder to yelda repo
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -32,7 +32,12 @@ const argv = yargs
|
|
|
32
32
|
destinationPath: {
|
|
33
33
|
description: 'Destination path to copy',
|
|
34
34
|
alias: 'd',
|
|
35
|
-
type: 'string'
|
|
35
|
+
type: 'string'
|
|
36
|
+
},
|
|
37
|
+
otp: {
|
|
38
|
+
description: 'Npm one-time password from your authenticator',
|
|
39
|
+
alias: 'o',
|
|
40
|
+
type: 'string'
|
|
36
41
|
}
|
|
37
42
|
})
|
|
38
43
|
.argv
|
|
@@ -47,7 +52,7 @@ const main = async () => {
|
|
|
47
52
|
await uploadToS3()
|
|
48
53
|
|
|
49
54
|
await copyDistToYelda()
|
|
50
|
-
|
|
55
|
+
|
|
51
56
|
const branchName = await getCurrentBranch()
|
|
52
57
|
|
|
53
58
|
const version = await updateNPMVersion()
|
|
@@ -117,7 +122,9 @@ const updateNPMVersion = async () => {
|
|
|
117
122
|
*/
|
|
118
123
|
const publishPackage = async () => {
|
|
119
124
|
console.info('Publishing the package ...')
|
|
120
|
-
|
|
125
|
+
const otp = (argv._.includes('build') && argv.otp) ? `--otp=${argv.otp}` : ''
|
|
126
|
+
|
|
127
|
+
return await executeCommand(`npm publish ${otp}`)
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
/**
|