@chat21/chat21-web-widget 5.1.8-ar → 5.1.9-ar
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/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
### **Copyrigth**:
|
|
7
7
|
*Tiledesk SRL*
|
|
8
8
|
|
|
9
|
+
# 5.1.9-ar
|
|
10
|
+
- **bug-fixed**: set default widget size
|
|
11
|
+
|
|
9
12
|
# 5.1.8-ar
|
|
10
13
|
- **changed**: update emoji detection logic in conversation-footer and utils
|
|
11
14
|
- **bug-fixed**: 'DOMAIN_NOT_ALLOWED' in textarea footer component
|
|
@@ -23,6 +26,9 @@
|
|
|
23
26
|
# 5.1.7-rc6
|
|
24
27
|
- **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
|
|
25
28
|
|
|
29
|
+
# this branch
|
|
30
|
+
- **bug-fixed**: set the color of the buttons with visibility control to the font color (setButtonColors function)
|
|
31
|
+
|
|
26
32
|
# 5.1.7-rc5
|
|
27
33
|
- **bug-fixed**: bug fixed BUTTON STYLES
|
|
28
34
|
|
package/package.json
CHANGED
package/src/app/app.component.ts
CHANGED
|
@@ -401,9 +401,11 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
401
401
|
this.triggerLoadParamsEvent(); // first trigger
|
|
402
402
|
//this.setAvailableAgentsStatus();
|
|
403
403
|
|
|
404
|
-
|
|
405
404
|
/** NETWORK STATUS */
|
|
406
|
-
this.listenToNetworkStatus()
|
|
405
|
+
this.listenToNetworkStatus();
|
|
406
|
+
|
|
407
|
+
/** SET WIDGET SIZE */
|
|
408
|
+
this.onWidgetSizeChange(this.g.size);
|
|
407
409
|
|
|
408
410
|
}
|
|
409
411
|
|
|
@@ -727,7 +729,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
727
729
|
// visualizzo l'iframe!!!
|
|
728
730
|
this.triggerOnViewInit();
|
|
729
731
|
this.g.setParentBodyStyleMobile(this.g.isOpen, this.g.isMobile);
|
|
730
|
-
this.g.setElementStyle(this.g.isOpen)
|
|
732
|
+
this.g.setElementStyle(this.g.isOpen);
|
|
731
733
|
// this.triggerOnAuthStateChanged(true)
|
|
732
734
|
// mostro il widget
|
|
733
735
|
// setTimeout(() => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { getColorBck } from 'src/chat21-core/utils/utils-user';
|
|
2
3
|
|
|
3
4
|
@Component({
|
|
4
5
|
selector: 'chat-action-button-attachment',
|
|
@@ -26,9 +27,10 @@ export class ActionButtonComponent implements OnInit {
|
|
|
26
27
|
//decomment if element should have same color of themeColor and fregroundColor
|
|
27
28
|
if(this.fontSize) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonFontSize', this.fontSize);
|
|
28
29
|
if(this.backgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonBackgroundColor', this.backgroundColor);
|
|
29
|
-
if(this.textColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--
|
|
30
|
+
if(this.textColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonTextColor', this.textColor);
|
|
30
31
|
if(this.hoverBackgroundColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverBackgroundColor', this.hoverBackgroundColor);
|
|
31
32
|
if(this.hoverTextColor) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverTextColor', this.hoverTextColor);
|
|
33
|
+
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
onMouseOver(event){
|
|
@@ -10,7 +10,7 @@ import { TemplateBindingParseResult } from '@angular/compiler';
|
|
|
10
10
|
import { AppStorageService } from '../../chat21-core/providers/abstract/app-storage.service';
|
|
11
11
|
import { LoggerService } from '../../chat21-core/providers/abstract/logger.service';
|
|
12
12
|
import { LoggerInstance } from '../../chat21-core/providers/logger/loggerInstance';
|
|
13
|
-
import { invertColor, isAllowedUrlInText, isJsonArray } from '../../chat21-core/utils/utils';
|
|
13
|
+
import { ensureAccessibleTextColor, invertColor, isAllowedUrlInText, isJsonArray, normalizeColorToHex } from '../../chat21-core/utils/utils';
|
|
14
14
|
import { AppConfigService } from './app-config.service';
|
|
15
15
|
|
|
16
16
|
|
|
@@ -322,10 +322,14 @@ export class GlobalSettingsService {
|
|
|
322
322
|
if (response !== null) {
|
|
323
323
|
this.setVariablesFromService(this.globals, response);
|
|
324
324
|
}
|
|
325
|
+
/** set button colors */
|
|
326
|
+
this.setButtonColors();
|
|
327
|
+
|
|
325
328
|
this.setVariableFromStorage(this.globals);
|
|
326
329
|
this.setVariablesFromSettings(this.globals);
|
|
327
330
|
this.setVariablesFromAttributeHtml(this.globals, this.el);
|
|
328
331
|
this.setVariablesFromUrlParameters(this.globals);
|
|
332
|
+
|
|
329
333
|
this.setDepartmentFromExternal();
|
|
330
334
|
/** set color with gradient from theme's colors */
|
|
331
335
|
this.globals.setColorWithGradient();
|
|
@@ -333,11 +337,19 @@ export class GlobalSettingsService {
|
|
|
333
337
|
this.setCssIframe();
|
|
334
338
|
/** set main style */
|
|
335
339
|
this.setStyle();
|
|
336
|
-
|
|
337
|
-
this.logger.debug('[GLOBAL-SET] ***** END SET PARAMETERS *****');
|
|
338
340
|
this.obsSettingsService.next(true);
|
|
339
341
|
}
|
|
340
342
|
|
|
343
|
+
private setButtonColors() {
|
|
344
|
+
this.logger.debug('[GLOBAL-SET] ***** END SET PARAMETERS *****', this.globals);
|
|
345
|
+
const bubbleSentBackground = this.globals?.bubbleSentBackground;
|
|
346
|
+
const buttonBackgroundColor = this.globals?.buttonBackgroundColor;
|
|
347
|
+
|
|
348
|
+
this.globals.buttonTextColor = ensureAccessibleTextColor(buttonBackgroundColor, bubbleSentBackground);
|
|
349
|
+
this.globals.buttonHoverTextColor = ensureAccessibleTextColor(bubbleSentBackground, buttonBackgroundColor);
|
|
350
|
+
|
|
351
|
+
}
|
|
352
|
+
|
|
341
353
|
/**
|
|
342
354
|
*
|
|
343
355
|
*/
|
|
@@ -1936,7 +1948,7 @@ export class GlobalSettingsService {
|
|
|
1936
1948
|
if (this.globals.departmentID) {
|
|
1937
1949
|
this.globals.departments.forEach(department => {
|
|
1938
1950
|
if (department._id === this.globals.departmentID) {
|
|
1939
|
-
|
|
1951
|
+
console.log('[GLOBAL-SET] setDepartmentFromExternal > EXTERNAL DEPARTMENT ::::' + department._id);
|
|
1940
1952
|
this.globals.setParameter('departmentDefault', department);
|
|
1941
1953
|
this.setDepartment(department);
|
|
1942
1954
|
isValidID = true;
|
|
@@ -1964,7 +1976,7 @@ export class GlobalSettingsService {
|
|
|
1964
1976
|
* save attributes in this.appStorageService
|
|
1965
1977
|
*/
|
|
1966
1978
|
setDepartment(department) {
|
|
1967
|
-
this.logger.
|
|
1979
|
+
this.logger.log('[GLOBAL-SET] setDepartment: ', JSON.stringify(department));
|
|
1968
1980
|
this.globals.setParameter('departmentSelected', department);
|
|
1969
1981
|
// let attributes = this.globals.attributes;
|
|
1970
1982
|
let attributes: any = JSON.parse(this.appStorageService.getItem('attributes'));
|
|
@@ -389,6 +389,115 @@ export function convertColorToRGBA(color, opacity) {
|
|
|
389
389
|
return result;
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
export function normalizeColorToHex(input?: string): string | null {
|
|
393
|
+
if (!input) {
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
let color = input.trim();
|
|
397
|
+
if (color.toLowerCase().includes('gradient')) {
|
|
398
|
+
const match = color.match(/(#[0-9a-fA-F]{3,8}|rgba?\([^)]*\))/);
|
|
399
|
+
if (!match) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
color = match[0];
|
|
403
|
+
}
|
|
404
|
+
if (color.startsWith('#')) {
|
|
405
|
+
const hex = color.slice(1);
|
|
406
|
+
if (hex.length === 3) {
|
|
407
|
+
return (
|
|
408
|
+
'#' +
|
|
409
|
+
hex
|
|
410
|
+
.split('')
|
|
411
|
+
.map((char) => char + char)
|
|
412
|
+
.join('')
|
|
413
|
+
.toLowerCase()
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
if (hex.length === 4) {
|
|
417
|
+
return (
|
|
418
|
+
'#' +
|
|
419
|
+
hex
|
|
420
|
+
.slice(0, 3)
|
|
421
|
+
.split('')
|
|
422
|
+
.map((char) => char + char)
|
|
423
|
+
.join('')
|
|
424
|
+
.toLowerCase()
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
if (hex.length === 6 || hex.length === 8) {
|
|
428
|
+
return '#' + hex.slice(0, 6).toLowerCase();
|
|
429
|
+
}
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
const rgbaMatch = color.match(/rgba?\s*\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)/i);
|
|
433
|
+
if (rgbaMatch) {
|
|
434
|
+
const [, r, g, b] = rgbaMatch;
|
|
435
|
+
const toHex = (value: number) => {
|
|
436
|
+
const clamped = Math.max(0, Math.min(255, Math.round(value)));
|
|
437
|
+
return clamped.toString(16).padStart(2, '0');
|
|
438
|
+
};
|
|
439
|
+
return `#${toHex(parseFloat(r))}${toHex(parseFloat(g))}${toHex(parseFloat(b))}`;
|
|
440
|
+
}
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export function ensureAccessibleTextColor(backgroundColor?: string, fontColor?: string, minContrast = 4.5): string | null {
|
|
445
|
+
const bgHex = normalizeColorToHex(backgroundColor);
|
|
446
|
+
if (!bgHex) {
|
|
447
|
+
return normalizeColorToHex(fontColor);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const fontHex = normalizeColorToHex(fontColor);
|
|
451
|
+
if (fontHex && getContrastRatio(bgHex, fontHex) >= minContrast) {
|
|
452
|
+
return fontHex;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const blackContrast = getContrastRatio(bgHex, '#000000');
|
|
456
|
+
const whiteContrast = getContrastRatio(bgHex, '#ffffff');
|
|
457
|
+
return blackContrast >= whiteContrast ? '#000000' : '#ffffff';
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function getContrastRatio(backgroundHex: string, foregroundHex: string): number {
|
|
461
|
+
const bg = hexToRgb(backgroundHex);
|
|
462
|
+
const fg = hexToRgb(foregroundHex);
|
|
463
|
+
if (!bg || !fg) {
|
|
464
|
+
return 1;
|
|
465
|
+
}
|
|
466
|
+
const l1 = relativeLuminance(bg);
|
|
467
|
+
const l2 = relativeLuminance(fg);
|
|
468
|
+
const lighter = Math.max(l1, l2);
|
|
469
|
+
const darker = Math.min(l1, l2);
|
|
470
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function relativeLuminance({ r, g, b }: { r: number; g: number; b: number }): number {
|
|
474
|
+
const srgb = [r, g, b].map((value) => {
|
|
475
|
+
const channel = value / 255;
|
|
476
|
+
return channel <= 0.03928 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);
|
|
477
|
+
});
|
|
478
|
+
return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
|
|
482
|
+
let value = hex.replace('#', '');
|
|
483
|
+
if (value.length === 3) {
|
|
484
|
+
value = value
|
|
485
|
+
.split('')
|
|
486
|
+
.map((char) => char + char)
|
|
487
|
+
.join('');
|
|
488
|
+
}
|
|
489
|
+
if (value.length !== 6) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
const r = parseInt(value.slice(0, 2), 16);
|
|
493
|
+
const g = parseInt(value.slice(2, 4), 16);
|
|
494
|
+
const b = parseInt(value.slice(4, 6), 16);
|
|
495
|
+
if ([r, g, b].some((channel) => Number.isNaN(channel))) {
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
return { r, g, b };
|
|
499
|
+
}
|
|
500
|
+
|
|
392
501
|
|
|
393
502
|
// export function setLanguage(windowContext, translatorService) {
|
|
394
503
|
// if (translatorService.getBrowserLanguage(windowContext)) {
|