@chat21/chat21-web-widget 5.0.58 → 5.0.59-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # chat21-web-widget ver 5.0
2
2
 
3
+ ### 5.0.59-rc.2
4
+ - added: handler for buttons in last-message component
5
+ - changed: tooltip custom directive
6
+ - changed: user-avatar size in last-message component
7
+
8
+ ### 5.0.59-rc.1
9
+ - added: hashing while building dist files
10
+
3
11
  ### 5.0.58 in PROD
4
12
 
5
13
  ### 5.0.57 in PROD
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chat21/chat21-web-widget",
3
3
  "author": "Tiledesk SRL",
4
- "version": "5.0.58",
4
+ "version": "5.0.59-rc.2",
5
5
  "license": "MIT",
6
6
  "homepage": "https://www.tiledesk.com",
7
7
  "repository": {
@@ -43,6 +43,7 @@
43
43
  "marked": "^4.0.16",
44
44
  "ngx-logger": "^5.0.11",
45
45
  "popper.js": "^1.16.1",
46
+ "replace": "^1.2.2",
46
47
  "rxjs": "~6.5.1",
47
48
  "source-map-explorer": "^2.5.3",
48
49
  "tslib": "^2.0.0",
@@ -208,6 +208,8 @@ textarea::placeholder {
208
208
 
209
209
  }
210
210
 
211
+
212
+ // TOOLTIP: start
211
213
  .tooltip-container {
212
214
  font-family: 'Roboto','Google Sans', Helvetica, Arial, sans-serif;
213
215
  font-size: 12px;
@@ -245,6 +247,68 @@ textarea::placeholder {
245
247
  }
246
248
  }
247
249
 
250
+ .ng-tooltip {
251
+ position: absolute;
252
+ max-width: 150px;
253
+ font-size: 14px;
254
+ text-align: center;
255
+ color: black;
256
+ padding: 3px 8px;
257
+ background:rgb(255, 255, 255);
258
+ -webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.3);
259
+ box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.3);
260
+ border-radius: 10px;
261
+ z-index: 1000;
262
+ opacity: 0;
263
+
264
+ font-family: 'Roboto','Google Sans', Helvetica, Arial, sans-serif;
265
+ font-size: 12px;
266
+ font-style: normal;
267
+ letter-spacing: normal;
268
+ font-stretch: normal;
269
+ font-variant: normal;
270
+ font-weight: 300;
271
+
272
+ }
273
+ .ng-tooltip:after {
274
+ content: "";
275
+ position: absolute;
276
+ border-style: solid;
277
+ }
278
+ .ng-tooltip-top:after {
279
+ top: 100%;
280
+ left: 50%;
281
+ margin-left: -5px;
282
+ border-width: 5px;
283
+ border-color: rgb(255, 255, 255) transparent transparent transparent;
284
+ }
285
+ .ng-tooltip-bottom:after {
286
+ bottom: 100%;
287
+ left: 50%;
288
+ margin-left: -5px;
289
+ border-width: 5px;
290
+ border-color: transparent transparent rgb(255, 255, 255) transparent;
291
+ }
292
+ .ng-tooltip-left:after {
293
+ top: 50%;
294
+ left: 100%;
295
+ margin-top: -5px;
296
+ border-width: 5px;
297
+ border-color: transparent transparent transparent rgb(255, 255, 255);
298
+ }
299
+ .ng-tooltip-right:after {
300
+ top: 50%;
301
+ right: 100%;
302
+ margin-top: -5px;
303
+ border-width: 5px;
304
+ border-color: transparent rgb(255, 255, 255) transparent transparent;
305
+ }
306
+ .ng-tooltip-show {
307
+ opacity: 1;
308
+ }
309
+
310
+ //TOOLTIP : end
311
+
248
312
  chat-root {
249
313
  position: absolute;
250
314
  display: block;
@@ -3,10 +3,10 @@
3
3
  :host .c21-avatar-image ::ng-deep > chat-avatar-image {
4
4
 
5
5
  .c21-icon-avatar {
6
- height: 32px;
7
- width: 32px;
8
- min-width: 32px;
9
- min-height: 32px;
6
+ height: 38px;
7
+ width: 38px;
8
+ min-width: 38px;
9
+ min-height: 38px;
10
10
  }
11
11
  }
12
12
  :host .previewNewMessagge ::ng-deep > chat-bubble-message > #bubble-message > div > div > chat-text {
@@ -152,10 +152,10 @@
152
152
 
153
153
  .c21-icon-avatar {
154
154
  position: absolute;
155
- width: 32px;
156
- height: 32px;
155
+ width: 38px;
156
+ height: 38px;
157
157
  bottom: 0px;
158
- left: -40px;
158
+ left: -46px;
159
159
  box-shadow: rgba(35, 47, 53, 0.09) 0px 2px 8px 0px;
160
160
  border-radius: 100%; //GAB
161
161
  border: 1px solid #eee;
@@ -163,8 +163,8 @@
163
163
  }
164
164
 
165
165
  .c21-avatar-image {
166
- width: 32px;
167
- height: 32px;
166
+ width: 38px;
167
+ height: 38px;
168
168
  display: block;
169
169
  position: absolute;
170
170
  }
@@ -167,8 +167,10 @@ export class LastMessageComponent implements OnInit, AfterViewInit, OnDestroy {
167
167
  onAttachmentButtonClicked(event: any){
168
168
  // this.onAttachmentButtonClicked.emit(event)
169
169
  this.logger.debug('[LASTMESSAGE] onAttachmentButtonClicked', event)
170
- this.events.publish('lastMessage:attachmentButtonClicked', event)
171
170
  this.openConversationByID(this.conversation);
171
+ setTimeout(() => {
172
+ this.events.publish('lastMessage:attachmentButtonClicked', event)
173
+ }, 500);
172
174
  }
173
175
  /** */
174
176
  openConversationByID(conversation) {
@@ -46,7 +46,7 @@
46
46
  <!-- <div *ngIf="message.type == 'text'"> -->
47
47
 
48
48
 
49
- <div *ngIf="message?.text" tooltip="{{message.timestamp | dateAgo}} ({{message.timestamp | date:'shortDate'}} {{message.timestamp | date:'HH:mm:ss'}})">
49
+ <div *ngIf="message?.text" tooltip="{{message.timestamp | dateAgo}} ({{message.timestamp | date:'shortDate'}} {{message.timestamp | date:'HH:mm:ss'}})" placement="bottom">
50
50
 
51
51
  <!-- [htmlEnabled]="(message?.type==='html')? true : false" -->
52
52
  <chat-text *ngIf="message?.type !=='html'"
@@ -1,8 +1,8 @@
1
1
  <div #actionButton id="actionButton" class="button-in-msg action"
2
2
  [ngClass]="{'disabled': isConversationArchived}"
3
- title="{{button?.value}}"
4
3
  (click)="actionButtonAction()"
5
4
  (mouseover)="onMouseOver($event)"
6
5
  (mouseout)="onMouseOut($event)">
7
6
  {{button?.value}}
8
7
  </div>
8
+ <!-- title="{{button?.value}}" -->
@@ -1,4 +1,5 @@
1
- <div class="button-in-msg url" (click)="actionButtonUrl()" title="{{button?.value}}"
1
+ <!-- title="{{button?.value}}" -->
2
+ <div class="button-in-msg url" (click)="actionButtonUrl()"
2
3
  (mouseover)="onMouseOver($event)" (mouseout)="onMouseOut($event)">
3
4
  <span *ngIf="button?.target !== 'self'" class="icon-button-action">
4
5
  <!-- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="black" width="12px" height="12px">
@@ -1,8 +1,8 @@
1
+ <!-- title="{{button?.value}}" -->
1
2
  <div class="button-in-msg text"
2
- [ngClass]="{'disabled': isConversationArchived}"
3
- title="{{button?.value}}"
4
- (click)="actionButtonText()"
5
- (mouseover)="onMouseOver($event)"
6
- (mouseout)="onMouseOut($event)">
3
+ [ngClass]="{'disabled': isConversationArchived}"
4
+ (click)="actionButtonText()"
5
+ (mouseover)="onMouseOver($event)"
6
+ (mouseout)="onMouseOut($event)">
7
7
  {{button?.value}}
8
8
  </div>
@@ -1,6 +1,5 @@
1
1
  <!-- [ngStyle] = "{ 'max-width': width +'px', 'max-height': height +'px' }" style="position: relative; text-align: center; margin: auto"-->
2
2
  <div class="c21-img-container" >
3
- <!-- <div *ngIf="loading" class="loader" [ngStyle] = "{ 'width': width , 'height': height }"></div> -->
4
3
  <img
5
4
  class="message-contentX message-content-imageX"
6
5
  [alt]="metadata?.name"
@@ -9,7 +8,4 @@
9
8
  [src]="metadata.src"
10
9
  (load)="onLoaded($event)"
11
10
  (click)="downloadImage(metadata.src, metadata.name)"/>
12
- <ng-template #timeTooltipRight>
13
- <span>{{ tooltipMessage }}</span>
14
- </ng-template>
15
11
  </div>
@@ -7,7 +7,7 @@
7
7
 
8
8
  <div style="max-width: 70%;">
9
9
 
10
- <span class="base_info" [innerHTML]="message?.text | marked" tooltip="{{message.timestamp | dateAgo}} ({{message.timestamp | date:'shortDate'}} {{message.timestamp | date:'HH:mm:ss'}})" placement="left" contentType="template"></span>
10
+ <span class="base_info" [innerHTML]="message?.text | marked" tooltip="{{message.timestamp | dateAgo}} ({{message.timestamp | date:'shortDate'}} {{message.timestamp | date:'HH:mm:ss'}})" placement="left"></span>
11
11
  <!-- <ng-template #timeTooltipLeft>
12
12
  <span>{{message.timestamp | amTimeAgo}} ({{message.timestamp | amLocal | amDateFormat: 'L HH:mm:ss'}})</span>
13
13
  </ng-template> -->
@@ -1,46 +1,134 @@
1
- import { Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
1
+ import { Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core';
2
+ import { isOnMobileDevice } from 'src/chat21-core/utils/utils';
2
3
 
3
4
  @Directive({
4
5
  selector: '[tooltip]'
5
6
  })
6
- export class TooltipDirective implements OnDestroy{
7
+ export class TooltipDirective {
7
8
 
8
- @Input() tooltip: any; // The text for the tooltip to display
9
- @Input() delay? = 190; // Optional delay input, in ms
9
+ @Input('tooltip') tooltipTitle: string;
10
+ @Input() placement: string;
11
+ @Input() delay: string;
12
+ tooltip: HTMLElement;
13
+
14
+ offset = 10;
15
+ isMobile = isOnMobileDevice()
10
16
 
11
- private myPopup;
12
- private timer;
17
+ constructor(private el: ElementRef, private renderer: Renderer2) {}
13
18
 
14
- constructor(private el: ElementRef) { }
19
+ @HostListener('mouseenter') onMouseEnter() {
20
+ if (!this.tooltip && !this.isMobile) { this.show(); }
21
+ }
15
22
 
16
- ngOnDestroy(): void {
17
- if (this.myPopup) { this.myPopup.remove() }
23
+ @HostListener('mouseleave') onMouseLeave() {
24
+ if (this.tooltip) { this.hide(); }
18
25
  }
19
26
 
20
- @HostListener('mouseenter') onMouseEnter() {
21
- this.timer = setTimeout(() => {
22
- let x = this.el.nativeElement.getBoundingClientRect().left + this.el.nativeElement.offsetWidth / 2; // Get the middle of the element
23
- let y = this.el.nativeElement.getBoundingClientRect().top + this.el.nativeElement.offsetHeight + 6; // Get the bottom of the element, plus a little extra
24
- this.createTooltipPopup(x, y);
25
- }, this.delay)
27
+ show() {
28
+ this.create();
29
+ this.setPosition();
30
+ this.renderer.addClass(this.tooltip, 'ng-tooltip-show');
26
31
  }
27
32
 
28
- @HostListener('mouseleave') onMouseLeave() {
29
- if (this.timer) clearTimeout(this.timer);
30
- if (this.myPopup) { this.myPopup.remove() }
33
+ hide() {
34
+ this.renderer.removeClass(this.tooltip, 'ng-tooltip-show');
35
+ window.setTimeout(() => {
36
+ this.renderer.removeChild(document.body, this.tooltip);
37
+ this.tooltip = null;
38
+ }, +this.delay);
39
+ }
40
+
41
+ create() {
42
+ this.tooltip = this.renderer.createElement('span');
43
+
44
+ this.renderer.appendChild(
45
+ this.tooltip,
46
+ this.renderer.createText(this.tooltipTitle) // textNode
47
+ );
48
+
49
+ this.renderer.appendChild(document.body, this.tooltip);
50
+ // this.renderer.appendChild(this.el.nativeElement, this.tooltip);
51
+
52
+ this.renderer.addClass(this.tooltip, 'ng-tooltip');
53
+ this.renderer.addClass(this.tooltip, `ng-tooltip-${this.placement}`);
54
+
55
+ // delay 설정
56
+ this.renderer.setStyle(this.tooltip, '-webkit-transition', `opacity ${this.delay}ms`);
57
+ this.renderer.setStyle(this.tooltip, '-moz-transition', `opacity ${this.delay}ms`);
58
+ this.renderer.setStyle(this.tooltip, '-o-transition', `opacity ${this.delay}ms`);
59
+ this.renderer.setStyle(this.tooltip, 'transition', `opacity ${this.delay}ms`);
31
60
  }
32
61
 
33
- private createTooltipPopup(x: number, y: number) {
34
- let popup = document.createElement('div');
35
- popup.innerHTML = this.tooltip;
36
- popup.setAttribute("class", "tooltip-container");
37
- popup.style.top = y.toString() + "px";
38
- popup.style.left = x.toString() + "px";
39
- document.body.appendChild(popup);
40
- this.myPopup = popup;
41
- setTimeout(() => {
42
- if (this.myPopup) this.myPopup.remove();
43
- }, 5000); // Remove tooltip after 5 seconds
62
+ setPosition() {
63
+ const hostPos = this.el.nativeElement.getBoundingClientRect();
64
+ const tooltipPos = this.tooltip.getBoundingClientRect();
65
+
66
+ const scrollPos = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
67
+
68
+ let top, left;
69
+
70
+ if (this.placement === 'top') {
71
+ top = hostPos.top - tooltipPos.height - this.offset;
72
+ left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
73
+ }
74
+
75
+ if (this.placement === 'bottom') {
76
+ top = hostPos.bottom + this.offset;
77
+ left = hostPos.left + (hostPos.width - tooltipPos.width) / 2;
78
+ }
79
+
80
+ if (this.placement === 'left') {
81
+ top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
82
+ left = hostPos.left - tooltipPos.width - this.offset;
83
+ }
84
+
85
+ if (this.placement === 'right') {
86
+ top = hostPos.top + (hostPos.height - tooltipPos.height) / 2;
87
+ left = hostPos.right + this.offset;
88
+ }
89
+
90
+ this.renderer.setStyle(this.tooltip, 'top', `${top + scrollPos}px`);
91
+ this.renderer.setStyle(this.tooltip, 'left', `${left}px`);
44
92
  }
45
93
 
94
+
95
+
96
+ // @Input() tooltip2: any; // The text for the tooltip to display
97
+ // @Input() delay? = 190; // Optional delay input, in ms
98
+
99
+ // private myPopup;
100
+ // private timer;
101
+
102
+
103
+ // ngOnDestroy(): void {
104
+ // if (this.myPopup) { this.myPopup.remove() }
105
+ // }
106
+
107
+ // @HostListener('mouseenter') onMouseEnter() {
108
+ // this.timer = setTimeout(() => {
109
+ // let x = this.el.nativeElement.getBoundingClientRect().left + this.el.nativeElement.offsetWidth / 2; // Get the middle of the element
110
+ // let y = this.el.nativeElement.getBoundingClientRect().top + this.el.nativeElement.offsetHeight + 6; // Get the bottom of the element, plus a little extra
111
+ // this.createTooltipPopup(x, y);
112
+ // }, this.delay)
113
+ // }
114
+
115
+ // @HostListener('mouseleave') onMouseLeave() {
116
+ // if (this.timer) clearTimeout(this.timer);
117
+ // if (this.myPopup) { this.myPopup.remove() }
118
+ // }
119
+
120
+ // private createTooltipPopup(x: number, y: number) {
121
+ // let popup = document.createElement('div');
122
+ // popup.innerHTML = this.tooltip2;
123
+ // popup.setAttribute("class", "tooltip-container");
124
+ // popup.style.top = y.toString() + "px";
125
+ // popup.style.left = x.toString() + "px";
126
+ // document.body.appendChild(popup);
127
+ // this.myPopup = popup;
128
+ // setTimeout(() => {
129
+ // if (this.myPopup) this.myPopup.remove();
130
+ // }, 5000); // Remove tooltip after 5 seconds
131
+ // }
132
+
133
+
46
134
  }
@@ -0,0 +1,71 @@
1
+ var glob = require("glob")
2
+ var replace = require("replace");
3
+
4
+ initReplacement()
5
+
6
+
7
+ function initReplacement(){
8
+ console.log('init replacement HEREEE')
9
+ fileToBeReplaced = {
10
+ 'main' : {name: 'main', extension: '.js', regex: /(?<=\/main\.)(.+?)(?=\.js|$)/},
11
+ 'runtime' : {name: 'runtime', extension: '.js', regex: /(?<=\/runtime\.)(.+?)(?=\.js|$)/},
12
+ 'polyfills' : {name: 'polyfills', extension: '.js', regex: /(?<=\/polyfills\.)(.+?)(?=\.js|$)/},
13
+ 'vendor' : {name: 'vendor', extension: '.js', regex: /(?<=\/vendor\.)(.+?)(?=\.js|$)/},
14
+ 'styles' : {name: 'styles', extension: '.css', regex: /(?<=\/styles\.)(.+?)(?=\.css|$)/},
15
+ }
16
+
17
+ Object.keys(fileToBeReplaced).forEach(key => {
18
+ replaceFile(key, fileToBeReplaced[key])
19
+ })
20
+ // glob("./dist/main*", function (er, files) {
21
+ // // files is an array of filenames.
22
+ // // If the `nonull` option is set, and nothing
23
+ // // was found, then files is ["**/*.js"]
24
+ // // er is an error object or null.
25
+ // console.log('fileeeeee', files)
26
+ // hashCode = files[0].match(/(?<=\/main\.)(.+?)(?=\.js|$)/)[0]
27
+ // console.log('hashhh',hashCode )
28
+ // replace({
29
+ // regex: "main",
30
+ // replacement: "main."+hashCode ,
31
+ // paths: [ './dist/launch.js' ],
32
+ // recursive: true,
33
+ // silent: false,
34
+ // }, (error,changedFiles)=>{
35
+ // if (error) {
36
+ // return console.error('Error occurred:', error);
37
+ // }
38
+ // console.log('Modified files:', changedFiles.join(', '));
39
+ // });
40
+
41
+ // })
42
+
43
+ }
44
+
45
+
46
+
47
+ function replaceFile(name, element){
48
+ let hashCode = ''
49
+ glob("./dist/"+name+"*", function (er, files) {
50
+ // files is an array of filenames.
51
+ // If the `nonull` option is set, and nothing
52
+ // was found, then files is ["**/*.js"]
53
+ // er is an error object or null.
54
+ console.log('fileeeeee', files, element)
55
+ hashCode = files[0].match(element.regex)[0]
56
+ console.log('hashhh',hashCode ,name )
57
+ replace({
58
+ regex: '{{'+ name + '}}'+ element.extension,
59
+ replacement: name + "." + hashCode + element.extension ,
60
+ paths: [ './dist/launch.js' ],
61
+ recursive: true,
62
+ silent: false,
63
+ }, (error,changedFiles)=>{
64
+ if (error) {
65
+ return console.error('Error occurred:', error);
66
+ }
67
+ console.log('Modified files:', changedFiles);
68
+ });
69
+
70
+ })
71
+ }
@@ -220,6 +220,7 @@ export function conversationToMessage(conversation: ConversationModel, currentUs
220
220
  message.sender_fullname = conversation.sender_fullname
221
221
  message.recipient = conversation.recipient
222
222
  message.recipient_fullname = conversation.recipient_fullname
223
+ message.conversation_with = conversation.conversation_with
223
224
  message.status = +conversation.status
224
225
  message.timestamp = conversation.timestamp
225
226
  message.metadata = conversation['metadata']
@@ -239,6 +240,7 @@ export function commandToMessage(msg: MessageModel, conversation: ConversationMo
239
240
  message.sender_fullname = conversation.sender_fullname
240
241
  message.recipient = conversation.recipient
241
242
  message.recipient_fullname = conversation.recipient_fullname
243
+ message.conversation_with = conversation.conversation_with
242
244
  message.status = +conversation.status
243
245
  message.timestamp = conversation.timestamp
244
246
  message.metadata = msg['metadata']
@@ -246,6 +248,7 @@ export function commandToMessage(msg: MessageModel, conversation: ConversationMo
246
248
  message.type = msg['type']
247
249
  message.isSender = isSender(message.sender, currentUserId)
248
250
  message.attributes = { ...conversation.attributes, ...msg['attributes']}
251
+
249
252
 
250
253
  return message as MessageModel
251
254
  }
@@ -19,6 +19,26 @@ export function windowsMatchMedia() {
19
19
  }
20
20
  }
21
21
 
22
+ /** */
23
+ export function isOniOSMobileDevice(): boolean {
24
+ let IS_ON_IOS_MOBILE_DEVICE = false;
25
+ if (/iPad|iPhone|iPod/i.test(window.navigator.userAgent)) {
26
+ IS_ON_IOS_MOBILE_DEVICE = true;
27
+
28
+ }
29
+ // console.log('[CONVS-DETAIL][HEADER] IS_ON_IOS_MOBILE_DEVICE ', this.IS_ON_IOS_MOBILE_DEVICE)
30
+ return IS_ON_IOS_MOBILE_DEVICE;
31
+ }
32
+
33
+ export function isOnMobileDevice() {
34
+ let IS_ON_MOBILE_DEVICE = false;
35
+ if (/Android|iPhone/i.test(window.navigator.userAgent)) {
36
+ IS_ON_MOBILE_DEVICE = true;
37
+ }
38
+ // this.logger.log('[APP-COMP] IS_ON_MOBILE_DEVICE', this.IS_ON_MOBILE_DEVICE)
39
+ return IS_ON_MOBILE_DEVICE;
40
+ }
41
+
22
42
  /**
23
43
  * chiamata da ChatConversationsHandler
24
44
  * restituisce url '/conversations'
@@ -0,0 +1,417 @@
1
+ /** */
2
+ ready(function() {
3
+ console.log('DOM is ready, call initWidget');
4
+ if(!window.tileDeskAsyncInit){
5
+ initAysncEvents();
6
+ }
7
+ initWidget();
8
+ });
9
+
10
+ /** */
11
+ function ready(callbackFunction){
12
+ // if(document.readyState != 'loading'){
13
+ // console.log('in ifffffff', document.readyState)
14
+ // callbackFunction()
15
+ // }
16
+ // else{
17
+ // document.addEventListener("DOMContentLoaded", callbackFunction)
18
+ // }
19
+ document.addEventListener('scroll', start);
20
+ document.addEventListener('mousedown', start);
21
+ document.addEventListener('mousemove', start);
22
+ document.addEventListener('touchstart', start);
23
+ document.addEventListener('keydown', start);
24
+
25
+ function start(){
26
+ if(document.readyState==='complete'){
27
+ callbackFunction()
28
+ }else if(window.attachEvent){
29
+ window.attachEvent('onload',callbackFunction);
30
+ }else{
31
+ window.addEventListener('load',callbackFunction,false);
32
+ }
33
+
34
+ document.removeEventListener('scroll', start);
35
+ document.removeEventListener('mousedown', start);
36
+ document.removeEventListener('mousemove', start);
37
+ document.removeEventListener('touchstart', start);
38
+ document.removeEventListener('scroll', start);
39
+ document.removeEventListener('keydown', start);
40
+ }
41
+
42
+
43
+ }
44
+
45
+
46
+ /** */
47
+ function loadIframe(tiledeskScriptBaseLocation) {
48
+ var dev = window.location.hostname.includes('localhost')? true: false;
49
+
50
+ var containerDiv = document.createElement('div');
51
+ containerDiv.setAttribute('id','tiledesk-container');
52
+ containerDiv.classList.add("closed");
53
+ document.body.appendChild(containerDiv);
54
+
55
+ var iDiv = document.createElement('div');
56
+ iDiv.setAttribute('id','tiledeskdiv');
57
+ containerDiv.appendChild(iDiv);
58
+
59
+ var ifrm = document.createElement("iframe");
60
+ ifrm.setAttribute("frameborder", "0");
61
+ ifrm.setAttribute("border", "0");
62
+ ifrm.setAttribute("title", "Tiledesk Widget")
63
+
64
+ var srcTileDesk = '<html lang="en">';
65
+ srcTileDesk += '<head>';
66
+ srcTileDesk += '<meta charset="utf-8">';
67
+ srcTileDesk += '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />';
68
+ srcTileDesk += '<title>Tilechat Widget</title>';
69
+ srcTileDesk += '<base href="'+tiledeskScriptBaseLocation+ '/">';
70
+ srcTileDesk += '<link rel="icon" type="image/x-icon" href="favicon.ico">';
71
+ srcTileDesk += '<link rel="stylesheet" type="text/css" href="' + tiledeskScriptBaseLocation +'/assets/styles/tiledesk_v1.scss" media="all">';
72
+ srcTileDesk += '</head>';
73
+ srcTileDesk += '<body>';
74
+ srcTileDesk += '<chat-root></chat-root>';
75
+ srcTileDesk += '<script async type="text/javascript" src="'+tiledeskScriptBaseLocation+'/{{runtime}}.js"></script>';
76
+ srcTileDesk += '<script async type="text/javascript" src="'+tiledeskScriptBaseLocation+'/{{polyfills}}.js"></script>';
77
+ srcTileDesk += '<script async type="text/javascript" src="'+tiledeskScriptBaseLocation+'/{{vendor}}.js"></script>';
78
+ srcTileDesk += '<script async type="text/javascript" src="'+tiledeskScriptBaseLocation+'/{{main}}.js"></script>';
79
+ srcTileDesk += '<link type="text/css" rel="stylesheet" href="'+tiledeskScriptBaseLocation+'/{{styles}}.css" media="all"></link>';
80
+ srcTileDesk += '</body>';
81
+ srcTileDesk += '</html>';
82
+
83
+ ifrm.setAttribute('id','tiledeskiframe');
84
+ ifrm.setAttribute('tiledesk_context','parent');
85
+
86
+ /** */
87
+ window.tiledesk.on('onInit', function(event_data) {
88
+ // console.log("launch onInit isopen", tiledeskScriptBaseLocation, window.tiledesk.angularcomponent.component.g.isOpen);
89
+ if (window.tiledesk.angularcomponent.component.g.isOpen) {
90
+ containerDiv.classList.add("open");
91
+ containerDiv.classList.remove("closed");
92
+ iDiv.classList.remove("callout");
93
+ } else {
94
+ containerDiv.classList.add("closed");
95
+ containerDiv.classList.remove("open");
96
+ iDiv.classList.remove("messagePreview");
97
+ }
98
+ });
99
+ /** */
100
+ window.tiledesk.on('onOpen', function(event_data) {
101
+ containerDiv.classList.add("open");
102
+ containerDiv.classList.remove("closed");
103
+ iDiv.classList.remove("callout");
104
+ iDiv.classList.remove("messagePreview");
105
+ });
106
+ /** */
107
+ window.tiledesk.on('onClose', function(event_data) {
108
+ containerDiv.classList.add("closed");
109
+ containerDiv.classList.remove("open");
110
+ });
111
+
112
+ /** */
113
+ window.tiledesk.on('onOpenEyeCatcher', function(event_data) {
114
+ iDiv.classList.add("callout");
115
+ });
116
+ /** */
117
+ window.tiledesk.on('onClosedEyeCatcher', function(event_data) {
118
+ iDiv.classList.remove("callout");
119
+ });
120
+
121
+ /** */
122
+ window.tiledesk.on('onConversationUpdated', function(event_data) {
123
+ const messagePreview = window.tiledesk.angularcomponent.component.g.isOpenNewMessage
124
+ const isOpen = window.tiledesk.angularcomponent.component.g.isOpen
125
+ try {
126
+ if (!isOpen && messagePreview) {
127
+ iDiv.classList.add("messagePreview");
128
+ iDiv.classList.remove("callout");
129
+ // ----------------------------//
130
+ }
131
+ } catch(er) {
132
+ console.error("onConversationUpdated > error: " + er);
133
+ }
134
+ });
135
+
136
+ window.tiledesk.on('onCloseMessagePreview', function(event_data) {
137
+ try {
138
+ iDiv.classList.remove("messagePreview");
139
+ } catch(er) {
140
+ console.error("onCloseMessagePreview > error: " + er);
141
+ }
142
+ });
143
+
144
+
145
+ /**** BEGIN EVENST ****/
146
+ /** */
147
+ window.tiledesk.on('onNewConversation', function(event_data) {
148
+ // console.log("test-custom-auth.html onNewConversation >>>",event_data);
149
+ const tiledeskToken = window.tiledesk.angularcomponent.component.g.tiledeskToken;
150
+ // console.log(">>>> tiledeskToken >>>> ",event_data.detail.appConfigs.apiUrl+event_data.detail.default_settings.projectid);
151
+ if(tiledeskToken) {
152
+ var httpRequest = createCORSRequest('POST', event_data.detail.appConfigs.apiUrl+event_data.detail.default_settings.projectid+'/events',true); //set async to false because loadParams must return when the get is complete
153
+ httpRequest.setRequestHeader('Content-type', 'application/json');
154
+ httpRequest.setRequestHeader('Authorization',tiledeskToken);
155
+ httpRequest.send(JSON.stringify({ "name":"new_conversation",
156
+ "attributes": {
157
+ "request_id":event_data.detail.newConvId,
158
+ "department": event_data.detail.global.departmentSelected.id,
159
+ "participants": event_data.detail.global.participants,
160
+ "language": event_data.detail.global.lang,
161
+ "subtype":"info",
162
+ "fullname":event_data.detail.global.attributes.userFullname,
163
+ "email":event_data.detail.global.attributes.userEmail,
164
+ "attributes":event_data.detail.global.attributes
165
+ }
166
+ }
167
+ ));
168
+ }
169
+ });
170
+
171
+ /** @deprecated event */
172
+ window.tiledesk.on('onLoggedIn', function(event_data) {
173
+ // console.log("test-custom-auth.html onLoggedIn",event_data);
174
+ const tiledeskToken = window.tiledesk.angularcomponent.component.g.tiledeskToken;
175
+ // console.log("------------------->>>> tiledeskToken: ",window.tiledesk.angularcomponent.component.g);
176
+ if(tiledeskToken) {
177
+ var httpRequest = createCORSRequest('POST', event_data.detail.appConfigs.apiUrl+event_data.detail.default_settings.projectid+'/events',true); //set async to false because loadParams must return when the get is complete
178
+ httpRequest.setRequestHeader('Content-type','application/json');
179
+ httpRequest.setRequestHeader('Authorization',tiledeskToken);
180
+ httpRequest.send(JSON.stringify({"name":"logged_in","attributes": {"fullname":event_data.detail.global.attributes.userFullname, "email":event_data.detail.global.attributes.userEmail, "language": event_data.detail.global.lang, "attributes":event_data.detail.global.attributes}}));
181
+ }
182
+ });
183
+
184
+ /** */
185
+ window.tiledesk.on('onAuthStateChanged', function(event_data) {
186
+ // console.log("test-custom-auth.html onAuthStateChanged",event_data);
187
+ const tiledeskToken = window.tiledesk.angularcomponent.component.g.tiledeskToken;
188
+ // console.log("------------------->>>> tiledeskToken: ",window.tiledesk.angularcomponent.component.g);
189
+ if(tiledeskToken) {
190
+ var httpRequest = createCORSRequest('POST', event_data.detail.appConfigs.apiUrl+event_data.detail.default_settings.projectid+'/events',true); //set async to false because loadParams must return when the get is complete
191
+ httpRequest.setRequestHeader('Content-type','application/json');
192
+ httpRequest.setRequestHeader('Authorization',tiledeskToken);
193
+ httpRequest.send(JSON.stringify({"name":"auth_state_changed","attributes": {"user_id":event_data.detail.global.senderId, "isLogged":event_data.detail.global.isLogged, "event":event_data.detail.event, "subtype":"info", "fullname":event_data.detail.global.attributes.userFullname, "email":event_data.detail.global.attributes.userEmail, "language":event_data.detail.global.lang, "attributes":event_data.detail.global.attributes}}));
194
+ httpRequest.onload = function(event) {
195
+ if(event.target && event.target.status === 401){
196
+ window.tiledesk.hide()
197
+ window.tiledesk.dispose()
198
+ }
199
+ }
200
+ }
201
+ });
202
+ /**** END EVENST ****/
203
+
204
+ iDiv.appendChild(ifrm);
205
+
206
+ if(tiledeskScriptBaseLocation.includes('localhost')){
207
+ ifrm.contentWindow.document.open();
208
+ ifrm.contentWindow.document.write(srcTileDesk);
209
+ ifrm.contentWindow.document.close();
210
+ }else {
211
+ ifrm.srcdoc = srcTileDesk
212
+ }
213
+
214
+
215
+ }
216
+
217
+
218
+ function initAysncEvents() {
219
+ console.log('INIT ASYNC EVENTS')
220
+
221
+ window.tileDeskAsyncInit = function() {
222
+ // console.log('launch tiledeskAsyncInit:::', window.Tiledesk.q)
223
+ window.tiledesk.on('onLoadParams', function(event_data) {
224
+ if (window.Tiledesk && window.Tiledesk.q && window.Tiledesk.q.length>0) {
225
+ window.Tiledesk.q.forEach(f => {
226
+ if (f.length>=1) {
227
+ var functionName = f[0];
228
+ if (functionName==="onLoadParams") {
229
+ //CALLING ONLY FUNCTION 'onLoadParams'
230
+ if (f.length==2) {
231
+ var functionCallback = f[1];
232
+ if(typeof functionCallback === "function") {
233
+ window.tiledesk.on(functionName, functionCallback);
234
+ functionCallback(event_data);
235
+ } else {
236
+ console.error("initAysncEvents --> functionCallback is not a function.");
237
+ }
238
+ }
239
+ }else if(functionName=='setParameter'){
240
+ //CALLING ONLY METHOD 'setParameter' AND CHECK IF IT HAS OBJECT ARG
241
+ if (f.length==2) {
242
+ var functionArgs = f[1];
243
+ if(typeof functionArgs === "object") {
244
+ window.tiledesk[functionName](functionArgs);
245
+ } else {
246
+ console.error("initAysncEvents --> functionArgs is not a object.");
247
+ }
248
+ }
249
+ }
250
+ }
251
+ });
252
+ }
253
+ });
254
+
255
+ window.tiledesk.on('onBeforeInit', function(event_data) {
256
+ if (window.Tiledesk && window.Tiledesk.q && window.Tiledesk.q.length>0) {
257
+ // console.log("w.q", window.Tiledesk.q);
258
+ window.Tiledesk.q.forEach(f => {
259
+ if (f.length>=1) {
260
+ var functionName = f[0];
261
+ if (functionName==="onLoadParams" || functionName==="setParameter") {
262
+ //SKIP FUNCTION WITH NAMES 'onLoadParams' AND METHOD 'setParameter'
263
+ } else if (functionName.startsWith("on")) {
264
+ // CALLING METHOD THAT STARTS WITH 'on'
265
+ if (f.length==2) {
266
+ var functionCallback = f[1];
267
+ if(typeof functionCallback === "function"){
268
+ window.tiledesk.on(functionName, functionCallback); //potrei usare window.Tiledesk ?!?
269
+ if (functionName==="onBeforeInit") {
270
+ functionCallback(event_data)
271
+ }
272
+ } else {
273
+ console.error("functionCallback is not a function.");
274
+ }
275
+ }
276
+ } else {
277
+ //CALLING REMAININGS METHOD and CHECK IF CONTAINS ARG TO PASS THROUGH THE METHOD
278
+ if (f.length==2) {
279
+ let args = f[1]
280
+ window.tiledesk[functionName](args);
281
+ } else {
282
+ window.tiledesk[functionName]();
283
+ }
284
+ }
285
+
286
+ }
287
+ });
288
+
289
+ }
290
+
291
+ // RICHIAMATO DOPO L'INIT DEL WIDGET
292
+ window.Tiledesk = function() {
293
+ if (arguments.length>=1) {
294
+ var functionName = arguments[0];
295
+ if (arguments.length==2) {
296
+ var functionCallback = arguments[1];
297
+ }
298
+ var methodOrProperty = window.tiledesk[functionName];
299
+ if(typeof methodOrProperty==="function"){
300
+ return window.tiledesk[functionName](functionCallback);
301
+ }else { //property
302
+ return window.tiledesk[functionName];
303
+ }
304
+ }
305
+ };
306
+
307
+ });
308
+ }
309
+ }
310
+
311
+
312
+ /**
313
+ *
314
+ */
315
+ function initWidget() {
316
+ var tiledeskroot = document.createElement('chat-root');
317
+ var tiledeskScriptLocation = document.getElementById("tiledesk-jssdk").src;
318
+ //var currentScript = document.currentScript;
319
+ //var tiledeskScriptLocation = '';
320
+ //setInterval(function(){
321
+ //tiledeskScriptLocation = currentScript.src;
322
+ var tiledeskScriptBaseLocation = tiledeskScriptLocation.replace("/launch.js","");
323
+ window.tiledesk = new function() {
324
+ //this.type = "macintosh";
325
+ this.tiledeskroot = tiledeskroot;
326
+ this.on = function (event_name, handler) {
327
+ tiledeskroot.addEventListener(event_name, handler);
328
+ };
329
+ this.getBaseLocation = function() {
330
+ return tiledeskScriptBaseLocation;
331
+ }
332
+ }
333
+
334
+ try {
335
+ window.tileDeskAsyncInit();
336
+ }catch(er) {
337
+ if (typeof window.tileDeskAsyncInit == "undefined") {
338
+ console.log("tileDeskAsyncInit() doesn't exists");
339
+ } else {
340
+ console.log(er);
341
+ }
342
+ }
343
+ document.body.appendChild(tiledeskroot);
344
+ initCSSWidget(tiledeskScriptBaseLocation);
345
+ loadIframe(tiledeskScriptBaseLocation);
346
+ //},2000);
347
+ }
348
+
349
+
350
+
351
+
352
+
353
+ function initCSSWidget(tiledeskScriptBaseLocation) {
354
+ var cssId = 'iframeCss'; // you could encode the css path itself to generate id..
355
+ // if (!document.getElementById(cssId))
356
+ // {
357
+ var head = document.getElementsByTagName('head')[0];
358
+ var link = document.createElement('link');
359
+ link.id = cssId;
360
+ link.rel = 'stylesheet';
361
+ link.type = 'text/css';
362
+ link.href = tiledeskScriptBaseLocation+'/iframe-style.css';
363
+ link.media = 'print';
364
+ link.onload = function(){
365
+ link.media = 'all'
366
+ }
367
+ head.appendChild(link);
368
+ // }
369
+ }
370
+
371
+
372
+ //DEPRECATED
373
+ function signInWithCustomToken() {
374
+ let json = JSON.stringify({
375
+ "id_project": "5b55e806c93dde00143163dd"
376
+ });
377
+ var httpRequest = createCORSRequest('POST', 'https://tiledesk-server-pre.herokuapp.com/auth/signinAnonymously',true);
378
+ if (!httpRequest) {
379
+ throw new Error('CORS not supported');
380
+ }
381
+ httpRequest.setRequestHeader('Content-type','application/json');
382
+ httpRequest.send(json);
383
+ httpRequest.onload = function() {
384
+ if (httpRequest.readyState === XMLHttpRequest.DONE) {
385
+ if (httpRequest.status === 200) {
386
+ try {
387
+ var response = JSON.parse(httpRequest.responseText);
388
+ window.tiledesk.signInWithCustomToken(response);
389
+ }
390
+ catch(err) {
391
+ console.error(err.message);
392
+ }
393
+ return true;
394
+ } else {
395
+ alert('There was a problem with the request.');
396
+ }
397
+ }
398
+ };
399
+ httpRequest.onerror = function() {
400
+ console.error('There was an error!');
401
+ return false;
402
+ };
403
+ }
404
+
405
+
406
+ function createCORSRequest(method, url, async) {
407
+ var xhr = new XMLHttpRequest();
408
+ if ("withCredentials" in xhr) {
409
+ xhr.open(method, url, async);
410
+ } else if (typeof XDomainRequest != "undefined") {
411
+ xhr = new XDomainRequest();
412
+ xhr.open(method, url);
413
+ } else {
414
+ xhr = null;
415
+ }
416
+ return xhr;
417
+ }