@chat21/chat21-web-widget 5.1.18 → 5.1.20-rc2

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 (40) hide show
  1. package/.github/workflows/docker-community-push-latest.yml +23 -13
  2. package/.github/workflows/docker-image-tag-community-tag-push.yml +22 -12
  3. package/CHANGELOG.md +68 -2
  4. package/Dockerfile +4 -5
  5. package/angular.json +2 -1
  6. package/deploy_amazon_beta.sh +17 -7
  7. package/deploy_amazon_prod.sh +4 -4
  8. package/package.json +1 -1
  9. package/src/app/app.component.html +8 -1
  10. package/src/app/app.component.scss +60 -4
  11. package/src/app/app.component.ts +63 -28
  12. package/src/app/component/conversation-detail/conversation/conversation.component.ts +84 -10
  13. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.ts +4 -0
  14. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +27 -1
  15. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +6 -6
  16. package/src/app/component/home-conversations/home-conversations.component.html +16 -6
  17. package/src/app/component/home-conversations/home-conversations.component.ts +29 -0
  18. package/src/app/component/launcher-button/launcher-button.component.html +1 -1
  19. package/src/app/component/launcher-button/launcher-button.component.ts +3 -2
  20. package/src/app/component/list-conversations/list-conversations.component.html +8 -3
  21. package/src/app/component/list-conversations/list-conversations.component.ts +29 -0
  22. package/src/app/component/message/html/html.component.html +5 -1
  23. package/src/app/component/message/html/html.component.scss +9 -0
  24. package/src/app/component/message/text/text.component.scss +4 -0
  25. package/src/app/pipe/marked.pipe.ts +31 -4
  26. package/src/app/providers/translator.service.ts +2 -0
  27. package/src/app/sass/normalize.scss +1 -0
  28. package/src/app/utils/globals.ts +1 -1
  29. package/src/assets/i18n/en.json +1 -0
  30. package/src/assets/i18n/es.json +1 -0
  31. package/src/assets/i18n/fr.json +1 -0
  32. package/src/assets/i18n/it.json +1 -0
  33. package/src/chat21-core/providers/abstract/upload.service.ts +5 -1
  34. package/src/chat21-core/providers/firebase/firebase-upload.service.ts +141 -12
  35. package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
  36. package/src/chat21-core/providers/native/native-upload-service.ts +143 -46
  37. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  38. package/src/chat21-core/utils/utils.ts +5 -2
  39. package/src/iframe-style.css +36 -12
  40. package/.vscode/settings.json +0 -3
@@ -31,7 +31,7 @@ export class FirebaseUploadService extends UploadService {
31
31
  super();
32
32
  }
33
33
 
