@chat21/chat21-web-widget 5.0.70 → 5.0.71-rc.10

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.
Files changed (46) hide show
  1. package/.github/workflows/build.yml +2 -2
  2. package/CHANGELOG.md +37 -0
  3. package/Dockerfile +1 -1
  4. package/package.json +1 -1
  5. package/src/app/app.component.ts +49 -49
  6. package/src/app/component/conversation-detail/conversation/conversation.component.html +3 -2
  7. package/src/app/component/conversation-detail/conversation/conversation.component.scss +3 -2
  8. package/src/app/component/conversation-detail/conversation/conversation.component.ts +3 -8
  9. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +2 -3
  10. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +2 -4
  11. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +1 -1
  12. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +8 -4
  13. package/src/app/component/last-message/last-message.component.scss +1 -1
  14. package/src/app/component/message/carousel/carousel.component.html +6 -2
  15. package/src/app/component/message/carousel/carousel.component.scss +22 -0
  16. package/src/app/component/message/carousel/carousel.component.ts +6 -5
  17. package/src/app/component/message/image/image.component.ts +0 -3
  18. package/src/app/providers/global-settings.service.ts +5 -0
  19. package/src/app/sass/_variables.scss +1 -1
  20. package/src/app/utils/constants.ts +0 -2
  21. package/src/app/utils/globals.ts +4 -3
  22. package/src/app/utils/rules.ts +1 -1
  23. package/src/assets/images/icons/no-image.svg +6 -0
  24. package/src/assets/js/chat21client.js +7 -3
  25. package/src/assets/twp/chatbot-panel.html +223 -19
  26. package/src/assets/twp/index-dev.html +56 -17
  27. package/src/assets/twp/index.html +110 -37
  28. package/src/chat21-core/models/conversation.ts +2 -1
  29. package/src/chat21-core/models/upload.ts +0 -1
  30. package/src/chat21-core/providers/abstract/upload.service.ts +3 -0
  31. package/src/chat21-core/providers/firebase/firebase-auth-service.ts +3 -3
  32. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +1 -1
  33. package/src/chat21-core/providers/firebase/firebase-conversations-handler.ts +2 -1
  34. package/src/chat21-core/providers/firebase/firebase-upload.service.ts +128 -6
  35. package/src/chat21-core/providers/mqtt/mqtt-auth-service.ts +1 -1
  36. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +1 -1
  37. package/src/chat21-core/providers/mqtt/mqtt-conversations-handler.ts +10 -1
  38. package/src/chat21-core/providers/mqtt/mqtt-presence.service.ts +1 -1
  39. package/src/chat21-core/providers/native/native-upload-service.ts +68 -0
  40. package/src/chat21-core/utils/constants.ts +15 -1
  41. package/src/chat21-core/utils/triggerHandler.ts +0 -1
  42. package/src/chat21-core/utils/utils-message.ts +8 -0
  43. package/src/chat21-core/utils/utils.ts +0 -39
  44. package/src/launch.js +0 -1
  45. package/src/widget-config-template.json +2 -2
  46. package/src/widget-config.json +2 -1
@@ -16,9 +16,11 @@
16
16
 
17
17
  #preloader {
18
18
  background: #fff;
19
- position: fixed;
19
+ position: absolute;
20
20
  top: 0;
21
21
  left: 0;
22
+ bottom: 0;
23
+ right: 0;
22
24
  height: 100%;
23
25
  width: 100%;
24
26
  z-index: 999999;
@@ -51,6 +53,52 @@
51
53
  animation:blink normal 2s infinite ease-in-out; /* Opera and prob css3 final iteration */
52
54
  }
53
55
 
