@chat21/chat21-web-widget 5.0.71-rc.1 → 5.0.71-rc.12

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 (48) hide show
  1. package/.github/workflows/build.yml +2 -2
  2. package/CHANGELOG.md +40 -0
  3. package/Dockerfile +1 -1
  4. package/package.json +1 -1
  5. package/src/app/app.component.ts +73 -94
  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 +4 -11
  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 +1 -1
  15. package/src/app/component/message/carousel/carousel.component.scss +1 -0
  16. package/src/app/component/message/carousel/carousel.component.ts +5 -4
  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/providers/translator.service.ts +2 -4
  20. package/src/app/sass/_variables.scss +1 -1
  21. package/src/app/utils/constants.ts +0 -3
  22. package/src/app/utils/globals.ts +4 -4
  23. package/src/app/utils/rules.ts +1 -1
  24. package/src/assets/i18n/en.json +5 -6
  25. package/src/assets/i18n/es.json +13 -10
  26. package/src/assets/i18n/fr.json +13 -10
  27. package/src/assets/i18n/it.json +13 -10
  28. package/src/assets/js/chat21client.js +5 -2
  29. package/src/assets/twp/chatbot-panel.html +205 -13
  30. package/src/assets/twp/index-dev.html +141 -33
  31. package/src/assets/twp/index.html +125 -39
  32. package/src/chat21-core/models/upload.ts +0 -1
  33. package/src/chat21-core/providers/abstract/upload.service.ts +3 -0
  34. package/src/chat21-core/providers/firebase/firebase-auth-service.ts +3 -3
  35. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +11 -20
  36. package/src/chat21-core/providers/firebase/firebase-conversations-handler.ts +2 -1
  37. package/src/chat21-core/providers/firebase/firebase-upload.service.ts +128 -6
  38. package/src/chat21-core/providers/mqtt/mqtt-auth-service.ts +1 -1
  39. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +11 -21
  40. package/src/chat21-core/providers/mqtt/mqtt-conversations-handler.ts +7 -1
  41. package/src/chat21-core/providers/native/native-upload-service.ts +68 -0
  42. package/src/chat21-core/utils/constants.ts +24 -8
  43. package/src/chat21-core/utils/triggerHandler.ts +0 -1
  44. package/src/chat21-core/utils/utils-message.ts +31 -1
  45. package/src/chat21-core/utils/utils.ts +0 -39
  46. package/src/launch.js +0 -1
  47. package/src/widget-config-template.json +2 -2
  48. package/src/widget-config.json +2 -1
@@ -14,11 +14,22 @@
14
14
  @-ms-keyframes blink {0%{opacity:1;} 50%{opacity:0;} 100%{opacity:1;}} /* IE */
15
15
  @keyframes blink {0%{opacity:1;} 50%{opacity:0;} 100%{opacity:1;}} /* Opera and prob css3 final iteration */
16
16
 
17
+ body{
18
+ --font-family-poppins: 'Poppins', 'Roboto', Arial, sans-serif;
19
+ --blu: #506493;
20
+ --gray-light-02: rgb(223, 227, 237);
21
+ --base-company-logo: rgb(224,106,88);
22
+ --header-height: 80px;
23
+ --footer-height: 80px;
24
+ }
25
+
17
26
  #preloader {
18
27
  background: #fff;
19
- position: fixed;
28
+ position: absolute;
20
29
  top: 0;
21
30
  left: 0;
31
+ bottom: 0;
32
+ right: 0;
22
33
  height: 100%;
23
34
  width: 100%;
24
35
  z-index: 999999;
@@ -51,6 +62,52 @@
51
62
  animation:blink normal 2s infinite ease-in-out; /* Opera and prob css3 final iteration */
52
63
  }
53
64
 