34
- public async initialize() {
34
+ public async initialize(projectId: string) {
35
35
  this.logger.debug('[FIREBASEUploadSERVICE] initialize');
36
36
 
37
37
  const { default: firebase} = await import("firebase/app");
@@ -96,14 +96,115 @@ export class FirebaseUploadService extends UploadService {
96
96
  }, async function complete() {
97
97
  // Handle successful uploads on complete
98
98
  that.logger.debug('[FIREBASEUploadSERVICE] Upload is complete', upload);
99
-
99
+
100
+ const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
101
+ resolve({downloadURL: downloadURL, src: downloadURL})
102
+ // that.BSStateUpload.next({upload: upload});
103
+
104
+ });
105
+ })
106
+
107
+ }
108
+
109
+ public uploadFile(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: any}> {
110
+ const that = this;
111
+ const uid = this.createGuid();
112
+ const urlImagesNodeFirebase = '/public/images/' + userId + '/' + uid + '/' + upload.file.name;
113
+ this.logger.debug('[FIREBASEUploadSERVICE] pushUpload ', urlImagesNodeFirebase, upload.file);
114
+
115
+ // Create a root reference
116
+ const storageRef = this.firebase.storage().ref();
117
+ this.logger.debug('[FIREBASEUploadSERVICE] storageRef', storageRef);
118
+
119
+ // Create a reference to 'mountains.jpg'
120
+ const mountainsRef = storageRef.child(urlImagesNodeFirebase);
121
+ this.logger.debug('[FIREBASEUploadSERVICE] mountainsRef ', mountainsRef);
122
+
123
+ // const metadata = {};
124
+ const metadata = { name: upload.file.name, contentType: upload.file.type, contentDisposition: 'attachment; filename=' + upload.file.name };
125
+
126
+ let uploadTask = mountainsRef.put(upload.file, metadata);
127
+
128
+ return new Promise((resolve, reject) => {
129
+ uploadTask.on('state_changed', function progress(snapshot) {
130
+ // Observe state change events such as progress, pause, and resume
131
+ // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
132
+ var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
133
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is ' + progress + '% done');
134
+
135
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
136
+ // BehaviorSubject publish the upload progress state - the subscriber is in ion-conversastion-detail.component.ts > listenToUploadFileProgress()
137
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
138
+
139
+ that.BSStateUpload.next({ upload: progress, type: upload.file.type });
140
+
141
+ switch (snapshot.state) {
142
+ case that.firebase.storage.TaskState.PAUSED: // or 'paused'
143
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is paused');
144
+
145
+ break;
146
+ case that.firebase.storage.TaskState.RUNNING: // or 'running'
147
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is running');
148
+
149
+ break;
150
+ }
151
+ }, function error(error) {
152
+ // Handle unsuccessful uploads
153
+ reject(error)
154
+ }, async function complete() {
155
+ // Handle successful uploads on complete
156
+ that.logger.debug('[FIREBASEUploadSERVICE] Upload is complete', upload);
157
+
100
158
  const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
101
- resolve({downloadURL : downloadURL, src: downloadURL})
159
+ resolve({downloadURL: downloadURL, src: downloadURL})
102
160
  // that.BSStateUpload.next({upload: upload});
103
161
 
104
162
  });
105
163
  })
164
+ }
165
+
166
+ public uploadAsset(userId: string, upload: UploadModel, expiration: number = 60): Promise<{downloadURL: string, src: any}> {
167
+ // expiration is ignored on Firebase, but kept for API compatibility with NativeUploadService
168
+ const that = this;
169
+ const uid = this.createGuid();
170
+ const urlAssetsNodeFirebase = '/public/assets/' + userId + '/' + uid + '/' + upload.file.name;
171
+ this.logger.debug('[FIREBASEUploadSERVICE] uploadAsset ', urlAssetsNodeFirebase, upload.file, 'expiration:', expiration);
106
172
 
173
+ // Create a root reference
174
+ const storageRef = this.firebase.storage().ref();
175
+ this.logger.debug('[FIREBASEUploadSERVICE] storageRef', storageRef);
176
+
177
+ const assetRef = storageRef.child(urlAssetsNodeFirebase);
178
+ this.logger.debug('[FIREBASEUploadSERVICE] assetRef ', assetRef);
179
+
180
+ const metadata = { name: upload.file.name, contentType: upload.file.type, contentDisposition: 'attachment; filename=' + upload.file.name };
181
+
182
+ let uploadTask = assetRef.put(upload.file, metadata);
183
+
184
+ return new Promise((resolve, reject) => {
185
+ uploadTask.on('state_changed', function progress(snapshot) {
186
+ var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
187
+ that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is ' + progress + '% done');
188
+
189
+ that.BSStateUpload.next({ upload: progress, type: upload.file.type });
190
+
191
+ switch (snapshot.state) {
192
+ case that.firebase.storage.TaskState.PAUSED:
193
+ that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is paused');
194
+ break;
195
+ case that.firebase.storage.TaskState.RUNNING:
196
+ that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is running');
197
+ break;
198
+ }
199
+ }, function error(error) {
200
+ reject(error)
201
+ }, async function complete() {
202
+ that.logger.debug('[FIREBASEUploadSERVICE] uploadAsset is complete', upload);
203
+
204
+ const downloadURL = await uploadTask.snapshot.ref.getDownloadURL();
205
+ resolve({downloadURL: downloadURL, src: downloadURL})
206
+ });
207
+ })
107
208
  }
108
209
 
109
210
  public uploadProfile(userId: string, upload: UploadModel): Promise<any> {
@@ -154,7 +255,9 @@ export class FirebaseUploadService extends UploadService {
154
255
  // Handle successful uploads on complete
155
256
  that.logger.debug('[FIREBASEUploadSERVICE] Upload is complete', upload);
156
257
 
157
- resolve(uploadTask.snapshot.ref.getDownloadURL())
258
+ const downloadURL = uploadTask.snapshot.ref.getDownloadURL();
259
+ resolve({downloadURL : downloadURL, url: downloadURL})
260
+
158
261
  // that.BSStateUpload.next({upload: upload});
159
262
 
160
263
  });