56
+ .loader{
57
+ display: block;
58
+ z-index: 99;
59
+ position: absolute;
60
+ top: calc( 50% - 50px);
61
+ left: calc( 50% - 50px);
62
+ width: 100px;
63
+ height: 100px;
64
+ border: 3px solid rgb(224, 106, 88);
65
+ border-radius: 50%;
66
+
67
+ animation: spin 7s ease-in-out;
68
+ animation-iteration-count: infinite;
69
+ transition-duration: 0.1s;
70
+ }
71
+
72
+ .loader:hover {
73
+ scale: 0.95;
74
+ /*Loader on hover effect*/
75
+ }
76
+
77
+ .loader:active {
78
+ scale: 1.2;
79
+ /*Loader on click effect*/
80
+ }
81
+
82
+ @keyframes spin {
83
+ 0% {
84
+ transform: rotate(0deg);
85
+ border-bottom: solid 3px transparent;
86
+ border-top: solid 3px transparent;
87
+ }
88
+ 50% {
89
+ transform: rotate(1800deg);
90
+ border: 3px solid white;
91
+ border-left: solid 3px transparent;
92
+ border-right: solid 3px transparent;
93
+ }
94
+ 100% {
95
+ /*Reversed spinning*/
96
+ transform: rotate(0deg);
97
+ border-bottom: solid 3px transparent;
98
+ border-top: solid 3px transparent;
99
+ }
100
+ }
101
+
54
102
  #deferred-styles {
55
103
  display: none;
56
104
  }
@@ -86,6 +134,17 @@
86
134
  height: 100%;
87
135
  }
88
136
 
137
+
138
+ .container{
139
+ display: flex;
140
+ align-items: center;
141
+ width: 100% !important;
142
+ justify-content: space-around;
143
+ }
144
+ #header-logo{
145
+ height: 50px;
146
+ }
147
+
89
148
  #wrapper {
90
149
  /* display: block!important; */
91
150
  min-height: 100%;
@@ -95,6 +154,8 @@
95
154
  #main {
96
155
  padding-bottom:100px;
97
156
  margin: 20px auto 0 auto;
157
+ width: 970px !important;
158
+ justify-content: start;
98
159
  }
99
160
 
100
161
  .row {
@@ -102,22 +163,6 @@
102
163
  margin-right: 0;
103
164
  }
104
165
 
105
- .b_frame {
106
- -webkit-box-shadow: 0px 19px 147px -41px rgba(0,0,0,0.75);
107
- -moz-box-shadow: 0px 19px 147px -41px rgba(0,0,0,0.75);
108
- box-shadow: 0px 19px 147px -41px rgba(0,0,0,0.75);
109
- border: 0;
110
- width: 400px;
111
- height: 530px;
112
- display: block;
113
- margin: 0 auto;
114
- margin-bottom: 40px;
115
- }
116
- .col-md-6 {
117
- margin-top: 30px;
118
- padding: 0;
119
- }
120
-
121
166
 
122
167
  .b_integrations_agent_links {
123
168
  margin-top: 50px;
@@ -159,7 +204,9 @@
159
204
  }
160
205
 
161
206
  .b-agent-demo_powered_by a {
162
- display: inline-block;
207
+ display: inline-flex;
208
+ align-items: center;
209
+ gap: 10px;
163
210
  margin-top: 30px;
164
211
  margin-bottom: 30px;
165
212
  text-decoration: none;
@@ -173,8 +220,7 @@
173
220
  }
174
221
  .b-agent-demo_powered_by img {
175
222
  display: inline-block;
176
- height: 24px;
177
- /* margin-left: 20px; */
223
+ height: 40px;
178
224
  }
179
225
 
180
226
 
@@ -230,7 +276,9 @@
230
276
 