65
+ .loader{
66
+ display: block;
67
+ z-index: 99;
68
+ position: absolute;
69
+ top: calc( 50% - 50px);
70
+ left: calc( 50% - 50px);
71
+ width: 100px;
72
+ height: 100px;
73
+ border: 3px solid var(--base-company-logo);
74
+ border-radius: 50%;
75
+
76
+ animation: spin 7s ease-in-out;
77
+ animation-iteration-count: infinite;
78
+ transition-duration: 0.1s;
79
+ }
80
+
81
+ .loader:hover {
82
+ scale: 0.95;
83
+ /*Loader on hover effect*/
84
+ }
85
+
86
+ .loader:active {
87
+ scale: 1.2;
88
+ /*Loader on click effect*/
89
+ }
90
+
91
+ @keyframes spin {
92
+ 0% {
93
+ transform: rotate(0deg);
94
+ border-bottom: solid 3px transparent;
95
+ border-top: solid 3px transparent;
96
+ }
97
+ 50% {
98
+ transform: rotate(1800deg);
99
+ border: 3px solid white;
100
+ border-left: solid 3px transparent;
101
+ border-right: solid 3px transparent;
102
+ }
103
+ 100% {
104
+ /*Reversed spinning*/
105
+ transform: rotate(0deg);
106
+ border-bottom: solid 3px transparent;
107
+ border-top: solid 3px transparent;
108
+ }
109
+ }
110
+
54
111
  #deferred-styles {
55
112
  display: none;
56
113
  }
@@ -86,6 +143,17 @@
86
143
  height: 100%;
87
144
  }
88
145
 
146
+
147
+ .container{
148
+ display: flex;
149
+ align-items: center;
150
+ width: 100% !important;
151
+ justify-content: space-around;
152
+ }
153
+ #header-logo{
154
+ max-height: 45px;
155
+ }
156
+
89
157
  #wrapper {
90
158
  /* display: block!important; */
91
159
  min-height: 100%;
@@ -95,27 +163,17 @@
95
163
  #main {
96
164
  padding-bottom:100px;
97
165
  margin: 20px auto 0 auto;
166
+ /* width: 970px !important; */
167
+ justify-content: start;
98
168
  }
99
169
 
100
- .row {
101
- margin-left: 0;
102
- margin-right: 0;
170
+ .navbar{
171
+ display: flex;
103
172
  }
104
173
 
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;
174
+ .row {
175
+ margin-left: 0 !important;
176
+ margin-right: 0 !important;
119
177
  }
120
178
 
121
179
 
@@ -150,7 +208,7 @@
150
208
 
151
209
  /* position: relative;
152
210
  margin-top: -100px; negative value of footer height */
153
- height: 80px;
211
+ height: var(--footer-height);
154
212
  clear:both;
155
213
 
156
214
  position: absolute;
@@ -159,7 +217,9 @@
159
217
  }
160
218
 
161
219
  .b-agent-demo_powered_by a {
162
- display: inline-block;
220
+ display: inline-flex;
221
+ align-items: center;
222
+ gap: 10px;
163
223
  margin-top: 30px;
164
224
  margin-bottom: 30px;
165
225
  text-decoration: none;
@@ -173,8 +233,7 @@
173
233
  }
174
234
  .b-agent-demo_powered_by img {
175
235
  display: inline-block;
176
- height: 24px;
177
- /* margin-left: 20px; */
236
+ height: 40px;
178
237
  }
179
238
 
180
239
 
@@ -230,7 +289,9 @@
230
289
 
