@chat21/chat21-web-widget 5.1.20 → 5.1.24-rc1

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 (35) 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 +64 -2
  4. package/Dockerfile +4 -5
  5. package/angular.json +2 -1
  6. package/deploy_amazon_beta.sh +17 -7
  7. package/package.json +1 -1
  8. package/src/app/app.component.html +8 -1
  9. package/src/app/app.component.scss +59 -0
  10. package/src/app/app.component.ts +92 -34
  11. package/src/app/component/conversation-detail/conversation/conversation.component.ts +18 -4
  12. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +25 -0
  13. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +2 -1
  14. package/src/app/component/home-conversations/home-conversations.component.html +16 -6
  15. package/src/app/component/home-conversations/home-conversations.component.ts +29 -0
  16. package/src/app/component/launcher-button/launcher-button.component.html +1 -1
  17. package/src/app/component/launcher-button/launcher-button.component.ts +3 -2
  18. package/src/app/component/list-conversations/list-conversations.component.html +8 -3
  19. package/src/app/component/list-conversations/list-conversations.component.ts +29 -0
  20. package/src/app/pipe/marked.pipe.ts +27 -154
  21. package/src/app/providers/global-settings.service.ts +1 -1
  22. package/src/app/providers/translator.service.ts +2 -0
  23. package/src/app/utils/globals.ts +1 -1
  24. package/src/assets/i18n/en.json +1 -0
  25. package/src/assets/i18n/es.json +1 -0
  26. package/src/assets/i18n/fr.json +1 -0
  27. package/src/assets/i18n/it.json +1 -0
  28. package/src/chat21-core/providers/abstract/upload.service.ts +5 -1
  29. package/src/chat21-core/providers/firebase/firebase-upload.service.ts +141 -12
  30. package/src/chat21-core/providers/native/native-image-repo.ts +1 -1
  31. package/src/chat21-core/providers/native/native-upload-service.ts +143 -46
  32. package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
  33. package/src/chat21-core/utils/utils.ts +5 -2
  34. package/src/iframe-style.css +5 -5
  35. package/deploy_amazon_prod.sh +0 -41
@@ -419,3 +419,28 @@ textarea:active{
419
419
  border: none;
420
420
  // margin: -2px -2px 0px;
421
421
  }
422
+
423
+
424
+ // aggiungi un'animazione di fade in e fade out quando .star-rating-widget è visibile con transition
425
+ .star-rating-widget {
426
+ transition: all 0.5s ease-in-out;
427
+ }
428
+
429
+ .star-rating-widget {
430
+ position: absolute;
431
+ left: 0;
432
+ right: 0;
433
+ bottom: -52px;
434
+ height: 100%;
435
+ width: 100%;
436
+ flex-direction: row;
437
+ justify-content: center;
438
+ background-color: rgb(255, 255, 255);
439
+ flex-wrap: nowrap;
440
+ &.active {
441
+ bottom: 0px;
442
+ }
443
+ &.inactive {
444
+ bottom: -52px;
445
+ }
446
+ }
@@ -87,6 +87,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
87
87
 
88
88
  file_size_limit = FILE_SIZE_LIMIT;
89
89
  attachmentTooltip: string = '';
90
+ isErrorNetwork: boolean = false;
90
91
 
91
92
 
92
93
  convertColorToRGBA = convertColorToRGBA;
@@ -316,7 +317,7 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
316
317
  // });
317
318
  // this.resetLoadImage();
318
319
 