231
277
  window.Tiledesk('onBeforeInit', function(event_data) {
232
278
  console.log("onBeforeInit Tiledesk FN", event_data);
233
-
279
+
280
+ var brandSrc = event_data.detail.appConfigs.brandSrc? getBrandResources(event_data.detail.appConfigs.brandSrc) : null;
281
+
234
282
  setTimeout(() => {
235
283
  if(event_data && event_data.detail && event_data.detail.appConfigs){
236
284
 
@@ -274,7 +322,6 @@
274
322
  }
275
323
 
276
324
 
277
-
278
325
  var currentUrl = window.location.href
279
326
  var baseUrl = window.location.origin
280
327
  function shareOnFacebook() {
@@ -337,6 +384,32 @@
337
384
  '_blank'
338
385
  );
339
386
  }
387
+
388
+ function getBrandResources(url) {
389
+ var xhr = new XMLHttpRequest();
390
+ xhr.onreadystatechange = function () {
391
+ if (xhr.readyState === 4) {
392
+ var brandJson = JSON.parse(xhr.response)
393
+ if(brandJson){
394
+ /** TITLE AND FAVICON **/
395
+ brandJson['WIDGET'].META_TITLE? document.body.title = brandJson['WIDGET'].META_TITLE : null;
396
+ brandJson['WIDGET'].FAVICON_URL? document.querySelector("link[rel~='icon']").setAttribute('href', brandJson['WIDGET'].FAVICON_URL) : null;
397
+ /** FOOTER-LOGO **/
398
+ brandJson['COMMON'].COMPANY_LOGO? document.getElementById('footer-logo').src = brandJson['COMMON'].COMPANY_LOGO : null;
399
+ brandJson['COMMON'].COMPANY_SITE_NAME? document.getElementById('footer-logo').alt = brandJson['COMMON'].COMPANY_SITE_NAME : null;
400
+ brandJson['COMMON'].COMPANY_SITE_URL? document.getElementById('footer-link').href = brandJson['COMMON'].COMPANY_SITE_URL : null;
401
+ /** HEADER-LOGO **/
402
+ brandJson['COMMON'].BASE_LOGO_WHITE? document.getElementById('header-logo').src = brandJson['COMMON'].BASE_LOGO_WHITE : null;
403
+ /** HEADER-DOCS RESOURCES **/
404
+ document.getElementsByClassName('docs')[0].style.display = 'none'
405
+ }
406
+
407
+ }
408
+ }
409
+ xhr.open('GET', url, true);
410
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
411
+ xhr.send();
412
+ }
340
413
 
341
414
  var url = new URL(currentUrl);
342
415
  var tiledesk_projectid = url.searchParams.get("tiledesk_projectid");
@@ -383,8 +456,12 @@
383
456
  </head>
384
457
 
385
458
  <body class="website white" >
386
- <div id="preloader">
459
+ <!-- <div id="preloader">
387
460
  <div class="logo"></div>
461
+ </div> -->
462
+
463
+ <div id="preloader">
464
+ <div class="loader"></div>
388
465
  </div>
389
466
 
390
467
  <div id="wrapper">
@@ -399,11 +476,11 @@
399
476
  <span class="icon-bar"></span>
400
477
  <span class="icon-bar"></span>
401
478
  </button>
402
- <a class="navbar-brand" href="https://console.tiledesk.com/"></a>
479
+ <img src="tiledesk_widget_files/logo.png" id="header-logo">
403
480
  </div>
404
481
 
405
482
  <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
406
- <ul class="nav navbar-nav">
483
+ <ul class="nav navbar-nav docs">
407
484
  <li><a href="https://developer.tiledesk.com/widget/web-sdk" target="_blank">WEB SDK &amp; Docs<span></span></a></li>
408
485
  <li><a href="https://www.tiledesk.com/pricing-cloud/" target="_blank">Pricing<span></span></a></li>
409
486
  <li><a href="https://www.tiledesk.com/blog/" target="_blank">Blog<span></span></a></li>
@@ -422,16 +499,12 @@
422
499
  </header>
423
500
 
424
501
  <div id="main" class="container">
425
- <div class="row">
426
- <div class="col-md-6">
427
- <h1 id="project_name" style="min-height: 39px;"></h1>
428
- <h2></h2>
429
- <div class="b_integrations_agent_links">
430
- <a href="" data-toggle="modal" data-target="#embedModal" id="enbed" style="display: none;"><em class="fa-code fa"></em>Embed</a>
431
- <a href="" data-toggle="modal" data-target="#shareModal"><em class="fa-reply fa"></em>Share</a>
432
- </div>
433
- </div>
434
- <div class="col-md-6">
502
+ <div class="row" style="width: 100%;">
503
+ <h1 id="project_name" style="min-height: 39px;"></h1>
504
+ <h2></h2>
505
+ <div class="b_integrations_agent_links">
506
+ <a href="" data-toggle="modal" data-target="#embedModal" id="enbed" style="display: none;"><em class="fa-code fa"></em>Embed</a>
507
+ <a href="" data-toggle="modal" data-target="#shareModal"><em class="fa-reply fa"></em>Share</a>
435
508
  </div>
436
509
  </div>
437
510
 
@@ -512,9 +585,9 @@
512
585
 
513
586
  <footer id="footer">
514
587
  <div class="b-agent-demo_powered_by">
515
- <a href="https://console.tiledesk.com/" target="_blank" style="cursor: pointer;text-decoration: none;">
588
+ <a href="https://tiledesk.com/" target="_blank" style="cursor: pointer;text-decoration: none;" id="footer-link">
516
589
  <span style="position: relative; top: 2px;">Powered by</span>
517
- <img src="./tiledesk_widget_files/logo@2x-black.png" alt="Tiledesk">
590
+ <img src="./tiledesk_widget_files/logo@2x-black.png" alt="Tiledesk" id="footer-logo">
518
591
  </a>
519
592
  </div>
520
593
  </footer>
@@ -20,6 +20,7 @@ export class ConversationModel {
20
20
  public color: string,
21
21
  public avatar: string,
22
22
  public archived: boolean,
23
- public type: string
23
+ public type: string,
24
+ public sound: boolean
24
25
  ) { }
25
26
  }
@@ -5,7 +5,6 @@ export class UploadModel {
5
5
  url: string;
6
6
  progress: number;
7
7
  createdAt: Date = new Date();
8
-
9
8
  constructor(file: File) {
10
9
  this.file = file;
11
10
  }
@@ -29,4 +29,7 @@ export abstract class UploadService {
29
29
  // functions
30
30
  abstract initialize(): void;
31
31
  abstract upload(userId: string, upload: UploadModel): Promise<any>;
32
+ abstract uploadProfile(userId: string, upload: UploadModel): Promise<any>;
33
+ abstract delete(userId: string, path: string): Promise<any>;
34
+ abstract deleteProfile(userId: string, path: string): Promise<any>
32
35
  }
@@ -131,8 +131,8 @@ export class FirebaseAuthService extends MessagingAuthService {
131
131
  break;
132
132
  }
133
133
  }
134
- return this.firebase.auth().setPersistence(firebasePersistence).then(async () => {
135
- return this.firebase.auth().signInWithCustomToken(token).then(async () => {
134
+ return that.firebase.auth().setPersistence(firebasePersistence).then(async () => {
135
+ return that.firebase.auth().signInWithCustomToken(token).then(async () => {
136
136
  // that.firebaseSignInWithCustomToken.next(response);
137
137
  }).catch((error) => {
138
138
  that.logger.error('[FIREBASEAuthSERVICE] signInFirebaseWithCustomToken Error: ', error);
@@ -181,7 +181,7 @@ export class FirebaseAuthService extends MessagingAuthService {
181
181
  */
182
182
  private signOut(): Promise<boolean> {
183
183
  const that = this;
184
- return new Promise((resolve, reject)=> {this.firebase.auth().signOut().then(() => {
184
+ return new Promise((resolve, reject)=> {that.firebase.auth().signOut().then(() => {
185
185
  that.logger.debug('[FIREBASEAuthSERVICE] firebase-sign-out');
186
186
  // cancello token
187
187
  // this.appStorage.removeItem('tiledeskToken');
@@ -447,7 +447,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
447
447
  if (msg.status < MSG_STATUS_RECEIVED ) { // && !msg.attributes.commands
448
448
  //get message uid from attributes.parentUid if msg is a splitted one, from msg.uid otherwize
449
449
  let uid = msg.uid
450
- msg.attributes.commands? uid = msg.attributes.parentUid: null
450
+ msg.attributes && msg.attributes.commands? uid = msg.attributes.parentUid: null
451
451
  if (msg.sender !== this.loggedUser.uid && msg.status < MSG_STATUS_RECEIVED) {
452
452
  const urlNodeMessagesUpdate = this.urlNodeFirebase + '/' + uid;
453
453
  this.logger.debug('[FIREBASEConversationHandlerSERVICE] update message status', urlNodeMessagesUpdate);
@@ -230,6 +230,7 @@ export class FirebaseConversationsHandler extends ConversationsHandlerService {
230
230
  archiveConversation(conversationId: string) {
231
231
  const that = this
232
232
  this.setClosingConversation(conversationId, true);
233
+ this.setConversationRead(conversationId)
233
234
  const index = searchIndexInArrayForUid(this.conversations, conversationId);
234
235
  // if (index > -1) {
235
236
  // this.conversations.splice(index, 1);
@@ -478,7 +479,7 @@ export class FirebaseConversationsHandler extends ConversationsHandlerService {
478
479
  private changed(childSnapshot: any) {
479
480
  const oldConversation = this.conversations[searchIndexInArrayForUid(this.conversations, childSnapshot.key)]
480
481
  //skip info message updates
481
- if(messageType(MESSAGE_TYPE_INFO, oldConversation) ){
482
+ if(messageType(MESSAGE_TYPE_INFO, childSnapshot.val()) ){
482
483
  return;
483
484
  }
484
485
  if (this.conversationGenerate(childSnapshot)) {
@@ -39,6 +39,14 @@ export class FirebaseUploadService extends UploadService {
39
39
  this.firebase = firebase
40
40
 
41
41
  }
42
+
43
+ private createGuid() {
44
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
45
+ // tslint:disable-next-line:no-bitwise
46
+ const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
47
+ return v.toString(16);
48
+ });
49
+ }
42
50
 
43
51
  public upload(userId: string, upload: UploadModel): Promise<any> {
44
52
  const that = this;
@@ -97,12 +105,126 @@ export class FirebaseUploadService extends UploadService {
97
105
 
98
106
  }
99
107
 
100
- private createGuid() {
101
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
102
- // tslint:disable-next-line:no-bitwise
103
- const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
104
- return v.toString(16);
105
- });
108
+ public uploadProfile(userId: string, upload: UploadModel): Promise<any> {
109
+ const that = this;
110
+ const urlImagesNodeFirebase = '/profiles/' + userId + '/photo.jpg'
111
+ this.logger.debug('[FIREBASEUploadSERVICE] uploadProfile ', urlImagesNodeFirebase, upload.file);
112
+
113
+ // Create a root reference
114
+ const storageRef = this.firebase.storage().ref();
115
+ this.logger.debug('[FIREBASEUploadSERVICE] storageRef', storageRef);
116
+
117
+ // Create a reference to 'mountains.jpg'
118
+ const mountainsRef = storageRef.child(urlImagesNodeFirebase);
119
+ this.logger.debug('[FIREBASEUploadSERVICE] mountainsRef ', mountainsRef);
120
+
121
+ // const metadata = {};
122
+ const metadata = { name: upload.file.name, contentType: upload.file.type, contentDisposition: 'attachment; filename=' + upload.file.name };
123
+
124
+ let uploadTask = mountainsRef.put(upload.file, metadata);
125
+
126
+ return new Promise((resolve, reject) => {
127
+ uploadTask.on('state_changed', function progress(snapshot) {
128
+ // Observe state change events such as progress, pause, and resume
129
+ // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
130
+ var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
131
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is ' + progress + '% done');
132
+
133
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
134
+ // BehaviorSubject publish the upload progress state - the subscriber is in ion-conversastion-detail.component.ts > listenToUploadFileProgress()
135
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
136
+
137
+ that.BSStateUpload.next({ upload: progress, type: upload.file.type });
138
+
139
+ switch (snapshot.state) {
140
+ case that.firebase.storage.TaskState.PAUSED: // or 'paused'
141
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is paused');
142
+
143
+ break;
144
+ case that.firebase.storage.TaskState.RUNNING: // or 'running'
145
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is running');
146
+
147
+ break;
148
+ }
149
+ }, function error(error) {
150
+ // Handle unsuccessful uploads
151
+ reject(error)
152
+ }, function complete() {
153
+ // Handle successful uploads on complete
154
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is complete', upload);
155
+
156
+ resolve(uploadTask.snapshot.ref.getDownloadURL())
157
+ // that.BSStateUpload.next({upload: upload});
158
+
159
+ });
160
+ })
161
+
162
+ }
163
+
164
+ public async delete(userId: string, path: string): Promise<any>{
165
+ const that = this;
166
+ const file_name_photo = 'photo.jpg';
167
+ const file_name_thumb_photo = 'thumb_photo.jpg';
168
+
169
+ that.logger.debug('[FIREBASEUploadSERVICE] delete image for USER', userId, path);
170
+
171
+ let uid = path.split(userId)[1].split('%2F')[1]; // get the UID of the image
172
+ let imageName = path.split(uid + '%2F')[1].split('?')[0];
173
+
174
+ // Create a root reference
175
+ const storageRef = this.firebase.storage().ref();
176
+ const ref = storageRef.child('public/images/' + userId + '/'+ uid + '/')
177
+ let arrayPromise = []
178
+ await ref.listAll().then((dir => {
179
+ dir.items.forEach(fileRef => arrayPromise.push(this.deleteFile(ref.fullPath, fileRef.name)));
180
+ })).catch(error => {
181
+ that.logger.error('[FIREBASEUploadSERVICE] delete: listAll error', error)
182
+ })
183
+
184
+ //AWAIT to return ALL the promise delete()
185
+ return new Promise((resolve, reject)=> {
186
+ Promise.all(arrayPromise).then(()=>{
187
+ resolve(true)
188
+ }).catch((error)=>{
189
+ reject(error)
190
+ })
191
+ })
192
+ }
193
+
194
+ public async deleteProfile(userId: string, path: string): Promise<any>{
195
+ const that = this;
196
+ const file_name_photo = 'photo.jpg';
197
+ const file_name_thumb_photo = 'thumb_photo.jpg';
198
+
199
+ that.logger.debug('[FIREBASEUploadSERVICE] delete image for USER', userId, path);
200
+
201
+ // Create a root reference
202
+ const storageRef = this.firebase.storage().ref();
203
+ const ref = storageRef.child('profiles/' + userId + '/')
204
+ let arrayPromise = []
205
+ await ref.listAll().then((dir => {
206
+ dir.items.forEach(fileRef => arrayPromise.push(this.deleteFile(ref.fullPath, fileRef.name)));
207
+ })).catch(error => {
208
+ that.logger.error('[FIREBASEUploadSERVICE] delete: listAll error', error)
209
+ })
210
+
211
+ //AWAIT to return ALL the promise delete()
212
+ return new Promise((resolve, reject)=> {
213
+ Promise.all(arrayPromise).then(()=>{
214
+ resolve(true)
215
+ }).catch((error)=>{
216
+ reject(error)
217
+ })
218
+ })
219
+ }
220
+
221
+ // // ------------------------------------
222
+ // // Delete the file photo
223
+ // // ------------------------------------
224
+ private deleteFile(pathToFile, fileName){
225
+ const ref = this.firebase.storage().ref(pathToFile);
226
+ const childRef = ref.child(fileName);
227
+ return childRef.delete()
106
228
  }
107
229
 
108
230
  }
@@ -263,7 +263,7 @@ z
263
263
  this.logger.debug('[MQTTAuthService] connectMQTT: **** credentials:', credentials);
264
264
  const userid = credentials.userid;
265
265
  this.chat21Service.chatClient.connect(userid, credentials.token, () => {
266
- this.logger.debug('[MQTTAuthService] connectMQTT: Chat connected.');
266
+ this.logger.debug('[MQTTAuthService] connectMQTT: Chat connected');
267
267
  this.BSAuthStateChanged.next('online');
268
268
  });
269
269
  }
@@ -444,7 +444,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
444
444
  if (msg['status'] < MSG_STATUS_RECEIVED && msg['status'] > 0) {
445
445
  this.logger.log('[MQTTConversationHandlerSERVICE] status ', msg['status'], ' < (RECEIVED:200)', MSG_STATUS_RECEIVED);
446
446
  let uid = msg.uid
447
- msg.attributes.commands? uid = msg.attributes.parentUid: null
447
+ msg.attributes && msg.attributes.commands? uid = msg.attributes.parentUid: null
448
448
  if (msg.sender !== this.loggedUser.uid && msg.status < MSG_STATUS_RECEIVED) {
449
449
  this.logger.log('[MQTTConversationHandlerSERVICE] updating message with status received');
450
450
  this.chat21Service.chatClient.updateMessageStatus(uid, this.conversationWith, MSG_STATUS_RECEIVED, null);
@@ -150,6 +150,7 @@ export class MQTTConversationsHandler extends ConversationsHandlerService {
150
150
  this.logger.debug('[MQTTConversationsHandler] connecting MQTT conversations handler');
151
151
  this.chat21Service.chatClient.onConversationAdded( (conv) => {
152
152
  let conversation = this.completeConversation(conv); // needed to get the "conversation_with", and find the conv in the conv-history
153
+ conversation.sound = true
153
154
  this.logger.log("[MQTTConversationsHandler] onConversationAdded completed:",conversation);
154
155
  const index = this.searchIndexInArrayForConversationWith(this.conversations, conversation.conversation_with);
155
156
  if (index > -1) {
@@ -162,6 +163,7 @@ export class MQTTConversationsHandler extends ConversationsHandlerService {
162
163
  }
163
164
  });
164
165
  this.chat21Service.chatClient.onConversationUpdated( (conv, topic) => {
166
+ conv.sound = true;
165
167
  this.logger.debug('[MQTTConversationsHandler] conversation updated:', JSON.stringify(conv));
166
168
  this.changed(conv);
167
169
  });
@@ -184,6 +186,7 @@ export class MQTTConversationsHandler extends ConversationsHandlerService {
184
186
  this.logger.debug('[MQTTConversationsHandler] Last conversations', conversations, 'err', err);
185
187
  if (!err) {
186
188
  conversations.forEach(conv => {
189
+ conv.sound = false;
187
190
  this.added(conv);
188
191
  });
189
192
  loaded();
@@ -331,6 +334,11 @@ export class MQTTConversationsHandler extends ConversationsHandlerService {
331
334
  // this.logger.debug('[MQTTConversationsHandler] aggiorno key:' + k);
332
335
  conv.type = snap[k];
333
336
  }
337
+ if (k === 'conversation_with_fullname') {
338
+ // this.logger.debug('[MQTTConversationsHandler] aggiorno key:' + k);
339
+ conv.conversation_with_fullname = snap[k];
340
+ }
341
+ conv = this.completeConversation(conv)
334
342
 
335
343
  });
336
344
  }
@@ -376,7 +384,8 @@ export class MQTTConversationsHandler extends ConversationsHandlerService {
376
384
  this.isConversationClosingMap.delete(conversationId);
377
385
  }
378
386
 
379
- archiveConversation(conversationId: string) {
387
+ archiveConversation(conversationId: string) {
388
+ this.setConversationRead(conversationId)
380
389
  this.chat21Service.chatClient.archiveConversation(conversationId);
381
390
  }
382
391
 
@@ -49,7 +49,7 @@ export class MQTTPresenceService extends PresenceService {
49
49
  const that = this;
50
50
  let local_BSIsOnline = new BehaviorSubject<any>(null);
51
51
  this.webSocketService.wsRequesterStatus$.subscribe((data: any) => {
52
- this.logger.log('[NATIVEPresenceSERVICE] $subs to wsService - data ', data, userid);
52
+ // this.logger.log('[NATIVEPresenceSERVICE] $subs to wsService - data ', data, userid);
53
53
  if (data && data.presence && data.presence.status === 'online' ) {
54
54
  that.BSIsOnline.next({ uid: data.uuid_user, isOnline: true });
55
55
  local_BSIsOnline.next({ uid: data.uuid_user, isOnline: true });
@@ -77,4 +77,72 @@ export class NativeUploadService extends UploadService {
77
77
  }
78
78
 
79
79
  }
80
+
81
+ uploadProfile(userId: string, upload: UploadModel): Promise<any> {
82
+ this.logger.log('[NATIVE UPLOAD] - upload new photo profile ... upload', upload)
83
+ const headers = new HttpHeaders({
84
+ Authorization: this.tiledeskToken,
85
+ // 'Content-Type': 'multipart/form-data',
86
+ });
87
+ const requestOptions = { headers: headers };
88
+ const formData = new FormData();
89
+ formData.append('file', upload.file);
90
+
91
+ // USE IMAGE API
92
+ const that = this;
93
+ const url = this.URL_TILEDESK_IMAGES + `/users/photo?force=true&user_id=${userId}`
94
+ return new Promise((resolve, reject) => {
95
+ that.http.put(url, formData, requestOptions).subscribe(data => {
96
+ const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['thumbnail'];
97
+ resolve(downloadURL)
98
+ // that.BSStateUpload.next({upload: upload});
99
+ }, (error) => {
100
+ reject(error)
101
+ });
102
+ });
103
+ }
104
+
105
+ delete(userId: string, path: string): Promise<any>{
106
+ this.logger.log('[NATIVE UPLOAD] - delete image ... upload', userId)
107
+ const headers = new HttpHeaders({
108
+ Authorization: this.tiledeskToken,
109
+ //'Content-Type': 'multipart/form-data',
110
+ });
111
+ const requestOptions = { headers: headers };
112
+
113
+ //USE IMAGE API
114
+ const that = this;
115
+ const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + path.split('path=')[1]
116
+ return new Promise((resolve, reject) => {
117
+ that.http.delete(url, requestOptions).subscribe(data => {
118
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
119
+ resolve(true)
120
+ // that.BSStateUpload.next({upload: upload});
121
+ }, (error) => {
122
+ reject(error)
123
+ });
124
+ });
125
+ }
126
+
127
+ deleteProfile(userId: string, path: string): Promise<any>{
128
+ this.logger.log('[NATIVE UPLOAD] - delete image ... upload', userId)
129
+ const headers = new HttpHeaders({
130
+ Authorization: this.tiledeskToken,
131
+ //'Content-Type': 'multipart/form-data',
132
+ });
133
+ const requestOptions = { headers: headers };
134
+
135
+ //USE IMAGE API
136
+ const that = this;
137
+ const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + "uploads/users/"+ userId + "/images/photo.jpg"
138
+ return new Promise((resolve, reject) => {
139
+ that.http.delete(url, requestOptions).subscribe(data => {
140
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
141
+ resolve(true)
142
+ // that.BSStateUpload.next({upload: upload});
143
+ }, (error) => {
144
+ reject(error)
145
+ });
146
+ });
147
+ }
80
148
  }
@@ -114,4 +114,18 @@ export const LogLevel = {
114
114
  'WARN' : 1,
115
115
  'INFO' : 2,
116
116
  'DEBUG' : 3
117
- }
117
+ }
118
+
119
+ export enum PLAN_NAME {
120
+ A = 'Growth',
121
+ B = 'Scale',
122
+ C = 'Plus',
123
+ }
124
+
125
+ export enum TYPE_BUTTON {
126
+ TEXT = 'text',
127
+ URL = 'url',
128
+ ACTION = 'action'
129
+ }
130
+
131
+ export const tranlatedLanguage = ['it', 'en', 'de', 'es', 'pt', 'fr', 'ru', 'tr', 'sr', 'ar', 'uk', 'sv', 'az', 'kk', 'uz']
@@ -1,6 +1,5 @@
1
1
  import { DepartmentModel } from './../../models/department';
2
2
  import { Injectable, ElementRef } from '@angular/core';
3
- import { Globals } from '../../app/utils/globals';
4
3
  import { ConversationModel } from '../models/conversation';
5
4
  import { LoggerInstance } from '../providers/logger/loggerInstance';
6
5
  import { LoggerService } from '../providers/abstract/logger.service';
@@ -10,6 +10,14 @@ import {
10
10
  TYPE_SUPPORT_GROUP
11
11
  } from './constants';
12
12
 
13
+ /** */
14
+ export function isCarousel(message: any) {
15
+ if (message && message.type && message.type === 'gallery' && message?.attributes && message?.attributes?.attachment && message?.attributes?.attachment?.gallery ) {
16
+ return true;
17
+ }
18
+ return false;
19
+ }
20
+
13
21
  /** */
14
22
  export function isImage(message: any) {
15
23
  if (message && message.type && message.type === 'image' && message.metadata && message.metadata.src) {