231
290
  window.Tiledesk('onBeforeInit', function(event_data) {
232
291
  console.log("onBeforeInit Tiledesk FN", event_data);
233
-
292
+
293
+ var brandSrc = event_data.detail.appConfigs.brandSrc? getBrandResources(event_data.detail.appConfigs.brandSrc) : null;
294
+
234
295
  setTimeout(() => {
235
296
  if(event_data && event_data.detail && event_data.detail.appConfigs){
236
297
 
@@ -274,7 +335,6 @@
274
335
  }
275
336
 
276
337
 
277
-
278
338
  var currentUrl = window.location.href
279
339
  var baseUrl = window.location.origin
280
340
  function shareOnFacebook() {
@@ -337,6 +397,32 @@
337
397
  '_blank'
338
398
  );
339
399
  }
400
+
401
+ function getBrandResources(url) {
402
+ var xhr = new XMLHttpRequest();
403
+ xhr.onreadystatechange = function () {
404
+ if (xhr.readyState === 4) {
405
+ var brandJson = JSON.parse(xhr.response)
406
+ if(brandJson){
407
+ /** TITLE AND FAVICON **/
408
+ brandJson['WIDGET'].META_TITLE? document.body.title = brandJson['WIDGET'].META_TITLE : null;
409
+ brandJson['WIDGET'].FAVICON_URL? document.querySelector("link[rel~='icon']").setAttribute('href', brandJson['WIDGET'].FAVICON_URL) : null;
410
+ /** FOOTER-LOGO **/
411
+ brandJson['COMMON'].COMPANY_LOGO? document.getElementById('footer-logo').src = brandJson['COMMON'].COMPANY_LOGO : null;
412
+ brandJson['COMMON'].COMPANY_SITE_NAME? document.getElementById('footer-logo').alt = brandJson['COMMON'].COMPANY_SITE_NAME : null;
413
+ brandJson['COMMON'].COMPANY_SITE_URL? document.getElementById('footer-link').href = brandJson['COMMON'].COMPANY_SITE_URL : null;
414
+ /** HEADER-LOGO **/
415
+ brandJson['COMMON'].BASE_LOGO_WHITE? document.getElementById('header-logo').src = brandJson['COMMON'].BASE_LOGO_WHITE : null;
416
+ /** HEADER-DOCS RESOURCES **/
417
+ document.getElementsByClassName('docs')[0].style.display = 'none'
418
+ }
419
+
420
+ }
421
+ }
422
+ xhr.open('GET', url, true);
423
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
424
+ xhr.send();
425
+ }
340
426
 
341
427
  var url = new URL(currentUrl);
342
428
  var tiledesk_projectid = url.searchParams.get("tiledesk_projectid");
@@ -383,8 +469,12 @@
383
469
  </head>
384
470
 
385
471
  <body class="website white" >
386
- <div id="preloader">
472
+ <!-- <div id="preloader">
387
473
  <div class="logo"></div>
474
+ </div> -->
475
+
476
+ <div id="preloader">
477
+ <div class="loader"></div>
388
478
  </div>
389
479
 
390
480
  <div id="wrapper">
@@ -399,11 +489,11 @@
399
489
  <span class="icon-bar"></span>
400
490
  <span class="icon-bar"></span>
401
491
  </button>
402
- <a class="navbar-brand" href="https://console.tiledesk.com/"></a>
492
+ <img src="tiledesk_widget_files/logo.png" id="header-logo">
403
493
  </div>
404
494
 
405
495
  <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
406
- <ul class="nav navbar-nav">
496
+ <ul class="nav navbar-nav docs">
407
497
  <li><a href="https://developer.tiledesk.com/widget/web-sdk" target="_blank">WEB SDK &amp; Docs<span></span></a></li>
408
498
  <li><a href="https://www.tiledesk.com/pricing-cloud/" target="_blank">Pricing<span></span></a></li>
409
499
  <li><a href="https://www.tiledesk.com/blog/" target="_blank">Blog<span></span></a></li>
@@ -422,16 +512,12 @@
422
512
  </header>
423
513
 
424
514
  <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">
515
+ <div class="row" style="width: 100%;">
516
+ <h1 id="project_name" style="min-height: 39px;"></h1>
517
+ <h2></h2>
518
+ <div class="b_integrations_agent_links">
519
+ <a href="" data-toggle="modal" data-target="#embedModal" id="enbed" style="display: none;"><em class="fa-code fa"></em>Embed</a>
520
+ <a href="" data-toggle="modal" data-target="#shareModal"><em class="fa-reply fa"></em>Share</a>
435
521
  </div>
436
522
  </div>
437
523
 
@@ -512,9 +598,9 @@
512
598
 
513
599
  <footer id="footer">
514
600
  <div class="b-agent-demo_powered_by">
515
- <a href="https://console.tiledesk.com/" target="_blank" style="cursor: pointer;text-decoration: none;">
601
+ <a href="https://tiledesk.com/" target="_blank" style="cursor: pointer;text-decoration: none;" id="footer-link">
516
602
  <span style="position: relative; top: 2px;">Powered by</span>
517
- <img src="./tiledesk_widget_files/logo@2x-black.png" alt="Tiledesk">
603
+ <img src="./tiledesk_widget_files/logo@2x-black.png" alt="Tiledesk" id="footer-logo">
518
604
  </a>
519
605
  </div>
520
606
  </footer>
@@ -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');
@@ -1,5 +1,3 @@
1
- import { LIVE_PAGE, MEMBER_LEFT_GROUP, TOUCHING_OPERATOR } from './../../utils/constants';
2
-
3
1
  import { Inject, Injectable } from '@angular/core';
4
2
  import { BehaviorSubject } from 'rxjs';
5
3
 
@@ -17,14 +15,10 @@ import { LoggerService } from '../abstract/logger.service';
17
15
  import { LoggerInstance } from '../logger/loggerInstance';
18
16
 
19
17
  // utils
20
- import { MSG_STATUS_RECEIVED, CHAT_REOPENED, CHAT_CLOSED, MEMBER_JOINED_GROUP, TYPE_DIRECT, MESSAGE_TYPE_INFO, LEAD_UPDATED } from '../../utils/constants';
21
- import {
22
- compareValues,
23
- searchIndexInArrayForUid,
24
- conversationMessagesRef
25
- } from '../../utils/utils';
18
+ import { MSG_STATUS_RECEIVED, TYPE_DIRECT, MESSAGE_TYPE_INFO, INFO_MESSAGE_TYPE } from '../../utils/constants';
19
+ import { compareValues, searchIndexInArrayForUid, conversationMessagesRef } from '../../utils/utils';
26
20
  import { v4 as uuidv4 } from 'uuid';
27
- import { messageType, checkIfIsMemberJoinedGroup, hideInfoMessage, isJustRecived, isSender } from '../../utils/utils-message';
21
+ import { messageType, checkIfIsMemberJoinedGroup, hideInfoMessage, isJustRecived, isSender, infoMessageType } from '../../utils/utils-message';
28
22
 
29
23
  // @Injectable({ providedIn: 'root' })
30
24
  @Injectable()
@@ -377,10 +371,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
377
371
  const INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU = this.translationMap.get('INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU');
378
372
  const INFO_SUPPORT_LIVE_PAGE = this.translationMap.get('INFO_SUPPORT_LIVE_PAGE');
379
373
 
380
- if (message.attributes.messagelabel
381
- && message.attributes.messagelabel.parameters
382
- && message.attributes.messagelabel.key === MEMBER_JOINED_GROUP
383
- ) {
374
+ if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_JOINED_GROUP && message.attributes.messagelabel.parameters) {
384
375
  let subject: string;
385
376
  let verb: string;
386
377
  let complement: string;
@@ -403,18 +394,18 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
403
394
  }
404
395
  }
405
396
  message.text = subject + ' ' + verb + ' ' + complement;
406
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === CHAT_REOPENED)) {
397
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.CHAT_REOPENED ) {
407
398
  message.text = INFO_SUPPORT_CHAT_REOPENED;
408
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === CHAT_CLOSED)) {
399
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.CHAT_CLOSED ) {
409
400
  message.text = INFO_SUPPORT_CHAT_CLOSED;
410
- } else if ((message.attributes && message.attributes.messagelabel && message.attributes.messagelabel.key === TOUCHING_OPERATOR) && message.sender === "system") {
401
+ } else if ((infoMessageType(message) === INFO_MESSAGE_TYPE.TOUCHING_OPERATOR) && message.sender === "system") {
411
402
  const textAfterColon = message.text.split(":")[1]
412
403
  if (textAfterColon !== undefined) {
413
404
  message.text = INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU + ': ' + textAfterColon;
414
405
  }
415
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === LEAD_UPDATED)) {
406
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.LEAD_UPDATED) {
416
407
  message.text = INFO_SUPPORT_LEAD_UPDATED;
417
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === MEMBER_LEFT_GROUP)) {
408
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_LEFT_GROUP) {
418
409
  let subject: string = '';
419
410
  if (message.attributes.messagelabel.parameters.fullname) {
420
411
  subject = message.attributes.messagelabel.parameters.fullname;
@@ -422,7 +413,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
422
413
  subject = message.attributes.messagelabel.parameters.member_id;
423
414
  }
424
415
  message.text = subject + ' ' + INFO_SUPPORT_MEMBER_LEFT_GROUP ;
425
- } else if(message.attributes.messagelabel && message.attributes.messagelabel.key === LIVE_PAGE){
416
+ } else if(infoMessageType(message) === INFO_MESSAGE_TYPE.LIVE_PAGE){
426
417
  let sourceUrl: string = '';
427
418
  if(message.attributes && message.attributes.sourcePage){
428
419
  sourceUrl = message.attributes.sourcePage
@@ -447,7 +438,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
447
438
  if (msg.status < MSG_STATUS_RECEIVED ) { // && !msg.attributes.commands
448
439
  //get message uid from attributes.parentUid if msg is a splitted one, from msg.uid otherwize
449
440
  let uid = msg.uid
450
- msg.attributes.commands? uid = msg.attributes.parentUid: null
441
+ msg.attributes && msg.attributes.commands? uid = msg.attributes.parentUid: null
451
442
  if (msg.sender !== this.loggedUser.uid && msg.status < MSG_STATUS_RECEIVED) {
452
443
  const urlNodeMessagesUpdate = this.urlNodeFirebase + '/' + uid;
453
444
  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
  }
@@ -1,5 +1,3 @@
1
- import { async } from '@angular/core/testing';
2
- import { LIVE_PAGE, TOUCHING_OPERATOR } from './../../utils/constants';
3
1
  import { Inject, Injectable } from '@angular/core';
4
2
  import { BehaviorSubject } from 'rxjs';
5
3
 
@@ -17,15 +15,10 @@ import { UserModel } from '../../models/user';
17
15
  import { ConversationHandlerService } from '../abstract/conversation-handler.service';
18
16
 
19
17
  // utils
20
- import { MSG_STATUS_RECEIVED, CHAT_REOPENED, CHAT_CLOSED, MEMBER_JOINED_GROUP, TYPE_DIRECT, MESSAGE_TYPE_INFO, LEAD_UPDATED, MEMBER_LEFT_GROUP } from '../../utils/constants';
21
- import {
22
- htmlEntities,
23
- compareValues,
24
- searchIndexInArrayForUid,
25
- conversationMessagesRef
26
- } from '../../utils/utils';
18
+ import { MSG_STATUS_RECEIVED, TYPE_DIRECT, MESSAGE_TYPE_INFO, INFO_MESSAGE_TYPE } from '../../utils/constants';
19
+ import { compareValues, searchIndexInArrayForUid } from '../../utils/utils';
20
+ import { messageType, checkIfIsMemberJoinedGroup, hideInfoMessage, isJustRecived, isSender, infoMessageType } from '../../utils/utils-message';
27
21
  import { v4 as uuidv4 } from 'uuid';
28
- import { messageType, checkIfIsMemberJoinedGroup, hideInfoMessage, isJustRecived, isSender } from '../../utils/utils-message';
29
22
 
30
23
 
31
24
  // @Injectable({ providedIn: 'root' })
@@ -373,10 +366,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
373
366
  const INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU = this.translationMap.get('INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU');
374
367
  const INFO_SUPPORT_LIVE_PAGE = this.translationMap.get('INFO_SUPPORT_LIVE_PAGE');
375
368
 
376
- if (message.attributes.messagelabel
377
- && message.attributes.messagelabel.parameters
378
- && message.attributes.messagelabel.key === MEMBER_JOINED_GROUP
379
- ) {
369
+ if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_JOINED_GROUP && message.attributes.messagelabel.parameters ) {
380
370
  let subject: string;
381
371
  let verb: string;
382
372
  let complement: string;
@@ -398,20 +388,20 @@ export class MQTTConversationHandler extends ConversationHandlerService {
398
388
  }
399
389
  }
400
390
  message.text = subject + ' ' + verb + ' ' + complement;
401
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === CHAT_REOPENED)) {
391
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.CHAT_REOPENED) {
402
392
  message.text = INFO_SUPPORT_CHAT_REOPENED;
403
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === CHAT_CLOSED)) {
393
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.CHAT_CLOSED) {
404
394
  message.text = INFO_SUPPORT_CHAT_CLOSED;
405
- } else if ((message.attributes && message.attributes.messagelabel && message.attributes.messagelabel.key === TOUCHING_OPERATOR) && message.sender === "system") {
395
+ } else if ((infoMessageType(message) ===INFO_MESSAGE_TYPE.TOUCHING_OPERATOR) && message.sender === "system") {
406
396
  // console.log('FIREBASEConversationHandlerSERVICE message text', message.text)
407
397
  const textAfterColon = message.text.split(":")[1]
408
398
  // console.log('FIREBASEConversationHandlerSERVICE message text - textAfterColon', textAfterColon)
409
399
  if (textAfterColon !== undefined) {
410
400
  message.text = INFO_A_NEW_SUPPORT_REQUEST_HAS_BEEN_ASSIGNED_TO_YOU + ': ' + textAfterColon;
411
401
  }
412
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === LEAD_UPDATED)) {
402
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.LEAD_UPDATED) {
413
403
  message.text = INFO_SUPPORT_LEAD_UPDATED;
414
- } else if ((message.attributes.messagelabel && message.attributes.messagelabel.key === MEMBER_LEFT_GROUP)) {
404
+ } else if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_LEFT_GROUP) {
415
405
  let subject: string;
416
406
  if (message.attributes.messagelabel.parameters.fullname) {
417
407
  subject = message.attributes.messagelabel.parameters.fullname;
@@ -419,7 +409,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
419
409
  subject = message.attributes.messagelabel.parameters.member_id;
420
410
  }
421
411
  message.text = subject + ' ' + INFO_SUPPORT_MEMBER_LEFT_GROUP ;
422
- } else if(message.attributes.messagelabel && message.attributes.messagelabel.key === LIVE_PAGE){
412
+ } else if(infoMessageType(message) === INFO_MESSAGE_TYPE.LIVE_PAGE){
423
413
  let sourceUrl: string = '';
424
414
  if(message.attributes && message.attributes.sourcePage){
425
415
  sourceUrl = message.attributes.sourcePage
@@ -444,7 +434,7 @@ export class MQTTConversationHandler extends ConversationHandlerService {
444
434
  if (msg['status'] < MSG_STATUS_RECEIVED && msg['status'] > 0) {
445
435
  this.logger.log('[MQTTConversationHandlerSERVICE] status ', msg['status'], ' < (RECEIVED:200)', MSG_STATUS_RECEIVED);
446
436
  let uid = msg.uid
447
- msg.attributes.commands? uid = msg.attributes.parentUid: null
437
+ msg.attributes && msg.attributes.commands? uid = msg.attributes.parentUid: null
448
438
  if (msg.sender !== this.loggedUser.uid && msg.status < MSG_STATUS_RECEIVED) {
449
439
  this.logger.log('[MQTTConversationHandlerSERVICE] updating message with status received');
450
440
  this.chat21Service.chatClient.updateMessageStatus(uid, this.conversationWith, MSG_STATUS_RECEIVED, null);