319
- this.uploadService.upload(this.senderId, currentUpload).then(data => {
320
+ this.uploadService.uploadFile(this.senderId, currentUpload).then(data => {
320
321
  that.logger.log('[CONV-FOOTER] AppComponent::uploadSingle:: downloadURL', data);
321
322
  that.logger.log(`[CONV-FOOTER] Successfully uploaded file and got download link - ${data}`);
322
323
 
@@ -38,9 +38,14 @@
38
38
  <!--CASE: no conversations EXIST - >1 agents is available -->
39
39
  <div *ngIf="(!listConversations || listConversations.length == 0) && availableAgents && availableAgents.length > 1 && g.showAvailableAgents === true" style="display: flex; margin: 20px 30px;">
40
40
  <div *ngFor="let agent of availableAgents" class="c21-pallozzo">
41
- <div class="c21-ball" [ngStyle] = "{ 'background-color':setColorFromString(agent.firstname) }" >
42
- <span class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
43
- <div *ngIf="agent.imageurl" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
41
+ <div class="c21-ball" [ngStyle] = "{ 'background-color': isImageLoaded(agent) ? 'transparent' : setColorFromString(agent.firstname) }" >
42
+ <span *ngIf="!isImageLoaded(agent)" class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
43
+ <img *ngIf="agent.imageurl"
44
+ [src]="agent.imageurl"
45
+ style="display: none;"
46
+ (load)="onImageLoad(agent)"
47
+ (error)="onImageError(agent)">
48
+ <div *ngIf="isImageLoaded(agent)" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
44
49
  </div>
45
50
  </div>
46
51
  </div>
@@ -48,9 +53,14 @@
48
53
  <!--CASE: no conversations EXIST - 1 agents is available -->
49
54
  <div class="flex-container" *ngIf="(!listConversations || listConversations.length == 0) && availableAgents && availableAgents.length === 1 && g.showAvailableAgents === true">
50
55
  <div *ngFor="let agent of availableAgents" class="c21-pallozzo flex-inline-agent ">
51
- <div class="c21-ball" [ngStyle] = "{ 'background-color':setColorFromString(agent.firstname) }" >
52
- <span class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
53
- <div *ngIf="agent.imageurl" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
56
+ <div class="c21-ball" [ngStyle] = "{ 'background-color': isImageLoaded(agent) ? 'transparent' : setColorFromString(agent.firstname) }" >
57
+ <span *ngIf="!isImageLoaded(agent)" class="c21-ball-label">{{avatarPlaceholder(agent.firstname)}}</span>
58
+ <img *ngIf="agent.imageurl"
59
+ [src]="agent.imageurl"
60
+ style="display: none;"
61
+ (load)="onImageLoad(agent)"
62
+ (error)="onImageError(agent)">
63
+ <div *ngIf="isImageLoaded(agent)" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + agent.imageurl + ')'"></div>
54
64
  </div>
55
65
  </div>
56
66
  <button tabindex="1040" aflistconv #aflistconv class="c21-button-primary" (click)="openNewConversation()" [ngStyle]="{'background-color': g.themeColor, 'border-color': g.themeColor, 'color': g.themeForegroundColor }">
@@ -65,6 +65,7 @@ export class HomeConversationsComponent implements OnInit, OnDestroy {
65
65
  themeForegroundColor = '';
66
66
  LABEL_START_NW_CONV: string;
67
67
  availableAgents: Array<UserAgent> = [];
68
+ imageLoadedMap: Map<string, boolean> = new Map<string, boolean>();
68
69
  // ========= end:: variabili del componente ======== //
69
70
 
70
71
  waitingTime: number;
@@ -203,6 +204,34 @@ export class HomeConversationsComponent implements OnInit, OnDestroy {
203
204
  this.onConversationLoaded.emit(conversation)
204
205
  }
205
206
 
207
+ /**
208
+ * Verifica se l'immagine dell'agente esiste e si carica correttamente
209
+ */
210
+ isImageLoaded(agent: UserAgent): boolean {
211
+ if (!agent?.imageurl) {
212
+ return false;
213
+ }
214
+ return this.imageLoadedMap.get(agent.id) === true;
215
+ }
216
+
217
+ /**
218
+ * Gestisce il caricamento riuscito dell'immagine
219
+ */
220
+ onImageLoad(agent: UserAgent) {
221
+ if (agent?.id && agent?.imageurl) {
222
+ this.imageLoadedMap.set(agent.id, true);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Gestisce l'errore di caricamento dell'immagine
228
+ */
229
+ onImageError(agent: UserAgent) {
230
+ if (agent?.id) {
231
+ this.imageLoadedMap.set(agent.id, false);
232
+ }
233
+ }
234
+
206
235
  private openConversationByID(conversation) {
207
236
  this.logger.debug('[HOMECONVERSATIONS] openConversationByID: ', conversation);
208
237
  if ( conversation ) {
@@ -1,7 +1,7 @@
1
1
  <!-- tabindex="000"-->
2
2
 
3
3
  <button aflauncherbutton #aflauncherbutton id="c21-launcher-button" class="c21-button-clean scale-in-center"
4
- *ngIf="g.isLogged == true && g.isOpen == false"
4
+ *ngIf="g.isOpen == false"
5
5
  [ngClass]="{'c21-align-left' : g.align === 'left', 'c21-align-right' : g.align !== 'left'}"
6
6
  [ngStyle]="{ 'background-color': g.baloonImage? null: g.themeColor, 'bottom': g.marginY+'px!important', 'left':(g.align==='left')?g.marginX+'px!important':'', 'right':(g.align==='right')?g.marginX+'px!important':'', 'width': g.launcherWidth, 'height': g.launcherHeight, 'border-radius': g.baloonShape}"
7
7
  (click)="openCloseWidget()"
@@ -67,8 +67,9 @@ export class LauncherButtonComponent implements OnInit, AfterViewInit {
67
67
  // this.g.isOpen = !this.g.isOpen;
68
68
  // this.g.setIsOpen(!this.g.isOpen);
69
69
  // this.appStorageService.setItem('isOpen', this.g.isOpen);
70
- this.onButtonClicked.emit( this.g.isOpen );
71
- }
70
+
71
+ }
72
+ this.onButtonClicked.emit( this.g.isOpen );
72
73
  }
73
74
 
74
75
  }
@@ -3,9 +3,14 @@
3
3
  <button tabindex="1103" class="c21-item-conversation" (click)="openConversationByID(conversation)">
4
4
  <div class="c21-body-conv">
5
5
  <div class="c21-left-conv">
6
- <div class="c21-ball" [ngStyle]="{'background': 'linear-gradient(rgb(255,255,255) -125%, ' + conversation.color + ')'}">
7
- <span class="c21-ball-label">{{conversation?.avatar}}</span>
8
- <div *ngIf="conversation?.image" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + conversation.image + ')'"></div>
6
+ <div class="c21-ball" [ngStyle]="{'background': isImageLoaded(conversation) ? 'transparent' : 'linear-gradient(rgb(255,255,255) -125%, ' + conversation.color + ')'}">
7
+ <span *ngIf="!isImageLoaded(conversation)" class="c21-ball-label">{{conversation?.avatar}}</span>
8
+ <img *ngIf="conversation?.image"
9
+ [src]="conversation.image"
10
+ style="display: none;"
11
+ (load)="onImageLoad(conversation)"
12
+ (error)="onImageError(conversation)">
13
+ <div *ngIf="isImageLoaded(conversation)" #avatarImage class="c21-avatar-image" [style.background-image]="'url(' + conversation.image + ')'"></div>
9
14
  </div>
10
15
  </div>
11
16
  <div class="c21-right-conv">
@@ -35,6 +35,7 @@ export class ListConversationsComponent implements OnInit {
35
35
  arrayDiffer: any;
36
36
 
37
37
  uidConvSelected: string;
38
+ imageLoadedMap: Map<string, boolean> = new Map<string, boolean>();
38
39
  constructor(private iterableDiffers: IterableDiffers) {
39
40
  this.iterableDifferListConv = this.iterableDiffers.find([]).create(null);
40
41
 
@@ -67,5 +68,33 @@ export class ListConversationsComponent implements OnInit {
67
68
 
68
69
  }
69
70
 
71
+ /**
72
+ * Verifica se l'immagine esiste e si carica correttamente
73
+ */
74
+ isImageLoaded(conversation: ConversationModel): boolean {
75
+ if (!conversation?.image) {
76
+ return false;
77
+ }
78
+ return this.imageLoadedMap.get(conversation.uid) === true;
79
+ }
80
+
81
+ /**
82
+ * Gestisce il caricamento riuscito dell'immagine
83
+ */
84
+ onImageLoad(conversation: ConversationModel) {
85
+ if (conversation?.uid && conversation?.image) {
86
+ this.imageLoadedMap.set(conversation.uid, true);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Gestisce l'errore di caricamento dell'immagine
92
+ */
93
+ onImageError(conversation: ConversationModel) {
94
+ if (conversation?.uid) {
95
+ this.imageLoadedMap.set(conversation.uid, false);
96
+ }
97
+ }
98
+
70
99
 
71
100
  }
@@ -1,184 +1,57 @@
1
1
  import { Pipe, PipeTransform } from '@angular/core';
2
2
  import { marked } from 'marked';
3
- import { BLOCKED_DOMAINS } from '../utils/utils';
4
- import { htmlEntities } from 'src/chat21-core/utils/utils';
5
-
6
3
 
7
4
  @Pipe({
8
5
  name: 'marked'
9
6
  })
10
-
11
7
  export class MarkedPipe implements PipeTransform {
8
+
12
9
  transform(value: any): any {
13
- // Security hardening:
14
- // - Do not allow raw HTML from chat messages to be interpreted as DOM.
15
- // - Keep Markdown working (marked will generate the needed HTML tags).
16
- // This makes inputs like "<h1>Title</h1>" render exactly as typed.
10
+ // Convertiamo tutto in stringa sicura
17
11
  const input =
18
12
  typeof value === 'string'
19
13
  ? value
20
14
  : (value === null || value === undefined) ? '' : String(value);
21
-
22
- // Converti i \n letterali in newline reali prima di htmlEntities
23
- // così il markdown con breaks: true li renderizzerà correttamente
15
+
16
+ // Converti \n letterali in newline reali
24
17
  const inputWithNewlines = input.replace(/\\n/g, '\n');
25
-
26
- // Proteggi i > usati per i blockquote markdown (all'inizio di riga)
27
- // sostituendoli temporaneamente con un placeholder
28
- const BLOCKQUOTE_PLACEHOLDER = '___MARKDOWN_BLOCKQUOTE___';
29
- const protectedInput = inputWithNewlines.replace(/^(\s*)>/gm, (match, spaces) => {
30
- return spaces + BLOCKQUOTE_PLACEHOLDER;
31
- });
32
-
33
- // Applica htmlEntities (che codificherà tutti gli altri >)
34
- let safeInput = htmlEntities(protectedInput);
35
-
36
- // Ripristina i > dei blockquote
37
- safeInput = safeInput.replace(new RegExp(BLOCKQUOTE_PLACEHOLDER, 'g'), '>');
38
18
 
19
+ // Renderer custom solo per i link
39
20
  const renderer = new marked.Renderer();
21
+ const originalLinkRenderer = renderer.link.bind(renderer);
22
+
23
+ // Lista protocolli / pattern pericolosi
24
+ const dangerousPatterns = [
25
+ /^javascript:/i,
26
+ /^data:/i,
27
+ /^vbscript:/i
28
+ ];
29
+
40
30
  renderer.link = function({ href, title, tokens }) {
41
- // Normalizza l'href per evitare falsi negativi
42
- const normalized = (href || '').trim().toLowerCase();
43
- // Pattern pericolosi da cercare nell'intero URL (non solo all'inizio)
44
- const dangerousPatterns = [
45
- /javascript:/i, // javascript: protocol
46
- /data:/i, // data: protocol
47
- /vbscript:/i, // vbscript: protocol
48
- /on\w+\s*=/i, // event handlers (onclick, onload, etc.)
49
- /alert\s*\(/i, // alert() function
50
- /eval\s*\(/i, // eval() function
51
- /document\./i, // document object access
52
- /window\./i, // window object access
53
- /\.appendChild\s*\(/i, // DOM manipulation
54
- /\.createElement\s*\(/i, // DOM creation
55
- /<script/i, // script tags
56
- /<\/script>/i, // closing script tags
57
- /function\s*\(/i, // function definitions
58
- /\(function/i, // IIFE patterns
59
- /setTimeout\s*\(/i, // setTimeout
60
- /setInterval\s*\(/i, // setInterval
61
- /location\./i, // location object manipulation
62
- /history\./i, // history object manipulation
63
- /localStorage\./i, // localStorage access
64
- /sessionStorage\./i, // sessionStorage access
65
- /cookie/i, // cookie manipulation
66
- /fetch\s*\(/i, // fetch API
67
- /XMLHttpRequest/i, // XHR
68
- /FormData/i, // FormData
69
- /Blob\s*\(/i, // Blob constructor
70
- /FileReader/i, // FileReader
71
- /crypto\./i, // crypto object
72
- /btoa\s*\(/i, // base64 encoding
73
- /atob\s*\(/i, // base64 decoding
74
- /decodeURI/i, // URI decoding
75
- /encodeURI/i, // URI encoding
76
- /String\.fromCharCode/i, // character code conversion
77
- /unescape\s*\(/i, // unescape function
78
- /escape\s*\(/i // escape function
79
- ];
31
+ const normalized = (href || '').trim();
80
32
 
81
- // Controlla se l'URL contiene pattern pericolosi
33
+ // Se il link è pericoloso, restituisci solo il testo
82
34
  const isDangerous = dangerousPatterns.some(pattern => pattern.test(normalized));
83
35
  if (isDangerous) {
84
- // Ritorna solo il testo come stringa, niente <a>
85
- return tokens ? tokens.map(token => token.raw).join('') : href || '';
36
+ return tokens ? tokens.map(t => t.raw).join('') : href || '';
86
37
  }
87
38
 
88
- // tokens = this.cleanInput(href);
89
-
90
- const text = tokens
91
- ? tokens.map(token => token.raw).join('')
92
- : href; // fallback se tokens non c'è
93
- if (!href) return text;
94
-
95
- return `<a href="${href}" target="_blank" rel="noopener noreferrer">${text}</a>`;
39
+ // Altrimenti delega al renderer originale di marked
40
+ return originalLinkRenderer({ href, title, tokens });
96
41
  };
97
-
42
+
43
+ // Opzioni marked
98
44
  marked.setOptions({
99
45
  renderer,
100
46
  gfm: true,
101
47
  breaks: true
102
48
  });
103
49
 
104
- if (safeInput && safeInput.length > 0) {
105
- try {
106
- return marked.parse(safeInput);
107
- } catch (err) {
108
- console.error('Errore nel parsing markdown:', err);
109
- return safeInput;
110
- }
50
+ try {
51
+ return marked.parse(inputWithNewlines);
52
+ } catch (err) {
53
+ console.error('Errore nel parsing markdown:', err);
54
+ return inputWithNewlines;
111
55
  }
112
- return safeInput;
113
- }
114
-
115
-
116
- private cleanInput(input: string): string {
117
- if (!input) return '';
118
- let cleaned = (input || '').trim().toLowerCase();
119
-
120
- BLOCKED_DOMAINS.forEach(domain => {
121
- const escapedDomain = domain.replace(/\./g, '\\.');
122
- // Pattern che copre TUTTI i casi
123
- const comprehensivePattern = new RegExp(
124
- `(\\[([^\\]]*)\\]\\([^)]*(?:https?://)?(?:www\\.)?${escapedDomain}(?:/[^)]*)?\\))|((?:https?://)?(?:www\\.)?${escapedDomain}(?:/\\S*)?)`,
125
- 'gi'
126
- );
127
-
128
- cleaned = cleaned.replace(comprehensivePattern, (match, p1, p2, p3) => {
129
- // Se è un link markdown [text](url), mantieni il testo
130
- if (p2) return `${p2} 🔒`;
131
- // Se è un URL diretto, sostituisci con dominio + 🔒
132
- if (p3) return `${domain} 🔒`;
133
- return match;
134
- });
135
-
136
- });
137
-
138
-
139
- // Pattern che sostituisce i link pericolosi con solo il testo
140
- const dangerousLinkPatterns = [
141
- // Sostituisce [text](javascript:...) con "text"
142
- /\[([^\]]*)\]\(javascript:[^)]*\)/gi,
143
- /\[([^\]]*)\]\(data:[^)]*\)/gi,
144
- /\[([^\]]*)\]\(vbscript:[^)]*\)/gi,
145
- /\[([^\]]*)\]\([^)]*alert\([^)]*\)/gi
146
- ];
147
-
148
- dangerousLinkPatterns.forEach(pattern => {
149
- cleaned = cleaned.replace(pattern, '$1'); // $1 = il testo del link
150
- });
151
-
152
- // Pattern generali per sicurezza (rimuovono completamente)
153
- const generalPatterns = [
154
- /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
155
- /<script[^>]*>[\s\S]*?<\/script>/gi, // Script multi-linea
156
- /<script[^>]*>.*?<\/script>/gi, // Script single-line
157
- /<script[^>]*>/gi, // Solo tag di apertura
158
- /<\/script>/gi, // Solo tag di chiusura
159
- /javascript:/gi,
160
- /vbscript:/gi,
161
- /data:/gi,
162
- /on\w+\s*=/gi,
163
- /alert\(/gi,
164
- /eval\(/gi,
165
- /document\./gi,
166
- /window\./gi,
167
- /\(function\s*\(\)\s*\{/gi,
168
- /\.appendChild\(/gi,
169
- /\.createElement\(/gi,
170
- /\.getElementsByTagName\(/gi,
171
-
172
- // ✅ PATTERN PER FUNZIONI IIFE (Immediately Invoked Function Expression):
173
- /\(function\s*\(\s*\)\s*\{[\s\S]*?\}\)\(\s*\)\s*;/gi,
174
- /\(function\s*\(\)\s*\{/gi
175
- ];
176
-
177
- generalPatterns.forEach(pattern => {
178
- cleaned = cleaned.replace(pattern, '');
179
- });
180
-
181
- return cleaned;
182
56
  }
183
-
184
- }
57
+ }
@@ -1963,7 +1963,7 @@ export class GlobalSettingsService {
1963
1963
  this.logger.debug('[GLOBAL-SET] setDepartmentFromExternal > END departmentID ::::' + this.globals.departmentID + isValidID);
1964
1964
  }
1965
1965
  //remove default department from list
1966
- this.globals.departments = this.globals.departments.filter(obj => obj['default'] !== true)
1966
+ this.globals.departments = this.globals.departments?.filter(obj => obj['default'] !== true) ?? []
1967
1967
  if(this.globals.departments && this.globals.departments.length === 1){
1968
1968
  this.setDepartment(this.globals.departments[0])
1969
1969
  }
@@ -302,6 +302,7 @@ export class TranslatorService {
302
302
  'CLOSED',
303
303
  'LABEL_PREVIEW',
304
304
  'MAX_ATTACHMENT',
305
+ 'MAX_ATTACHMENT_ERROR',
305
306
  'EMOJI'
306
307
  ];
307
308
 
@@ -358,6 +359,7 @@ export class TranslatorService {
358
359
  globals.LABEL_PREVIEW = res['LABEL_PREVIEW']
359
360
  globals.LABEL_ERROR_FIELD_REQUIRED= res['LABEL_ERROR_FIELD_REQUIRED']
360
361
  globals.MAX_ATTACHMENT = res['MAX_ATTACHMENT']
362
+ globals.MAX_ATTACHMENT_ERROR = res['MAX_ATTACHMENT_ERROR']
361
363
  globals.EMOJI = res['EMOJI']
362
364
 
363
365
 
@@ -247,7 +247,7 @@ export class Globals {
247
247
 
248
248
  // ============ BEGIN: SET EXTERNAL PARAMETERS ==============//
249
249
  this.baseLocation = 'https://widget.tiledesk.com/v2';
250
- this.autoStart = true;
250
+ this.autoStart = false;
251
251
  /** start Authentication and startUI */
252
252
  this.startHidden = false;
253
253
  /** show/hide all widget -> js call: showAllWidget */
@@ -96,5 +96,6 @@
96
96
  "EMOJI_NOT_ELLOWED":"Emoji not allowed",
97
97
  "DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
98
98
  "MAX_ATTACHMENT": "Max allowed size {{FILE_SIZE_LIMIT}}Mb",
99
+ "MAX_ATTACHMENT_ERROR": "The file exceeds the maximum allowed size",
99
100
  "EMOJI": "Emoji"
100
101
  }
@@ -96,5 +96,6 @@
96
96
  "EMOJI_NOT_ELLOWED":"Emoji no permitido",
97
97
  "DOMAIN_NOT_ALLOWED":"La URL contiene un dominio no permitido",
98
98
  "MAX_ATTACHMENT": "Tamaño máximo permitido {{FILE_SIZE_LIMIT}}Mb",
99
+ "MAX_ATTACHMENT_ERROR": "El archivo supera el tamaño máximo permitido",
99
100
  "EMOJI": "Emoji"
100
101
  }
@@ -96,5 +96,6 @@
96
96
  "EMOJI_NOT_ELLOWED":"Emoji non autorisé",
97
97
  "DOMAIN_NOT_ALLOWED":"L'URL contient un domaine non autorisé",
98
98
  "MAX_ATTACHMENT": "Taille maximale autorisée {{FILE_SIZE_LIMIT}}Mo",
99
+ "MAX_ATTACHMENT_ERROR": "Le fichier dépasse la taille maximale autorisée",
99
100
  "EMOJI": "Emoji"
100
101
  }
@@ -94,5 +94,6 @@
94
94
  "EMOJI_NOT_ELLOWED":"Emoji non consentiti",
95
95
  "DOMAIN_NOT_ALLOWED":"L'URL contiene un dominio non consentito",
96
96
  "MAX_ATTACHMENT": "Dimensione massima consentita {{FILE_SIZE_LIMIT}}Mb",
97
+ "MAX_ATTACHMENT_ERROR": "Il file supera la dimensione massima consentita",
97
98
  "EMOJI": "Emoji"
98
99
  }
@@ -27,9 +27,13 @@ export abstract class UploadService {
27
27
  abstract BSStateUpload: BehaviorSubject<any>;
28
28
 
29
29
  // functions
30
- abstract initialize(): void;
30
+ abstract initialize(projectId?: string): void;
31
31
  abstract upload(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}>;
32
+ abstract uploadFile(userId: string, upload: UploadModel): Promise<{downloadURL: string, src: string}>;
33
+ abstract uploadAsset(userId: string, upload: UploadModel, expiration?: number): Promise<{downloadURL: string, src: string}>;
32
34
  abstract uploadProfile(userId: string, upload: UploadModel): Promise<any>;
33
35
  abstract delete(userId: string, path: string): Promise<any>;
36
+ abstract deleteFile(userId: string, path: string): Promise<any>;
37
+ abstract deleteAsset(userId: string, path: string): Promise<any>
34
38
  abstract deleteProfile(userId: string, path: string): Promise<any>
35
39
  }