Skip to content

Commit 7b2b498

Browse files
author
Gabriele Panico
committed
Merge commit '6b23df8d532fafbbda2300164911f4d1e3cd9f6b'
2 parents a7a0301 + 6b23df8 commit 7b2b498

File tree

15 files changed

+156
-32
lines changed

15 files changed

+156
-32
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ src/widget-config-docker.json
5050
src/widget-config-native-mqtt.json
5151

5252
.angular/cache/
53+
docs/agents

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@
66
### **Copyrigth**:
77
*Tiledesk SRL*
88

9+
10+
# 5.1.19
11+
- **bug fixed**: show bottom scroll button and unread message badge only when I'm not at the bottom of the page
12+
- **changed**: allow HTML code to be inserted into messages, but do not parse the code. Ensure coexistence with Markdown.
13+
- **bug fixed**: after sending a multi-line message, the text area remains open on multiple lines.
14+
- **bug fixed**: fixed widget animation when opened
15+
- **bug-fixed**: line-height in markdown
16+
- **bug-fixed**: when i move to top mode and close the widget, the balloon moves to the right
17+
- **changed**: saved the widget's size state to local storage. The parameter flow is (default → storage → settings → URL)
18+
919
# 5.1.18
1020
- **added**: Implemented Shadow DOM in the text component to isolate HTML and Markdown rendering in a safe and protected context
1121
- **changed**: Adapted text component styles to support Shadow DOM (removed ::ng-deep, added styles for common markdown elements)
1222
- **security**: HTML/Markdown content is now rendered in an isolated Shadow DOM, improving security and preventing interference with the rest of the application
1323

