@chat21/chat21-web-widget 5.1.6 → 5.1.7-rc9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/docker-community-push-latest.yml +23 -13
- package/.github/workflows/docker-image-tag-community-tag-push.yml +22 -12
- package/CHANGELOG.md +33 -0
- package/Dockerfile +4 -5
- package/angular.json +2 -1
- package/deploy_amazon_prod.sh +5 -5
- package/package.json +1 -1
- package/src/app/app.component.html +3 -3
- package/src/app/app.component.scss +1 -1
- package/src/app/app.component.ts +23 -11
- package/src/app/app.module.ts +16 -10
- package/src/app/component/conversation-detail/conversation/conversation.component.scss +1 -1
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +20 -5
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +1 -0
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +8 -11
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +25 -0
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +57 -23
- package/src/app/component/{network-offline/network-offline.component.html → error-alert/error-alert.component.html} +4 -2
- package/src/app/component/{network-offline/network-offline.component.scss → error-alert/error-alert.component.scss} +3 -1
- package/src/app/component/{network-offline/network-offline.component.spec.ts → error-alert/error-alert.component.spec.ts} +8 -6
- package/src/app/component/error-alert/error-alert.component.ts +47 -0
- package/src/app/component/message/buttons/action-button/action-button.component.scss +6 -6
- package/src/app/component/message/buttons/action-button/action-button.component.ts +1 -1
- package/src/app/component/message/buttons/link-button/link-button.component.scss +5 -5
- package/src/app/component/message/buttons/link-button/link-button.component.ts +2 -2
- package/src/app/component/message/buttons/text-button/text-button.component.scss +9 -12
- package/src/app/component/message/buttons/text-button/text-button.component.ts +4 -4
- package/src/app/component/message-attachment/message-attachment.component.html +3 -7
- package/src/app/providers/translator.service.ts +8 -2
- package/src/app/sass/_variables.scss +1 -1
- package/src/app/utils/constants.ts +3 -0
- package/src/app/utils/utils.ts +8 -10
- package/src/assets/i18n/en.json +4 -1
- package/src/assets/i18n/es.json +6 -1
- package/src/assets/i18n/fr.json +6 -1
- package/src/assets/i18n/it.json +6 -3
- package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +2 -2
- package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +22 -11
- package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
- package/src/chat21-core/utils/utils.ts +15 -4
- package/src/iframe-style.css +1 -1
- package/src/app/component/network-offline/network-offline.component.ts +0 -24
package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Component, ComponentFactoryResolver, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core';
|
|
2
|
+
import { error } from 'console';
|
|
3
|
+
import { FILE_SIZE_LIMIT } from 'src/app/utils/constants';
|
|
2
4
|
import { Globals } from 'src/app/utils/globals';
|
|
3
5
|
import { checkAcceptedFile } from 'src/app/utils/utils';
|
|
4
6
|
import { MessageModel } from 'src/chat21-core/models/message';
|
|
@@ -82,7 +84,11 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
showAlertEmoji: boolean = false
|
|
85
|
-
|
|
87
|
+
|
|
88
|
+
file_size_limit = FILE_SIZE_LIMIT;
|
|
89
|
+
attachmentTooltip: string = '';
|
|
90
|
+
isErrorNetwork: boolean = false;
|
|
91
|
+
|
|
86
92
|
|
|
87
93
|
convertColorToRGBA = convertColorToRGBA;
|
|
88
94
|
private logger: LoggerService = LoggerInstance.getInstance()
|
|
@@ -91,8 +97,10 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
91
97
|
private uploadService: UploadService) { }
|
|
92
98
|
|
|
93
99
|
ngOnInit() {
|
|
100
|
+
// this.updateAttachmentTooltip();
|
|
94
101
|
}
|
|
95
102
|
|
|
103
|
+
|
|
96
104
|
ngOnChanges(changes: SimpleChanges){
|
|
97
105
|
if(changes['conversationWith'] && changes['conversationWith'].currentValue !== undefined){
|
|
98
106
|
this.conversationHandlerService = this.chatManager.getConversationHandlerByConversationId(this.conversationWith);
|
|
@@ -105,6 +113,10 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
105
113
|
this.onDrop(this.dropEvent)
|
|
106
114
|
}
|
|
107
115
|
|
|
116
|
+
// if(changes['translationMap'] && changes['translationMap'].currentValue !== undefined){
|
|
117
|
+
// this.updateAttachmentTooltip();
|
|
118
|
+
// }
|
|
119
|
+
|
|
108
120
|
}
|
|
109
121
|
|
|
110
122
|
ngAfterViewInit() {
|
|
@@ -112,8 +124,25 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
112
124
|
// setTimeout(() => {
|
|
113
125
|
this.showEmojiPicker = true
|
|
114
126
|
// }, 500);
|
|
127
|
+
// this.updateAttachmentTooltip();
|
|
115
128
|
}
|
|
116
129
|
|
|
130
|
+
|
|
131
|
+
// updateAttachmentTooltip() {
|
|
132
|
+
// // Use setTimeout to wait for the async translation map to be populated
|
|
133
|
+
// setTimeout(() => {
|
|
134
|
+
// this.logger.log('[CONV-FOOTER] updateAttachmentTooltip - translationMap:', this.translationMap);
|
|
135
|
+
// if (this.translationMap && this.translationMap.has('MAX_ATTACHMENT')) {
|
|
136
|
+
// const template = this.translationMap.get('MAX_ATTACHMENT');
|
|
137
|
+
// this.logger.log('[CONV-FOOTER] MAX_ATTACHMENT template:', template);
|
|
138
|
+
// // this.attachmentTooltip = template.replace('{{file_size_limit}}', this.file_size_limit.toString());
|
|
139
|
+
// this.logger.log('[CONV-FOOTER] attachmentTooltip:', this.attachmentTooltip);
|
|
140
|
+
// } else {
|
|
141
|
+
// this.logger.log('[CONV-FOOTER] MAX_ATTACHMENT not found in translationMap');
|
|
142
|
+
// }
|
|
143
|
+
// }, 500);
|
|
144
|
+
// }
|
|
145
|
+
|
|
117
146
|
// ========= begin:: functions send image ======= //
|
|
118
147
|
// START LOAD IMAGE //
|
|
119
148
|
/** load the selected image locally and open the pop up preview */
|
|
@@ -202,7 +231,12 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
202
231
|
const fileXLoad = this.arrayFilesLoad[0].file;
|
|
203
232
|
const uid = this.arrayFilesLoad[0].uid;
|
|
204
233
|
const type = this.arrayFilesLoad[0].type;
|
|
205
|
-
const size = this.arrayFilesLoad[0].size
|
|
234
|
+
const size = this.arrayFilesLoad[0].size;
|
|
235
|
+
if(size > this.file_size_limit * 1024 * 1024){
|
|
236
|
+
this.logger.error('[CONV-FOOTER] file size is greater than the limit: ', size, this.file_size_limit * 1024 * 1024);
|
|
237
|
+
this.showErrorNetwork();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
206
240
|
this.logger.log('[CONV-FOOTER] that.fileXLoad: ', type);
|
|
207
241
|
let metadata;
|
|
208
242
|
if (type.startsWith('image') && !type.includes('svg')) {
|
|
@@ -239,6 +273,17 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
239
273
|
}
|
|
240
274
|
|
|
241
275
|
|
|
276
|
+
private showErrorNetwork() {
|
|
277
|
+
// posso anche passare solo keyMessage, nel caso non voglio passare un messaggio custom posso passare message e params(se il messaggio possiede dei parametri),
|
|
278
|
+
//window.dispatchEvent(new CustomEvent('tooltipErrorMessage', { detail: { error: true, message: 'File size is greater than the limit {{file_size_limit}}', keyMessage: null, params: { file_size_limit: this.file_size_limit } } }));
|
|
279
|
+
window.dispatchEvent(new CustomEvent('tooltipErrorMessage', { detail: { error: true, keyMessage: 'MAX_ATTACHMENT' } }));
|
|
280
|
+
setTimeout(() => {
|
|
281
|
+
this.isFilePendingToUpload = false;
|
|
282
|
+
this.hideTextReply = false;
|
|
283
|
+
window.dispatchEvent(new CustomEvent('tooltipErrorMessage', { detail: { error: false, message: '', keyMessage: null } }));
|
|
284
|
+
}, 5000);
|
|
285
|
+
}
|
|
286
|
+
|
|
242
287
|
uploadSingle(metadata, file, messageText?: string) {
|
|
243
288
|
const that = this;
|
|
244
289
|
try {
|
|
@@ -319,14 +364,14 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
319
364
|
* @param additional_attributes
|
|
320
365
|
*/
|
|
321
366
|
sendMessage(msg: string, type: string, metadata?: any, additional_attributes?: any) { // sponziello
|
|
367
|
+
|
|
322
368
|
(metadata) ? metadata = metadata : metadata = '';
|
|
323
369
|
this.onEmojiiPickerShow.emit(false)
|
|
324
370
|
this.logger.log('[CONV-FOOTER] SEND MESSAGE: ', msg, type, metadata, additional_attributes);
|
|
325
371
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
return
|
|
372
|
+
let check = this.checkForEmojii(this.textInputTextArea)
|
|
373
|
+
if(!check){
|
|
374
|
+
return;
|
|
330
375
|
}
|
|
331
376
|
|
|
332
377
|
if (msg && msg.trim() !== '' || type === TYPE_MSG_IMAGE || type === TYPE_MSG_FILE ) {
|
|
@@ -536,22 +581,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
536
581
|
this.showAlertEmoji = false;
|
|
537
582
|
return true
|
|
538
583
|
}
|
|
539
|
-
|
|
540
|
-
checkForUrlDomain(text){
|
|
541
|
-
if(this.project && this.project.settings?.allowed_urls === true && this.project.settings?.allowed_urls_list){
|
|
542
|
-
this.showAlertUrl = !isAllowedUrlInText(text, this.project.settings?.allowed_urls_list);
|
|
543
|
-
if(this.showAlertUrl){
|
|
544
|
-
return false
|
|
545
|
-
}
|
|
546
|
-
this.showAlertUrl = false
|
|
547
|
-
return true
|
|
548
|
-
}
|
|
549
|
-
this.showAlertUrl = false
|
|
550
|
-
return true
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
}
|
|
554
|
-
|
|
555
584
|
|
|
556
585
|
|
|
557
586
|
onTextAreaChange(){
|
|
@@ -560,7 +589,6 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
560
589
|
|
|
561
590
|
//reset alert to defalt values before checking again
|
|
562
591
|
this.showAlertEmoji= false;
|
|
563
|
-
this.showAlertUrl = false;
|
|
564
592
|
let check = this.checkForEmojii(this.textInputTextArea)
|
|
565
593
|
if(!check){
|
|
566
594
|
return;
|
|
@@ -570,6 +598,9 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
570
598
|
onSendPressed(event) {
|
|
571
599
|
this.logger.log('[CONV-FOOTER] onSendPressed:event', event);
|
|
572
600
|
event.preventDefault();
|
|
601
|
+
if(this.showAlertEmoji){
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
573
604
|
this.logger.log('[CONV-FOOTER] AppComponent::onSendPressed::isFilePendingToUpload:', this.isFilePendingToUpload);
|
|
574
605
|
if (this.isFilePendingToUpload) {
|
|
575
606
|
this.logger.log('[CONV-FOOTER] AppComponent::onSendPressed', 'is a file');
|
|
@@ -697,6 +728,9 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
|
|
|
697
728
|
const keyCode = event.which || event.keyCode;
|
|
698
729
|
this.textInputTextArea = ((document.getElementById('chat21-main-message-context') as HTMLInputElement).value);
|
|
699
730
|
if (keyCode === 13) { // ENTER pressed
|
|
731
|
+
if(this.showAlertEmoji){
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
700
734
|
if (this.textInputTextArea && this.textInputTextArea.trim() !== '') {
|
|
701
735
|
// that.logger.log('[CONV-FOOTER] sendMessage -> ', this.textInputTextArea);
|
|
702
736
|
// this.resizeInputField();
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
<path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>
|
|
4
4
|
</svg>
|
|
5
5
|
<div class="alert-content">
|
|
6
|
-
{{
|
|
6
|
+
{{ errorMessage }}
|
|
7
7
|
</div>
|
|
8
|
-
</div>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { ErrorAlertComponent } from './error-alert.component';
|
|
4
4
|
|
|
5
|
-
describe('
|
|
6
|
-
let component:
|
|
7
|
-
let fixture: ComponentFixture<
|
|
5
|
+
describe('ErrorAlertComponent', () => {
|
|
6
|
+
let component: ErrorAlertComponent;
|
|
7
|
+
let fixture: ComponentFixture<ErrorAlertComponent>;
|
|
8
8
|
|
|
9
9
|
beforeEach(async () => {
|
|
10
10
|
await TestBed.configureTestingModule({
|
|
11
|
-
declarations: [
|
|
11
|
+
declarations: [ ErrorAlertComponent ]
|
|
12
12
|
})
|
|
13
13
|
.compileComponents();
|
|
14
14
|
|
|
15
|
-
fixture = TestBed.createComponent(
|
|
15
|
+
fixture = TestBed.createComponent(ErrorAlertComponent);
|
|
16
16
|
component = fixture.componentInstance;
|
|
17
17
|
fixture.detectChanges();
|
|
18
18
|
});
|
|
@@ -21,3 +21,5 @@ describe('NetworkOfflineComponent', () => {
|
|
|
21
21
|
expect(component).toBeTruthy();
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
|
+
|
|
25
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Component, Input, OnInit } from '@angular/core';
|
|
2
|
+
import { CustomTranslateService } from 'src/chat21-core/providers/custom-translate.service';
|
|
3
|
+
import * as CONSTANTS from 'src/app/utils/constants';
|
|
4
|
+
|
|
5
|
+
@Component({
|
|
6
|
+
selector: 'chat-error-alert',
|
|
7
|
+
templateUrl: './error-alert.component.html',
|
|
8
|
+
styleUrls: ['./error-alert.component.scss']
|
|
9
|
+
})
|
|
10
|
+
export class ErrorAlertComponent implements OnInit {
|
|
11
|
+
|
|
12
|
+
@Input() errorMessage: string = '';
|
|
13
|
+
@Input() errorKeyMessage: string = '';
|
|
14
|
+
@Input() errorParams: Record<string, any> = {};
|
|
15
|
+
|
|
16
|
+
translationMap: Map<string, string>;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
private customTranslateService: CustomTranslateService,
|
|
20
|
+
){}
|
|
21
|
+
|
|
22
|
+
ngOnInit(): void {
|
|
23
|
+
let rawMessage: string = '';
|
|
24
|
+
// Combina costanti globali + parametri passati come input
|
|
25
|
+
const replacements = { ...CONSTANTS, ...this.errorParams };
|
|
26
|
+
if (this.errorKeyMessage) {
|
|
27
|
+
// Traduci il messaggio e sostituisci i placeholder
|
|
28
|
+
rawMessage = this.customTranslateService
|
|
29
|
+
.translateLanguage([this.errorKeyMessage])
|
|
30
|
+
.get(this.errorKeyMessage);
|
|
31
|
+
} else if (this.errorMessage) {
|
|
32
|
+
rawMessage = this.errorMessage;
|
|
33
|
+
}
|
|
34
|
+
this.errorMessage = this.interpolate(rawMessage, replacements);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Sostituisce {{placeholders}} con i valori corrispondenti */
|
|
38
|
+
private interpolate(template: string, variables: Record<string, any>): string {
|
|
39
|
+
return template.replace(/\{\{(.*?)\}\}/g, (_, key) => {
|
|
40
|
+
const trimmedKey = key.trim();
|
|
41
|
+
return variables[trimmedKey] ?? `{{${trimmedKey}}}`;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
:host {
|
|
2
2
|
--backgroundColor: #{var(--blue)};
|
|
3
|
-
--
|
|
3
|
+
--buttonTextColor: #{var(--bck-msg-sent)};
|
|
4
4
|
--hoverBackgroundColor: #{var(--bck-msg-sent)};
|
|
5
5
|
--hoverTextColor: #{var(--blue)};
|
|
6
|
-
--
|
|
6
|
+
--buttonFontSize: #{var(--button-font-size)};
|
|
7
7
|
--max-width: #{var(--button-in-msg-max-width)};
|
|
8
8
|
--padding: #{var(--button-in-msg-padding)};
|
|
9
9
|
--font-family: #{var(--button-in-msg-font-family)};
|
|
10
10
|
--buttonBorderColor: #{var(--button-border-color)};
|
|
11
11
|
--buttonColor: #{var(--button-color)};
|
|
12
|
-
--buttonBackgroundColor: #
|
|
12
|
+
--buttonBackgroundColor: #{var(--button-background-color)};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.button-in-msg {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
border: 1px solid var(--buttonBorderColor);
|
|
21
21
|
background: var(--buttonBackgroundColor);
|
|
22
22
|
font-family: var(--font-family);
|
|
23
|
-
font-size: var(--
|
|
24
|
-
color: var(--
|
|
23
|
+
font-size: var(--buttonFontSize);
|
|
24
|
+
color: var(--buttonTextColor);
|
|
25
25
|
overflow: hidden;
|
|
26
26
|
-o-text-overflow: ellipsis;
|
|
27
27
|
text-overflow: ellipsis;
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
.action {
|
|
41
|
-
background: var(--backgroundColor);
|
|
41
|
+
// background: var(--backgroundColor);
|
|
42
42
|
transition: background-color .6s ease;
|
|
43
43
|
&:focus,
|
|
44
44
|
&:hover {
|
|
@@ -25,7 +25,7 @@ export class ActionButtonComponent implements OnInit {
|
|
|
25
25
|
ngOnChanges(changes: SimpleChanges){
|
|
26
26
|
//decomment if element should have same color of themeColor and fregroundColor
|
|
27
27
|
if(this.fontSize) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonFontSize', this.fontSize);
|
|
28
|
-
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--
|
|
28
|
+
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
|
|
29
29
|
if(this.textColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--textColor', this.textColor);
|
|
30
30
|
if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverBackgroundColor', this.hoverBackgroundColor);
|
|
31
31
|
if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverTextColor', this.hoverTextColor);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
:host {
|
|
2
2
|
--backgroundColor: #{var(--blue)};
|
|
3
|
-
--
|
|
3
|
+
--buttonTextColor: #{var(--bck-msg-sent)};
|
|
4
4
|
--hoverBackgroundColor: #{var(--bck-msg-sent)};
|
|
5
5
|
--hoverTextColor: #{var(--blue)};
|
|
6
|
-
--
|
|
6
|
+
--buttonFontSize: #{var(--button-font-size)};
|
|
7
7
|
--max-width: #{var(--button-in-msg-max-width)};
|
|
8
8
|
--padding: #{var(--button-in-msg-padding)};
|
|
9
9
|
--font-family: #{var(--button-in-msg-font-family)};
|
|
10
10
|
--buttonBorderColor: #{var(--button-border-color)};
|
|
11
11
|
--buttonColor: #{var(--button-color)};
|
|
12
|
-
--buttonBackgroundColor: #
|
|
12
|
+
--buttonBackgroundColor: #{var(--button-background-color)};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
border: 1px solid var(--buttonBorderColor);
|
|
22
22
|
background: var(--buttonBackgroundColor);
|
|
23
23
|
font-family: var(--font-family);
|
|
24
|
-
font-size: var(--
|
|
25
|
-
color: var(--
|
|
24
|
+
font-size: var(--buttonFontSize);
|
|
25
|
+
color: var(--buttonTextColor);
|
|
26
26
|
overflow: hidden;
|
|
27
27
|
-o-text-overflow: ellipsis;
|
|
28
28
|
text-overflow: ellipsis;
|
|
@@ -23,8 +23,8 @@ export class LinkButtonComponent implements OnInit {
|
|
|
23
23
|
ngOnChanges(changes: SimpleChanges){
|
|
24
24
|
//decomment if element should have same color of themeColor and fregroundColor
|
|
25
25
|
if(this.fontSize) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--buttonFontSize', this.fontSize);
|
|
26
|
-
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--
|
|
27
|
-
if(this.textColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--
|
|
26
|
+
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
|
|
27
|
+
if(this.textColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--buttonTextColor', this.textColor);
|
|
28
28
|
if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--hoverBackgroundColor', this.hoverBackgroundColor);
|
|
29
29
|
if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.url').style.setProperty('--hoverTextColor', this.hoverTextColor);
|
|
30
30
|
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
:host {
|
|
2
2
|
--backgroundColor: #{var(--blue)};
|
|
3
|
-
--
|
|
4
|
-
--
|
|
5
|
-
--
|
|
6
|
-
--
|
|
3
|
+
--buttonTextColor: #{var(--bck-msg-sent)};
|
|
4
|
+
--buttonHoverBackgroundColor: #{var(--bck-msg-sent)};
|
|
5
|
+
--buttonHoverTextColor: #{var(--blue)};
|
|
6
|
+
--buttonFontSize: #{var(--button-font-size)};
|
|
7
7
|
--max-width: #{var(--button-in-msg-max-width)};
|
|
8
8
|
--padding: #{var(--button-in-msg-padding)};
|
|
9
9
|
--font-family: #{var(--button-in-msg-font-family)};
|
|
10
10
|
--buttonBorderColor: #{var(--button-border-color)};
|
|
11
|
-
|
|
12
|
-
--buttonBackgroundColor: #ffffff; //#{var(--button-background-color)};
|
|
11
|
+
--buttonBackgroundColor: #{var(--button-background-color)};
|
|
13
12
|
--buttonColor: #{var(--button-color)};
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -21,11 +20,9 @@
|
|
|
21
20
|
cursor: pointer;
|
|
22
21
|
border: 1px solid var(--buttonBorderColor);
|
|
23
22
|
background: var(--buttonBackgroundColor);
|
|
24
|
-
// background: var(--backgroundColor);
|
|
25
23
|
font-family: var(--font-family);
|
|
26
|
-
font-size: var(--
|
|
27
|
-
|
|
28
|
-
color: var(--textColor);
|
|
24
|
+
font-size: var(--buttonFontSize);
|
|
25
|
+
color: var(--buttonTextColor);
|
|
29
26
|
overflow: hidden;
|
|
30
27
|
-o-text-overflow: ellipsis;
|
|
31
28
|
text-overflow: ellipsis;
|
|
@@ -47,8 +44,8 @@
|
|
|
47
44
|
transition: background-color .6s ease;
|
|
48
45
|
&:focus,
|
|
49
46
|
&:hover {
|
|
50
|
-
color: var(--
|
|
51
|
-
background: var(--
|
|
47
|
+
color: var(--buttonHoverTextColor);
|
|
48
|
+
background: var(--buttonHoverBackgroundColor);
|
|
52
49
|
// transform: scale(1.05);
|
|
53
50
|
.icon-button-action {
|
|
54
51
|
svg {
|
|
@@ -26,10 +26,10 @@ export class TextButtonComponent implements OnInit {
|
|
|
26
26
|
ngOnChanges(changes: SimpleChanges){
|
|
27
27
|
//decomment if element should have same color of themeColor and fregroundColor
|
|
28
28
|
if(this.fontSize) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonFontSize', this.fontSize);
|
|
29
|
-
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--
|
|
30
|
-
if(this.textColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--
|
|
31
|
-
if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--
|
|
32
|
-
if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--
|
|
29
|
+
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
|
|
30
|
+
if(this.textColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonTextColor', this.textColor);
|
|
31
|
+
if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonHoverBackgroundColor', this.hoverBackgroundColor);
|
|
32
|
+
if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.text').style.setProperty('--buttonHoverTextColor', this.hoverTextColor);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
onMouseOver(event){
|
|
@@ -3,15 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
<span *ngFor="let button of buttons | slice:0:limit" class="div-button">
|
|
5
5
|
|
|
6
|
-
<!--
|
|
7
|
-
// bubbleReceivedBackground
|
|
8
|
-
// buttonBackgroundColor
|
|
9
|
-
-->
|
|
10
6
|
<chat-text-button-attachment *ngIf="button.type === 'text' && isLastMessage === true" class="div-button"
|
|
11
7
|
[button]="button"
|
|
12
8
|
[isConversationArchived]="isConversationArchived"
|
|
13
9
|
[fontSize]="stylesMap.get('buttonFontSize')"
|
|
14
|
-
[backgroundColor]="stylesMap.get('
|
|
10
|
+
[backgroundColor]="stylesMap.get('buttonBackgroundColor')"
|
|
15
11
|
[textColor]="stylesMap.get('buttonTextColor')"
|
|
16
12
|
[hoverBackgroundColor]="stylesMap.get('buttonHoverBackgroundColor')"
|
|
17
13
|
[hoverTextColor]="stylesMap.get('buttonHoverTextColor')"
|
|
@@ -21,7 +17,7 @@
|
|
|
21
17
|
<chat-link-button-attachment *ngIf="button.type === 'url'" class="div-button"
|
|
22
18
|
[button]="button"
|
|
23
19
|
[fontSize]="stylesMap.get('buttonFontSize')"
|
|
24
|
-
[backgroundColor]="stylesMap.get('
|
|
20
|
+
[backgroundColor]="stylesMap.get('buttonBackgroundColor')"
|
|
25
21
|
[textColor]="stylesMap.get('buttonTextColor')"
|
|
26
22
|
[hoverBackgroundColor]="stylesMap.get('buttonHoverBackgroundColor')"
|
|
27
23
|
[hoverTextColor]="stylesMap.get('buttonHoverTextColor')"
|
|
@@ -32,7 +28,7 @@
|
|
|
32
28
|
[button]="button"
|
|
33
29
|
[isConversationArchived]="isConversationArchived"
|
|
34
30
|
[fontSize]="stylesMap.get('buttonFontSize')"
|
|
35
|
-
[backgroundColor]="stylesMap.get('
|
|
31
|
+
[backgroundColor]="stylesMap.get('buttonBackgroundColor')"
|
|
36
32
|
[textColor]="stylesMap.get('buttonTextColor')"
|
|
37
33
|
[hoverBackgroundColor]="stylesMap.get('buttonHoverBackgroundColor')"
|
|
38
34
|
[hoverTextColor]="stylesMap.get('buttonHoverTextColor')"
|
|
@@ -99,7 +99,7 @@ export class TranslatorService {
|
|
|
99
99
|
|
|
100
100
|
// https://github.com/ngx-translate/core/issues/282
|
|
101
101
|
initI18n(): Promise<any> {
|
|
102
|
-
this._translate.addLangs(['en', 'it']);
|
|
102
|
+
this._translate.addLangs(['en', 'it', 'es', 'fr']);
|
|
103
103
|
this.logger.debug('[TRANSLATOR-SERV]»»»» initI18n getLangs ', this._translate.getLangs());
|
|
104
104
|
|
|
105
105
|
// Set the default language for translation strings.
|
|
@@ -261,7 +261,10 @@ export class TranslatorService {
|
|
|
261
261
|
'WAITING_TIME_FOUND',
|
|
262
262
|
'WAITING_TIME_NOT_FOUND',
|
|
263
263
|
'CLOSED',
|
|
264
|
-
'LABEL_PREVIEW'
|
|
264
|
+
'LABEL_PREVIEW',
|
|
265
|
+
'MAX_ATTACHMENT',
|
|
266
|
+
'MAX_ATTACHMENT_ERROR',
|
|
267
|
+
'EMOJI'
|
|
265
268
|
];
|
|
266
269
|
|
|
267
270
|
|
|
@@ -316,6 +319,9 @@ export class TranslatorService {
|
|
|
316
319
|
globals.CLOSED = res['CLOSED'];
|
|
317
320
|
globals.LABEL_PREVIEW = res['LABEL_PREVIEW']
|
|
318
321
|
globals.LABEL_ERROR_FIELD_REQUIRED= res['LABEL_ERROR_FIELD_REQUIRED']
|
|
322
|
+
globals.MAX_ATTACHMENT = res['MAX_ATTACHMENT']
|
|
323
|
+
globals.MAX_ATTACHMENT_ERROR = res['MAX_ATTACHMENT_ERROR']
|
|
324
|
+
globals.EMOJI = res['EMOJI']
|
|
319
325
|
|
|
320
326
|
|
|
321
327
|
if(globals.WELCOME_TITLE === 'WELLCOME_TITLE') globals.WELCOME_TITLE = res['WELCOME_TITLE']
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
--button-in-msg-max-width: 280px;
|
|
25
25
|
--button-in-msg-padding: 8px 16px;
|
|
26
26
|
--button-color: #5c6c73;
|
|
27
|
-
--button-background-color: #f5f5f5; // #f9fcff;
|
|
27
|
+
--button-background-color: #ffffff;//#f5f5f5; // #f9fcff;
|
|
28
28
|
--button-border-color: #0000000f; //#e4ebf2;
|
|
29
29
|
--button-font-size: 13px;
|
|
30
30
|
|
package/src/app/utils/utils.ts
CHANGED
|
@@ -396,7 +396,7 @@ export function checkAcceptedFile(nameFile, fileType, fileUploadAccept): boolean
|
|
|
396
396
|
return acceptedTypes.some((accept) => {
|
|
397
397
|
accept = accept.trim();
|
|
398
398
|
|
|
399
|
-
// Controlla
|
|
399
|
+
// Controlla wildcard MIME type (es. "image/*")
|
|
400
400
|
if (accept.endsWith('/*')) {
|
|
401
401
|
const baseMimeType = fileType.split('/')[0]; // Ottieni la parte principale del MIME type
|
|
402
402
|
return accept.replace('/*', '') === baseMimeType;
|
|
@@ -413,19 +413,17 @@ export function checkAcceptedFile(nameFile, fileType, fileUploadAccept): boolean
|
|
|
413
413
|
return true;
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
-
//
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
416
|
+
// Controlla estensione con punto (es. ".pdf")
|
|
417
|
+
if (accept.startsWith('.')) {
|
|
418
|
+
return fileExtension === accept.slice(1);
|
|
419
|
+
}
|
|
420
420
|
|
|
421
|
-
// Controlla se
|
|
422
|
-
|
|
423
|
-
const acceptedTypes = fileUploadAccept.split(',');
|
|
424
|
-
//verifica se l'estensione del file è accettata
|
|
425
|
-
if (acceptedTypes.includes(fileExtension)) {
|
|
421
|
+
// Controlla se accept è un'estensione senza punto (es. "pdf")
|
|
422
|
+
if (!accept.includes('/') && fileExtension === accept) {
|
|
426
423
|
return true;
|
|
427
424
|
}
|
|
428
425
|
|
|
426
|
+
|
|
429
427
|
return false;
|
|
430
428
|
});
|
|
431
429
|
}
|
package/src/assets/i18n/en.json
CHANGED
|
@@ -94,5 +94,8 @@
|
|
|
94
94
|
"SWITCH_TO": "Or switch to:",
|
|
95
95
|
"CONNECTION_NETWORK_ERROR": "Our apologies. There was some trouble connecting to network",
|
|
96
96
|
"EMOJI_NOT_ELLOWED":"Emoji not allowed",
|
|
97
|
-
"DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain"
|
|
97
|
+
"DOMAIN_NOT_ALLOWED":"URL contains a non-allowed domain",
|
|
98
|
+
"MAX_ATTACHMENT": "Max allowed size {{FILE_SIZE_LIMIT}}Mb",
|
|
99
|
+
"MAX_ATTACHMENT_ERROR": "The file exceeds the maximum allowed size",
|
|
100
|
+
"EMOJI": "Emoji"
|
|
98
101
|
}
|
package/src/assets/i18n/es.json
CHANGED
|
@@ -92,5 +92,10 @@
|
|
|
92
92
|
|
|
93
93
|
"LABEL_PREVIEW": "Avance",
|
|
94
94
|
"SWITCH_TO":"O cambiar a:",
|
|
95
|
-
"CONNECTION_NETWORK_ERROR": "Nuestras disculpas. Hubo algunos problemas para conectarse a la red"
|
|
95
|
+
"CONNECTION_NETWORK_ERROR": "Nuestras disculpas. Hubo algunos problemas para conectarse a la red",
|
|
96
|
+
"EMOJI_NOT_ELLOWED":"Emoji no permitido",
|
|
97
|
+
"DOMAIN_NOT_ALLOWED":"La URL contiene un dominio no permitido",
|
|
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",
|
|
100
|
+
"EMOJI": "Emoji"
|
|
96
101
|
}
|
package/src/assets/i18n/fr.json
CHANGED
|
@@ -92,5 +92,10 @@
|
|
|
92
92
|
|
|
93
93
|
"LABEL_PREVIEW": "Aperçu",
|
|
94
94
|
"SWITCH_TO":"Ou passer à:",
|
|
95
|
-
"CONNECTION_NETWORK_ERROR": "Nos excuses. Il y a eu des problèmes de connexion au réseau"
|
|
95
|
+
"CONNECTION_NETWORK_ERROR": "Nos excuses. Il y a eu des problèmes de connexion au réseau",
|
|
96
|
+
"EMOJI_NOT_ELLOWED":"Emoji non autorisé",
|
|
97
|
+
"DOMAIN_NOT_ALLOWED":"L'URL contient un domaine non autorisé",
|
|
98
|
+
"MAX_ATTACHMENT": "Taille maximale autorisée {{FILE_SIZE_LIMIT}}Mo",
|
|
99
|
+
"MAX_ATTACHMENT_ERROR": "Le fichier dépasse la taille maximale autorisée",
|
|
100
|
+
"EMOJI": "Emoji"
|
|
96
101
|
}
|
package/src/assets/i18n/it.json
CHANGED
|
@@ -86,11 +86,14 @@
|
|
|
86
86
|
"LABEL_LAST_ACCESS": "ultimo accesso",
|
|
87
87
|
"LABEL_TO": "a",
|
|
88
88
|
"ARRAY_DAYS": ["Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"],
|
|
89
|
-
|
|
90
89
|
"SENT_AN_ATTACHMENT": "ha inviato un allegato",
|
|
91
90
|
"SENT_AN_IMAGE":"ha inviato un'immagine",
|
|
92
|
-
|
|
93
91
|
"LABEL_PREVIEW": "Anteprima",
|
|
94
92
|
"SWITCH_TO":"Oppure passa a:",
|
|
95
|
-
"CONNECTION_NETWORK_ERROR": "Ci scusiamo. Si sono verificati problemi di connessione di rete"
|
|
93
|
+
"CONNECTION_NETWORK_ERROR": "Ci scusiamo. Si sono verificati problemi di connessione di rete",
|
|
94
|
+
"EMOJI_NOT_ELLOWED":"Emoji non consentiti",
|
|
95
|
+
"DOMAIN_NOT_ALLOWED":"L'URL contiene un dominio non consentito",
|
|
96
|
+
"MAX_ATTACHMENT": "Dimensione massima consentita {{FILE_SIZE_LIMIT}}Mb",
|
|
97
|
+
"MAX_ATTACHMENT_ERROR": "Il file supera la dimensione massima consentita",
|
|
98
|
+
"EMOJI": "Emoji"
|
|
96
99
|
}
|
|
@@ -413,8 +413,8 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
|
|
|
413
413
|
message.text = INFO_SUPPORT_LEAD_UPDATED;
|
|
414
414
|
} else if (infoMessageType(message) === INFO_MESSAGE_TYPE.MEMBER_LEFT_GROUP) {
|
|
415
415
|
let subject: string = '';
|
|
416
|
-
if (message.attributes.messagelabel.parameters.
|
|
417
|
-
subject = message.attributes.messagelabel.parameters.
|
|
416
|
+
if (message.attributes.messagelabel.parameters.firstname) {
|
|
417
|
+
subject = message.attributes.messagelabel.parameters.firstname;
|
|
418
418
|
}else{
|
|
419
419
|
subject = message.attributes.messagelabel.parameters.member_id;
|
|
420
420
|
}
|