@@ -192,6 +295,40 @@ export class FirebaseUploadService extends UploadService {
192
295
  })
193
296
  }
194
297
 
298
+ public async deleteFile(userId: string, path: string): Promise<any>{
299
+ const that = this;
300
+ const file_name_photo = 'photo.jpg';
301
+ const file_name_thumb_photo = 'thumb_photo.jpg';
302
+
303
+ that.logger.debug('[FIREBASEUploadSERVICE] delete image for USER', userId, path);
304
+
305
+ let uid = path.split(userId)[1].split('%2F')[1]; // get the UID of the image
306
+ let imageName = path.split(uid + '%2F')[1].split('?')[0];
307
+
308
+ // Create a root reference
309
+ const storageRef = this.firebase.storage().ref();
310
+ const ref = storageRef.child('public/images/' + userId + '/'+ uid + '/')
311
+ let arrayPromise = []
312
+ await ref.listAll().then((dir => {
313
+ dir.items.forEach(fileRef => arrayPromise.push(this.deleteFile(ref.fullPath, fileRef.name)));
314
+ })).catch(error => {
315
+ that.logger.error('[FIREBASEUploadSERVICE] delete: listAll error', error)
316
+ })
317
+
318
+ //AWAIT to return ALL the promise delete()
319
+ return new Promise((resolve, reject)=> {
320
+ Promise.all(arrayPromise).then(()=>{
321
+ resolve(true)
322
+ }).catch((error)=>{
323
+ reject(error)
324
+ })
325
+ })
326
+ }
327
+
328
+ public async deleteAsset(userId: string, path: string): Promise<any>{
329
+ return this.deleteProfile(userId, path);
330
+ }
331
+
195
332
  public async deleteProfile(userId: string, path: string): Promise<any>{
196
333
  const that = this;
197
334
  const file_name_photo = 'photo.jpg';
@@ -219,13 +356,5 @@ export class FirebaseUploadService extends UploadService {
219
356
  })
220
357
  }
221
358
 
222
- // // ------------------------------------
223
- // // Delete the file photo
224
- // // ------------------------------------
225
- private deleteFile(pathToFile, fileName){
226
- const ref = this.firebase.storage().ref(pathToFile);
227
- const childRef = ref.child(fileName);
228
- return childRef.delete()
229
- }
230
359
 
231
360
  }
