yelda-webchat 1.1.2 → 1.1.7
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 +51 -0
- package/dist/css/yeldaWebchatInjector.min.css +6 -0
- package/dist/css/yeldaWebchatInjector.min.css.map +1 -1
- package/dist/js/yeldaWebchatInjector.js +288 -57
- package/dist/js/yeldaWebchatInjector.js.map +1 -1
- package/dist/js/yeldaWebchatInjector.min.js +2 -2
- package/package.json +2 -2
- package/src/config/index.js +20 -0
- package/src/css/yeldaWebchatInjector.css +51 -0
- package/src/js/yeldaWebchatInjector.js +223 -40
- 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.7",
|
|
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
|
}
|
|
@@ -138,7 +138,58 @@
|
|
|
138
138
|
overflow: hidden;
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
+
/** CSS for assistant bubble text */
|
|
142
|
+
#yelda_assistant_bubble_text {
|
|
143
|
+
position: absolute;
|
|
144
|
+
white-space: nowrap;
|
|
145
|
+
text-align: center;
|
|
146
|
+
transform: translate(-104%, -140%);
|
|
147
|
+
padding: 5px;
|
|
148
|
+
border: 1px solid #000000;
|
|
149
|
+
border-radius: 3px;
|
|
150
|
+
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
|
|
151
|
+
background-color: white;
|
|
152
|
+
cursor: pointer;
|
|
153
|
+
animation: 1s ease-out 0s 1 fadeAndSlideInFromRight;
|
|
154
|
+
}
|
|
141
155
|
|
|
156
|
+
#yelda_assistant_bubble_text.hidden {
|
|
157
|
+
display: none;
|
|
158
|
+
}
|
|
142
159
|
|
|
160
|
+
/** css for adding tooltip like triangle to the assistant bubble text */
|
|
161
|
+
#yelda_assistant_bubble_text::before,
|
|
162
|
+
#yelda_assistant_bubble_text::after {
|
|
163
|
+
content: "";
|
|
164
|
+
position: absolute;
|
|
165
|
+
border-top: 5px solid transparent;
|
|
166
|
+
border-bottom: 5px solid transparent;
|
|
167
|
+
top: 50%;
|
|
168
|
+
left: 100%;
|
|
169
|
+
}
|
|
143
170
|
|
|
171
|
+
/* The border of the triangle */
|
|
172
|
+
#yelda_assistant_bubble_text::before {
|
|
173
|
+
border-left: 10px solid #000;
|
|
174
|
+
margin-top: -5px;
|
|
175
|
+
margin-left: 1px;
|
|
176
|
+
}
|
|
144
177
|
|
|
178
|
+
/* The white fill of the triangle */
|
|
179
|
+
#yelda_assistant_bubble_text::after {
|
|
180
|
+
border-left: 10px solid white;
|
|
181
|
+
margin-top: -5px;
|
|
182
|
+
z-index: 1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Animation for assistant bubble text */
|
|
186
|
+
@keyframes fadeAndSlideInFromRight {
|
|
187
|
+
0% {
|
|
188
|
+
transform: translateX(0%) translateY(-140%);
|
|
189
|
+
opacity: 0;
|
|
190
|
+
}
|
|
191
|
+
100% {
|
|
192
|
+
transform: translateX(-104%) translateY(-140%);
|
|
193
|
+
opacity: 1;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -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,19 +82,23 @@ 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 = this.webchatSettings.bubbleText
|
|
98
|
+
this.assistantBubbleText.innerText = text || this.webchatSettings.bubbleText
|
|
95
99
|
|
|
96
100
|
// Add click event to assistant text
|
|
97
|
-
this.assistantBubbleText.addEventListener('click', this.openChat)
|
|
101
|
+
this.assistantBubbleText.addEventListener('click', this.openChat.bind(this))
|
|
98
102
|
|
|
99
103
|
// add assistant text to webChatContainer using the webchatSettings
|
|
100
104
|
this.webChatContainer.appendChild(this.assistantBubbleText)
|
|
@@ -131,7 +135,7 @@ class YeldaChat {
|
|
|
131
135
|
this.assistantImage.innerHTML = '<i class="fas fa-comment"></i>'
|
|
132
136
|
|
|
133
137
|
// Add click event to assistant image
|
|
134
|
-
this.assistantImage.addEventListener('click', this.openChat)
|
|
138
|
+
this.assistantImage.addEventListener('click', this.openChat.bind(this))
|
|
135
139
|
|
|
136
140
|
// add assistantImage to webChatContainer using the webchatSettings
|
|
137
141
|
this.updateAssistantImageWithAssistantSettings()
|
|
@@ -276,7 +280,7 @@ class YeldaChat {
|
|
|
276
280
|
/**
|
|
277
281
|
* add CSS class which controls the opacity of the frame container if the iframe:
|
|
278
282
|
* - should be opened on load OR has a start button
|
|
279
|
-
* - cannot be closed (canBeClosed
|
|
283
|
+
* - cannot be closed (canBeClosed explicitly set to false)
|
|
280
284
|
*
|
|
281
285
|
* 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
286
|
* Otherwise,
|
|
@@ -365,41 +369,81 @@ class YeldaChat {
|
|
|
365
369
|
}
|
|
366
370
|
|
|
367
371
|
/**
|
|
368
|
-
* Handles
|
|
372
|
+
* Handles communication between parent window and iframe, mainly for open and closing the chat
|
|
369
373
|
* handles also the chat bubble style
|
|
370
374
|
* @param {event} event
|
|
371
375
|
*/
|
|
372
376
|
messageListener(event) {
|
|
373
|
-
|
|
374
|
-
|
|
377
|
+
// event.message is only there to support IE11.
|
|
378
|
+
const eventData = event.data || event.message
|
|
379
|
+
if (!eventData) {
|
|
375
380
|
return
|
|
376
381
|
}
|
|
377
382
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
383
|
+
/*
|
|
384
|
+
* Simple event management parent.postMessage('string message')
|
|
385
|
+
*/
|
|
386
|
+
if (!eventData.event) {
|
|
387
|
+
switch(eventData) {
|
|
388
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.OPEN_CHAT:
|
|
389
|
+
// 'openChat' event triggered from webchat
|
|
390
|
+
this.openChat()
|
|
391
|
+
break
|
|
392
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.CLOSE_CHAT:
|
|
393
|
+
// 'closeChat' event triggered from webchat
|
|
394
|
+
this.closeChat()
|
|
395
|
+
break
|
|
396
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ABSTAIN_LEAVE_VIEWPORT:
|
|
397
|
+
// 'abstainLeaveViewport' event triggered from webchat to stop listening to the leave viewport event
|
|
398
|
+
this.listenLeaveViewport(true)
|
|
399
|
+
break
|
|
400
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.LISTEN_LEAVE_VIEWPORT:
|
|
401
|
+
// Triggered from webchat to listen leave viewport event
|
|
402
|
+
this.listenLeaveViewport()
|
|
403
|
+
break
|
|
404
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.LISTEN_URL_UPDATE:
|
|
405
|
+
// Triggered from webchat to listen for url update
|
|
406
|
+
this.listenUrlUpdate()
|
|
407
|
+
break
|
|
408
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ABSTAIN_URL_UPDATE:
|
|
409
|
+
// Triggered form webchat to stop listening for url update
|
|
410
|
+
this.listenUrlUpdate(true)
|
|
411
|
+
break
|
|
412
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ADD_BUBBLE_TEXT:
|
|
413
|
+
// Triggered from webchat to add assistant bubble text if possible
|
|
414
|
+
if (!this.configurationData.hasOwnProperty('canBeClosed') || this.configurationData.canBeClosed) {
|
|
415
|
+
this.addAssistantBubbleText()
|
|
416
|
+
}
|
|
417
|
+
break;
|
|
386
418
|
}
|
|
387
|
-
|
|
388
|
-
this.handleLightGallery(event.data)
|
|
389
419
|
return
|
|
390
420
|
}
|
|
391
421
|
|
|
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
|
|
422
|
+
/*
|
|
423
|
+
* Complex event management parent.postMessage({ event: 'xxxx', data: yyyy })
|
|
397
424
|
*/
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
425
|
+
switch(eventData.event) {
|
|
426
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.OPEN_LIGHT_GALLERY:
|
|
427
|
+
if (!eventData.mediaSources || !eventData.mediaSources.length) {
|
|
428
|
+
return
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
this.handleLightGallery(eventData)
|
|
432
|
+
break
|
|
433
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.IS_SENDING_MESSAGE:
|
|
434
|
+
/**
|
|
435
|
+
* Custom event to send to Yelda to keep track of the webchat ability to receive a new message
|
|
436
|
+
* If isSendingMessage data is true, it means that a user message has already been sent to the webchat and
|
|
437
|
+
* is still waiting for an answer
|
|
438
|
+
* If isSendingMessage data is false, the webchat is ready to receive new user messages
|
|
439
|
+
*/
|
|
440
|
+
if (eventData.hasOwnProperty('data')) {
|
|
441
|
+
window.dispatchEvent(new CustomEvent('isSendingMessage', { detail: eventData.data }))
|
|
442
|
+
}
|
|
443
|
+
break
|
|
444
|
+
case config.FRAME_EVENT_TYPES.RECEIVED.ADD_MINIMAL_NOTIFICATION_TEXT:
|
|
445
|
+
this.addAssistantBubbleText(eventData.text)
|
|
446
|
+
break;
|
|
403
447
|
}
|
|
404
448
|
}
|
|
405
449
|
|
|
@@ -483,8 +527,16 @@ class YeldaChat {
|
|
|
483
527
|
yeldaIframeContainerElement.classList.add('y_active')
|
|
484
528
|
}
|
|
485
529
|
|
|
530
|
+
// hide the assistant bubble text while opening the webchat window
|
|
531
|
+
if (this.assistantBubbleText) {
|
|
532
|
+
this.assistantBubbleText = null
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Remove assistant bubble text while opening the webchat window
|
|
536
|
+
this.removeElement('yelda_assistant_bubble_text')
|
|
537
|
+
|
|
486
538
|
// Propagate the event to the webchat
|
|
487
|
-
document.getElementById('web_chat_frame').contentWindow.postMessage(
|
|
539
|
+
document.getElementById('web_chat_frame').contentWindow.postMessage(config.FRAME_EVENT_TYPES.SENT.OPEN_CHAT, '*')
|
|
488
540
|
}
|
|
489
541
|
|
|
490
542
|
/**
|
|
@@ -509,7 +561,7 @@ class YeldaChat {
|
|
|
509
561
|
}
|
|
510
562
|
|
|
511
563
|
/**
|
|
512
|
-
* Load CSS
|
|
564
|
+
* Load CSS asynchronously
|
|
513
565
|
*/
|
|
514
566
|
loadCssAsync() {
|
|
515
567
|
const head = document.getElementsByTagName('head')[0]
|
|
@@ -523,7 +575,7 @@ class YeldaChat {
|
|
|
523
575
|
}
|
|
524
576
|
|
|
525
577
|
/**
|
|
526
|
-
*
|
|
578
|
+
* Generate webchatURL and create webchatIframe
|
|
527
579
|
* @param {Object} data { chatUrl, assistantId, assistantSlug, shouldBeOpened, isStartBtn, canBeClosed }
|
|
528
580
|
*/
|
|
529
581
|
setUpChatIFrame(data) {
|
|
@@ -674,7 +726,7 @@ class YeldaChat {
|
|
|
674
726
|
return isFound
|
|
675
727
|
}
|
|
676
728
|
|
|
677
|
-
|
|
729
|
+
/**
|
|
678
730
|
* return getAssistantSettings endpoint URL from data
|
|
679
731
|
* @param {Object} data { assistantUrl, assistantId, settingId }
|
|
680
732
|
* @return {String} url
|
|
@@ -737,10 +789,15 @@ class YeldaChat {
|
|
|
737
789
|
return resolve()
|
|
738
790
|
}
|
|
739
791
|
|
|
792
|
+
|
|
793
|
+
// These data will be needed to avoid loading outdated data in the chat (in case of multiple chat load requests)
|
|
794
|
+
this.assistantId = data.assistantId
|
|
795
|
+
this.locale = data.locale
|
|
796
|
+
this.settingId = data.settingId
|
|
797
|
+
|
|
740
798
|
// Get assistant settings from backend
|
|
741
799
|
try {
|
|
742
800
|
this.webchatSettings = await this.getAssistantSettings(data)
|
|
743
|
-
|
|
744
801
|
// Webchat can be loaded thanks to a single settingId or group of data : {assistantId, assistantSlug, locale}
|
|
745
802
|
// If only settingId is provided, then we will fill {assistantId, assistantSlug, locale} thanks to the assistant settings
|
|
746
803
|
data = this.updateAssistantData(data, this.webchatSettings)
|
|
@@ -749,7 +806,13 @@ class YeldaChat {
|
|
|
749
806
|
this.webchatSettings = null
|
|
750
807
|
}
|
|
751
808
|
|
|
809
|
+
// Remove event listeners when switching bots
|
|
810
|
+
this.listenLeaveViewport(true)
|
|
811
|
+
this.listenUrlUpdate(true)
|
|
812
|
+
|
|
752
813
|
this.loadChat(data)
|
|
814
|
+
|
|
815
|
+
this.configurationData = data
|
|
753
816
|
return resolve()
|
|
754
817
|
})
|
|
755
818
|
}
|
|
@@ -767,7 +830,9 @@ class YeldaChat {
|
|
|
767
830
|
return false
|
|
768
831
|
}
|
|
769
832
|
|
|
770
|
-
// if webchatSettings is null
|
|
833
|
+
// if webchatSettings is null, it means that the admins didn't created custom webchat settings or
|
|
834
|
+
// or that the API call to get the settings failed
|
|
835
|
+
// In this case we can still load the webchat with the default settings
|
|
771
836
|
if (!webchatSettings) {
|
|
772
837
|
return true
|
|
773
838
|
}
|
|
@@ -786,11 +851,47 @@ class YeldaChat {
|
|
|
786
851
|
return true
|
|
787
852
|
}
|
|
788
853
|
|
|
854
|
+
/**
|
|
855
|
+
* Return if the webchat loadChat settings are different from the yeldaChat global assistant settings
|
|
856
|
+
*
|
|
857
|
+
* - yeldaChat can be init (and reset) either with the settingId parameter or the pair (assistantId, locale) that we store globally
|
|
858
|
+
* - Each new webchat loading request implies a "getAssistantSettings" async API call,
|
|
859
|
+
* => If multiple new webchat loading requests are done in a short amount of time,
|
|
860
|
+
* "getAssistantSettings" response can be subject to a race condition issue:
|
|
861
|
+
* The latest requested answer received might not be the latest API call answer.
|
|
862
|
+
*
|
|
863
|
+
* isDataOutdated checks if one of the global parameter is different the ones from the webchat settings we got from the "getAssistantSettings" API call
|
|
864
|
+
* so the "loadChat" function can be informed that the latest request is not the one currently handled
|
|
865
|
+
* And can stop the current process to let the chat load with the global latest requested settings
|
|
866
|
+
*
|
|
867
|
+
* @param {Object} webchatSettings - current settings from the reset or init yeldaChat request
|
|
868
|
+
* @param {String} webchatSettings.settingId
|
|
869
|
+
* @param {String} webchatSettings.assistantId
|
|
870
|
+
* @param {String} webchatSettings.locale
|
|
871
|
+
* @param {Object} globalData - latest globally stored settings from the reset or init yeldaChat request
|
|
872
|
+
* @param {String} globalData.settingId
|
|
873
|
+
* @param {String} globalData.assistantId
|
|
874
|
+
* @param {String} globalData.locale
|
|
875
|
+
* @returns {Boolean}
|
|
876
|
+
*/
|
|
877
|
+
isDataOutdated(data, { settingId, assistantId, locale }) {
|
|
878
|
+
if (data.settingId && data.settingId !== settingId) {
|
|
879
|
+
return true
|
|
880
|
+
}
|
|
881
|
+
if (!data.settingId && (data.assistantId !== assistantId || data.locale !== locale)) {
|
|
882
|
+
return true
|
|
883
|
+
}
|
|
884
|
+
return false
|
|
885
|
+
}
|
|
886
|
+
|
|
789
887
|
/**
|
|
790
888
|
* Load the chat after getting the webchat settings if publication is enabled
|
|
791
|
-
* @param {Object} data { data.assistantUrl, data.assistantId }
|
|
889
|
+
* @param {Object} data { data.assistantUrl, data.assistantId, data.locale }
|
|
792
890
|
*/
|
|
793
891
|
loadChat(data) {
|
|
892
|
+
if (this.isDataOutdated(data, this)) {
|
|
893
|
+
return
|
|
894
|
+
}
|
|
794
895
|
if (!this.shouldChatBeLoaded(this.webchatSettings, data)) {
|
|
795
896
|
this.unLoadChat()
|
|
796
897
|
return
|
|
@@ -818,7 +919,6 @@ class YeldaChat {
|
|
|
818
919
|
// because the assistant image containing the openChat event wouldn't have been created
|
|
819
920
|
if (!data.hasOwnProperty('canBeClosed') || data.canBeClosed) {
|
|
820
921
|
this.addAssistantImage()
|
|
821
|
-
this.addAssistantBubbleText()
|
|
822
922
|
}
|
|
823
923
|
|
|
824
924
|
// add the frame lister to receive message from iframe to the parent
|
|
@@ -836,7 +936,7 @@ class YeldaChat {
|
|
|
836
936
|
if (this.bubbleContainer) {
|
|
837
937
|
this.assistantImage.removeAttribute('id', 'yelda_assistant_img')
|
|
838
938
|
this.assistantImage.removeAttribute('class', 'yelda_assistant_img default')
|
|
839
|
-
this.assistantImage.removeEventListener('click', this.openChat)
|
|
939
|
+
this.assistantImage.removeEventListener('click', this.openChat.bind(this))
|
|
840
940
|
this.assistantImage.replaceWith(this.bubbleContainerClone)
|
|
841
941
|
} else {
|
|
842
942
|
this.removeElement('yelda_assistant_img')
|
|
@@ -903,9 +1003,92 @@ class YeldaChat {
|
|
|
903
1003
|
const webchatFrame = document.getElementById('web_chat_frame')
|
|
904
1004
|
if (webchatFrame) {
|
|
905
1005
|
this.openChat()
|
|
906
|
-
webchatFrame.contentWindow.postMessage({ event:
|
|
1006
|
+
webchatFrame.contentWindow.postMessage({ event: config.FRAME_EVENT_TYPES.SENT.SEND_USER_MESSAGE, data: message })
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Listen to url update on the page
|
|
1012
|
+
* @param {Boolean} shouldRemoveEvent
|
|
1013
|
+
*/
|
|
1014
|
+
listenUrlUpdate(shouldRemoveEvent = false) {
|
|
1015
|
+
if (shouldRemoveEvent && this.urlObserver) {
|
|
1016
|
+
this.urlObserver.disconnect()
|
|
1017
|
+
this.urlObserver = null
|
|
1018
|
+
return
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
try {
|
|
1022
|
+
this.previousUrl = ''
|
|
1023
|
+
this.urlObserver = new MutationObserver(() => {
|
|
1024
|
+
if (location.href === this.previousUrl) {
|
|
1025
|
+
return
|
|
1026
|
+
}
|
|
1027
|
+
this.previousUrl = location.href
|
|
1028
|
+
this.urlUpdateListener()
|
|
1029
|
+
})
|
|
1030
|
+
|
|
1031
|
+
this.urlObserver.observe(document, {childList: true, subtree: true})
|
|
1032
|
+
} catch(err) {
|
|
1033
|
+
console.warn('listenUrlUpdate error', err)
|
|
907
1034
|
}
|
|
908
1035
|
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* Callback for url update listener
|
|
1039
|
+
*/
|
|
1040
|
+
urlUpdateListener() {
|
|
1041
|
+
const webchatFrame = document.getElementById('web_chat_frame')
|
|
1042
|
+
|
|
1043
|
+
if (!webchatFrame) {
|
|
1044
|
+
return
|
|
1045
|
+
}
|
|
1046
|
+
webchatFrame.contentWindow.postMessage({ event: config.FRAME_EVENT_TYPES.SENT.URL_UPDATE, data: window.location.href }, '*')
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Listen leave viewport event handling
|
|
1051
|
+
* @param {Boolean} shouldRemoveEvent - default false
|
|
1052
|
+
*/
|
|
1053
|
+
listenLeaveViewport(shouldRemoveEvent = false) {
|
|
1054
|
+
const md = new MobileDetect(navigator.userAgent)
|
|
1055
|
+
const isMobile = md.mobile() !== null
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* Not needed to listen on mobile since webchat covers the full page of the site
|
|
1059
|
+
* and we can't able to detect mouseout events
|
|
1060
|
+
*/
|
|
1061
|
+
if (isMobile) {
|
|
1062
|
+
return
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
const eventHandler = window[shouldRemoveEvent ? 'removeEventListener' : 'addEventListener']
|
|
1066
|
+
|
|
1067
|
+
if (!this.viewportListenerBind) {
|
|
1068
|
+
this.viewportListenerBind = this.viewportListener.bind(this)
|
|
1069
|
+
}
|
|
1070
|
+
// mouseout event is used to listen leave viewport
|
|
1071
|
+
eventHandler('mouseout', this.viewportListenerBind)
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* Callback for leave viewport listener
|
|
1076
|
+
* @param {Event} event
|
|
1077
|
+
*/
|
|
1078
|
+
viewportListener(event) {
|
|
1079
|
+
/**
|
|
1080
|
+
* when mouse moves between dom elements mouseout event is trigged but we need to trigger
|
|
1081
|
+
* the event when mouse moves out of the viewport so toElement and relatedTarget is checked
|
|
1082
|
+
*/
|
|
1083
|
+
if (event.toElement || event.relatedTarget) {
|
|
1084
|
+
return
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// When mouse leaves the viewport send 'leaveViewPort' to webchat
|
|
1088
|
+
document.getElementById('web_chat_frame').contentWindow.postMessage({
|
|
1089
|
+
event: config.FRAME_EVENT_TYPES.SENT.LEAVE_VIEWPORT
|
|
1090
|
+
}, '*')
|
|
1091
|
+
}
|
|
909
1092
|
}
|
|
910
1093
|
|
|
911
1094
|
let yeldaChat = new YeldaChat()
|
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
|
/**
|