14-
1524
# 5.1.17
1625
- **bug-fixed**: set the maximum width on a message with iframe
1726

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@chat21/chat21-web-widget",
33
"author": "Tiledesk SRL",
4-
"version": "5.1.18",
4+
"version": "5.1.19",
55
"license": "MIT",
66
"homepage": "https://www.tiledesk.com",
77
"repository": {

src/app/app.component.scss

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,14 +488,11 @@ chat-root {
488488
right: 0px;
489489
top: 0px;
490490
bottom: 0px;
491-
// border-radius: 16px;
492491
overflow: hidden;
493492
background-color: transparent;
494-
// border: 1px solid #cccccc; //NEW GAB
495493
margin: 0px;
496494
padding: 0px;
497-
// box-shadow:rgba(0, 0, 0, 0.16) 0px 8px 36px 0px; //NEW GAB
498-
495+
opacity: 0;
499496
&.full-screen-mode {
500497
width: 100%;
501498
height: 100%;

src/app/component/conversation-detail/conversation-content/conversation-content.component.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ export class ConversationContentComponent implements OnInit {
187187
objDiv.parentElement.scrollTop = objDiv.scrollHeight;
188188
objDiv.style.opacity = '1';
189189
that.firstScroll = false;
190+
// Keep parent state in sync even when scroll is programmatic.
191+
// Without this, the "scroll to bottom" button/badge can remain visible
192+
// because (scroll) event might not fire reliably for programmatic scrollTop.
193+
that.onScrollContent.emit(true);
190194
}, 0);
191195
} catch (err) {
192196
this.logger.error('[CONV-CONTENT] scrollToBottom > Error :' + err);

src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,10 @@ textarea:active{
192192
max-height: 110px;
193193
min-height: auto;
194194
height: 20px;
195-
padding: 0px 12px; //0px 40px 0px 70px; //NEW FOR EMOJII BUTTON
195+
padding: 0px 12px;
196196
margin: 10px 0px 10px;
197197
border: none;
198+
display: inline-block;
198199

199200
&::-webkit-scrollbar {
200201
width: 6px;

src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -447,20 +447,19 @@ export class ConversationFooterComponent implements OnInit, OnChanges {
447447
}
448448

449449
private restoreTextArea() {
450-
// that.logger.log('[CONV-FOOTER] AppComponent:restoreTextArea::restoreTextArea');
451-
this.resizeInputField();
452450
const textArea = (<HTMLInputElement>document.getElementById('chat21-main-message-context'));
453-
this.textInputTextArea = ''; // clear the textarea
451+
this.textInputTextArea = '';
454452
if (textArea) {
455-
textArea.value = ''; // clear the textarea
456-
textArea.placeholder = this.translationMap.get('LABEL_PLACEHOLDER'); // restore the placholder
453+
textArea.value = '';
454+
textArea.placeholder = this.translationMap.get('LABEL_PLACEHOLDER');
457455
if(textArea.style.height > this.HEIGHT_DEFAULT){
458456
document.getElementById('chat21-button-send').style.removeProperty('right')
459457
}
460458
this.logger.log('[CONV-FOOTER] AppComponent:restoreTextArea::restoreTextArea::textArea:', 'restored');
461459
}
462460
this.setFocusOnId('chat21-main-message-context');
463461
this.isStopRec= false;
462+
this.resizeInputField();
464463
}
465464

466465
/**

src/app/component/conversation-detail/conversation/conversation.component.ts

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,19 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
298298
if (this.afConversationComponent) {
299299
this.afConversationComponent.nativeElement.focus();
300300
}
301+
// Sync initial "scroll to bottom" button/badge visibility.
302+
// The state is normally driven by real scroll events, but on first render
303+
// we might not get any scroll event -> stale UI.
304+
setTimeout(() => {
305+
try {
306+
const isAtBottom = this.conversationContent?.checkContentScrollPosition();
307+
if (typeof isAtBottom === 'boolean') {
308+
this.onScrollContent(isAtBottom);
309+
}
310+
} catch (e) {
311+
this.logger.error('[CONV-COMP] initial scroll state sync error:', e);
312+
}
313+
}, 0);
301314
this.isButtonsDisabled = false;
302315
}, 300);
303316
}
@@ -1074,29 +1087,76 @@ export class ConversationComponent implements OnInit, AfterViewInit, OnChanges {
10741087
// this.hideTextAreaContent = true
10751088
}
10761089
/** CALLED BY: conv-header component */
1077-
onWidgetSizeChange(mode: 'min' | 'max' | 'top'){
1078-
var tiledeskDiv = this.g.windowContext.window.document.getElementById('tiledeskdiv');
1079-
this.g.size = mode
1090+
onWidgetSizeChange(mode: any){
1091+
const normalize = (val: any): 'min' | 'max' | 'top' => {
1092+
const v = (typeof val === 'string') ? val.toLowerCase().trim() : '';
1093+
return (v === 'min' || v === 'max' || v === 'top') ? (v as any) : 'min';
1094+
};
1095+
1096+
const normalizedMode = normalize(mode);
1097+
const tiledeskDiv = this.g.windowContext?.window?.document?.getElementById('tiledeskdiv');
1098+
if(!tiledeskDiv){
1099+
this.g.size = normalizedMode;
1100+
this.isMenuShow = false;
1101+
return;
1102+
}
1103+
1104+
this.g.size = normalizedMode;
10801105
const parent = tiledeskDiv.parentElement as HTMLElement | null;
1081-
if(mode==='max'){
1106+
if(normalizedMode==='max'){
1107+
this.restoreInlinePositionStylesForPopup(tiledeskDiv);
10821108
tiledeskDiv.classList.add('max-size')
10831109
tiledeskDiv.classList.remove('min-size')
10841110
tiledeskDiv.classList.remove('top-size')
10851111
if(parent) parent.classList.remove('overlay--popup');
1086-
} else if(mode==='min'){
1112+
} else if(normalizedMode==='min'){
1113+
this.restoreInlinePositionStylesForPopup(tiledeskDiv);
10871114
tiledeskDiv.classList.add('min-size')
10881115
tiledeskDiv.classList.remove('max-size')
10891116
tiledeskDiv.classList.remove('top-size')
10901117
if(parent) parent.classList.remove('overlay--popup');
1091-
} else if(mode=== 'top'){
1118+
} else if(normalizedMode=== 'top'){
1119+
// Remove inline positioning so CSS can control centering without needing `!important`.
1120+
// this.clearInlinePositionStylesForPopup(tiledeskDiv);
10921121
tiledeskDiv.classList.add('top-size')
10931122
tiledeskDiv.classList.remove('max-size')
10941123
tiledeskDiv.classList.remove('min-size')
10951124
if(parent) parent.classList.add('overlay--popup');
10961125
}
1126+
1127+
// Persist user-driven size changes so, when `size` is not specified via URL/settings,
1128+
// GlobalSettingsService can restore it from storage (it already loads `size` from storage).
1129+
try{
1130+
this.appStorageService.setItem('size', normalizedMode);
1131+
}catch(e){
1132+
this.logger.warn('[CONV-COMP] onWidgetSizeChange > cannot persist size', e);
1133+
}
1134+
10971135
this.isMenuShow = false;
10981136
}
10991137

1138+
// private clearInlinePositionStylesForPopup(tiledeskDiv: HTMLElement) {
1139+
// tiledeskDiv.style.removeProperty('left');
1140+
// tiledeskDiv.style.removeProperty('right');
1141+
// tiledeskDiv.style.removeProperty('top');
1142+
// tiledeskDiv.style.removeProperty('bottom');
1143+
// }
1144+
1145+
private restoreInlinePositionStylesForPopup(tiledeskDiv: HTMLElement) {
1146+
const marginX = this.g.isMobile ? this.g.mobileMarginX : this.g.marginX;
1147+
const marginY = this.g.isMobile ? this.g.mobileMarginY : this.g.marginY;
1148+
1149+
if (this.g.align === 'left') {
1150+
tiledeskDiv.style.left = marginX;
1151+
tiledeskDiv.style.removeProperty('right');
1152+
} else {
1153+
tiledeskDiv.style.right = marginX;
1154+
tiledeskDiv.style.removeProperty('left');
1155+
}
1156+
tiledeskDiv.style.bottom = marginY;
1157+
tiledeskDiv.style.removeProperty('top');
1158+
}
1159+
11001160

11011161
/** CALLED BY: conv-header component */
11021162
onSignOutFN(event){
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
<div id="htmlCode" #htmlCode [innerHTML]="htmlText | safeHtml"></div>
1+
<!--
2+
Security: render HTML messages as plain text (no DOM interpretation).
3+
This preserves the exact input (e.g. "<h1>...</h1>") including line breaks.
4+
-->
5+
<pre id="htmlCode" #htmlCode [textContent]="htmlText"></pre>

0 commit comments

Comments
 (0)