@@ -16,7 +16,7 @@ export class NativeImageRepoService extends ImageRepoService {
16
16
  * @param uid
17
17
  */
18
18
  getImagePhotoUrl(uid: string): string {
19
- this.baseImageURL = this.getImageBaseUrl() + 'images'
19
+ this.baseImageURL = this.getImageBaseUrl() + 'files'
20
20
  let sender_id = '';
21
21
  if (uid.includes('bot_')) {
22
22
  sender_id = uid.slice(4)
@@ -1,7 +1,7 @@
1
1
  import { UploadService } from '../abstract/upload.service';
2
2
  import { HttpClient, HttpHeaders } from '@angular/common/http';
3
3
  import { Injectable } from '@angular/core';
4
- import { BehaviorSubject } from 'rxjs';
4
+ import { BehaviorSubject, first } from 'rxjs';
5
5
  import { UploadModel } from '../../models/upload';
6
6
  import { AppStorageService } from '../abstract/app-storage.service';
7
7
  import { LoggerService } from '../abstract/logger.service';
@@ -14,8 +14,8 @@ export class NativeUploadService extends UploadService {
14
14
  BSStateUpload: BehaviorSubject<any> = new BehaviorSubject<any>(null)
15
15
 
16
16
  private tiledeskToken: string;
17
- private URL_TILEDESK_IMAGES: string;
18
17
  private URL_TILEDESK_FILE: string;
18
+ private URL_TILEDESK_UPLOAD: string;
19
19
  private logger: LoggerService = LoggerInstance.getInstance()
20
20
 
21
21
  constructor(
@@ -25,16 +25,18 @@ export class NativeUploadService extends UploadService {
25
25
  super();
26
26
  }
27
27
 
28
- initialize(): void {
29
- this.logger.debug('[NATIVE UPLOAD] initialize')
30
- this.URL_TILEDESK_FILE = this.getBaseUrl() + 'files'
31
- this.URL_TILEDESK_IMAGES = this.getBaseUrl() + 'images'
28
+ initialize(projectId?: string): void {
29
+ this.logger.info('[NATIVE UPLOAD] initialize', this.getBaseUrl())
30
+ if (projectId) {
31
+ this.URL_TILEDESK_FILE = this.getBaseUrl() + projectId + '/files'
32
+ }
33
+ this.URL_TILEDESK_UPLOAD = this.getBaseUrl();
32
34
  this.tiledeskToken = this.appStorage.getItem('tiledeskToken')
33
35
  }
34
36
 
35
37
 
36
38
  upload(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}> {
37
- this.logger.debug('[NATIVE UPLOAD] - upload new image/file ... upload', upload)
39
+ this.logger.log('[NATIVE UPLOAD] - upload new image/file ... upload', upload)
38
40
  const headers = new HttpHeaders({
39
41
  Authorization: this.tiledeskToken,
40
42
  //'Content-Type': 'multipart/form-data',
@@ -45,37 +47,93 @@ export class NativeUploadService extends UploadService {
45
47
 
46
48
  const that = this;
47
49
  if ((upload.file.type.startsWith('image') && (!upload.file.type.includes('svg')))) {
48
- this.logger.debug('[NATIVE UPLOAD] - upload new image')
49
50
  //USE IMAGE API
50
- const url = this.URL_TILEDESK_IMAGES + '/users'
51
+ const url = this.URL_TILEDESK_UPLOAD + 'images/users'
51
52
  return new Promise((resolve, reject) => {
52
- that.http.post(url, formData, requestOptions).subscribe(data => {
53
- const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
54
- resolve({downloadURL : downloadURL, src: downloadURL})
55
- // that.BSStateUpload.next({upload: upload});
56
- }, (error) => {
57
- reject(error)
53
+ that.http.post(url, formData, requestOptions).pipe(first()).subscribe({
54
+ next: (data) => {
55
+ const downloadURL = this.URL_TILEDESK_UPLOAD + 'images?path=' + encodeURIComponent(data?.['filename']);
56
+ resolve({downloadURL : downloadURL, src: downloadURL})
57
+ // that.BSStateUpload.next({upload: upload});
58
+ },
59
+ error: (error) => {
60
+ reject(error)
61
+ }
58
62
  });
59
63
  });
60
64
  } else {
61
- this.logger.debug('[NATIVE UPLOAD] - upload new file')
62
65
  //USE FILE API
63
- const url = this.URL_TILEDESK_FILE + '/users'
66
+ const url = this.URL_TILEDESK_UPLOAD + 'files/users'
64
67
  return new Promise((resolve, reject) => {
65
- that.http.post(url, formData, requestOptions).subscribe(data => {
66
- const src = this.URL_TILEDESK_FILE + '?path=' + encodeURI(data['filename']);
67
- const downloadURL = this.URL_TILEDESK_FILE + '/download' + '?path=' + encodeURI(data['filename']);
68
- resolve({downloadURL : downloadURL, src: src})
69
- // that.BSStateUpload.next({upload: upload});
70
- }, (error) => {
71
- this.logger.error('[NATIVE UPLOAD] - ERROR upload new file ', error)
72
- reject(error)
68
+ that.http.post(url, formData, requestOptions).pipe(first()).subscribe({
69
+ next: (data) => {
70
+ const src = this.URL_TILEDESK_UPLOAD + 'files?path=' + encodeURIComponent(data['filename']);
71
+ const downloadURL = this.URL_TILEDESK_UPLOAD + 'files/download' + '?path=' + encodeURIComponent(data['filename']);
72
+ resolve({downloadURL : downloadURL, src: src})
73
+ // that.BSStateUpload.next({upload: upload});
74
+ },
75
+ error: (error) => {
76
+ this.logger.error('[NATIVE UPLOAD] - ERROR upload new file ', error)
77
+ reject(error)
78
+ }
73
79
  });
74
80
  });
75
81
  }
76
82
 
77
83
  }
78
84
 
85
+ uploadFile(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}> {
86
+ this.logger.log('[NATIVE UPLOAD] - upload new image/file ... upload', upload)
87
+ const headers = new HttpHeaders({
88
+ Authorization: this.tiledeskToken,
89
+ //'Content-Type': 'multipart/form-data',
90
+ });
91
+ const requestOptions = { headers: headers };
92
+ const formData = new FormData();
93
+ formData.append('file', upload.file);
94
+
95
+ const that = this;
96
+ const url = this.URL_TILEDESK_FILE + '/chat'
97
+ return new Promise((resolve, reject) => {
98
+ that.http.post(url, formData, requestOptions).pipe(first()).subscribe({
99
+ next: (data) => {
100
+ const src = this.URL_TILEDESK_UPLOAD + 'files?path=' + encodeURIComponent(data['filename']);
101
+ const downloadURL = this.URL_TILEDESK_UPLOAD + 'files/download?path=' + encodeURIComponent(data['filename']);
102
+ resolve({downloadURL : downloadURL, src: src})
103
+ },
104
+ error: (error) => {
105
+ reject(error)
106
+ }
107
+ });
108
+ });
109
+ }
110
+
111
+ uploadAsset(userId: string, upload: UploadModel, expiration: number = 60): Promise<{downloadURL: string, src: string}> {
112
+ this.logger.log('[NATIVE UPLOAD] - upload new asset ... upload', upload, 'expiration:', expiration)
113
+ const headers = new HttpHeaders({
114
+ Authorization: this.tiledeskToken,
115
+ });
116
+ const requestOptions = { headers: headers };
117
+ const formData = new FormData();
118
+ formData.append('file', upload.file);
119
+
120
+ const that = this;
121
+ const queryString = expiration !== undefined ? `?expiration=${encodeURIComponent(String(expiration))}` : ''
122
+ const url = this.URL_TILEDESK_FILE + `/assets${queryString}`
123
+ return new Promise((resolve, reject) => {
124
+ that.http.post(url, formData, requestOptions).pipe(first()).subscribe({
125
+ next: (data) => {
126
+ const src = this.URL_TILEDESK_UPLOAD + 'files?path=' + data['filename'];
127
+ const downloadURL = this.URL_TILEDESK_UPLOAD + 'files/download?path=' + encodeURIComponent(data['filename']);
128
+ resolve({downloadURL : downloadURL, src: src})
129
+ },
130
+ error: (error) => {
131
+ reject(error)
132
+ }
133
+ });
134
+ });
135
+ }
136
+
79
137
  uploadProfile(userId: string, upload: UploadModel): Promise<any> {
80
138
  this.logger.log('[NATIVE UPLOAD] - upload new photo profile ... upload', upload)
81
139
  const headers = new HttpHeaders({
@@ -88,14 +146,18 @@ export class NativeUploadService extends UploadService {
88
146
 
89
147
  // USE IMAGE API
90
148
  const that = this;
91
- const url = this.URL_TILEDESK_IMAGES + `/users/photo?force=true&user_id=${userId}`
149
+ const queryString = userId?.startsWith('bot_') ? `?bot_id=${encodeURIComponent(userId.substring('bot_'.length))}` : ''
150
+ const url = this.URL_TILEDESK_FILE + `/users/photo${queryString}`
92
151
  return new Promise((resolve, reject) => {
93
- that.http.put(url, formData, requestOptions).subscribe(data => {
94
- const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['thumbnail'];
95
- resolve(downloadURL)
96
- // that.BSStateUpload.next({upload: upload});
97
- }, (error) => {
98
- reject(error)
152
+ that.http.put(url, formData, requestOptions).pipe(first()).subscribe({
153
+ next: (data) => {
154
+ const downloadURL = this.getBaseUrl() + 'files?path=' + data['thumbnail'];
155
+ resolve(downloadURL)
156
+ // that.BSStateUpload.next({upload: upload});
157
+ },
158
+ error: (error) => {
159
+ reject(error)
160
+ }
99
161
  });
100
162
  });
101
163
  }
@@ -110,18 +172,50 @@ export class NativeUploadService extends UploadService {
110
172
 
111
173
  //USE IMAGE API
112
174
  const that = this;
113
- const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + path.split('path=')[1]
175
+ const url = this.URL_TILEDESK_UPLOAD + 'images/users' + '?path=' + path.split('path=')[1]
176
+ return new Promise((resolve, reject) => {
177
+ that.http.delete(url, requestOptions).pipe(first()).subscribe({
178
+ next: (data) => {
179
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
180
+ resolve(true)
181
+ // that.BSStateUpload.next({upload: upload});
182
+ },
183
+ error: (error) => {
184
+ reject(error)
185
+ }
186
+ });
187
+ });
188
+ }
189
+
190
+ deleteFile(userId: string, path: string): Promise<any>{
191
+ this.logger.log('[NATIVE UPLOAD] - delete image ... upload', userId)
192
+ const headers = new HttpHeaders({
193
+ Authorization: this.tiledeskToken,
194
+ //'Content-Type': 'multipart/form-data',
195
+ });
196
+ const requestOptions = { headers: headers };
197
+
198
+ //USE IMAGE API
199
+ const that = this;
200
+ const url = this.URL_TILEDESK_FILE + '?path=' + path.split('path=')[1]
114
201
  return new Promise((resolve, reject) => {
115
- that.http.delete(url, requestOptions).subscribe(data => {
116
- // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
117
- resolve(true)
118
- // that.BSStateUpload.next({upload: upload});
119
- }, (error) => {
120
- reject(error)
202
+ that.http.delete(url, requestOptions).pipe(first()).subscribe({
203
+ next: (data) => {
204
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
205
+ resolve(true)
206
+ // that.BSStateUpload.next({upload: upload});
207
+ },
208
+ error: (error) => {
209
+ reject(error)
210
+ }
121
211
  });
122
212
  });
123
213
  }
124
214
 
215
+ deleteAsset(userId: string, path: string): Promise<any>{
216
+ return this.deleteFile(userId, path);
217
+ }
218
+
125
219
  deleteProfile(userId: string, path: string): Promise<any>{
126
220
  this.logger.log('[NATIVE UPLOAD] - delete image ... upload', userId)
127
221
  const headers = new HttpHeaders({
@@ -132,14 +226,17 @@ export class NativeUploadService extends UploadService {
132
226
 
133
227
  //USE IMAGE API
134
228
  const that = this;
135
- const url = this.URL_TILEDESK_IMAGES + '/users' + '?path=' + "uploads/users/"+ userId + "/images/photo.jpg"
229
+ const url = this.URL_TILEDESK_FILE + '?path=' + "uploads/users/"+ userId + "/images/photo.jpg"
136
230
  return new Promise((resolve, reject) => {
137
- that.http.delete(url, requestOptions).subscribe(data => {
138
- // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
139
- resolve(true)
140
- // that.BSStateUpload.next({upload: upload});
141
- }, (error) => {
142
- reject(error)
231
+ that.http.delete(url, requestOptions).pipe(first()).subscribe({
232
+ next: (data) => {
233
+ // const downloadURL = this.URL_TILEDESK_IMAGES + '?path=' + data['filename'];
234
+ resolve(true)
235
+ // that.BSStateUpload.next({upload: upload});
236
+ },
237
+ error: (error) => {
238
+ reject(error)
239
+ }
143
240
  });
144
241
  });
145
242
  }
@@ -71,7 +71,7 @@ export class TiledeskRequestsService {
71
71
 
72
72
  public getMyRequests(): Promise<{ requests: Array<any>}> {
73
73
  this.tiledeskToken = this.appStorage.getItem('tiledeskToken')
74
- const url = this.URL_TILEDESK_REQUEST + '/me?preflight=true'
74
+ const url = this.URL_TILEDESK_REQUEST + 'me?preflight=true'
75
75
  this.logger.log('[TILEDESK-SERVICE] - GET REQUEST url ', url);
76
76
  const httpOptions = {
77
77
  headers: new HttpHeaders({
@@ -773,6 +773,11 @@ export function isAllowedUrlInText(text: string, allowedUrls: string[]) {
773
773
  return nonWhitelistedDomains.length === 0;
774
774
  }
775
775
 
776
+ // function extractUrls(text: string): string[] {
777
+ // const urlRegex = /https?:\/\/[^\s]+/g;
778
+ // return text.match(urlRegex) || [];
779
+ // }
780
+
776
781
  function extractUrls(text: string): string[] {
777
782
  // Rileva URL con o senza protocollo (http/https)
778
783
  const urlRegex = /\b((https?:\/\/)?(www\.)?[a-z0-9.-]+\.[a-z]{2,})(\/[^\s]*)?/gi;
@@ -787,5 +792,3 @@ function extractUrls(text: string): string[] {
787
792
  }
788
793
 
789
794
 
790
-
791
-
@@ -13,10 +13,28 @@
13
13
  bottom: 0px;
14
14
  width: auto;
15
15
  height: auto;
16
- display: none;
16
+ display: block;
17
17
  z-index: 3000000000; /*999999*/;
18
18
  }
19
19
 
20
+ #tiledesk-container.open {
21
+ /*
22
+ Fade-in the whole container when the "open" class is added.
23
+ This avoids the initial "flash" while the widget is still small.
24
+ */
25
+ opacity: 0;
26
+ animation: tiledesk-container-fade-in 400ms ease-in both;
27
+ will-change: opacity;
28
+ }
29
+
30
+ @keyframes tiledesk-container-fade-in {
31
+ /* Stay invisible, then become visible very fast at the end */
32
+ 0% { opacity: 0; }
33
+ 80% { opacity: 0.15; }
34
+ 92% { opacity: 0.30; }
35
+ 100% { opacity: 1; }
36
+ }
37
+
20
38
  #tiledesk-container.open.overlay--popup {
21
39
  background-color: rgba(0, 0, 0, 0.4);
22
40
  position: fixed;
@@ -57,8 +75,8 @@
57
75
  margin: auto;
58
76
  top: 0;
59
77
  bottom: 0;
60
- left: 0!important;
61
- right: 0!important;
78
+ left: 0;
79
+ right: 0;
62
80
  height: 100%; /*var(--iframeMaxHeight);*/
63
81
  /* transform: translate(-50%, -50%); */
64
82
  /* transform: translate(-50%, 0%); */
@@ -66,12 +84,12 @@
66
84
  max-width: 1024px;
67
85
  max-height: 100%;
68
86
 
69
- transition:
87
+ /* transition:
70
88
  width 300ms,
71
89
  height 300ms,
72
90
  max-height 300ms,
73
91
  transform 300ms cubic-bezier(0, 1.2, 1, 1),
74
- opacity 300ms ease-out;
92
+ opacity 300ms ease-out; */
75
93
  /* per migliorare le prestazioni quando si usa transform */
76
94
  will-change: transform, opacity, width, height;
77
95
  }
@@ -130,9 +148,20 @@
130
148
  display: block;
131
149
  /*width: 376px;*/
132
150
  border-radius: 16px;
151
+ /*
152
+ Fade-in: keep content transparent while the widget grows (width/height transition
153
+ lives on #tiledeskdiv.{min-size|max-size|top-size}), then show it near full size.
154
+ */
155
+ opacity: 0;
156
+ animation: tiledesk-iframe-fade-in 220ms ease-out 140ms both;
133
157
  transition: box-shadow 0.8s ease-in;
134
158
  box-shadow: rgba(0, 0, 0, 0.16) 0px 8px 36px 0px; /*NEW GAB*/
135
159
  }
160
+
161
+ @keyframes tiledesk-iframe-fade-in {
162
+ from { opacity: 0; }
163
+ to { opacity: 1; }
164
+ }
136
165
  /*
137
166
  #tiledesk-container.open #tiledeskdiv.shadow {
138
167
  transition: box-shadow 0.8s ease-in;
@@ -140,25 +169,20 @@
140
169
  }
141
170
  */
142
171
 
143
- #tiledesk-container.open #tiledeskdiv {
144
- /* transition: box-shadow 0.8s ease-in;
145
- box-shadow: rgba(0, 0, 0, 0.16) 0px 8px 36px 0px; */
146
- }
147
-
148
172
  #tiledesk-container.closed #tiledeskiframe {
149
173
  display: block;
150
174
  box-shadow: none;
151
175
  }
152
176
 
153
177
  #tiledesk-container.open #tiledeskdiv.min-size {
154
- transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out;
178
+ /* transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out; */
155
179
  width: var(--iframeMinWidth);
156
180
  height: var(--iframeMinHeight);
157
181
  }
158
182
 
159
183
  #tiledesk-container.open #tiledeskdiv.max-size {
160
184
  /* transition: width 1s, height 1s; */
161
- transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out;
185
+ /* transition: width 200ms, height 200ms, max-height 200ms, transform 300ms cubic-bezier(0, 1.2, 1, 1), opacity 83ms ease-out; */
162
186
  width: var(--iframeMaxWidth);
163
187
  height: var(--iframeMaxHeight);
164
188
  }
@@ -1,3 +0,0 @@
1
- {
2
- "git.ignoreLimitWarning": true
3
- }