@trixwell/ngx-parl 5.0.0 → 6.0.0

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.
@@ -2,18 +2,18 @@ import * as i0 from '@angular/core';
2
2
  import { input, inject, model, computed, effect, ViewChild, Component, Injectable, Pipe, signal, ViewEncapsulation, Optional, isDevMode } from '@angular/core';
3
3
  import { NgClass, NgOptimizedImage, DatePipe } from '@angular/common';
4
4
  import { toSignal } from '@angular/core/rxjs-interop';
5
+ import { filter, map, startWith, of } from 'rxjs';
5
6
  import { FormsModule } from '@angular/forms';
6
7
  import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu';
7
8
  import * as i2 from '@ngneat/transloco';
8
- import { TranslocoPipe, TranslocoService, TranslocoModule, provideTransloco } from '@ngneat/transloco';
9
+ import { TranslocoPipe, TranslocoService, getValue, TranslocoModule, provideTransloco } from '@ngneat/transloco';
9
10
  import { FocusTrapFactory } from '@angular/cdk/a11y';
10
- import { IonButton, IonAlert } from '@ionic/angular/standalone';
11
11
  import * as i1 from '@angular/common/http';
12
12
  import { InfiniteScrollDirective } from 'ngx-infinite-scroll';
13
+ import { IonAlert } from '@ionic/angular/standalone';
13
14
  import * as i3 from '@angular/material/dialog';
14
15
  import { MatDialogContent, MatDialogTitle } from '@angular/material/dialog';
15
16
  import { MatProgressSpinner } from '@angular/material/progress-spinner';
16
- import { of } from 'rxjs';
17
17
 
18
18
  class ChatMessage {
19
19
  id;
@@ -68,16 +68,16 @@ var MessageType;
68
68
  })(MessageType || (MessageType = {}));
69
69
 
70
70
  class PreviewFile {
71
- srcList = input([], ...(ngDevMode ? [{ debugName: "srcList" }] : []));
72
- startIndex = input(0, ...(ngDevMode ? [{ debugName: "startIndex" }] : []));
73
- title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
74
- openerElement = input(null, ...(ngDevMode ? [{ debugName: "openerElement" }] : []));
75
- closeHandler = input(null, ...(ngDevMode ? [{ debugName: "closeHandler" }] : []));
71
+ srcList = input([], ...(ngDevMode ? [{ debugName: "srcList" }] : /* istanbul ignore next */ []));
72
+ startIndex = input(0, ...(ngDevMode ? [{ debugName: "startIndex" }] : /* istanbul ignore next */ []));
73
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
74
+ openerElement = input(null, ...(ngDevMode ? [{ debugName: "openerElement" }] : /* istanbul ignore next */ []));
75
+ closeHandler = input(null, ...(ngDevMode ? [{ debugName: "closeHandler" }] : /* istanbul ignore next */ []));
76
76
  focusTrapFactory = inject(FocusTrapFactory);
77
- activeIndex = model(0, ...(ngDevMode ? [{ debugName: "activeIndex" }] : []));
78
- viewReady = model(false, ...(ngDevMode ? [{ debugName: "viewReady" }] : []));
79
- userNavigated = model(false, ...(ngDevMode ? [{ debugName: "userNavigated" }] : []));
80
- previousListLength = model(0, ...(ngDevMode ? [{ debugName: "previousListLength" }] : []));
77
+ activeIndex = model(0, ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
78
+ viewReady = model(false, ...(ngDevMode ? [{ debugName: "viewReady" }] : /* istanbul ignore next */ []));
79
+ userNavigated = model(false, ...(ngDevMode ? [{ debugName: "userNavigated" }] : /* istanbul ignore next */ []));
80
+ previousListLength = model(0, ...(ngDevMode ? [{ debugName: "previousListLength" }] : /* istanbul ignore next */ []));
81
81
  focusTrap = null;
82
82
  dialogElement;
83
83
  closeButton;
@@ -85,7 +85,7 @@ class PreviewFile {
85
85
  const list = this.srcList();
86
86
  const index = this.activeIndex();
87
87
  return list[index] ?? '';
88
- }, ...(ngDevMode ? [{ debugName: "currentSrc" }] : []));
88
+ }, ...(ngDevMode ? [{ debugName: "currentSrc" }] : /* istanbul ignore next */ []));
89
89
  constructor() {
90
90
  effect(() => {
91
91
  const list = this.srcList();
@@ -209,10 +209,10 @@ class PreviewFile {
209
209
  }
210
210
  return this;
211
211
  }
212
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewFile, deps: [], target: i0.ɵɵFactoryTarget.Component });
213
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: PreviewFile, isStandalone: true, selector: "lib-preview-file", inputs: { srcList: { classPropertyName: "srcList", publicName: "srcList", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, openerElement: { classPropertyName: "openerElement", publicName: "openerElement", isSignal: true, isRequired: false, transformFunction: null }, closeHandler: { classPropertyName: "closeHandler", publicName: "closeHandler", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, viewReady: { classPropertyName: "viewReady", publicName: "viewReady", isSignal: true, isRequired: false, transformFunction: null }, userNavigated: { classPropertyName: "userNavigated", publicName: "userNavigated", isSignal: true, isRequired: false, transformFunction: null }, previousListLength: { classPropertyName: "previousListLength", publicName: "previousListLength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange", viewReady: "viewReadyChange", userNavigated: "userNavigatedChange", previousListLength: "previousListLengthChange" }, viewQueries: [{ propertyName: "dialogElement", first: true, predicate: ["dialog"], descendants: true }, { propertyName: "closeButton", first: true, predicate: ["closeButton"], descendants: true }], ngImport: i0, template: "<div class=\"preview\" (click)=\"requestClose()\">\n <div class=\"preview__dialog\"\n #dialog\n tabindex=\"-1\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"title() || ('chat.photo_preview' | transloco)\"\n (keydown)=\"onKeyDown($event)\"\n (click)=\"$event.stopPropagation()\">\n <div class=\"preview__header\">\n <h3 class=\"preview__title\">\n {{ title() || ('chat.photo_preview' | transloco) }}\n </h3>\n <button type=\"button\"\n class=\"preview__close\"\n [attr.aria-label]=\"'chat.close' | transloco\"\n #closeButton\n (click)=\"requestClose()\">\n <span class=\"preview__close-icon\" aria-hidden=\"true\"></span>\n </button>\n </div>\n <div class=\"preview__body\">\n @if (srcList().length > 1) {\n <button type=\"button\"\n class=\"preview__nav preview__nav--prev\"\n [attr.aria-label]=\"'chat.previous' | transloco\"\n (click)=\"prev()\">\n </button>\n <button type=\"button\"\n class=\"preview__nav preview__nav--next\"\n [attr.aria-label]=\"'chat.next' | transloco\"\n (click)=\"next()\">\n </button>\n }\n <img [src]=\"currentSrc()\"\n [attr.alt]=\"'chat.photo_preview_image_x_of_y' | transloco : { index: activeIndex() + 1, total: srcList().length }\"\n class=\"preview__image\"\n (click)=\"next()\"\n (keydown.enter)=\"$event.preventDefault(); next()\"\n (keydown.space)=\"$event.preventDefault(); next()\"/>\n </div>\n @if (srcList().length > 1) {\n <div class=\"preview__thumbs\">\n @for (file of srcList(); track file; let i = $index) {\n <button type=\"button\"\n class=\"preview__thumb\"\n [class.preview__thumb--active]=\"i === activeIndex()\"\n (click)=\"select(i)\">\n <img [src]=\"file\"\n [attr.alt]=\"'chat.thumbnail_alt' | transloco : { index: i + 1, total: srcList().length }\"/>\n </button>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".preview{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:20px;background:#0e101299;z-index:1000}.preview__dialog{width:400px;max-width:calc(100vw - 56px);display:flex;flex-direction:column;gap:20px;padding:20px;background:#fff;border-radius:16px;box-shadow:0 8px 16px #0003}.preview__header{display:flex;align-items:center;justify-content:space-between;gap:16px}.preview__title{margin:0;font:600 20px/24px inter,sans-serif;color:#0e1012}.preview__close{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;border:none;background:none;color:#6c757d;border-radius:1000px;cursor:pointer;transition:background-color .16s ease,color .16s ease}.preview__close:hover{color:#212529;background-color:#e9ecefcc}.preview__close:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.preview__close-icon{width:20px;height:20px;display:block;background-color:currentColor;mask-image:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0A<path d=\"M6.39945 18.6532L5.3457 17.5995L10.9457 11.9995L5.3457 6.39945L6.39945 5.3457L11.9995 10.9457L17.5995 5.3457L18.6532 6.39945L13.0532 11.9995L18.6532 17.5995L17.5995 18.6532L11.9995 13.0532L6.39945 18.6532Z\" fill=\"white\"/>%0A</svg>%0A');mask-size:contain;mask-repeat:no-repeat;mask-position:center;-webkit-mask-image:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0A<path d=\"M6.39945 18.6532L5.3457 17.5995L10.9457 11.9995L5.3457 6.39945L6.39945 5.3457L11.9995 10.9457L17.5995 5.3457L18.6532 6.39945L13.0532 11.9995L18.6532 17.5995L17.5995 18.6532L11.9995 13.0532L6.39945 18.6532Z\" fill=\"white\"/>%0A</svg>%0A');-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center}.preview__body{position:relative;display:flex;align-items:center;justify-content:center}.preview__image{display:block;width:100%;height:auto;max-height:60vh;object-fit:contain;border-radius:12px;background:#fff;cursor:pointer}.preview__nav{position:absolute;top:50%;transform:translateY(-50%);width:32px;height:32px;border-radius:1000px;border:1px solid #E9ECEF;background:#fff;opacity:.7;box-shadow:0 2px 4px #0000001a;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background-color .16s ease}.preview__nav:hover{background:#f8f9fa}.preview__nav:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.preview__nav:before{content:\"\";width:8px;height:8px;border:2px solid #6C757D;border-top:none;border-right:none;transform:rotate(45deg);margin-left:4px}.preview__nav--prev{left:8px}.preview__nav--next{right:8px}.preview__nav--next:before{transform:rotate(-135deg);margin-left:0;margin-right:2px}.preview__thumbs{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}.preview__thumb{width:64px;height:64px;border-radius:8px;border:1px solid #E9ECEF;padding:0;background:#fff;overflow:hidden;cursor:pointer}.preview__thumb img{width:100%;height:100%;object-fit:cover;display:block}.preview__thumb--active{border-color:#5a72d7}\n"], dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
212
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: PreviewFile, deps: [], target: i0.ɵɵFactoryTarget.Component });
213
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: PreviewFile, isStandalone: true, selector: "lib-preview-file", inputs: { srcList: { classPropertyName: "srcList", publicName: "srcList", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, openerElement: { classPropertyName: "openerElement", publicName: "openerElement", isSignal: true, isRequired: false, transformFunction: null }, closeHandler: { classPropertyName: "closeHandler", publicName: "closeHandler", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, viewReady: { classPropertyName: "viewReady", publicName: "viewReady", isSignal: true, isRequired: false, transformFunction: null }, userNavigated: { classPropertyName: "userNavigated", publicName: "userNavigated", isSignal: true, isRequired: false, transformFunction: null }, previousListLength: { classPropertyName: "previousListLength", publicName: "previousListLength", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeIndex: "activeIndexChange", viewReady: "viewReadyChange", userNavigated: "userNavigatedChange", previousListLength: "previousListLengthChange" }, viewQueries: [{ propertyName: "dialogElement", first: true, predicate: ["dialog"], descendants: true }, { propertyName: "closeButton", first: true, predicate: ["closeButton"], descendants: true }], ngImport: i0, template: "<div class=\"preview\" (click)=\"requestClose()\">\n <div class=\"preview__dialog\"\n #dialog\n tabindex=\"-1\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"title() || ('chat.photo_preview' | transloco)\"\n (keydown)=\"onKeyDown($event)\"\n (click)=\"$event.stopPropagation()\">\n <div class=\"preview__header\">\n <h3 class=\"preview__title\">\n {{ title() || ('chat.photo_preview' | transloco) }}\n </h3>\n <button type=\"button\"\n class=\"preview__close\"\n [attr.aria-label]=\"'chat.close' | transloco\"\n #closeButton\n (click)=\"requestClose()\">\n <span class=\"preview__close-icon\" aria-hidden=\"true\"></span>\n </button>\n </div>\n <div class=\"preview__body\">\n @if (srcList().length > 1) {\n <button type=\"button\"\n class=\"preview__nav preview__nav--prev\"\n [attr.aria-label]=\"'chat.previous' | transloco\"\n (click)=\"prev()\">\n </button>\n <button type=\"button\"\n class=\"preview__nav preview__nav--next\"\n [attr.aria-label]=\"'chat.next' | transloco\"\n (click)=\"next()\">\n </button>\n }\n <img [src]=\"currentSrc()\"\n [attr.alt]=\"'chat.photo_preview_image_x_of_y' | transloco : { index: activeIndex() + 1, total: srcList().length }\"\n class=\"preview__image\"\n (click)=\"next()\"\n (keydown.enter)=\"$event.preventDefault(); next()\"\n (keydown.space)=\"$event.preventDefault(); next()\"/>\n </div>\n @if (srcList().length > 1) {\n <div class=\"preview__thumbs\">\n @for (file of srcList(); track file; let i = $index) {\n <button type=\"button\"\n class=\"preview__thumb\"\n [class.preview__thumb--active]=\"i === activeIndex()\"\n (click)=\"select(i)\">\n <img [src]=\"file\"\n [attr.alt]=\"'chat.thumbnail_alt' | transloco : { index: i + 1, total: srcList().length }\"/>\n </button>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".preview{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;padding:20px;background:#0e101299;z-index:1000}.preview__dialog{width:400px;max-width:calc(100vw - 56px);display:flex;flex-direction:column;gap:20px;padding:20px;background:#fff;border-radius:16px;box-shadow:0 8px 16px #0003}.preview__header{display:flex;align-items:center;justify-content:space-between;gap:16px}.preview__title{margin:0;font:600 20px/24px inter,sans-serif;color:#0e1012}.preview__close{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;border:none;background:none;color:#6c757d;border-radius:1000px;cursor:pointer;transition:background-color .16s ease,color .16s ease}.preview__close:hover{color:#212529;background-color:#e9ecefcc}.preview__close:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.preview__close-icon{width:20px;height:20px;display:block;background-color:currentColor;mask-image:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0A<path d=\"M6.39945 18.6532L5.3457 17.5995L10.9457 11.9995L5.3457 6.39945L6.39945 5.3457L11.9995 10.9457L17.5995 5.3457L18.6532 6.39945L13.0532 11.9995L18.6532 17.5995L17.5995 18.6532L11.9995 13.0532L6.39945 18.6532Z\" fill=\"white\"/>%0A</svg>%0A');mask-size:contain;mask-repeat:no-repeat;mask-position:center;-webkit-mask-image:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">%0A<path d=\"M6.39945 18.6532L5.3457 17.5995L10.9457 11.9995L5.3457 6.39945L6.39945 5.3457L11.9995 10.9457L17.5995 5.3457L18.6532 6.39945L13.0532 11.9995L18.6532 17.5995L17.5995 18.6532L11.9995 13.0532L6.39945 18.6532Z\" fill=\"white\"/>%0A</svg>%0A');-webkit-mask-size:contain;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center}.preview__body{position:relative;display:flex;align-items:center;justify-content:center}.preview__image{display:block;width:100%;height:auto;max-height:60vh;object-fit:contain;border-radius:12px;background:#fff;cursor:pointer}.preview__nav{position:absolute;top:50%;transform:translateY(-50%);width:32px;height:32px;border-radius:1000px;border:1px solid #E9ECEF;background:#fff;opacity:.7;box-shadow:0 2px 4px #0000001a;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background-color .16s ease}.preview__nav:hover{background:#f8f9fa}.preview__nav:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.preview__nav:before{content:\"\";width:8px;height:8px;border:2px solid #6C757D;border-top:none;border-right:none;transform:rotate(45deg);margin-left:4px}.preview__nav--prev{left:8px}.preview__nav--next{right:8px}.preview__nav--next:before{transform:rotate(-135deg);margin-left:0;margin-right:2px}.preview__thumbs{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}.preview__thumb{width:64px;height:64px;border-radius:8px;border:1px solid #E9ECEF;padding:0;background:#fff;overflow:hidden;cursor:pointer}.preview__thumb img{width:100%;height:100%;object-fit:cover;display:block}.preview__thumb--active{border-color:#5a72d7}\n"], dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
214
214
  }
215
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: PreviewFile, decorators: [{
215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: PreviewFile, decorators: [{
216
216
  type: Component,
217
217
  args: [{ selector: 'lib-preview-file', imports: [
218
218
  TranslocoPipe,
@@ -263,10 +263,10 @@ class UtilsService {
263
263
  }
264
264
  return cleanedPath.replace(/^\.{1,2}\//, '/');
265
265
  }
266
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UtilsService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
267
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UtilsService, providedIn: 'root' });
266
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UtilsService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
267
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UtilsService, providedIn: 'root' });
268
268
  }
269
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: UtilsService, decorators: [{
269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: UtilsService, decorators: [{
270
270
  type: Injectable,
271
271
  args: [{
272
272
  providedIn: 'root'
@@ -274,21 +274,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
274
274
  }], ctorParameters: () => [{ type: i1.HttpClient }] });
275
275
 
276
276
  class ChatMessageComponent {
277
- utils;
278
- currentMessage = input.required(...(ngDevMode ? [{ debugName: "currentMessage" }] : []));
279
- edit = model(false, ...(ngDevMode ? [{ debugName: "edit" }] : []));
280
- previewList = model([], ...(ngDevMode ? [{ debugName: "previewList" }] : []));
281
- previewIndex = model(0, ...(ngDevMode ? [{ debugName: "previewIndex" }] : []));
282
- previewOpener = model(null, ...(ngDevMode ? [{ debugName: "previewOpener" }] : []));
277
+ utils = inject(UtilsService);
278
+ currentMessage = input.required(...(ngDevMode ? [{ debugName: "currentMessage" }] : /* istanbul ignore next */ []));
279
+ edit = model(false, ...(ngDevMode ? [{ debugName: "edit" }] : /* istanbul ignore next */ []));
280
+ previewList = model([], ...(ngDevMode ? [{ debugName: "previewList" }] : /* istanbul ignore next */ []));
281
+ previewIndex = model(0, ...(ngDevMode ? [{ debugName: "previewIndex" }] : /* istanbul ignore next */ []));
282
+ previewOpener = model(null, ...(ngDevMode ? [{ debugName: "previewOpener" }] : /* istanbul ignore next */ []));
283
283
  closePreviewHandler = () => this.closePreview();
284
- requestEdit = model(null, ...(ngDevMode ? [{ debugName: "requestEdit" }] : []));
285
- requestDelete = model(null, ...(ngDevMode ? [{ debugName: "requestDelete" }] : []));
286
- mobileMode = input(false, ...(ngDevMode ? [{ debugName: "mobileMode" }] : []));
287
- quickActions = input([], ...(ngDevMode ? [{ debugName: "quickActions" }] : []));
288
- quickActionClick = model(null, ...(ngDevMode ? [{ debugName: "quickActionClick" }] : []));
289
- constructor(utils) {
290
- this.utils = utils;
291
- }
284
+ requestEdit = model(null, ...(ngDevMode ? [{ debugName: "requestEdit" }] : /* istanbul ignore next */ []));
285
+ requestDelete = model(null, ...(ngDevMode ? [{ debugName: "requestDelete" }] : /* istanbul ignore next */ []));
286
+ mobileMode = input(false, ...(ngDevMode ? [{ debugName: "mobileMode" }] : /* istanbul ignore next */ []));
287
+ logoChat = input('', ...(ngDevMode ? [{ debugName: "logoChat" }] : /* istanbul ignore next */ []));
288
+ quickActions = input([], ...(ngDevMode ? [{ debugName: "quickActions" }] : /* istanbul ignore next */ []));
289
+ quickActionClick = model(null, ...(ngDevMode ? [{ debugName: "quickActionClick" }] : /* istanbul ignore next */ []));
290
+ messageType = MessageType;
292
291
  attachments = computed(() => {
293
292
  const message = this.currentMessage();
294
293
  const filePath = message.file_path;
@@ -308,7 +307,8 @@ class ChatMessageComponent {
308
307
  .filter(Boolean);
309
308
  }
310
309
  }
311
- catch { }
310
+ catch {
311
+ }
312
312
  }
313
313
  if (rawFilePath.startsWith('data:')) {
314
314
  return [rawFilePath];
@@ -320,31 +320,40 @@ class ChatMessageComponent {
320
320
  return rawFilePath.split(',').map(p => this.utils.normalizeSourcePath(p)).filter(Boolean);
321
321
  }
322
322
  return [];
323
- }, ...(ngDevMode ? [{ debugName: "attachments" }] : []));
323
+ }, ...(ngDevMode ? [{ debugName: "attachments" }] : /* istanbul ignore next */ []));
324
324
  avatarSrc = computed(() => {
325
325
  const message = this.currentMessage();
326
- const fallback = message.type === 'incoming'
327
- ? 'assets/ngx-parl/icons/avatar_anonym.svg'
328
- : 'assets/ngx-parl/icons/avatar_manager.svg';
329
- return message.avatar || fallback;
330
- }, ...(ngDevMode ? [{ debugName: "avatarSrc" }] : []));
326
+ const anonymFallback = 'assets/ngx-parl/icons/avatar_anonym.svg';
327
+ const managerFallback = 'assets/ngx-parl/icons/avatar_manager.svg';
328
+ const logoTrimmed = (this.logoChat() ?? '').trim();
329
+ const outgoingFallback = logoTrimmed.length > 0 ? logoTrimmed : managerFallback;
330
+ const fallback = message.type === this.messageType.Incoming ? anonymFallback : outgoingFallback;
331
+ const raw = message.avatar && String(message.avatar).trim().length > 0
332
+ ? message.avatar
333
+ : fallback;
334
+ return this.utils.normalizeSourcePath(raw);
335
+ }, ...(ngDevMode ? [{ debugName: "avatarSrc" }] : /* istanbul ignore next */ []));
336
+ isOutgoingMessage = computed(() => this.currentMessage().type === this.messageType.Outgoing, ...(ngDevMode ? [{ debugName: "isOutgoingMessage" }] : /* istanbul ignore next */ []));
337
+ hasQuickActionButtons = computed(() => this.isOutgoingMessage() && this.quickActions().length > 0, ...(ngDevMode ? [{ debugName: "hasQuickActionButtons" }] : /* istanbul ignore next */ []));
338
+ showMessageBubble = computed(() => {
339
+ const msg = this.currentMessage();
340
+ if (msg.type !== this.messageType.Outgoing) {
341
+ return true;
342
+ }
343
+ if (!this.hasQuickActionButtons()) {
344
+ return true;
345
+ }
346
+ return !!(msg.content && String(msg.content).trim().length > 0);
347
+ }, ...(ngDevMode ? [{ debugName: "showMessageBubble" }] : /* istanbul ignore next */ []));
348
+ showMessageBody = computed(() => this.showMessageBubble() || this.attachments().length > 0, ...(ngDevMode ? [{ debugName: "showMessageBody" }] : /* istanbul ignore next */ []));
331
349
  showAvatar = computed(() => {
332
350
  const isMobile = this.mobileMode();
333
- const isOutgoing = this.currentMessage().type === this.messageType.Outgoing;
334
- return !(isMobile && isOutgoing);
335
- }, ...(ngDevMode ? [{ debugName: "showAvatar" }] : []));
336
- showQuickActions = computed(() => {
337
- const isOutgoing = this.currentMessage().type === this.messageType.Outgoing;
338
- return isOutgoing && this.quickActions().length > 0;
339
- }, ...(ngDevMode ? [{ debugName: "showQuickActions" }] : []));
340
- showMessageBubble = computed(() => !this.showQuickActions(), ...(ngDevMode ? [{ debugName: "showMessageBubble" }] : []));
341
- showMessageBody = computed(() => this.showMessageBubble() || this.attachments().length > 0, ...(ngDevMode ? [{ debugName: "showMessageBody" }] : []));
351
+ return !(isMobile && this.isOutgoingMessage());
352
+ }, ...(ngDevMode ? [{ debugName: "showAvatar" }] : /* istanbul ignore next */ []));
342
353
  canOpenContextMenu = computed(() => {
343
354
  const message = this.currentMessage();
344
- const isOutgoing = message.type === this.messageType.Outgoing;
345
- const isSent = message.pending !== true;
346
- return isOutgoing && isSent;
347
- }, ...(ngDevMode ? [{ debugName: "canOpenContextMenu" }] : []));
355
+ return message.type === this.messageType.Outgoing && message.pending !== true;
356
+ }, ...(ngDevMode ? [{ debugName: "canOpenContextMenu" }] : /* istanbul ignore next */ []));
348
357
  openContextMenu(event, trigger, triggerElement) {
349
358
  if (!this.canOpenContextMenu()) {
350
359
  return this;
@@ -388,23 +397,21 @@ class ChatMessageComponent {
388
397
  return this;
389
398
  }
390
399
  onQuickAction(action) {
391
- const messageId = this.currentMessage().id;
400
+ const title = (action.title ?? '').trim();
392
401
  const value = (action.value ?? '').trim();
393
- if (!value) {
402
+ const content = value || title;
403
+ if (!content) {
394
404
  return this;
395
405
  }
396
- this.quickActionClick.set({ actionId: action.id, messageId, value });
397
- setTimeout(() => this.quickActionClick.set(null), 0);
406
+ const messageId = this.currentMessage().id;
407
+ this.quickActionClick.set({ actionId: action.id, messageId, value: content });
408
+ queueMicrotask(() => this.quickActionClick.set(null));
398
409
  return this;
399
410
  }
400
- canDelete(message) {
401
- return message.type === this.messageType.Outgoing;
402
- }
403
- messageType = MessageType;
404
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChatMessageComponent, deps: [{ token: UtilsService }], target: i0.ɵɵFactoryTarget.Component });
405
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ChatMessageComponent, isStandalone: true, selector: "lib-chat-message", inputs: { currentMessage: { classPropertyName: "currentMessage", publicName: "currentMessage", isSignal: true, isRequired: true, transformFunction: null }, edit: { classPropertyName: "edit", publicName: "edit", isSignal: true, isRequired: false, transformFunction: null }, previewList: { classPropertyName: "previewList", publicName: "previewList", isSignal: true, isRequired: false, transformFunction: null }, previewIndex: { classPropertyName: "previewIndex", publicName: "previewIndex", isSignal: true, isRequired: false, transformFunction: null }, previewOpener: { classPropertyName: "previewOpener", publicName: "previewOpener", isSignal: true, isRequired: false, transformFunction: null }, requestEdit: { classPropertyName: "requestEdit", publicName: "requestEdit", isSignal: true, isRequired: false, transformFunction: null }, requestDelete: { classPropertyName: "requestDelete", publicName: "requestDelete", isSignal: true, isRequired: false, transformFunction: null }, mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: true, isRequired: false, transformFunction: null }, quickActions: { classPropertyName: "quickActions", publicName: "quickActions", isSignal: true, isRequired: false, transformFunction: null }, quickActionClick: { classPropertyName: "quickActionClick", publicName: "quickActionClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { edit: "editChange", previewList: "previewListChange", previewIndex: "previewIndexChange", previewOpener: "previewOpenerChange", requestEdit: "requestEditChange", requestDelete: "requestDeleteChange", quickActionClick: "quickActionClickChange" }, ngImport: i0, template: "<div class=\"message\"\n [ngClass]=\"{\n 'message--outgoing': currentMessage().type === messageType.Outgoing,\n 'message--incoming': currentMessage().type === messageType.Incoming,\n 'message--mobile': mobileMode()\n }\">\n @if (showAvatar()) {\n <div class=\"message__avatar\">\n <img [ngSrc]=\"avatarSrc()\" width=\"36\" height=\"36\" alt=\"avatar\"/>\n </div>\n }\n\n @if (showMessageBody()) {\n <div class=\"message__body\"\n (contextmenu)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\"\n (keydown.shift.F10)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\">\n <button type=\"button\"\n class=\"message__menu-trigger\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n #menuTrigger=\"matMenuTrigger\"\n #menuTriggerEl\n [matMenuTriggerFor]=\"messageMenu\">\n </button>\n\n @if (attachments().length) {\n <div class=\"message__attachments\">\n @for (file of attachments(); track file; let i = $index) {\n <button type=\"button\"\n class=\"message__image-button\"\n (click)=\"openPreview(i, $event)\"\n [attr.aria-label]=\"'chat.photo_preview' | transloco\">\n <img [src]=\"file\"\n alt=\"attachment\"\n class=\"message__image\"\n loading=\"lazy\"/>\n </button>\n }\n </div>\n }\n\n @if (showMessageBubble()) {\n <div class=\"message__bubble\" tabindex=\"0\">\n <div class=\"message__text\">{{ currentMessage().content }}</div>\n\n <div class=\"message__meta\">\n <time class=\"message__time\">\n {{ currentMessage().cr_time | date:'HH:mm' }}\n </time>\n @if (currentMessage().type === messageType.Outgoing) {\n @if (currentMessage().pending) {\n <span class=\"message__loading\" aria-label=\"Sending\"></span>\n } @else if (currentMessage().checked) {\n <img ngSrc=\"assets/ngx-parl/icons/checked-message.svg\"\n class=\"message__icon\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n } @else {\n <img ngSrc=\"assets/ngx-parl/icons/no-check.svg\"\n class=\"message__icon\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n }\n }\n </div>\n </div>\n }\n\n </div>\n }\n\n @if (showQuickActions()) {\n <div class=\"message__quick-actions-wrap\" role=\"group\" aria-label=\"Quick actions\">\n <div class=\"message__quick-actions\">\n @for (action of quickActions(); track action.id) {\n <ion-button\n class=\"message__quick-action-button\"\n fill=\"outline\"\n expand=\"block\"\n [disabled]=\"action.disabled === true\"\n (click)=\"onQuickAction(action)\">\n {{ action.title }}\n </ion-button>\n }\n </div>\n </div>\n }\n</div>\n@if (!showQuickActions()) {\n <div class=\"message__user\" [ngClass]=\"{'message__user--mobile': mobileMode()}\">\n @if (currentMessage().type === messageType.Outgoing) {\n <span class=\"message__user-name\">{{ currentMessage().user }}</span>\n }\n </div>\n}\n\n@if (previewList().length) {\n <lib-preview-file\n [srcList]=\"previewList()\"\n [startIndex]=\"previewIndex()\"\n [openerElement]=\"previewOpener()\"\n [closeHandler]=\"closePreviewHandler\">\n </lib-preview-file>\n}\n\n<mat-menu #messageMenu=\"matMenu\" yPosition=\"below\" xPosition=\"before\" class=\"message__menu\">\n @if (currentMessage().type === messageType.Outgoing) {\n <button mat-menu-item (click)=\"editMessage(currentMessage())\">\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\n class=\"message__icon--menu\"\n width=\"20\" height=\"20\" alt=\"hide\"/>\n <span>{{ 'chat.edit' | transloco }}</span>\n </button>\n }\n @if (canDelete(currentMessage())) {\n <button mat-menu-item (click)=\"deleteMessage(currentMessage())\">\n <img ngSrc=\"assets/ngx-parl/icons/trash.svg\"\n class=\"message__icon--menu\"\n width=\"20\" height=\"20\" alt=\"hide\"/>\n <span>{{ 'chat.remove' | transloco }}</span>\n </button>\n }\n</mat-menu>\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.message{display:flex;gap:8px;align-items:flex-end;max-width:80%;animation:pop .12s ease-out}.message__avatar img{display:block;border-radius:1000px}.message__body{padding:8px 12px;min-width:0;font:400 16px/20px inter,sans-serif;border-radius:16px;position:relative}.message__bubble{display:grid;grid-template-columns:1fr auto;column-gap:8px;align-items:end;max-width:100%;word-break:break-word;white-space:pre-wrap}.message__quick-actions-wrap{display:flex;margin-top:12px;width:100%;background:transparent}.message__quick-actions{display:grid;gap:8px;width:234px;max-width:100%;background:transparent}.message__quick-action-button{--border-radius: 16px;--border-width: 1px;--border-style: solid;--border-color: #2563EB;--color: #2563EB;--padding-top: tokens.$space-3;--padding-bottom: tokens.$space-3;--padding-start: tokens.$space-6;--padding-end: tokens.$space-6;height:48px;text-transform:none;font:500 14px/18px inter,sans-serif;margin:0}.message__text{min-width:0}.message__meta{display:inline-flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;line-height:1;margin:0}.message__time{font:400 12px/16px inter,sans-serif}.message__attachments{display:grid;gap:8px;justify-content:start;width:100%;margin-bottom:8px}.message__attachments:has(:only-child){grid-template-columns:repeat(1,minmax(0,140px))}.message__attachments:has(:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,145px))}.message__attachments:has(:nth-child(3)){grid-template-columns:repeat(3,minmax(0,150px))}.message__body--attachments-1{max-width:164px}.message__body--attachments-2{max-width:312px}.message__body--attachments-3{max-width:460px}.message__body--attachments-1 .message__bubble,.message__body--attachments-2 .message__bubble,.message__body--attachments-3 .message__bubble{grid-template-columns:1fr;row-gap:4px}.message__body--attachments-1 .message__meta,.message__body--attachments-2 .message__meta,.message__body--attachments-3 .message__meta{justify-self:end}.message__image-button{display:block;border:none;padding:0;background:transparent;border-radius:12px;overflow:hidden;cursor:pointer}.message__image-button:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.message__menu-trigger{position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}.message__image{display:block;width:100%;height:140px;object-fit:cover;border-radius:12px;aspect-ratio:1/1}.message__bubble:after{content:\"\";display:block;clear:both}.message__time{font:400 12px/16px inter,sans-serif;min-width:30px}.message__icon{width:14px;height:14px;vertical-align:middle}.message__icon--menu{width:20px;height:20px}.message__loading{display:inline-block;width:10px;height:10px;border:2px solid #E9ECEF;border-top-color:#5a72d7;border-radius:50%;animation:message-loading-spin .8s linear infinite}.message--incoming{margin-right:auto}.message--incoming .message__body{border-bottom-right-radius:16px}.message--incoming .message__bubble{border-top-left-radius:4px}.message--incoming .message__time{color:#adb5bd}.message--incoming .message__quick-actions-wrap{justify-content:flex-start}.message--outgoing{margin-left:auto;flex-direction:row-reverse}.message--outgoing .message__body{border-bottom-right-radius:0}.message--outgoing .message__bubble{border-top-right-radius:4px}.message--outgoing .message__time{color:#e9ecef}.message--outgoing .message__menu-trigger{right:auto}.message--outgoing .message__quick-actions-wrap{justify-content:flex-end}.message--mobile .message__user{padding-right:5px!important}.message--mobile.message--outgoing .message__body{border-bottom-right-radius:0}.message__user{display:flex;justify-content:flex-end;max-width:80%;margin-left:auto;margin-top:4px;padding-right:46px}.message__user--mobile{padding-right:5px!important}.message__user-name{font:400 12px/16px inter,sans-serif;color:#ced4da}@keyframes pop{0%{transform:translateY(2px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes message-loading-spin{to{transform:rotate(360deg)}}::ng-deep .mat-mdc-menu-content{background:#fff;width:160px;border-radius:8px;gap:4px;border:1px solid #E1E7F8;padding:8px 4px;box-shadow:0 2px 4px #0000001a;overflow:hidden;font:400 14px/18px inter,sans-serif}::ng-deep .mat-mdc-menu-item-text{font:400 14px/18px inter,sans-serif!important;font-weight:500!important;color:#343a40!important;display:flex;justify-content:flex-start;align-items:center;gap:4px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: PreviewFile, selector: "lib-preview-file", inputs: ["srcList", "startIndex", "title", "openerElement", "closeHandler", "activeIndex", "viewReady", "userNavigated", "previousListLength"], outputs: ["activeIndexChange", "viewReadyChange", "userNavigatedChange", "previousListLengthChange"] }, { kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
411
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
412
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: ChatMessageComponent, isStandalone: true, selector: "lib-chat-message", inputs: { currentMessage: { classPropertyName: "currentMessage", publicName: "currentMessage", isSignal: true, isRequired: true, transformFunction: null }, edit: { classPropertyName: "edit", publicName: "edit", isSignal: true, isRequired: false, transformFunction: null }, previewList: { classPropertyName: "previewList", publicName: "previewList", isSignal: true, isRequired: false, transformFunction: null }, previewIndex: { classPropertyName: "previewIndex", publicName: "previewIndex", isSignal: true, isRequired: false, transformFunction: null }, previewOpener: { classPropertyName: "previewOpener", publicName: "previewOpener", isSignal: true, isRequired: false, transformFunction: null }, requestEdit: { classPropertyName: "requestEdit", publicName: "requestEdit", isSignal: true, isRequired: false, transformFunction: null }, requestDelete: { classPropertyName: "requestDelete", publicName: "requestDelete", isSignal: true, isRequired: false, transformFunction: null }, mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: true, isRequired: false, transformFunction: null }, logoChat: { classPropertyName: "logoChat", publicName: "logoChat", isSignal: true, isRequired: false, transformFunction: null }, quickActions: { classPropertyName: "quickActions", publicName: "quickActions", isSignal: true, isRequired: false, transformFunction: null }, quickActionClick: { classPropertyName: "quickActionClick", publicName: "quickActionClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { edit: "editChange", previewList: "previewListChange", previewIndex: "previewIndexChange", previewOpener: "previewOpenerChange", requestEdit: "requestEditChange", requestDelete: "requestDeleteChange", quickActionClick: "quickActionClickChange" }, ngImport: i0, template: "<div class=\"message\"\r\n [ngClass]=\"{\r\n 'message--outgoing': isOutgoingMessage(),\r\n 'message--incoming': !isOutgoingMessage(),\r\n 'message--mobile': mobileMode()\r\n }\">\r\n @if (showAvatar()) {\r\n <div class=\"message__avatar\">\r\n <img [ngSrc]=\"avatarSrc()\" width=\"36\" height=\"36\" alt=\"avatar\"/>\r\n </div>\r\n }\r\n\r\n @if (showMessageBody()) {\r\n <div class=\"message__body\"\r\n (contextmenu)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\"\r\n (keydown.shift.F10)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\">\r\n <button type=\"button\"\r\n class=\"message__menu-trigger\"\r\n aria-hidden=\"true\"\r\n tabindex=\"-1\"\r\n #menuTrigger=\"matMenuTrigger\"\r\n #menuTriggerEl\r\n [matMenuTriggerFor]=\"messageMenu\">\r\n </button>\r\n\r\n @if (attachments().length) {\r\n <div class=\"message__attachments\">\r\n @for (file of attachments(); track file; let i = $index) {\r\n <button type=\"button\"\r\n class=\"message__image-button\"\r\n (click)=\"openPreview(i, $event)\"\r\n [attr.aria-label]=\"'chat.photo_preview' | transloco\">\r\n <img [src]=\"file\"\r\n alt=\"attachment\"\r\n class=\"message__image\"\r\n loading=\"lazy\"/>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (showMessageBubble()) {\r\n <div class=\"message__bubble\" tabindex=\"0\">\r\n <div class=\"message__text\">{{ currentMessage().content }}</div>\r\n\r\n <div class=\"message__meta\">\r\n <time class=\"message__time\">\r\n {{ currentMessage().cr_time | date:'HH:mm' }}\r\n </time>\r\n @if (isOutgoingMessage()) {\r\n @if (currentMessage().pending) {\r\n <span class=\"message__loading\" aria-label=\"Sending\"></span>\r\n } @else if (currentMessage().checked) {\r\n <img ngSrc=\"assets/ngx-parl/icons/checked-message.svg\"\r\n class=\"message__icon\"\r\n width=\"18\" height=\"18\" alt=\"hide\"/>\r\n } @else {\r\n <img ngSrc=\"assets/ngx-parl/icons/no-check.svg\"\r\n class=\"message__icon\"\r\n width=\"18\" height=\"18\" alt=\"hide\"/>\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n }\r\n\r\n @if (hasQuickActionButtons()) {\r\n <div class=\"message__quick-actions-wrap\" role=\"group\" [attr.aria-label]=\"'chat.quick_actions' | transloco\">\r\n <div class=\"message__quick-actions\">\r\n @for (action of quickActions(); track action.id) {\r\n <button\r\n class=\"message__quick-action-button\"\r\n type=\"button\"\r\n [disabled]=\"action.disabled === true\"\r\n (click)=\"onQuickAction(action)\">\r\n {{ action.title }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n@if (!hasQuickActionButtons()) {\r\n <div class=\"message__user\" [ngClass]=\"{'message__user--mobile': mobileMode()}\">\r\n @if (isOutgoingMessage()) {\r\n <span class=\"message__user-name\">{{ currentMessage().user }}</span>\r\n }\r\n </div>\r\n}\r\n\r\n@if (previewList().length) {\r\n <lib-preview-file [srcList]=\"previewList()\"\r\n [startIndex]=\"previewIndex()\"\r\n [openerElement]=\"previewOpener()\"\r\n [closeHandler]=\"closePreviewHandler\">\r\n </lib-preview-file>\r\n}\r\n\r\n<mat-menu #messageMenu=\"matMenu\" yPosition=\"below\" xPosition=\"before\" class=\"message__menu\">\r\n @if (isOutgoingMessage()) {\r\n <button mat-menu-item (click)=\"editMessage(currentMessage())\">\r\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\r\n class=\"message__icon--menu\"\r\n width=\"20\" height=\"20\" alt=\"hide\"/>\r\n <span>{{ 'chat.edit' | transloco }}</span>\r\n </button>\r\n <button mat-menu-item (click)=\"deleteMessage(currentMessage())\">\r\n <img ngSrc=\"assets/ngx-parl/icons/trash.svg\"\r\n class=\"message__icon--menu\"\r\n width=\"20\" height=\"20\" alt=\"hide\"/>\r\n <span>{{ 'chat.remove' | transloco }}</span>\r\n </button>\r\n }\r\n</mat-menu>\r\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.message{display:flex;gap:8px;align-items:flex-end;max-width:80%;animation:pop .12s ease-out}.message__avatar{flex:0 0 36px;width:36px;height:36px;min-width:36px;align-self:flex-end}.message__avatar img{display:block;width:36px;height:36px;border-radius:1000px;object-fit:cover}.message__body{padding:8px 12px;min-width:0;font:400 16px/20px inter,sans-serif;border-radius:16px;position:relative}.message__bubble{display:grid;grid-template-columns:1fr auto;column-gap:8px;align-items:end;max-width:100%;word-break:break-word;white-space:pre-wrap}.message__quick-actions-wrap{display:flex;margin-top:12px;width:100%;background:transparent}.message__quick-actions{display:grid;gap:8px;width:234px;max-width:100%;background:transparent}.message__quick-action-button{display:inline-flex;width:100%;align-items:center;justify-content:center;border-radius:16px;border:1px solid #2563EB;color:#2563eb;background:transparent;padding:12px 24px;height:48px;text-transform:none;font:500 14px/18px inter,sans-serif;margin:0;cursor:pointer}.message__quick-action-button:disabled{opacity:.6;cursor:not-allowed}.message__quick-action-button:hover:not(:disabled),.message__quick-action-button:focus-visible:not(:disabled){background:#2563eb0f}.message__quick-action-button:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.message__text{min-width:0}.message__meta{display:inline-flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;line-height:1;margin:0}.message__time{font:400 12px/16px inter,sans-serif}.message__attachments{display:grid;gap:8px;justify-content:start;width:100%;margin-bottom:8px}.message__attachments:has(:only-child){grid-template-columns:repeat(1,minmax(0,140px))}.message__attachments:has(:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,145px))}.message__attachments:has(:nth-child(3)){grid-template-columns:repeat(3,minmax(0,150px))}.message__body--attachments-1{max-width:164px}.message__body--attachments-2{max-width:312px}.message__body--attachments-3{max-width:460px}.message__body--attachments-1 .message__bubble,.message__body--attachments-2 .message__bubble,.message__body--attachments-3 .message__bubble{grid-template-columns:1fr;row-gap:4px}.message__body--attachments-1 .message__meta,.message__body--attachments-2 .message__meta,.message__body--attachments-3 .message__meta{justify-self:end}.message__image-button{display:block;border:none;padding:0;background:transparent;border-radius:12px;overflow:hidden;cursor:pointer}.message__image-button:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.message__menu-trigger{position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}.message__image{display:block;width:100%;height:140px;object-fit:cover;border-radius:12px;aspect-ratio:1/1}.message__bubble:after{content:\"\";display:block;clear:both}.message__time{font:400 12px/16px inter,sans-serif;min-width:30px}.message__icon{width:14px;height:14px;vertical-align:middle}.message__icon--menu{width:20px;height:20px}.message__loading{display:inline-block;width:10px;height:10px;border:2px solid #E9ECEF;border-top-color:#5a72d7;border-radius:50%;animation:message-loading-spin .8s linear infinite}.message--incoming{margin-right:auto}.message--incoming .message__body{border-bottom-right-radius:16px}.message--incoming .message__bubble{border-top-left-radius:4px}.message--incoming .message__time{color:#adb5bd}.message--incoming .message__quick-actions-wrap{justify-content:flex-start}.message--outgoing{margin-left:auto;flex-direction:row-reverse}.message--outgoing .message__body{border-bottom-right-radius:0}.message--outgoing .message__bubble{border-top-right-radius:4px}.message--outgoing .message__time{color:#e9ecef}.message--outgoing .message__menu-trigger{right:auto}.message--outgoing .message__quick-actions-wrap{justify-content:flex-end}.message--mobile .message__user{padding-right:5px!important}.message--mobile.message--outgoing .message__body{border-bottom-right-radius:0}.message__user{display:flex;justify-content:flex-end;max-width:80%;margin-left:auto;margin-top:4px;padding-right:46px}.message__user--mobile{padding-right:5px!important}.message__user-name{font:400 12px/16px inter,sans-serif;color:#ced4da}@keyframes pop{0%{transform:translateY(2px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes message-loading-spin{to{transform:rotate(360deg)}}::ng-deep .message__menu.mat-mdc-menu-panel{min-width:160px!important;max-width:160px!important;width:160px!important;background:#fff!important;border-radius:8px!important;border:1px solid #E9ECEF!important;box-shadow:0 2px 4px #0000001a!important;overflow:hidden!important}::ng-deep .message__menu .mat-mdc-menu-content{background:#fff!important;width:160px!important;min-height:88px!important;border-radius:8px!important;border:none!important;padding:4px 0!important;box-shadow:none!important;overflow:hidden!important;font:400 14px/18px inter,sans-serif!important;color:#343a40!important;gap:0!important}::ng-deep .message__menu .mat-mdc-menu-item{min-height:40px!important;height:40px!important;background:#fff!important;color:#343a40!important;font:400 14px/18px inter,sans-serif!important;font-weight:500!important;padding-inline:12px!important}::ng-deep .message__menu .mat-mdc-menu-item:hover,::ng-deep .message__menu .mat-mdc-menu-item.mat-mdc-menu-item-highlighted{background:#e9ecef!important;color:#212529!important}::ng-deep .message__menu .mat-mdc-menu-item .mat-mdc-menu-item-text{font:400 14px/18px inter,sans-serif!important;font-weight:500!important;color:inherit!important;display:flex!important;justify-content:flex-start!important;align-items:center!important;gap:8px!important}::ng-deep .message__menu .mat-mdc-menu-item .mdc-list-item__primary-text{color:inherit!important}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: PreviewFile, selector: "lib-preview-file", inputs: ["srcList", "startIndex", "title", "openerElement", "closeHandler", "activeIndex", "viewReady", "userNavigated", "previousListLength"], outputs: ["activeIndexChange", "viewReadyChange", "userNavigatedChange", "previousListLengthChange"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
406
413
  }
407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChatMessageComponent, decorators: [{
414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ChatMessageComponent, decorators: [{
408
415
  type: Component,
409
416
  args: [{ selector: 'lib-chat-message', imports: [
410
417
  NgClass,
@@ -415,9 +422,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
415
422
  MatMenuTrigger,
416
423
  TranslocoPipe,
417
424
  PreviewFile,
418
- IonButton,
419
- ], standalone: true, template: "<div class=\"message\"\n [ngClass]=\"{\n 'message--outgoing': currentMessage().type === messageType.Outgoing,\n 'message--incoming': currentMessage().type === messageType.Incoming,\n 'message--mobile': mobileMode()\n }\">\n @if (showAvatar()) {\n <div class=\"message__avatar\">\n <img [ngSrc]=\"avatarSrc()\" width=\"36\" height=\"36\" alt=\"avatar\"/>\n </div>\n }\n\n @if (showMessageBody()) {\n <div class=\"message__body\"\n (contextmenu)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\"\n (keydown.shift.F10)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\">\n <button type=\"button\"\n class=\"message__menu-trigger\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n #menuTrigger=\"matMenuTrigger\"\n #menuTriggerEl\n [matMenuTriggerFor]=\"messageMenu\">\n </button>\n\n @if (attachments().length) {\n <div class=\"message__attachments\">\n @for (file of attachments(); track file; let i = $index) {\n <button type=\"button\"\n class=\"message__image-button\"\n (click)=\"openPreview(i, $event)\"\n [attr.aria-label]=\"'chat.photo_preview' | transloco\">\n <img [src]=\"file\"\n alt=\"attachment\"\n class=\"message__image\"\n loading=\"lazy\"/>\n </button>\n }\n </div>\n }\n\n @if (showMessageBubble()) {\n <div class=\"message__bubble\" tabindex=\"0\">\n <div class=\"message__text\">{{ currentMessage().content }}</div>\n\n <div class=\"message__meta\">\n <time class=\"message__time\">\n {{ currentMessage().cr_time | date:'HH:mm' }}\n </time>\n @if (currentMessage().type === messageType.Outgoing) {\n @if (currentMessage().pending) {\n <span class=\"message__loading\" aria-label=\"Sending\"></span>\n } @else if (currentMessage().checked) {\n <img ngSrc=\"assets/ngx-parl/icons/checked-message.svg\"\n class=\"message__icon\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n } @else {\n <img ngSrc=\"assets/ngx-parl/icons/no-check.svg\"\n class=\"message__icon\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n }\n }\n </div>\n </div>\n }\n\n </div>\n }\n\n @if (showQuickActions()) {\n <div class=\"message__quick-actions-wrap\" role=\"group\" aria-label=\"Quick actions\">\n <div class=\"message__quick-actions\">\n @for (action of quickActions(); track action.id) {\n <ion-button\n class=\"message__quick-action-button\"\n fill=\"outline\"\n expand=\"block\"\n [disabled]=\"action.disabled === true\"\n (click)=\"onQuickAction(action)\">\n {{ action.title }}\n </ion-button>\n }\n </div>\n </div>\n }\n</div>\n@if (!showQuickActions()) {\n <div class=\"message__user\" [ngClass]=\"{'message__user--mobile': mobileMode()}\">\n @if (currentMessage().type === messageType.Outgoing) {\n <span class=\"message__user-name\">{{ currentMessage().user }}</span>\n }\n </div>\n}\n\n@if (previewList().length) {\n <lib-preview-file\n [srcList]=\"previewList()\"\n [startIndex]=\"previewIndex()\"\n [openerElement]=\"previewOpener()\"\n [closeHandler]=\"closePreviewHandler\">\n </lib-preview-file>\n}\n\n<mat-menu #messageMenu=\"matMenu\" yPosition=\"below\" xPosition=\"before\" class=\"message__menu\">\n @if (currentMessage().type === messageType.Outgoing) {\n <button mat-menu-item (click)=\"editMessage(currentMessage())\">\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\n class=\"message__icon--menu\"\n width=\"20\" height=\"20\" alt=\"hide\"/>\n <span>{{ 'chat.edit' | transloco }}</span>\n </button>\n }\n @if (canDelete(currentMessage())) {\n <button mat-menu-item (click)=\"deleteMessage(currentMessage())\">\n <img ngSrc=\"assets/ngx-parl/icons/trash.svg\"\n class=\"message__icon--menu\"\n width=\"20\" height=\"20\" alt=\"hide\"/>\n <span>{{ 'chat.remove' | transloco }}</span>\n </button>\n }\n</mat-menu>\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.message{display:flex;gap:8px;align-items:flex-end;max-width:80%;animation:pop .12s ease-out}.message__avatar img{display:block;border-radius:1000px}.message__body{padding:8px 12px;min-width:0;font:400 16px/20px inter,sans-serif;border-radius:16px;position:relative}.message__bubble{display:grid;grid-template-columns:1fr auto;column-gap:8px;align-items:end;max-width:100%;word-break:break-word;white-space:pre-wrap}.message__quick-actions-wrap{display:flex;margin-top:12px;width:100%;background:transparent}.message__quick-actions{display:grid;gap:8px;width:234px;max-width:100%;background:transparent}.message__quick-action-button{--border-radius: 16px;--border-width: 1px;--border-style: solid;--border-color: #2563EB;--color: #2563EB;--padding-top: tokens.$space-3;--padding-bottom: tokens.$space-3;--padding-start: tokens.$space-6;--padding-end: tokens.$space-6;height:48px;text-transform:none;font:500 14px/18px inter,sans-serif;margin:0}.message__text{min-width:0}.message__meta{display:inline-flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;line-height:1;margin:0}.message__time{font:400 12px/16px inter,sans-serif}.message__attachments{display:grid;gap:8px;justify-content:start;width:100%;margin-bottom:8px}.message__attachments:has(:only-child){grid-template-columns:repeat(1,minmax(0,140px))}.message__attachments:has(:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,145px))}.message__attachments:has(:nth-child(3)){grid-template-columns:repeat(3,minmax(0,150px))}.message__body--attachments-1{max-width:164px}.message__body--attachments-2{max-width:312px}.message__body--attachments-3{max-width:460px}.message__body--attachments-1 .message__bubble,.message__body--attachments-2 .message__bubble,.message__body--attachments-3 .message__bubble{grid-template-columns:1fr;row-gap:4px}.message__body--attachments-1 .message__meta,.message__body--attachments-2 .message__meta,.message__body--attachments-3 .message__meta{justify-self:end}.message__image-button{display:block;border:none;padding:0;background:transparent;border-radius:12px;overflow:hidden;cursor:pointer}.message__image-button:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.message__menu-trigger{position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}.message__image{display:block;width:100%;height:140px;object-fit:cover;border-radius:12px;aspect-ratio:1/1}.message__bubble:after{content:\"\";display:block;clear:both}.message__time{font:400 12px/16px inter,sans-serif;min-width:30px}.message__icon{width:14px;height:14px;vertical-align:middle}.message__icon--menu{width:20px;height:20px}.message__loading{display:inline-block;width:10px;height:10px;border:2px solid #E9ECEF;border-top-color:#5a72d7;border-radius:50%;animation:message-loading-spin .8s linear infinite}.message--incoming{margin-right:auto}.message--incoming .message__body{border-bottom-right-radius:16px}.message--incoming .message__bubble{border-top-left-radius:4px}.message--incoming .message__time{color:#adb5bd}.message--incoming .message__quick-actions-wrap{justify-content:flex-start}.message--outgoing{margin-left:auto;flex-direction:row-reverse}.message--outgoing .message__body{border-bottom-right-radius:0}.message--outgoing .message__bubble{border-top-right-radius:4px}.message--outgoing .message__time{color:#e9ecef}.message--outgoing .message__menu-trigger{right:auto}.message--outgoing .message__quick-actions-wrap{justify-content:flex-end}.message--mobile .message__user{padding-right:5px!important}.message--mobile.message--outgoing .message__body{border-bottom-right-radius:0}.message__user{display:flex;justify-content:flex-end;max-width:80%;margin-left:auto;margin-top:4px;padding-right:46px}.message__user--mobile{padding-right:5px!important}.message__user-name{font:400 12px/16px inter,sans-serif;color:#ced4da}@keyframes pop{0%{transform:translateY(2px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes message-loading-spin{to{transform:rotate(360deg)}}::ng-deep .mat-mdc-menu-content{background:#fff;width:160px;border-radius:8px;gap:4px;border:1px solid #E1E7F8;padding:8px 4px;box-shadow:0 2px 4px #0000001a;overflow:hidden;font:400 14px/18px inter,sans-serif}::ng-deep .mat-mdc-menu-item-text{font:400 14px/18px inter,sans-serif!important;font-weight:500!important;color:#343a40!important;display:flex;justify-content:flex-start;align-items:center;gap:4px}\n"] }]
420
- }], ctorParameters: () => [{ type: UtilsService }], propDecorators: { currentMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentMessage", required: true }] }], edit: [{ type: i0.Input, args: [{ isSignal: true, alias: "edit", required: false }] }, { type: i0.Output, args: ["editChange"] }], previewList: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewList", required: false }] }, { type: i0.Output, args: ["previewListChange"] }], previewIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewIndex", required: false }] }, { type: i0.Output, args: ["previewIndexChange"] }], previewOpener: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewOpener", required: false }] }, { type: i0.Output, args: ["previewOpenerChange"] }], requestEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestEdit", required: false }] }, { type: i0.Output, args: ["requestEditChange"] }], requestDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestDelete", required: false }] }, { type: i0.Output, args: ["requestDeleteChange"] }], mobileMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileMode", required: false }] }], quickActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActions", required: false }] }], quickActionClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionClick", required: false }] }, { type: i0.Output, args: ["quickActionClickChange"] }] } });
425
+ ], standalone: true, template: "<div class=\"message\"\r\n [ngClass]=\"{\r\n 'message--outgoing': isOutgoingMessage(),\r\n 'message--incoming': !isOutgoingMessage(),\r\n 'message--mobile': mobileMode()\r\n }\">\r\n @if (showAvatar()) {\r\n <div class=\"message__avatar\">\r\n <img [ngSrc]=\"avatarSrc()\" width=\"36\" height=\"36\" alt=\"avatar\"/>\r\n </div>\r\n }\r\n\r\n @if (showMessageBody()) {\r\n <div class=\"message__body\"\r\n (contextmenu)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\"\r\n (keydown.shift.F10)=\"openContextMenu($event, menuTrigger, menuTriggerEl)\">\r\n <button type=\"button\"\r\n class=\"message__menu-trigger\"\r\n aria-hidden=\"true\"\r\n tabindex=\"-1\"\r\n #menuTrigger=\"matMenuTrigger\"\r\n #menuTriggerEl\r\n [matMenuTriggerFor]=\"messageMenu\">\r\n </button>\r\n\r\n @if (attachments().length) {\r\n <div class=\"message__attachments\">\r\n @for (file of attachments(); track file; let i = $index) {\r\n <button type=\"button\"\r\n class=\"message__image-button\"\r\n (click)=\"openPreview(i, $event)\"\r\n [attr.aria-label]=\"'chat.photo_preview' | transloco\">\r\n <img [src]=\"file\"\r\n alt=\"attachment\"\r\n class=\"message__image\"\r\n loading=\"lazy\"/>\r\n </button>\r\n }\r\n </div>\r\n }\r\n\r\n @if (showMessageBubble()) {\r\n <div class=\"message__bubble\" tabindex=\"0\">\r\n <div class=\"message__text\">{{ currentMessage().content }}</div>\r\n\r\n <div class=\"message__meta\">\r\n <time class=\"message__time\">\r\n {{ currentMessage().cr_time | date:'HH:mm' }}\r\n </time>\r\n @if (isOutgoingMessage()) {\r\n @if (currentMessage().pending) {\r\n <span class=\"message__loading\" aria-label=\"Sending\"></span>\r\n } @else if (currentMessage().checked) {\r\n <img ngSrc=\"assets/ngx-parl/icons/checked-message.svg\"\r\n class=\"message__icon\"\r\n width=\"18\" height=\"18\" alt=\"hide\"/>\r\n } @else {\r\n <img ngSrc=\"assets/ngx-parl/icons/no-check.svg\"\r\n class=\"message__icon\"\r\n width=\"18\" height=\"18\" alt=\"hide\"/>\r\n }\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n </div>\r\n }\r\n\r\n @if (hasQuickActionButtons()) {\r\n <div class=\"message__quick-actions-wrap\" role=\"group\" [attr.aria-label]=\"'chat.quick_actions' | transloco\">\r\n <div class=\"message__quick-actions\">\r\n @for (action of quickActions(); track action.id) {\r\n <button\r\n class=\"message__quick-action-button\"\r\n type=\"button\"\r\n [disabled]=\"action.disabled === true\"\r\n (click)=\"onQuickAction(action)\">\r\n {{ action.title }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n@if (!hasQuickActionButtons()) {\r\n <div class=\"message__user\" [ngClass]=\"{'message__user--mobile': mobileMode()}\">\r\n @if (isOutgoingMessage()) {\r\n <span class=\"message__user-name\">{{ currentMessage().user }}</span>\r\n }\r\n </div>\r\n}\r\n\r\n@if (previewList().length) {\r\n <lib-preview-file [srcList]=\"previewList()\"\r\n [startIndex]=\"previewIndex()\"\r\n [openerElement]=\"previewOpener()\"\r\n [closeHandler]=\"closePreviewHandler\">\r\n </lib-preview-file>\r\n}\r\n\r\n<mat-menu #messageMenu=\"matMenu\" yPosition=\"below\" xPosition=\"before\" class=\"message__menu\">\r\n @if (isOutgoingMessage()) {\r\n <button mat-menu-item (click)=\"editMessage(currentMessage())\">\r\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\r\n class=\"message__icon--menu\"\r\n width=\"20\" height=\"20\" alt=\"hide\"/>\r\n <span>{{ 'chat.edit' | transloco }}</span>\r\n </button>\r\n <button mat-menu-item (click)=\"deleteMessage(currentMessage())\">\r\n <img ngSrc=\"assets/ngx-parl/icons/trash.svg\"\r\n class=\"message__icon--menu\"\r\n width=\"20\" height=\"20\" alt=\"hide\"/>\r\n <span>{{ 'chat.remove' | transloco }}</span>\r\n </button>\r\n }\r\n</mat-menu>\r\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.message{display:flex;gap:8px;align-items:flex-end;max-width:80%;animation:pop .12s ease-out}.message__avatar{flex:0 0 36px;width:36px;height:36px;min-width:36px;align-self:flex-end}.message__avatar img{display:block;width:36px;height:36px;border-radius:1000px;object-fit:cover}.message__body{padding:8px 12px;min-width:0;font:400 16px/20px inter,sans-serif;border-radius:16px;position:relative}.message__bubble{display:grid;grid-template-columns:1fr auto;column-gap:8px;align-items:end;max-width:100%;word-break:break-word;white-space:pre-wrap}.message__quick-actions-wrap{display:flex;margin-top:12px;width:100%;background:transparent}.message__quick-actions{display:grid;gap:8px;width:234px;max-width:100%;background:transparent}.message__quick-action-button{display:inline-flex;width:100%;align-items:center;justify-content:center;border-radius:16px;border:1px solid #2563EB;color:#2563eb;background:transparent;padding:12px 24px;height:48px;text-transform:none;font:500 14px/18px inter,sans-serif;margin:0;cursor:pointer}.message__quick-action-button:disabled{opacity:.6;cursor:not-allowed}.message__quick-action-button:hover:not(:disabled),.message__quick-action-button:focus-visible:not(:disabled){background:#2563eb0f}.message__quick-action-button:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.message__text{min-width:0}.message__meta{display:inline-flex;align-items:center;gap:4px;-webkit-user-select:none;user-select:none;line-height:1;margin:0}.message__time{font:400 12px/16px inter,sans-serif}.message__attachments{display:grid;gap:8px;justify-content:start;width:100%;margin-bottom:8px}.message__attachments:has(:only-child){grid-template-columns:repeat(1,minmax(0,140px))}.message__attachments:has(:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,145px))}.message__attachments:has(:nth-child(3)){grid-template-columns:repeat(3,minmax(0,150px))}.message__body--attachments-1{max-width:164px}.message__body--attachments-2{max-width:312px}.message__body--attachments-3{max-width:460px}.message__body--attachments-1 .message__bubble,.message__body--attachments-2 .message__bubble,.message__body--attachments-3 .message__bubble{grid-template-columns:1fr;row-gap:4px}.message__body--attachments-1 .message__meta,.message__body--attachments-2 .message__meta,.message__body--attachments-3 .message__meta{justify-self:end}.message__image-button{display:block;border:none;padding:0;background:transparent;border-radius:12px;overflow:hidden;cursor:pointer}.message__image-button:focus-visible{outline:2px solid #5A72D7;outline-offset:4px}.message__menu-trigger{position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}.message__image{display:block;width:100%;height:140px;object-fit:cover;border-radius:12px;aspect-ratio:1/1}.message__bubble:after{content:\"\";display:block;clear:both}.message__time{font:400 12px/16px inter,sans-serif;min-width:30px}.message__icon{width:14px;height:14px;vertical-align:middle}.message__icon--menu{width:20px;height:20px}.message__loading{display:inline-block;width:10px;height:10px;border:2px solid #E9ECEF;border-top-color:#5a72d7;border-radius:50%;animation:message-loading-spin .8s linear infinite}.message--incoming{margin-right:auto}.message--incoming .message__body{border-bottom-right-radius:16px}.message--incoming .message__bubble{border-top-left-radius:4px}.message--incoming .message__time{color:#adb5bd}.message--incoming .message__quick-actions-wrap{justify-content:flex-start}.message--outgoing{margin-left:auto;flex-direction:row-reverse}.message--outgoing .message__body{border-bottom-right-radius:0}.message--outgoing .message__bubble{border-top-right-radius:4px}.message--outgoing .message__time{color:#e9ecef}.message--outgoing .message__menu-trigger{right:auto}.message--outgoing .message__quick-actions-wrap{justify-content:flex-end}.message--mobile .message__user{padding-right:5px!important}.message--mobile.message--outgoing .message__body{border-bottom-right-radius:0}.message__user{display:flex;justify-content:flex-end;max-width:80%;margin-left:auto;margin-top:4px;padding-right:46px}.message__user--mobile{padding-right:5px!important}.message__user-name{font:400 12px/16px inter,sans-serif;color:#ced4da}@keyframes pop{0%{transform:translateY(2px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes message-loading-spin{to{transform:rotate(360deg)}}::ng-deep .message__menu.mat-mdc-menu-panel{min-width:160px!important;max-width:160px!important;width:160px!important;background:#fff!important;border-radius:8px!important;border:1px solid #E9ECEF!important;box-shadow:0 2px 4px #0000001a!important;overflow:hidden!important}::ng-deep .message__menu .mat-mdc-menu-content{background:#fff!important;width:160px!important;min-height:88px!important;border-radius:8px!important;border:none!important;padding:4px 0!important;box-shadow:none!important;overflow:hidden!important;font:400 14px/18px inter,sans-serif!important;color:#343a40!important;gap:0!important}::ng-deep .message__menu .mat-mdc-menu-item{min-height:40px!important;height:40px!important;background:#fff!important;color:#343a40!important;font:400 14px/18px inter,sans-serif!important;font-weight:500!important;padding-inline:12px!important}::ng-deep .message__menu .mat-mdc-menu-item:hover,::ng-deep .message__menu .mat-mdc-menu-item.mat-mdc-menu-item-highlighted{background:#e9ecef!important;color:#212529!important}::ng-deep .message__menu .mat-mdc-menu-item .mat-mdc-menu-item-text{font:400 14px/18px inter,sans-serif!important;font-weight:500!important;color:inherit!important;display:flex!important;justify-content:flex-start!important;align-items:center!important;gap:8px!important}::ng-deep .message__menu .mat-mdc-menu-item .mdc-list-item__primary-text{color:inherit!important}\n"] }]
426
+ }], propDecorators: { currentMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentMessage", required: true }] }], edit: [{ type: i0.Input, args: [{ isSignal: true, alias: "edit", required: false }] }, { type: i0.Output, args: ["editChange"] }], previewList: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewList", required: false }] }, { type: i0.Output, args: ["previewListChange"] }], previewIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewIndex", required: false }] }, { type: i0.Output, args: ["previewIndexChange"] }], previewOpener: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewOpener", required: false }] }, { type: i0.Output, args: ["previewOpenerChange"] }], requestEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestEdit", required: false }] }, { type: i0.Output, args: ["requestEditChange"] }], requestDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestDelete", required: false }] }, { type: i0.Output, args: ["requestDeleteChange"] }], mobileMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileMode", required: false }] }], logoChat: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoChat", required: false }] }], quickActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActions", required: false }] }], quickActionClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionClick", required: false }] }, { type: i0.Output, args: ["quickActionClickChange"] }] } });
421
427
 
422
428
  class ToggleDisplayChatStartDayPipe {
423
429
  utils;
@@ -434,10 +440,10 @@ class ToggleDisplayChatStartDayPipe {
434
440
  const prevDay = prev ? datePipe.transform(new Date(prev.cr_time), 'shortDate') : undefined;
435
441
  return prev ? currDay !== prevDay : true;
436
442
  }
437
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ToggleDisplayChatStartDayPipe, deps: [{ token: UtilsService }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Pipe });
438
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: ToggleDisplayChatStartDayPipe, isStandalone: true, name: "toggleDisplayChatStartDay" });
443
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ToggleDisplayChatStartDayPipe, deps: [{ token: UtilsService }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Pipe });
444
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.12", ngImport: i0, type: ToggleDisplayChatStartDayPipe, isStandalone: true, name: "toggleDisplayChatStartDay" });
439
445
  }
440
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ToggleDisplayChatStartDayPipe, decorators: [{
446
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ToggleDisplayChatStartDayPipe, decorators: [{
441
447
  type: Pipe,
442
448
  args: [{
443
449
  name: 'toggleDisplayChatStartDay'
@@ -464,65 +470,110 @@ class ChatStartDayPipe {
464
470
  ? (locale.startsWith('uk') ? 'Сьогодні' : 'Today')
465
471
  : (datePipe.transform(valueDate, format) ?? '');
466
472
  }
467
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChatStartDayPipe, deps: [{ token: UtilsService }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Pipe });
468
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: ChatStartDayPipe, isStandalone: true, name: "chatStartDay" });
473
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ChatStartDayPipe, deps: [{ token: UtilsService }, { token: i2.TranslocoService }], target: i0.ɵɵFactoryTarget.Pipe });
474
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.12", ngImport: i0, type: ChatStartDayPipe, isStandalone: true, name: "chatStartDay" });
469
475
  }
470
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChatStartDayPipe, decorators: [{
476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ChatStartDayPipe, decorators: [{
471
477
  type: Pipe,
472
478
  args: [{
473
479
  name: 'chatStartDay'
474
480
  }]
475
481
  }], ctorParameters: () => [{ type: UtilsService }, { type: i2.TranslocoService }] });
476
482
 
483
+ /**
484
+ * Maps `message.actions` to quick action buttons for outgoing messages.
485
+ * Used when `[quickActionsResolver]` is not provided. Independent of `mobileMode`.
486
+ */
487
+ function messageHasActionButtons(message) {
488
+ const t = message.type;
489
+ const outgoing = t === MessageType.Outgoing ||
490
+ (typeof t === 'string' && t.toLowerCase() === MessageType.Outgoing);
491
+ if (!outgoing) {
492
+ return false;
493
+ }
494
+ return Array.isArray(message.actions) && message.actions.length > 0;
495
+ }
496
+ function defaultParlQuickActionsResolver(context) {
497
+ const message = context.message;
498
+ if (!messageHasActionButtons(message)) {
499
+ return [];
500
+ }
501
+ const raw = message.actions;
502
+ return raw.map((a) => ({
503
+ id: String(a.id),
504
+ title: a.title,
505
+ value: a.value,
506
+ }));
507
+ }
508
+ function resolveParlQuickActions(context, resolver) {
509
+ if (!resolver) {
510
+ const actions = defaultParlQuickActionsResolver(context);
511
+ return Array.isArray(actions) && actions.length > 0 ? actions : [];
512
+ }
513
+ const resolved = resolver(context);
514
+ if (resolved == null || !Array.isArray(resolved)) {
515
+ return [];
516
+ }
517
+ return resolved;
518
+ }
519
+
477
520
  class ChatFlowComponent {
478
521
  flowRef;
479
522
  transloco = inject(TranslocoService);
523
+ utils = inject(UtilsService);
480
524
  translocoLang = toSignal(this.transloco.langChanges$, {
481
525
  initialValue: this.transloco.getActiveLang(),
482
526
  });
483
- scrollToBottomTrigger = model(0, ...(ngDevMode ? [{ debugName: "scrollToBottomTrigger" }] : []));
484
- loadHistory = model(false, ...(ngDevMode ? [{ debugName: "loadHistory" }] : []));
485
- messageListInput = model.required(...(ngDevMode ? [{ debugName: "messageListInput" }] : []));
486
- messageList = computed(() => this.messageListInput(), ...(ngDevMode ? [{ debugName: "messageList" }] : []));
487
- selectedForEdit = model.required(...(ngDevMode ? [{ debugName: "selectedForEdit" }] : []));
488
- requestDelete = model(null, ...(ngDevMode ? [{ debugName: "requestDelete" }] : []));
489
- mobileMode = input(false, ...(ngDevMode ? [{ debugName: "mobileMode" }] : []));
490
- quickActionsResolver = input(null, ...(ngDevMode ? [{ debugName: "quickActionsResolver" }] : []));
491
- quickActionClick = model(null, ...(ngDevMode ? [{ debugName: "quickActionClick" }] : []));
492
- deleteConfirmOpen = signal(false, ...(ngDevMode ? [{ debugName: "deleteConfirmOpen" }] : []));
493
- pendingDeleteMessageId = signal(null, ...(ngDevMode ? [{ debugName: "pendingDeleteMessageId" }] : []));
527
+ translocoTranslationTick = toSignal(this.transloco.events$.pipe(filter((e) => e.type === 'translationLoadSuccess'), map(() => Date.now()), startWith(0)), { initialValue: 0 });
528
+ scrollToBottomTrigger = model(0, ...(ngDevMode ? [{ debugName: "scrollToBottomTrigger" }] : /* istanbul ignore next */ []));
529
+ loadHistory = model(false, ...(ngDevMode ? [{ debugName: "loadHistory" }] : /* istanbul ignore next */ []));
530
+ messageListInput = model.required(...(ngDevMode ? [{ debugName: "messageListInput" }] : /* istanbul ignore next */ []));
531
+ messageList = computed(() => this.messageListInput(), ...(ngDevMode ? [{ debugName: "messageList" }] : /* istanbul ignore next */ []));
532
+ selectedForEdit = model.required(...(ngDevMode ? [{ debugName: "selectedForEdit" }] : /* istanbul ignore next */ []));
533
+ requestDelete = model(null, ...(ngDevMode ? [{ debugName: "requestDelete" }] : /* istanbul ignore next */ []));
534
+ mobileMode = input(false, ...(ngDevMode ? [{ debugName: "mobileMode" }] : /* istanbul ignore next */ []));
535
+ logoChat = input('', ...(ngDevMode ? [{ debugName: "logoChat" }] : /* istanbul ignore next */ []));
536
+ logoChatSrc = computed(() => {
537
+ const trimmed = (this.logoChat() ?? '').trim();
538
+ const path = trimmed.length > 0
539
+ ? trimmed
540
+ : 'assets/ngx-parl/icons/avatar_manager.svg';
541
+ return this.utils.normalizeSourcePath(path);
542
+ }, ...(ngDevMode ? [{ debugName: "logoChatSrc" }] : /* istanbul ignore next */ []));
543
+ quickActionsResolver = input(null, ...(ngDevMode ? [{ debugName: "quickActionsResolver" }] : /* istanbul ignore next */ []));
544
+ quickActionClick = model(null, ...(ngDevMode ? [{ debugName: "quickActionClick" }] : /* istanbul ignore next */ []));
545
+ deleteConfirmOpen = signal(false, ...(ngDevMode ? [{ debugName: "deleteConfirmOpen" }] : /* istanbul ignore next */ []));
546
+ pendingDeleteMessageId = signal(null, ...(ngDevMode ? [{ debugName: "pendingDeleteMessageId" }] : /* istanbul ignore next */ []));
494
547
  deleteAlertButtons = computed(() => {
495
548
  this.translocoLang();
549
+ this.translocoTranslationTick();
496
550
  return [
497
551
  {
498
- text: this.transloco.translate('chat.cancel'),
552
+ text: this.translateChatKey('chat.cancel', 'Cancel'),
499
553
  role: 'cancel',
500
554
  handler: () => this.closeDeleteConfirm(),
501
555
  },
502
556
  {
503
- text: this.transloco.translate('chat.remove'),
557
+ text: this.translateChatKey('chat.remove', 'Delete'),
504
558
  role: 'destructive',
505
559
  cssClass: 'chat__delete-alert-destructive',
506
560
  handler: () => this.confirmDelete(),
507
561
  },
508
562
  ];
509
- }, ...(ngDevMode ? [{ debugName: "deleteAlertButtons" }] : []));
563
+ }, ...(ngDevMode ? [{ debugName: "deleteAlertButtons" }] : /* istanbul ignore next */ []));
510
564
  quickActionsByMessageId = computed(() => {
511
565
  const messages = this.messageList();
512
566
  const resolver = this.quickActionsResolver();
513
567
  const isMobile = this.mobileMode();
514
568
  const map = new Map();
515
- if (!resolver || !isMobile) {
516
- return map;
517
- }
518
569
  for (const message of messages) {
519
- const actions = resolver({ message, isMobile });
520
- if (Array.isArray(actions) && actions.length) {
570
+ const actions = resolveParlQuickActions({ message, isMobile }, resolver);
571
+ if (actions.length > 0) {
521
572
  map.set(message.id, actions);
522
573
  }
523
574
  }
524
575
  return map;
525
- }, ...(ngDevMode ? [{ debugName: "quickActionsByMessageId" }] : []));
576
+ }, ...(ngDevMode ? [{ debugName: "quickActionsByMessageId" }] : /* istanbul ignore next */ []));
526
577
  viewInitialized = false;
527
578
  previousMessageCount = 0;
528
579
  previousFirstMessageId = null;
@@ -532,8 +583,8 @@ class ChatFlowComponent {
532
583
  previousScrollTop = 0;
533
584
  isUserAtBottom = true;
534
585
  resizeObserver = null;
535
- showScrollToBottom = signal(false, ...(ngDevMode ? [{ debugName: "showScrollToBottom" }] : []));
536
- historyLoadThreshold = signal(1, ...(ngDevMode ? [{ debugName: "historyLoadThreshold" }] : []));
586
+ showScrollToBottom = signal(false, ...(ngDevMode ? [{ debugName: "showScrollToBottom" }] : /* istanbul ignore next */ []));
587
+ historyLoadThreshold = signal(1, ...(ngDevMode ? [{ debugName: "historyLoadThreshold" }] : /* istanbul ignore next */ []));
537
588
  constructor() {
538
589
  effect(() => {
539
590
  const messages = this.messageList();
@@ -704,11 +755,6 @@ class ChatFlowComponent {
704
755
  return this;
705
756
  }
706
757
  this.selectedForEdit.set(null);
707
- if (!this.mobileMode()) {
708
- this.requestDelete.set(messageId);
709
- queueMicrotask(() => this.requestDelete.set(null));
710
- return this;
711
- }
712
758
  this.pendingDeleteMessageId.set(messageId);
713
759
  this.deleteConfirmOpen.set(true);
714
760
  return this;
@@ -728,14 +774,23 @@ class ChatFlowComponent {
728
774
  queueMicrotask(() => this.requestDelete.set(null));
729
775
  return this;
730
776
  }
777
+ translateChatKey(key, fallbackEn) {
778
+ const lang = this.transloco.getActiveLang();
779
+ const translation = this.transloco.getTranslation(lang);
780
+ const value = getValue(translation, key);
781
+ if (typeof value === 'string' && value.trim().length > 0) {
782
+ return value;
783
+ }
784
+ return fallbackEn;
785
+ }
731
786
  trackByMessageId(index, message) {
732
787
  return `${message.chat_id}-${message.type}-${message.id}-${index}`;
733
788
  }
734
789
  Math = Math;
735
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChatFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
736
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: ChatFlowComponent, isStandalone: true, selector: "app-chat-flow", inputs: { scrollToBottomTrigger: { classPropertyName: "scrollToBottomTrigger", publicName: "scrollToBottomTrigger", isSignal: true, isRequired: false, transformFunction: null }, loadHistory: { classPropertyName: "loadHistory", publicName: "loadHistory", isSignal: true, isRequired: false, transformFunction: null }, messageListInput: { classPropertyName: "messageListInput", publicName: "messageListInput", isSignal: true, isRequired: true, transformFunction: null }, selectedForEdit: { classPropertyName: "selectedForEdit", publicName: "selectedForEdit", isSignal: true, isRequired: true, transformFunction: null }, requestDelete: { classPropertyName: "requestDelete", publicName: "requestDelete", isSignal: true, isRequired: false, transformFunction: null }, mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: true, isRequired: false, transformFunction: null }, quickActionsResolver: { classPropertyName: "quickActionsResolver", publicName: "quickActionsResolver", isSignal: true, isRequired: false, transformFunction: null }, quickActionClick: { classPropertyName: "quickActionClick", publicName: "quickActionClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrollToBottomTrigger: "scrollToBottomTriggerChange", loadHistory: "loadHistoryChange", messageListInput: "messageListInputChange", selectedForEdit: "selectedForEditChange", requestDelete: "requestDeleteChange", quickActionClick: "quickActionClickChange" }, viewQueries: [{ propertyName: "flowRef", first: true, predicate: ["chatFlowRef"], descendants: true }], ngImport: i0, template: "<div class=\"chat\">\n @if (messageList()) {\n <div #chatFlowRef\n class=\"chat__flow\"\n infiniteScroll\n [scrollWindow]=\"false\"\n [infiniteScrollUpDistance]=\"Math.max(historyLoadThreshold(), 2)\"\n [infiniteScrollThrottle]=\"100\"\n (scrolledUp)=\"onScrollUp()\"\n >\n <div class=\"chat__manager-header\" aria-hidden=\"true\">\n <div class=\"chat__manager-icon\">\n <img ngSrc=\"assets/ngx-parl/icons/avatar_manager.svg\"\n alt=\"manager\"\n width=\"72\"\n height=\"72\"/>\n </div>\n </div>\n\n @for (message of messageList(); track trackByMessageId(i, message); let i = $index) {\n @if (message | toggleDisplayChatStartDay: messageList() : i) {\n <span class=\"chat__start-day\">\n {{ message.cr_time | chatStartDay:'d MMMM' }}\n </span>\n }\n\n <div class=\"chat__message\" [attr.data-message-id]=\"message.id\">\n <lib-chat-message\n [currentMessage]=\"message\"\n [edit]=\"message.edit\"\n [mobileMode]=\"mobileMode()\"\n [quickActions]=\"quickActionsByMessageId().get(message.id) ?? []\"\n [(quickActionClick)]=\"quickActionClick\"\n (editChange)=\"onEditChange(message.id, $event)\"\n (requestEditChange)=\"onRequestEdit($event)\"\n (requestDeleteChange)=\"onRequestDelete($event)\">\n </lib-chat-message>\n </div>\n }\n </div>\n\n @if (mobileMode()) {\n <ion-alert mode=\"md\"\n [header]=\"'chat.delete_message_title' | transloco\"\n cssClass=\"chat__delete-alert\"\n [isOpen]=\"deleteConfirmOpen()\"\n [buttons]=\"deleteAlertButtons()\"\n (didDismiss)=\"closeDeleteConfirm()\"\n [backdropDismiss]=\"false\">\n </ion-alert>\n }\n\n @if (showScrollToBottom()) {\n <button class=\"chat__scroll-button\"\n type=\"button\"\n (click)=\"scrollToBottomSmooth()\"\n aria-label=\"Scroll to bottom\">\n <img ngSrc=\"assets/ngx-parl/icons/bottom-scroll.svg\"\n alt=\"\"\n width=\"14\"\n height=\"14\"/>\n </button>\n }\n } @else {\n <div class=\"chat__flow__empty\">\n <img ngSrc=\"assets/ngx-parl/icons/lucide_send.svg\"\n class=\"message__icon\"\n width=\"18\" height=\"24\" alt=\"hide\"/>\n\n\n <div class=\"chat__flow__empty--header\">\n <h3 class=\"chat__flow__empty--title\">{{ 'chat.chat_empty_title' | transloco }}</h3>\n <p class=\"chat__flow__empty--subscription\">{{ 'chat.chat_empty_subscription' | transloco }}</p>\n </div>\n </div>\n }\n</div>\n\n", styles: [":host{display:block;height:100%;min-height:0}.chat{background:#fff;height:100%;display:flex;flex-direction:column;min-height:0;width:100%;position:relative}.chat__flow{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:12px;padding:12px 16px;overscroll-behavior:contain}.chat__flow__empty{display:flex;gap:16px;flex-direction:column;align-items:center;justify-content:center;padding:72px 16px;height:100%}.chat__flow__empty .message__icon{width:56px;height:56px}.chat__flow__empty--header{width:285px;display:flex;gap:12px;flex-direction:column;align-items:center}.chat__flow__empty--title{margin:0;font:600 16px/20px inter,sans-serif;color:#212529}.chat__flow__empty--subscription{margin:0;font:400 16px/20px inter,sans-serif;color:#495057}.chat__manager-header{display:flex;justify-content:center;padding:24px 16px 8px}.chat__manager-icon{width:132px;height:132px;border-radius:1000px;display:grid;place-items:center}.chat__manager-icon img{display:block;border-radius:1000px}.chat__start-day{display:flex;justify-content:center;background:#f8f9fa;color:#6c757d;font:400 12px/16px inter,sans-serif;width:92px;height:22px;margin:0 auto;border-radius:1000px;gap:8px;padding:4px 8px}.chat__scroll-button{position:absolute;right:8px;bottom:8px;width:35px;height:35px;display:inline-flex;align-items:center;justify-content:center;padding:8px;border:none;border-radius:1000px;background:#c9d4f4;box-shadow:0 2px 4px #0000001a;opacity:.6;cursor:pointer;transition:background-color .15s ease,opacity .15s ease}.chat__scroll-button:hover,.chat__scroll-button:focus-visible{background:#dee2e6;opacity:1}.chat__scroll-button img{display:block}.chat ::-webkit-scrollbar{width:6px}.chat ::-webkit-scrollbar-track{background:transparent}.chat ::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.chat ::-webkit-scrollbar-button{display:none}.chat__delete-alert{--background: #ffffff;--backdrop-opacity: .32;--max-width: 520px}.chat__delete-alert .alert-wrapper{border-radius:16px;box-shadow:0 10px 30px #00000026}.chat__delete-alert .alert-head{padding-top:18px}.chat__delete-alert .alert-title{color:#0f172a;font-weight:500}.chat__delete-alert .alert-button-group{padding:8px 12px 12px}.chat__delete-alert .alert-button{color:#2563eb;font-weight:500}.chat__delete-alert .alert-button-role-destructive,.chat__delete-alert .alert-button-role-destructive .alert-button-inner{color:#dc2626!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ChatMessageComponent, selector: "lib-chat-message", inputs: ["currentMessage", "edit", "previewList", "previewIndex", "previewOpener", "requestEdit", "requestDelete", "mobileMode", "quickActions", "quickActionClick"], outputs: ["editChange", "previewListChange", "previewIndexChange", "previewOpenerChange", "requestEditChange", "requestDeleteChange", "quickActionClickChange"] }, { kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "directive", type: InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: IonAlert, selector: "ion-alert", inputs: ["animated", "backdropDismiss", "buttons", "cssClass", "enterAnimation", "header", "htmlAttributes", "inputs", "isOpen", "keyboardClose", "leaveAnimation", "message", "mode", "subHeader", "translucent", "trigger"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: ToggleDisplayChatStartDayPipe, name: "toggleDisplayChatStartDay" }, { kind: "pipe", type: ChatStartDayPipe, name: "chatStartDay" }], encapsulation: i0.ViewEncapsulation.None });
790
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ChatFlowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
791
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: ChatFlowComponent, isStandalone: true, selector: "app-chat-flow", inputs: { scrollToBottomTrigger: { classPropertyName: "scrollToBottomTrigger", publicName: "scrollToBottomTrigger", isSignal: true, isRequired: false, transformFunction: null }, loadHistory: { classPropertyName: "loadHistory", publicName: "loadHistory", isSignal: true, isRequired: false, transformFunction: null }, messageListInput: { classPropertyName: "messageListInput", publicName: "messageListInput", isSignal: true, isRequired: true, transformFunction: null }, selectedForEdit: { classPropertyName: "selectedForEdit", publicName: "selectedForEdit", isSignal: true, isRequired: true, transformFunction: null }, requestDelete: { classPropertyName: "requestDelete", publicName: "requestDelete", isSignal: true, isRequired: false, transformFunction: null }, mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: true, isRequired: false, transformFunction: null }, logoChat: { classPropertyName: "logoChat", publicName: "logoChat", isSignal: true, isRequired: false, transformFunction: null }, quickActionsResolver: { classPropertyName: "quickActionsResolver", publicName: "quickActionsResolver", isSignal: true, isRequired: false, transformFunction: null }, quickActionClick: { classPropertyName: "quickActionClick", publicName: "quickActionClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrollToBottomTrigger: "scrollToBottomTriggerChange", loadHistory: "loadHistoryChange", messageListInput: "messageListInputChange", selectedForEdit: "selectedForEditChange", requestDelete: "requestDeleteChange", quickActionClick: "quickActionClickChange" }, viewQueries: [{ propertyName: "flowRef", first: true, predicate: ["chatFlowRef"], descendants: true }], ngImport: i0, template: "<div class=\"chat\">\r\n @if (messageList()) {\r\n <div #chatFlowRef\r\n class=\"chat__flow\"\r\n infiniteScroll\r\n [scrollWindow]=\"false\"\r\n [infiniteScrollUpDistance]=\"Math.max(historyLoadThreshold(), 2)\"\r\n [infiniteScrollThrottle]=\"100\"\r\n (scrolledUp)=\"onScrollUp()\"\r\n >\r\n <div class=\"chat__manager-header\" aria-hidden=\"true\">\r\n <div class=\"chat__manager-icon\">\r\n <img [ngSrc]=\"logoChatSrc()\"\r\n alt=\"\"\r\n width=\"72\"\r\n height=\"72\"/>\r\n </div>\r\n </div>\r\n\r\n @for (message of messageList(); track trackByMessageId(i, message); let i = $index) {\r\n @if (message | toggleDisplayChatStartDay: messageList() : i) {\r\n <span class=\"chat__start-day\">\r\n {{ message.cr_time | chatStartDay:'d MMMM' }}\r\n </span>\r\n }\r\n\r\n <div class=\"chat__message\" [attr.data-message-id]=\"message.id\">\r\n <lib-chat-message\r\n [currentMessage]=\"message\"\r\n [edit]=\"message.edit\"\r\n [logoChat]=\"logoChat()\"\r\n [mobileMode]=\"mobileMode()\"\r\n [quickActions]=\"quickActionsByMessageId().get(message.id) ?? []\"\r\n [quickActionClick]=\"quickActionClick()\"\r\n (quickActionClickChange)=\"quickActionClick.set($event)\"\r\n (editChange)=\"onEditChange(message.id, $event)\"\r\n (requestEditChange)=\"onRequestEdit($event)\"\r\n (requestDeleteChange)=\"onRequestDelete($event)\">\r\n </lib-chat-message>\r\n </div>\r\n }\r\n </div>\r\n\r\n <ion-alert mode=\"md\"\r\n [header]=\"'chat.delete_message_title' | transloco\"\r\n cssClass=\"chat__delete-alert\"\r\n [isOpen]=\"deleteConfirmOpen()\"\r\n [buttons]=\"deleteAlertButtons()\"\r\n (didDismiss)=\"closeDeleteConfirm()\"\r\n [backdropDismiss]=\"false\">\r\n </ion-alert>\r\n\r\n @if (showScrollToBottom()) {\r\n <button class=\"chat__scroll-button\"\r\n type=\"button\"\r\n (click)=\"scrollToBottomSmooth()\"\r\n aria-label=\"Scroll to bottom\">\r\n <img ngSrc=\"assets/ngx-parl/icons/bottom-scroll.svg\"\r\n alt=\"\"\r\n width=\"14\"\r\n height=\"14\"/>\r\n </button>\r\n }\r\n } @else {\r\n <div class=\"chat__flow__empty\">\r\n <img ngSrc=\"assets/ngx-parl/icons/lucide_send.svg\"\r\n class=\"message__icon\"\r\n width=\"18\" height=\"24\" alt=\"hide\"/>\r\n\r\n\r\n <div class=\"chat__flow__empty--header\">\r\n <h3 class=\"chat__flow__empty--title\">{{ 'chat.chat_empty_title' | transloco }}</h3>\r\n <p class=\"chat__flow__empty--subscription\">{{ 'chat.chat_empty_subscription' | transloco }}</p>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n", styles: [":host{display:block;height:100%;min-height:0}.chat{background:#fff;height:100%;display:flex;flex-direction:column;min-height:0;width:100%;position:relative}.chat__flow{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:12px;padding:12px 16px;overscroll-behavior:contain}.chat__flow__empty{display:flex;gap:16px;flex-direction:column;align-items:center;justify-content:center;padding:72px 16px;height:100%}.chat__flow__empty .message__icon{width:56px;height:56px}.chat__flow__empty--header{width:285px;display:flex;gap:12px;flex-direction:column;align-items:center}.chat__flow__empty--title{margin:0;font:600 16px/20px inter,sans-serif;color:#212529}.chat__flow__empty--subscription{margin:0;font:400 16px/20px inter,sans-serif;color:#495057}.chat__manager-header{display:flex;justify-content:center;padding:24px 16px 8px}.chat__manager-icon{width:132px;height:132px;border-radius:1000px;display:grid;place-items:center}.chat__manager-icon img{display:block;border-radius:1000px}.chat__start-day{display:flex;justify-content:center;background:#f8f9fa;color:#6c757d;font:400 12px/16px inter,sans-serif;width:98px;height:22px;margin:0 auto;border-radius:1000px;gap:8px;padding:4px 8px}.chat__scroll-button{position:absolute;right:8px;bottom:8px;width:35px;height:35px;display:inline-flex;align-items:center;justify-content:center;padding:8px;border:none;border-radius:1000px;background:#c9d4f4;box-shadow:0 2px 4px #0000001a;opacity:.6;cursor:pointer;transition:background-color .15s ease,opacity .15s ease}.chat__scroll-button:hover,.chat__scroll-button:focus-visible{background:#dee2e6;opacity:1}.chat__scroll-button img{display:block}.chat ::-webkit-scrollbar{width:6px}.chat ::-webkit-scrollbar-track{background:transparent}.chat ::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.chat ::-webkit-scrollbar-button{display:none}.chat__delete-alert{--background: #ffffff;--backdrop-opacity: .32;--max-width: 520px}.chat__delete-alert .alert-wrapper{border-radius:16px;box-shadow:0 10px 30px #00000026}.chat__delete-alert .alert-head{padding-top:18px}.chat__delete-alert .alert-title{color:#212529!important;font-weight:400!important}.chat__delete-alert .alert-button-group{padding:8px 12px 12px}.chat__delete-alert .alert-button-role-cancel,.chat__delete-alert .alert-button-role-cancel .alert-button-inner{color:#2563eb!important;font-weight:500!important}.chat__delete-alert .alert-button-role-destructive,.chat__delete-alert .alert-button-role-destructive .alert-button-inner,.chat__delete-alert .chat__delete-alert-destructive,.chat__delete-alert .chat__delete-alert-destructive .alert-button-inner{color:#dc2626!important;font-weight:500!important}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "component", type: ChatMessageComponent, selector: "lib-chat-message", inputs: ["currentMessage", "edit", "previewList", "previewIndex", "previewOpener", "requestEdit", "requestDelete", "mobileMode", "logoChat", "quickActions", "quickActionClick"], outputs: ["editChange", "previewListChange", "previewIndexChange", "previewOpenerChange", "requestEditChange", "requestDeleteChange", "quickActionClickChange"] }, { kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "directive", type: InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: IonAlert, selector: "ion-alert", inputs: ["animated", "backdropDismiss", "buttons", "cssClass", "enterAnimation", "header", "htmlAttributes", "inputs", "isOpen", "keyboardClose", "leaveAnimation", "message", "mode", "subHeader", "translucent", "trigger"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "pipe", type: ToggleDisplayChatStartDayPipe, name: "toggleDisplayChatStartDay" }, { kind: "pipe", type: ChatStartDayPipe, name: "chatStartDay" }], encapsulation: i0.ViewEncapsulation.None });
737
792
  }
738
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ChatFlowComponent, decorators: [{
793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ChatFlowComponent, decorators: [{
739
794
  type: Component,
740
795
  args: [{ selector: 'app-chat-flow', imports: [
741
796
  FormsModule,
@@ -746,11 +801,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
746
801
  ToggleDisplayChatStartDayPipe,
747
802
  ChatStartDayPipe,
748
803
  IonAlert,
749
- ], standalone: true, encapsulation: ViewEncapsulation.None, template: "<div class=\"chat\">\n @if (messageList()) {\n <div #chatFlowRef\n class=\"chat__flow\"\n infiniteScroll\n [scrollWindow]=\"false\"\n [infiniteScrollUpDistance]=\"Math.max(historyLoadThreshold(), 2)\"\n [infiniteScrollThrottle]=\"100\"\n (scrolledUp)=\"onScrollUp()\"\n >\n <div class=\"chat__manager-header\" aria-hidden=\"true\">\n <div class=\"chat__manager-icon\">\n <img ngSrc=\"assets/ngx-parl/icons/avatar_manager.svg\"\n alt=\"manager\"\n width=\"72\"\n height=\"72\"/>\n </div>\n </div>\n\n @for (message of messageList(); track trackByMessageId(i, message); let i = $index) {\n @if (message | toggleDisplayChatStartDay: messageList() : i) {\n <span class=\"chat__start-day\">\n {{ message.cr_time | chatStartDay:'d MMMM' }}\n </span>\n }\n\n <div class=\"chat__message\" [attr.data-message-id]=\"message.id\">\n <lib-chat-message\n [currentMessage]=\"message\"\n [edit]=\"message.edit\"\n [mobileMode]=\"mobileMode()\"\n [quickActions]=\"quickActionsByMessageId().get(message.id) ?? []\"\n [(quickActionClick)]=\"quickActionClick\"\n (editChange)=\"onEditChange(message.id, $event)\"\n (requestEditChange)=\"onRequestEdit($event)\"\n (requestDeleteChange)=\"onRequestDelete($event)\">\n </lib-chat-message>\n </div>\n }\n </div>\n\n @if (mobileMode()) {\n <ion-alert mode=\"md\"\n [header]=\"'chat.delete_message_title' | transloco\"\n cssClass=\"chat__delete-alert\"\n [isOpen]=\"deleteConfirmOpen()\"\n [buttons]=\"deleteAlertButtons()\"\n (didDismiss)=\"closeDeleteConfirm()\"\n [backdropDismiss]=\"false\">\n </ion-alert>\n }\n\n @if (showScrollToBottom()) {\n <button class=\"chat__scroll-button\"\n type=\"button\"\n (click)=\"scrollToBottomSmooth()\"\n aria-label=\"Scroll to bottom\">\n <img ngSrc=\"assets/ngx-parl/icons/bottom-scroll.svg\"\n alt=\"\"\n width=\"14\"\n height=\"14\"/>\n </button>\n }\n } @else {\n <div class=\"chat__flow__empty\">\n <img ngSrc=\"assets/ngx-parl/icons/lucide_send.svg\"\n class=\"message__icon\"\n width=\"18\" height=\"24\" alt=\"hide\"/>\n\n\n <div class=\"chat__flow__empty--header\">\n <h3 class=\"chat__flow__empty--title\">{{ 'chat.chat_empty_title' | transloco }}</h3>\n <p class=\"chat__flow__empty--subscription\">{{ 'chat.chat_empty_subscription' | transloco }}</p>\n </div>\n </div>\n }\n</div>\n\n", styles: [":host{display:block;height:100%;min-height:0}.chat{background:#fff;height:100%;display:flex;flex-direction:column;min-height:0;width:100%;position:relative}.chat__flow{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:12px;padding:12px 16px;overscroll-behavior:contain}.chat__flow__empty{display:flex;gap:16px;flex-direction:column;align-items:center;justify-content:center;padding:72px 16px;height:100%}.chat__flow__empty .message__icon{width:56px;height:56px}.chat__flow__empty--header{width:285px;display:flex;gap:12px;flex-direction:column;align-items:center}.chat__flow__empty--title{margin:0;font:600 16px/20px inter,sans-serif;color:#212529}.chat__flow__empty--subscription{margin:0;font:400 16px/20px inter,sans-serif;color:#495057}.chat__manager-header{display:flex;justify-content:center;padding:24px 16px 8px}.chat__manager-icon{width:132px;height:132px;border-radius:1000px;display:grid;place-items:center}.chat__manager-icon img{display:block;border-radius:1000px}.chat__start-day{display:flex;justify-content:center;background:#f8f9fa;color:#6c757d;font:400 12px/16px inter,sans-serif;width:92px;height:22px;margin:0 auto;border-radius:1000px;gap:8px;padding:4px 8px}.chat__scroll-button{position:absolute;right:8px;bottom:8px;width:35px;height:35px;display:inline-flex;align-items:center;justify-content:center;padding:8px;border:none;border-radius:1000px;background:#c9d4f4;box-shadow:0 2px 4px #0000001a;opacity:.6;cursor:pointer;transition:background-color .15s ease,opacity .15s ease}.chat__scroll-button:hover,.chat__scroll-button:focus-visible{background:#dee2e6;opacity:1}.chat__scroll-button img{display:block}.chat ::-webkit-scrollbar{width:6px}.chat ::-webkit-scrollbar-track{background:transparent}.chat ::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.chat ::-webkit-scrollbar-button{display:none}.chat__delete-alert{--background: #ffffff;--backdrop-opacity: .32;--max-width: 520px}.chat__delete-alert .alert-wrapper{border-radius:16px;box-shadow:0 10px 30px #00000026}.chat__delete-alert .alert-head{padding-top:18px}.chat__delete-alert .alert-title{color:#0f172a;font-weight:500}.chat__delete-alert .alert-button-group{padding:8px 12px 12px}.chat__delete-alert .alert-button{color:#2563eb;font-weight:500}.chat__delete-alert .alert-button-role-destructive,.chat__delete-alert .alert-button-role-destructive .alert-button-inner{color:#dc2626!important}\n"] }]
804
+ ], standalone: true, encapsulation: ViewEncapsulation.None, template: "<div class=\"chat\">\r\n @if (messageList()) {\r\n <div #chatFlowRef\r\n class=\"chat__flow\"\r\n infiniteScroll\r\n [scrollWindow]=\"false\"\r\n [infiniteScrollUpDistance]=\"Math.max(historyLoadThreshold(), 2)\"\r\n [infiniteScrollThrottle]=\"100\"\r\n (scrolledUp)=\"onScrollUp()\"\r\n >\r\n <div class=\"chat__manager-header\" aria-hidden=\"true\">\r\n <div class=\"chat__manager-icon\">\r\n <img [ngSrc]=\"logoChatSrc()\"\r\n alt=\"\"\r\n width=\"72\"\r\n height=\"72\"/>\r\n </div>\r\n </div>\r\n\r\n @for (message of messageList(); track trackByMessageId(i, message); let i = $index) {\r\n @if (message | toggleDisplayChatStartDay: messageList() : i) {\r\n <span class=\"chat__start-day\">\r\n {{ message.cr_time | chatStartDay:'d MMMM' }}\r\n </span>\r\n }\r\n\r\n <div class=\"chat__message\" [attr.data-message-id]=\"message.id\">\r\n <lib-chat-message\r\n [currentMessage]=\"message\"\r\n [edit]=\"message.edit\"\r\n [logoChat]=\"logoChat()\"\r\n [mobileMode]=\"mobileMode()\"\r\n [quickActions]=\"quickActionsByMessageId().get(message.id) ?? []\"\r\n [quickActionClick]=\"quickActionClick()\"\r\n (quickActionClickChange)=\"quickActionClick.set($event)\"\r\n (editChange)=\"onEditChange(message.id, $event)\"\r\n (requestEditChange)=\"onRequestEdit($event)\"\r\n (requestDeleteChange)=\"onRequestDelete($event)\">\r\n </lib-chat-message>\r\n </div>\r\n }\r\n </div>\r\n\r\n <ion-alert mode=\"md\"\r\n [header]=\"'chat.delete_message_title' | transloco\"\r\n cssClass=\"chat__delete-alert\"\r\n [isOpen]=\"deleteConfirmOpen()\"\r\n [buttons]=\"deleteAlertButtons()\"\r\n (didDismiss)=\"closeDeleteConfirm()\"\r\n [backdropDismiss]=\"false\">\r\n </ion-alert>\r\n\r\n @if (showScrollToBottom()) {\r\n <button class=\"chat__scroll-button\"\r\n type=\"button\"\r\n (click)=\"scrollToBottomSmooth()\"\r\n aria-label=\"Scroll to bottom\">\r\n <img ngSrc=\"assets/ngx-parl/icons/bottom-scroll.svg\"\r\n alt=\"\"\r\n width=\"14\"\r\n height=\"14\"/>\r\n </button>\r\n }\r\n } @else {\r\n <div class=\"chat__flow__empty\">\r\n <img ngSrc=\"assets/ngx-parl/icons/lucide_send.svg\"\r\n class=\"message__icon\"\r\n width=\"18\" height=\"24\" alt=\"hide\"/>\r\n\r\n\r\n <div class=\"chat__flow__empty--header\">\r\n <h3 class=\"chat__flow__empty--title\">{{ 'chat.chat_empty_title' | transloco }}</h3>\r\n <p class=\"chat__flow__empty--subscription\">{{ 'chat.chat_empty_subscription' | transloco }}</p>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n\r\n", styles: [":host{display:block;height:100%;min-height:0}.chat{background:#fff;height:100%;display:flex;flex-direction:column;min-height:0;width:100%;position:relative}.chat__flow{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:12px;padding:12px 16px;overscroll-behavior:contain}.chat__flow__empty{display:flex;gap:16px;flex-direction:column;align-items:center;justify-content:center;padding:72px 16px;height:100%}.chat__flow__empty .message__icon{width:56px;height:56px}.chat__flow__empty--header{width:285px;display:flex;gap:12px;flex-direction:column;align-items:center}.chat__flow__empty--title{margin:0;font:600 16px/20px inter,sans-serif;color:#212529}.chat__flow__empty--subscription{margin:0;font:400 16px/20px inter,sans-serif;color:#495057}.chat__manager-header{display:flex;justify-content:center;padding:24px 16px 8px}.chat__manager-icon{width:132px;height:132px;border-radius:1000px;display:grid;place-items:center}.chat__manager-icon img{display:block;border-radius:1000px}.chat__start-day{display:flex;justify-content:center;background:#f8f9fa;color:#6c757d;font:400 12px/16px inter,sans-serif;width:98px;height:22px;margin:0 auto;border-radius:1000px;gap:8px;padding:4px 8px}.chat__scroll-button{position:absolute;right:8px;bottom:8px;width:35px;height:35px;display:inline-flex;align-items:center;justify-content:center;padding:8px;border:none;border-radius:1000px;background:#c9d4f4;box-shadow:0 2px 4px #0000001a;opacity:.6;cursor:pointer;transition:background-color .15s ease,opacity .15s ease}.chat__scroll-button:hover,.chat__scroll-button:focus-visible{background:#dee2e6;opacity:1}.chat__scroll-button img{display:block}.chat ::-webkit-scrollbar{width:6px}.chat ::-webkit-scrollbar-track{background:transparent}.chat ::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.chat ::-webkit-scrollbar-button{display:none}.chat__delete-alert{--background: #ffffff;--backdrop-opacity: .32;--max-width: 520px}.chat__delete-alert .alert-wrapper{border-radius:16px;box-shadow:0 10px 30px #00000026}.chat__delete-alert .alert-head{padding-top:18px}.chat__delete-alert .alert-title{color:#212529!important;font-weight:400!important}.chat__delete-alert .alert-button-group{padding:8px 12px 12px}.chat__delete-alert .alert-button-role-cancel,.chat__delete-alert .alert-button-role-cancel .alert-button-inner{color:#2563eb!important;font-weight:500!important}.chat__delete-alert .alert-button-role-destructive,.chat__delete-alert .alert-button-role-destructive .alert-button-inner,.chat__delete-alert .chat__delete-alert-destructive,.chat__delete-alert .chat__delete-alert-destructive .alert-button-inner{color:#dc2626!important;font-weight:500!important}\n"] }]
750
805
  }], ctorParameters: () => [], propDecorators: { flowRef: [{
751
806
  type: ViewChild,
752
807
  args: ['chatFlowRef']
753
- }], scrollToBottomTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToBottomTrigger", required: false }] }, { type: i0.Output, args: ["scrollToBottomTriggerChange"] }], loadHistory: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadHistory", required: false }] }, { type: i0.Output, args: ["loadHistoryChange"] }], messageListInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageListInput", required: true }] }, { type: i0.Output, args: ["messageListInputChange"] }], selectedForEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedForEdit", required: true }] }, { type: i0.Output, args: ["selectedForEditChange"] }], requestDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestDelete", required: false }] }, { type: i0.Output, args: ["requestDeleteChange"] }], mobileMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileMode", required: false }] }], quickActionsResolver: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionsResolver", required: false }] }], quickActionClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionClick", required: false }] }, { type: i0.Output, args: ["quickActionClickChange"] }] } });
808
+ }], scrollToBottomTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToBottomTrigger", required: false }] }, { type: i0.Output, args: ["scrollToBottomTriggerChange"] }], loadHistory: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadHistory", required: false }] }, { type: i0.Output, args: ["loadHistoryChange"] }], messageListInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageListInput", required: true }] }, { type: i0.Output, args: ["messageListInputChange"] }], selectedForEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedForEdit", required: true }] }, { type: i0.Output, args: ["selectedForEditChange"] }], requestDelete: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestDelete", required: false }] }, { type: i0.Output, args: ["requestDeleteChange"] }], mobileMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileMode", required: false }] }], logoChat: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoChat", required: false }] }], quickActionsResolver: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionsResolver", required: false }] }], quickActionClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionClick", required: false }] }, { type: i0.Output, args: ["quickActionClickChange"] }] } });
754
809
 
755
810
  class ImageFile {
756
811
  id;
@@ -771,30 +826,30 @@ var FileType;
771
826
  class InputMessageComponent {
772
827
  inputTextElement;
773
828
  mirrorElement;
774
- editMessage = input(null, ...(ngDevMode ? [{ debugName: "editMessage" }] : []));
829
+ editMessage = input(null, ...(ngDevMode ? [{ debugName: "editMessage" }] : /* istanbul ignore next */ []));
775
830
  hasOriginalAttachments = computed(() => {
776
831
  const filePaths = this.editFilePaths();
777
832
  return filePaths.length > 0;
778
- }, ...(ngDevMode ? [{ debugName: "hasOriginalAttachments" }] : []));
779
- hasNewAttachments = computed(() => (this.previews()?.length ?? 0) > 0, ...(ngDevMode ? [{ debugName: "hasNewAttachments" }] : []));
780
- cancelEdit = model(null, ...(ngDevMode ? [{ debugName: "cancelEdit" }] : []));
781
- input_text = model('', ...(ngDevMode ? [{ debugName: "input_text" }] : []));
782
- draft = signal('', ...(ngDevMode ? [{ debugName: "draft" }] : []));
783
- focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : []));
784
- sending = signal(false, ...(ngDevMode ? [{ debugName: "sending" }] : []));
785
- hasText = computed(() => this.draft().trim().length > 0, ...(ngDevMode ? [{ debugName: "hasText" }] : []));
786
- dragActive = signal(false, ...(ngDevMode ? [{ debugName: "dragActive" }] : []));
787
- isEditMode = computed(() => !!this.editMessage(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : []));
833
+ }, ...(ngDevMode ? [{ debugName: "hasOriginalAttachments" }] : /* istanbul ignore next */ []));
834
+ hasNewAttachments = computed(() => (this.previews()?.length ?? 0) > 0, ...(ngDevMode ? [{ debugName: "hasNewAttachments" }] : /* istanbul ignore next */ []));
835
+ cancelEdit = model(null, ...(ngDevMode ? [{ debugName: "cancelEdit" }] : /* istanbul ignore next */ []));
836
+ input_text = model('', ...(ngDevMode ? [{ debugName: "input_text" }] : /* istanbul ignore next */ []));
837
+ draft = signal('', ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
838
+ focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
839
+ sending = signal(false, ...(ngDevMode ? [{ debugName: "sending" }] : /* istanbul ignore next */ []));
840
+ hasText = computed(() => this.draft().trim().length > 0, ...(ngDevMode ? [{ debugName: "hasText" }] : /* istanbul ignore next */ []));
841
+ dragActive = signal(false, ...(ngDevMode ? [{ debugName: "dragActive" }] : /* istanbul ignore next */ []));
842
+ isEditMode = computed(() => !!this.editMessage(), ...(ngDevMode ? [{ debugName: "isEditMode" }] : /* istanbul ignore next */ []));
788
843
  canSend = computed(() => this.hasText() ||
789
844
  this.hasNewAttachments() ||
790
- (this.isEditMode() && this.hasOriginalAttachments()), ...(ngDevMode ? [{ debugName: "canSend" }] : []));
791
- files = model([], ...(ngDevMode ? [{ debugName: "files" }] : []));
792
- previews = model([], ...(ngDevMode ? [{ debugName: "previews" }] : []));
845
+ (this.isEditMode() && this.hasOriginalAttachments()), ...(ngDevMode ? [{ debugName: "canSend" }] : /* istanbul ignore next */ []));
846
+ files = model([], ...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
847
+ previews = model([], ...(ngDevMode ? [{ debugName: "previews" }] : /* istanbul ignore next */ []));
793
848
  lastHeightPx = 0;
794
849
  lastRows = 1;
795
850
  resizeRaf = null;
796
851
  dragDepth = 0;
797
- messageEvent = model(null, ...(ngDevMode ? [{ debugName: "messageEvent" }] : []));
852
+ messageEvent = model(null, ...(ngDevMode ? [{ debugName: "messageEvent" }] : /* istanbul ignore next */ []));
798
853
  constructor() {
799
854
  effect(() => {
800
855
  const message = this.editMessage();
@@ -1123,10 +1178,10 @@ class InputMessageComponent {
1123
1178
  return this;
1124
1179
  }
1125
1180
  FileType = FileType;
1126
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1127
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InputMessageComponent, isStandalone: true, selector: "app-input-message", inputs: { editMessage: { classPropertyName: "editMessage", publicName: "editMessage", isSignal: true, isRequired: false, transformFunction: null }, cancelEdit: { classPropertyName: "cancelEdit", publicName: "cancelEdit", isSignal: true, isRequired: false, transformFunction: null }, input_text: { classPropertyName: "input_text", publicName: "input_text", isSignal: true, isRequired: false, transformFunction: null }, files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null }, previews: { classPropertyName: "previews", publicName: "previews", isSignal: true, isRequired: false, transformFunction: null }, messageEvent: { classPropertyName: "messageEvent", publicName: "messageEvent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cancelEdit: "cancelEditChange", input_text: "input_textChange", files: "filesChange", previews: "previewsChange", messageEvent: "messageEventChange" }, viewQueries: [{ propertyName: "inputTextElement", first: true, predicate: ["inputText"], descendants: true }, { propertyName: "mirrorElement", first: true, predicate: ["mirror"], descendants: true }], ngImport: i0, template: "<section class=\"message\"\n [class.message--focus]=\"focused()\"\n [class.message--filled]=\"hasText()\"\n [class.message--sending]=\"sending()\"\n [class.message--dragover]=\"dragActive()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n @if (isEditMode()) {\n <div class=\"message__wrap\">\n <div class=\"message__wrap--input\">\n <button class=\"message__button message__button--attach\">\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\n class=\"message__icon message__icon--edit\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <div class=\"message__edit-hint\">\n <p>{{ editMessage()?.content }}</p>\n </div>\n </div>\n\n <button class=\"message__button message__button--close\"\n type=\"button\"\n (click)=\"cancelEditMessage()\">\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\"\n class=\"message__icon message__icon--close\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n </div>\n }\n\n <div class=\"message__wrap\">\n <div class=\"message__wrap--input\">\n <button type=\"button\"\n class=\"message__button message__button--attach\"\n [attr.aria-label]=\"'chat.attach' | transloco\"\n (click)=\"fileDialog.click()\">\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\n class=\"message__icon message__icon--attach\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <input #fileDialog\n type=\"file\"\n class=\"hidden\"\n accept=\"image/*\"\n multiple\n (change)=\"inputFileChange($event)\">\n\n <div #inputText\n role=\"textbox\"\n class=\"message__input\"\n spellcheck=\"true\"\n contenteditable=\"true\"\n aria-multiline=\"true\"\n [attr.data-placeholder]=\"isEditMode()\n ? ('chat.edit_placeholder' | transloco)\n : ('chat.placeholder' | transloco)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (input)=\"onInput()\"\n (paste)=\"onPaste()\"\n (keydown)=\"onKeyDown($event)\">\n </div>\n\n <div #mirror class=\"message__input-mirror\" aria-hidden=\"true\"></div>\n\n <ng-content></ng-content>\n </div>\n\n <button class=\"message__button message__button--send\"\n type=\"button\"\n (click)=\"enterDown()\"\n [attr.aria-label]=\"'chat.send' | transloco\"\n [disabled]=\"!canSend()\">\n <img ngSrc=\"assets/ngx-parl/icons/send.svg\"\n class=\"message__icon message__icon--send\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n\n </button>\n </div>\n\n @if (previews().length) {\n <div class=\"message__files\">\n @for (item of previews(); track $index) {\n <div class=\"message__file\" [attr.data-kind]=\"item.originalKind\">\n <button type=\"button\"\n class=\"message__file-remove\"\n [attr.aria-label]=\"'chat.delete_file' | transloco\"\n (click)=\"removeFile($index, $event)\">\n <img ngSrc=\"assets/ngx-parl/icons/remove.svg\"\n class=\"message__icon message__icon--file\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <div class=\"message__file-media\" (click)=\"openPreview(item, $index)\">\n <img [src]=\"item.src\" [alt]=\"item.name\" class=\"message__file-img\"/>\n\n @if (item.originalKind === FileType.GIF) {\n <span class=\"message__file-badge message__file-badge--gif\">\n {{ 'chat.gif' | transloco }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n</section>\n\n\n", styles: [":host{display:block}.message{--lh: 24px;--max-rows: 8;display:flex;flex-direction:column;justify-content:space-between;background:#fff;border-top:1px solid #E1E7F8;padding:4px 8px;margin-top:4px;gap:8px;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:box-shadow .18s ease,background-color .18s ease,border-color .18s ease}.message__wrap{display:flex;width:100%;min-width:0}.message__wrap--input{position:relative;display:flex;align-items:center;gap:12px;flex:1;min-width:0;padding:8px 0}.message__wrap--input:focus-within{border-color:#f8f9fa}.message__wrap--input::-webkit-scrollbar{width:4px;height:4px}.message__wrap--input::-webkit-scrollbar-track{background:transparent}.message__wrap--input::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.message__wrap--input::-webkit-scrollbar-button{display:none}.message__input{flex:1 1 auto;min-height:var(--lh);line-height:var(--lh);font:400 16px/20px inter,sans-serif;outline:none;border:none;background:transparent;color:#343a40;box-sizing:content-box;resize:none;white-space:pre-wrap;overflow-wrap:break-word;caret-color:#3c46b9;transition:height .16s ease;padding:0 4px 0 0;overflow-y:auto;max-height:calc(var(--lh) * var(--max-rows))}.message__input:empty:before{content:attr(data-placeholder);color:#ced4da;pointer-events:none;display:inline-block;animation:subtle-rise .18s ease both}.message__input-mirror{position:absolute;visibility:hidden;pointer-events:none;z-index:-1;white-space:pre-wrap;overflow-wrap:break-word;word-break:normal}.message__button{cursor:pointer;background:none;border:none;transition:transform .12s ease,opacity .12s ease,background-color .12s ease}.message__button:active{transform:scale(.96)}.message__button:disabled{opacity:.45;pointer-events:none}.message__icon{display:inline-flex;width:22px;height:22px}.message__icon:not(.message__icon--file):hover{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(93%) contrast(91%)}.message__icon--focus,.message__icon--filled{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(93%) contrast(91%)}.message__icon--edit{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(73%) contrast(99%)}.message__icon--close{filter:invert(1%) sepia(1%) saturate(1%) hue-rotate(100deg) brightness(100%) contrast(30%)}.message__files{display:flex;flex-wrap:wrap;gap:8px}.message__file{position:relative;width:40px;height:40px;flex:0 0 auto;overflow:visible}.message__file-media{width:100%;height:100%;border-radius:8px;overflow:hidden;cursor:pointer;position:relative;background:#f8f9fa}.message__file-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}.message__file-badge{position:absolute;left:6px;top:6px;z-index:2;display:inline-flex;align-items:center;justify-content:center;height:18px;padding:0 6px;border-radius:4px;font:400 16px/20px inter,sans-serif;background:#0009;color:#fff;letter-spacing:.3px;line-height:1}.message__file-badge--video{width:28px;height:28px;padding:0;left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%;background:#00000073}.message__file-badge--video img{width:18px;height:18px;filter:invert(100%)}.message__file-badge--gif{font-weight:700}.message__file-duration{position:absolute;right:6px;bottom:6px;background:#0009;color:#fff;border-radius:4px;padding:1px;font:400 16px/20px inter,sans-serif;z-index:2px;line-height:1.1}.message__file-remove{position:absolute;top:-6px;right:-6px;width:16px;height:16px;padding:0;border:none;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;z-index:3;cursor:pointer;transition:transform .12s ease,box-shadow .12s ease}.message__file-remove:hover{transform:scale(1.05)}.message__file-remove:active{transform:scale(.96)}.message__file-remove .message__icon--file{width:14px;height:14px}.message__edit-hint{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:8px;border-radius:4px;border-left:2px solid #4656CA;padding:4px 8px}.message__edit-hint p{color:#ced4da;font:400 16px/20px inter,sans-serif;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hidden{position:absolute;opacity:0;width:0;height:0;pointer-events:none}@keyframes subtle-rise{0%{transform:translateY(2px);opacity:.6}to{transform:translateY(0);opacity:1}}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
1181
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: InputMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1182
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: InputMessageComponent, isStandalone: true, selector: "app-input-message", inputs: { editMessage: { classPropertyName: "editMessage", publicName: "editMessage", isSignal: true, isRequired: false, transformFunction: null }, cancelEdit: { classPropertyName: "cancelEdit", publicName: "cancelEdit", isSignal: true, isRequired: false, transformFunction: null }, input_text: { classPropertyName: "input_text", publicName: "input_text", isSignal: true, isRequired: false, transformFunction: null }, files: { classPropertyName: "files", publicName: "files", isSignal: true, isRequired: false, transformFunction: null }, previews: { classPropertyName: "previews", publicName: "previews", isSignal: true, isRequired: false, transformFunction: null }, messageEvent: { classPropertyName: "messageEvent", publicName: "messageEvent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cancelEdit: "cancelEditChange", input_text: "input_textChange", files: "filesChange", previews: "previewsChange", messageEvent: "messageEventChange" }, viewQueries: [{ propertyName: "inputTextElement", first: true, predicate: ["inputText"], descendants: true }, { propertyName: "mirrorElement", first: true, predicate: ["mirror"], descendants: true }], ngImport: i0, template: "<section class=\"message\"\n [class.message--focus]=\"focused()\"\n [class.message--filled]=\"hasText()\"\n [class.message--sending]=\"sending()\"\n [class.message--dragover]=\"dragActive()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n @if (isEditMode()) {\n <div class=\"message__wrap\">\n <div class=\"message__wrap--input\">\n <button class=\"message__button message__button--attach\">\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\n class=\"message__icon message__icon--edit\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <div class=\"message__edit-hint\">\n <p>{{ editMessage()?.content }}</p>\n </div>\n </div>\n\n <button class=\"message__button message__button--close\"\n type=\"button\"\n (click)=\"cancelEditMessage()\">\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\"\n class=\"message__icon message__icon--close\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n </div>\n }\n\n <div class=\"message__wrap\">\n <div class=\"message__wrap--input\">\n <button type=\"button\"\n class=\"message__button message__button--attach\"\n [attr.aria-label]=\"'chat.attach' | transloco\"\n (click)=\"fileDialog.click()\">\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\n class=\"message__icon message__icon--attach\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <input #fileDialog\n type=\"file\"\n class=\"hidden\"\n accept=\"image/*\"\n multiple\n (change)=\"inputFileChange($event)\">\n\n <div #inputText\n role=\"textbox\"\n class=\"message__input\"\n spellcheck=\"true\"\n contenteditable=\"true\"\n aria-multiline=\"true\"\n [attr.data-placeholder]=\"isEditMode()\n ? ('chat.edit_placeholder' | transloco)\n : ('chat.placeholder' | transloco)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (input)=\"onInput()\"\n (paste)=\"onPaste()\"\n (keydown)=\"onKeyDown($event)\">\n </div>\n\n <div #mirror class=\"message__input-mirror\" aria-hidden=\"true\"></div>\n\n <ng-content></ng-content>\n </div>\n\n <button class=\"message__button message__button--send\"\n type=\"button\"\n (click)=\"enterDown()\"\n [attr.aria-label]=\"'chat.send' | transloco\"\n [disabled]=\"!canSend()\">\n <img ngSrc=\"assets/ngx-parl/icons/send.svg\"\n class=\"message__icon message__icon--send\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n\n </button>\n </div>\n\n @if (previews().length) {\n <div class=\"message__files\">\n @for (item of previews(); track $index) {\n <div class=\"message__file\" [attr.data-kind]=\"item.originalKind\">\n <button type=\"button\"\n class=\"message__file-remove\"\n [attr.aria-label]=\"'chat.delete_file' | transloco\"\n (click)=\"removeFile($index, $event)\">\n <img ngSrc=\"assets/ngx-parl/icons/remove.svg\"\n class=\"message__icon message__icon--file\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <div class=\"message__file-media\" (click)=\"openPreview(item, $index)\">\n <img [src]=\"item.src\" [alt]=\"item.name\" class=\"message__file-img\"/>\n\n @if (item.originalKind === FileType.GIF) {\n <span class=\"message__file-badge message__file-badge--gif\">\n {{ 'chat.gif' | transloco }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n</section>\n\n\n", styles: [":host{display:block}.message{--lh: 24px;--max-rows: 8;display:flex;flex-direction:column;justify-content:space-between;background:#fff;border-top:1px solid #E1E7F8;padding:4px 8px;margin-top:4px;gap:8px;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:box-shadow .18s ease,background-color .18s ease,border-color .18s ease}.message__wrap{display:flex;width:100%;min-width:0}.message__wrap--input{position:relative;display:flex;align-items:center;gap:12px;flex:1;min-width:0;padding:8px 0}.message__wrap--input:focus-within{border-color:#f8f9fa}.message__wrap--input::-webkit-scrollbar{width:4px;height:4px}.message__wrap--input::-webkit-scrollbar-track{background:transparent}.message__wrap--input::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.message__wrap--input::-webkit-scrollbar-button{display:none}.message__input{flex:1 1 auto;min-height:var(--lh);line-height:var(--lh);font:400 16px/20px inter,sans-serif;outline:none;border:none;background:transparent;color:#343a40;box-sizing:content-box;resize:none;white-space:pre-wrap;overflow-wrap:break-word;caret-color:#3c46b9;transition:height .16s ease;padding:0 4px 0 0;overflow-y:auto;max-height:calc(var(--lh) * var(--max-rows))}.message__input:empty:before{content:attr(data-placeholder);color:#ced4da;pointer-events:none;display:inline-block;animation:subtle-rise .18s ease both}.message__input-mirror{position:absolute;visibility:hidden;pointer-events:none;z-index:-1;white-space:pre-wrap;overflow-wrap:break-word;word-break:normal}.message__button{cursor:pointer;background:none;border:none;transition:transform .12s ease,opacity .12s ease,background-color .12s ease}.message__button:active{transform:scale(.96)}.message__button:disabled{opacity:.45;pointer-events:none}.message__icon{display:inline-flex;width:22px;height:22px}.message__icon:not(.message__icon--file):hover{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(93%) contrast(91%)}.message__icon--focus,.message__icon--filled{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(93%) contrast(91%)}.message__icon--edit{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(73%) contrast(99%)}.message__icon--close{filter:invert(1%) sepia(1%) saturate(1%) hue-rotate(100deg) brightness(100%) contrast(30%)}.message__files{display:flex;flex-wrap:wrap;gap:8px}.message__file{position:relative;width:40px;height:40px;flex:0 0 auto;overflow:visible}.message__file-media{width:100%;height:100%;border-radius:8px;overflow:hidden;cursor:pointer;position:relative;background:#f8f9fa}.message__file-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}.message__file-badge{position:absolute;left:6px;top:6px;z-index:2;display:inline-flex;align-items:center;justify-content:center;height:18px;padding:0 6px;border-radius:4px;font:400 16px/20px inter,sans-serif;background:#0009;color:#fff;letter-spacing:.3px;line-height:1}.message__file-badge--video{width:28px;height:28px;padding:0;left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%;background:#00000073}.message__file-badge--video img{width:18px;height:18px;filter:invert(100%)}.message__file-badge--gif{font-weight:700}.message__file-duration{position:absolute;right:6px;bottom:6px;background:#0009;color:#fff;border-radius:4px;padding:1px;font:400 16px/20px inter,sans-serif;z-index:2px;line-height:1.1}.message__file-remove{position:absolute;top:-6px;right:-6px;width:16px;height:16px;padding:0;border:none;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;z-index:3;cursor:pointer;transition:transform .12s ease,box-shadow .12s ease}.message__file-remove:hover{transform:scale(1.05)}.message__file-remove:active{transform:scale(.96)}.message__file-remove .message__icon--file{width:14px;height:14px}.message__edit-hint{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:8px;border-radius:4px;border-left:2px solid #4656CA;padding:4px 8px}.message__edit-hint p{color:#ced4da;font:400 16px/20px inter,sans-serif;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hidden{position:absolute;opacity:0;width:0;height:0;pointer-events:none}@keyframes subtle-rise{0%{transform:translateY(2px);opacity:.6}to{transform:translateY(0);opacity:1}}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }] });
1128
1183
  }
1129
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputMessageComponent, decorators: [{
1184
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: InputMessageComponent, decorators: [{
1130
1185
  type: Component,
1131
1186
  args: [{ selector: 'app-input-message', imports: [TranslocoPipe, NgOptimizedImage], standalone: true, template: "<section class=\"message\"\n [class.message--focus]=\"focused()\"\n [class.message--filled]=\"hasText()\"\n [class.message--sending]=\"sending()\"\n [class.message--dragover]=\"dragActive()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n\n @if (isEditMode()) {\n <div class=\"message__wrap\">\n <div class=\"message__wrap--input\">\n <button class=\"message__button message__button--attach\">\n <img ngSrc=\"assets/ngx-parl/icons/icon-edit.svg\"\n class=\"message__icon message__icon--edit\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <div class=\"message__edit-hint\">\n <p>{{ editMessage()?.content }}</p>\n </div>\n </div>\n\n <button class=\"message__button message__button--close\"\n type=\"button\"\n (click)=\"cancelEditMessage()\">\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\"\n class=\"message__icon message__icon--close\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n </div>\n }\n\n <div class=\"message__wrap\">\n <div class=\"message__wrap--input\">\n <button type=\"button\"\n class=\"message__button message__button--attach\"\n [attr.aria-label]=\"'chat.attach' | transloco\"\n (click)=\"fileDialog.click()\">\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\n class=\"message__icon message__icon--attach\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <input #fileDialog\n type=\"file\"\n class=\"hidden\"\n accept=\"image/*\"\n multiple\n (change)=\"inputFileChange($event)\">\n\n <div #inputText\n role=\"textbox\"\n class=\"message__input\"\n spellcheck=\"true\"\n contenteditable=\"true\"\n aria-multiline=\"true\"\n [attr.data-placeholder]=\"isEditMode()\n ? ('chat.edit_placeholder' | transloco)\n : ('chat.placeholder' | transloco)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n (input)=\"onInput()\"\n (paste)=\"onPaste()\"\n (keydown)=\"onKeyDown($event)\">\n </div>\n\n <div #mirror class=\"message__input-mirror\" aria-hidden=\"true\"></div>\n\n <ng-content></ng-content>\n </div>\n\n <button class=\"message__button message__button--send\"\n type=\"button\"\n (click)=\"enterDown()\"\n [attr.aria-label]=\"'chat.send' | transloco\"\n [disabled]=\"!canSend()\">\n <img ngSrc=\"assets/ngx-parl/icons/send.svg\"\n class=\"message__icon message__icon--send\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n\n </button>\n </div>\n\n @if (previews().length) {\n <div class=\"message__files\">\n @for (item of previews(); track $index) {\n <div class=\"message__file\" [attr.data-kind]=\"item.originalKind\">\n <button type=\"button\"\n class=\"message__file-remove\"\n [attr.aria-label]=\"'chat.delete_file' | transloco\"\n (click)=\"removeFile($index, $event)\">\n <img ngSrc=\"assets/ngx-parl/icons/remove.svg\"\n class=\"message__icon message__icon--file\"\n width=\"18\" height=\"18\" alt=\"hide\"/>\n </button>\n\n <div class=\"message__file-media\" (click)=\"openPreview(item, $index)\">\n <img [src]=\"item.src\" [alt]=\"item.name\" class=\"message__file-img\"/>\n\n @if (item.originalKind === FileType.GIF) {\n <span class=\"message__file-badge message__file-badge--gif\">\n {{ 'chat.gif' | transloco }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n</section>\n\n\n", styles: [":host{display:block}.message{--lh: 24px;--max-rows: 8;display:flex;flex-direction:column;justify-content:space-between;background:#fff;border-top:1px solid #E1E7F8;padding:4px 8px;margin-top:4px;gap:8px;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:box-shadow .18s ease,background-color .18s ease,border-color .18s ease}.message__wrap{display:flex;width:100%;min-width:0}.message__wrap--input{position:relative;display:flex;align-items:center;gap:12px;flex:1;min-width:0;padding:8px 0}.message__wrap--input:focus-within{border-color:#f8f9fa}.message__wrap--input::-webkit-scrollbar{width:4px;height:4px}.message__wrap--input::-webkit-scrollbar-track{background:transparent}.message__wrap--input::-webkit-scrollbar-thumb{background-color:#e9ecef;border-radius:4px;border:1px solid #E9ECEF}.message__wrap--input::-webkit-scrollbar-button{display:none}.message__input{flex:1 1 auto;min-height:var(--lh);line-height:var(--lh);font:400 16px/20px inter,sans-serif;outline:none;border:none;background:transparent;color:#343a40;box-sizing:content-box;resize:none;white-space:pre-wrap;overflow-wrap:break-word;caret-color:#3c46b9;transition:height .16s ease;padding:0 4px 0 0;overflow-y:auto;max-height:calc(var(--lh) * var(--max-rows))}.message__input:empty:before{content:attr(data-placeholder);color:#ced4da;pointer-events:none;display:inline-block;animation:subtle-rise .18s ease both}.message__input-mirror{position:absolute;visibility:hidden;pointer-events:none;z-index:-1;white-space:pre-wrap;overflow-wrap:break-word;word-break:normal}.message__button{cursor:pointer;background:none;border:none;transition:transform .12s ease,opacity .12s ease,background-color .12s ease}.message__button:active{transform:scale(.96)}.message__button:disabled{opacity:.45;pointer-events:none}.message__icon{display:inline-flex;width:22px;height:22px}.message__icon:not(.message__icon--file):hover{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(93%) contrast(91%)}.message__icon--focus,.message__icon--filled{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(93%) contrast(91%)}.message__icon--edit{filter:invert(33%) sepia(79%) saturate(2933%) hue-rotate(205deg) brightness(73%) contrast(99%)}.message__icon--close{filter:invert(1%) sepia(1%) saturate(1%) hue-rotate(100deg) brightness(100%) contrast(30%)}.message__files{display:flex;flex-wrap:wrap;gap:8px}.message__file{position:relative;width:40px;height:40px;flex:0 0 auto;overflow:visible}.message__file-media{width:100%;height:100%;border-radius:8px;overflow:hidden;cursor:pointer;position:relative;background:#f8f9fa}.message__file-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}.message__file-badge{position:absolute;left:6px;top:6px;z-index:2;display:inline-flex;align-items:center;justify-content:center;height:18px;padding:0 6px;border-radius:4px;font:400 16px/20px inter,sans-serif;background:#0009;color:#fff;letter-spacing:.3px;line-height:1}.message__file-badge--video{width:28px;height:28px;padding:0;left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%;background:#00000073}.message__file-badge--video img{width:18px;height:18px;filter:invert(100%)}.message__file-badge--gif{font-weight:700}.message__file-duration{position:absolute;right:6px;bottom:6px;background:#0009;color:#fff;border-radius:4px;padding:1px;font:400 16px/20px inter,sans-serif;z-index:2px;line-height:1.1}.message__file-remove{position:absolute;top:-6px;right:-6px;width:16px;height:16px;padding:0;border:none;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;z-index:3;cursor:pointer;transition:transform .12s ease,box-shadow .12s ease}.message__file-remove:hover{transform:scale(1.05)}.message__file-remove:active{transform:scale(.96)}.message__file-remove .message__icon--file{width:14px;height:14px}.message__edit-hint{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:flex;align-items:center;gap:8px;border-radius:4px;border-left:2px solid #4656CA;padding:4px 8px}.message__edit-hint p{color:#ced4da;font:400 16px/20px inter,sans-serif;margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hidden{position:absolute;opacity:0;width:0;height:0;pointer-events:none}@keyframes subtle-rise{0%{transform:translateY(2px);opacity:.6}to{transform:translateY(0);opacity:1}}\n"] }]
1132
1187
  }], ctorParameters: () => [], propDecorators: { inputTextElement: [{
@@ -1150,28 +1205,29 @@ class NgxParlComponent {
1150
1205
  chatFlow;
1151
1206
  inputMessage;
1152
1207
  ai_run_in_progress = false;
1153
- dragActive = model(false, ...(ngDevMode ? [{ debugName: "dragActive" }] : []));
1208
+ dragActive = model(false, ...(ngDevMode ? [{ debugName: "dragActive" }] : /* istanbul ignore next */ []));
1154
1209
  dragDepth = 0;
1155
1210
  lastUpdateKey = null;
1156
- theme = input(FlowTheme.PRIMARY, ...(ngDevMode ? [{ debugName: "theme" }] : []));
1157
- header = input(true, ...(ngDevMode ? [{ debugName: "header" }] : []));
1158
- language = input('en', ...(ngDevMode ? [{ debugName: "language" }] : []));
1159
- messageList = model([], ...(ngDevMode ? [{ debugName: "messageList" }] : []));
1160
- messageUpdate = model(...(ngDevMode ? [undefined, { debugName: "messageUpdate" }] : []));
1161
- selectedForEdit = model(null, ...(ngDevMode ? [{ debugName: "selectedForEdit" }] : []));
1162
- messageAction = model(null, ...(ngDevMode ? [{ debugName: "messageAction" }] : []));
1163
- incomingUser = input('', ...(ngDevMode ? [{ debugName: "incomingUser" }] : []));
1164
- transportType = input('', ...(ngDevMode ? [{ debugName: "transportType" }] : []));
1165
- transportTypeIcon = input('', ...(ngDevMode ? [{ debugName: "transportTypeIcon" }] : []));
1166
- transportTypeIconSrc = computed(() => this.utils.normalizeSourcePath(this.transportTypeIcon()), ...(ngDevMode ? [{ debugName: "transportTypeIconSrc" }] : []));
1167
- mobileMode = input(false, ...(ngDevMode ? [{ debugName: "mobileMode" }] : []));
1168
- quickActionsResolver = input(null, ...(ngDevMode ? [{ debugName: "quickActionsResolver" }] : []));
1169
- quickActionClick = model(null, ...(ngDevMode ? [{ debugName: "quickActionClick" }] : []));
1170
- quickActionsAutoSend = input(true, ...(ngDevMode ? [{ debugName: "quickActionsAutoSend" }] : []));
1171
- hideHandler = input(null, ...(ngDevMode ? [{ debugName: "hideHandler" }] : []));
1172
- closeHandler = input(null, ...(ngDevMode ? [{ debugName: "closeHandler" }] : []));
1173
- scrollToBottomTrigger = model(0, ...(ngDevMode ? [{ debugName: "scrollToBottomTrigger" }] : []));
1174
- loadHistory = model(false, ...(ngDevMode ? [{ debugName: "loadHistory" }] : []));
1211
+ theme = input(FlowTheme.PRIMARY, ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
1212
+ header = input(true, ...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
1213
+ language = input('en', ...(ngDevMode ? [{ debugName: "language" }] : /* istanbul ignore next */ []));
1214
+ messageList = model([], ...(ngDevMode ? [{ debugName: "messageList" }] : /* istanbul ignore next */ []));
1215
+ messageUpdate = model(...(ngDevMode ? [undefined, { debugName: "messageUpdate" }] : /* istanbul ignore next */ []));
1216
+ selectedForEdit = model(null, ...(ngDevMode ? [{ debugName: "selectedForEdit" }] : /* istanbul ignore next */ []));
1217
+ messageAction = model(null, ...(ngDevMode ? [{ debugName: "messageAction" }] : /* istanbul ignore next */ []));
1218
+ incomingUser = input('', ...(ngDevMode ? [{ debugName: "incomingUser" }] : /* istanbul ignore next */ []));
1219
+ transportType = input('', ...(ngDevMode ? [{ debugName: "transportType" }] : /* istanbul ignore next */ []));
1220
+ transportTypeIcon = input('', ...(ngDevMode ? [{ debugName: "transportTypeIcon" }] : /* istanbul ignore next */ []));
1221
+ transportTypeIconSrc = computed(() => this.utils.normalizeSourcePath(this.transportTypeIcon()), ...(ngDevMode ? [{ debugName: "transportTypeIconSrc" }] : /* istanbul ignore next */ []));
1222
+ logoChat = input('', ...(ngDevMode ? [{ debugName: "logoChat" }] : /* istanbul ignore next */ []));
1223
+ mobileMode = input(false, ...(ngDevMode ? [{ debugName: "mobileMode" }] : /* istanbul ignore next */ []));
1224
+ quickActionsResolver = input(null, ...(ngDevMode ? [{ debugName: "quickActionsResolver" }] : /* istanbul ignore next */ []));
1225
+ quickActionClick = model(null, ...(ngDevMode ? [{ debugName: "quickActionClick" }] : /* istanbul ignore next */ []));
1226
+ quickActionsAutoSend = input(true, ...(ngDevMode ? [{ debugName: "quickActionsAutoSend" }] : /* istanbul ignore next */ []));
1227
+ hideHandler = input(null, ...(ngDevMode ? [{ debugName: "hideHandler" }] : /* istanbul ignore next */ []));
1228
+ closeHandler = input(null, ...(ngDevMode ? [{ debugName: "closeHandler" }] : /* istanbul ignore next */ []));
1229
+ scrollToBottomTrigger = model(0, ...(ngDevMode ? [{ debugName: "scrollToBottomTrigger" }] : /* istanbul ignore next */ []));
1230
+ loadHistory = model(false, ...(ngDevMode ? [{ debugName: "loadHistory" }] : /* istanbul ignore next */ []));
1175
1231
  focusTimers = [];
1176
1232
  afterOpenedSubscription;
1177
1233
  constructor(utils, transloco, dialogRef) {
@@ -1221,6 +1277,22 @@ class NgxParlComponent {
1221
1277
  }, 0);
1222
1278
  });
1223
1279
  }
1280
+ onQuickActionClick(event) {
1281
+ this.quickActionClick.set(event);
1282
+ if (!event) {
1283
+ return this;
1284
+ }
1285
+ const content = (event.value ?? '').trim();
1286
+ if (this.quickActionsAutoSend() && content) {
1287
+ try {
1288
+ this.sendMessage({ content });
1289
+ }
1290
+ catch (error) {
1291
+ console.error('Quick action send failed', error);
1292
+ }
1293
+ }
1294
+ return this;
1295
+ }
1224
1296
  ngAfterViewInit() {
1225
1297
  if (this.dialogRef) {
1226
1298
  this.afterOpenedSubscription = this.dialogRef.afterOpened().subscribe(() => {
@@ -1481,16 +1553,16 @@ class NgxParlComponent {
1481
1553
  return this;
1482
1554
  }
1483
1555
  FlowTheme = FlowTheme;
1484
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxParlComponent, deps: [{ token: UtilsService }, { token: i2.TranslocoService }, { token: i3.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1485
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: NgxParlComponent, isStandalone: true, selector: "ngx-parl", inputs: { dragActive: { classPropertyName: "dragActive", publicName: "dragActive", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, messageList: { classPropertyName: "messageList", publicName: "messageList", isSignal: true, isRequired: false, transformFunction: null }, messageUpdate: { classPropertyName: "messageUpdate", publicName: "messageUpdate", isSignal: true, isRequired: false, transformFunction: null }, selectedForEdit: { classPropertyName: "selectedForEdit", publicName: "selectedForEdit", isSignal: true, isRequired: false, transformFunction: null }, messageAction: { classPropertyName: "messageAction", publicName: "messageAction", isSignal: true, isRequired: false, transformFunction: null }, incomingUser: { classPropertyName: "incomingUser", publicName: "incomingUser", isSignal: true, isRequired: false, transformFunction: null }, transportType: { classPropertyName: "transportType", publicName: "transportType", isSignal: true, isRequired: false, transformFunction: null }, transportTypeIcon: { classPropertyName: "transportTypeIcon", publicName: "transportTypeIcon", isSignal: true, isRequired: false, transformFunction: null }, mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: true, isRequired: false, transformFunction: null }, quickActionsResolver: { classPropertyName: "quickActionsResolver", publicName: "quickActionsResolver", isSignal: true, isRequired: false, transformFunction: null }, quickActionClick: { classPropertyName: "quickActionClick", publicName: "quickActionClick", isSignal: true, isRequired: false, transformFunction: null }, quickActionsAutoSend: { classPropertyName: "quickActionsAutoSend", publicName: "quickActionsAutoSend", isSignal: true, isRequired: false, transformFunction: null }, hideHandler: { classPropertyName: "hideHandler", publicName: "hideHandler", isSignal: true, isRequired: false, transformFunction: null }, closeHandler: { classPropertyName: "closeHandler", publicName: "closeHandler", isSignal: true, isRequired: false, transformFunction: null }, scrollToBottomTrigger: { classPropertyName: "scrollToBottomTrigger", publicName: "scrollToBottomTrigger", isSignal: true, isRequired: false, transformFunction: null }, loadHistory: { classPropertyName: "loadHistory", publicName: "loadHistory", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragActive: "dragActiveChange", messageList: "messageListChange", messageUpdate: "messageUpdateChange", selectedForEdit: "selectedForEditChange", messageAction: "messageActionChange", quickActionClick: "quickActionClickChange", scrollToBottomTrigger: "scrollToBottomTriggerChange", loadHistory: "loadHistoryChange" }, providers: [], viewQueries: [{ propertyName: "chatFlow", first: true, predicate: ChatFlowComponent, descendants: true }, { propertyName: "inputMessage", first: true, predicate: InputMessageComponent, descendants: true }], ngImport: i0, template: "<div class=\"modal-chat\" [ngClass]=\"'flow-theme-' + theme()\">\n <div class=\"modal-chat__body\">\n @if (header()) {\n <header class=\"modal-chat__header\" mat-dialog-title>\n <div class=\"modal-chat__hide-block\"></div>\n\n <div class=\"modal-chat__title\">\n <h1 class=\"modal-chat__heading\" id=\"modal-chat__heading\">\n @if (transportTypeIconSrc()) {\n <img [ngSrc]=\"transportTypeIconSrc()\"\n class=\"modal-chat__heading-icon\"\n width=\"20\"\n height=\"20\"\n [attr.alt]=\"transportType() || 'transport icon'\"/>\n }\n <span class=\"modal-chat__heading-text\">\n {{ transportType() }} {{ incomingUser() }}\n </span>\n </h1>\n </div>\n\n <div class=\"modal-chat__actions\">\n <img ngSrc=\"assets/ngx-parl/icons/hide.svg\" class=\"modal-chat__icon modal-chat__icon--hide\"\n width=\"24\" height=\"24\" alt=\"hide\"\n (click)=\"onHideClick()\"/>\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\" class=\"modal-chat__icon modal-chat__icon--close\"\n width=\"24\" height=\"24\" alt=\"close\"\n (click)=\"onCloseClick()\"/>\n </div>\n </header>\n }\n\n <mat-dialog-content class=\"modal-chat__content\"\n [class.modal-chat__content--header]=\"header() === false\"\n [class.modal-chat__content--dragover]=\"dragActive()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n @if (dragActive()) {\n <div class=\"modal-chat__drag-overlay\"\n role=\"status\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'chat.drag_title' | transloco\">\n <div class=\"modal-chat__drag-card\">\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\n class=\"modal-chat__drag-icon\"\n alt=\"\"\n width=\"56\"\n height=\"56\"/>\n\n <div class=\"modal-chat__drag-title\">\n {{ 'chat.drag_title' | transloco }}\n </div>\n <div class=\"modal-chat__drag-subtitle\">\n {{ 'chat.drag_subtitle' | transloco }}\n </div>\n </div>\n </div>\n }\n <app-chat-flow [messageListInput]=\"messageList()\"\n [(selectedForEdit)]=\"selectedForEdit\"\n (requestDeleteChange)=\"onRequestDelete($event)\"\n [mobileMode]=\"mobileMode()\"\n [quickActionsResolver]=\"quickActionsResolver()\"\n [(quickActionClick)]=\"quickActionClick\"\n [(scrollToBottomTrigger)]=\"scrollToBottomTrigger\"\n [(loadHistory)]=\"loadHistory\">\n </app-chat-flow>\n\n <app-input-message [editMessage]=\"selectedForEdit()\"\n (cancelEditChange)=\"onCancelEdit($event)\"\n (input_textChange)=\"sendMessage($event)\">\n @if (ai_run_in_progress) {\n <mat-spinner [diameter]=\"30\"></mat-spinner>\n }\n </app-input-message>\n </mat-dialog-content>\n </div>\n</div>\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.modal-chat{width:800px;height:600px;border-radius:16px}.modal-chat__body{display:flex;flex-direction:column;height:100%}.modal-chat__header{height:56px;min-height:56px;max-height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;gap:12px;border-top-left-radius:16px;border-top-right-radius:16px;flex-direction:row}.modal-chat__hide-block{width:48px;color:#5a72d7}.modal-chat__title #modal-chat__heading{color:#fff;font:600 16px/20px inter,sans-serif;display:inline-flex;align-items:center;gap:8px}.modal-chat__heading-icon{width:20px;height:20px;border-radius:1000px;flex:0 0 auto}.modal-chat__actions{display:flex;gap:8px}.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;background:#fff;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:background-color .16s ease,box-shadow .16s ease;position:relative}.modal-chat__content--header{border-top-left-radius:16px;border-top-right-radius:16px}.modal-chat__content--dragover:after{content:\"\";position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 2px #e9ecef inset;background:#fff0;pointer-events:none;z-index:1000}.modal-chat__content app-chat-flow{flex:1 1 auto;min-height:0px;overflow:auto;display:flex;align-items:flex-end}.modal-chat__drag-overlay{position:absolute;inset:16px;display:flex;align-items:center;justify-content:center;border-radius:16px;border:2px dashed #7A95E0;background:#ffffffeb;z-index:1000;pointer-events:none}.modal-chat__drag-card{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 24px;border-radius:16px;background:#fff;box-shadow:0 2px 4px #0000001a;text-align:center}.modal-chat__drag-icon{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.modal-chat__drag-title{font:600 20px/24px inter,sans-serif;color:#4656ca}.modal-chat__drag-subtitle{font:400 14px/18px inter,sans-serif;color:#6c757d}.modal-chat__input{flex:0px 0px auto;border-bottom-left-radius:16px;border-bottom-right-radius:16px}:host ::ng-deep .mat-mdc-dialog-content.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;padding:0;max-height:none;overflow:hidden}img{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: ChatFlowComponent, selector: "app-chat-flow", inputs: ["scrollToBottomTrigger", "loadHistory", "messageListInput", "selectedForEdit", "requestDelete", "mobileMode", "quickActionsResolver", "quickActionClick"], outputs: ["scrollToBottomTriggerChange", "loadHistoryChange", "messageListInputChange", "selectedForEditChange", "requestDeleteChange", "quickActionClickChange"] }, { kind: "component", type: InputMessageComponent, selector: "app-input-message", inputs: ["editMessage", "cancelEdit", "input_text", "files", "previews", "messageEvent"], outputs: ["cancelEditChange", "input_textChange", "filesChange", "previewsChange", "messageEventChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
1556
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: NgxParlComponent, deps: [{ token: UtilsService }, { token: i2.TranslocoService }, { token: i3.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1557
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.12", type: NgxParlComponent, isStandalone: true, selector: "ngx-parl", inputs: { dragActive: { classPropertyName: "dragActive", publicName: "dragActive", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, messageList: { classPropertyName: "messageList", publicName: "messageList", isSignal: true, isRequired: false, transformFunction: null }, messageUpdate: { classPropertyName: "messageUpdate", publicName: "messageUpdate", isSignal: true, isRequired: false, transformFunction: null }, selectedForEdit: { classPropertyName: "selectedForEdit", publicName: "selectedForEdit", isSignal: true, isRequired: false, transformFunction: null }, messageAction: { classPropertyName: "messageAction", publicName: "messageAction", isSignal: true, isRequired: false, transformFunction: null }, incomingUser: { classPropertyName: "incomingUser", publicName: "incomingUser", isSignal: true, isRequired: false, transformFunction: null }, transportType: { classPropertyName: "transportType", publicName: "transportType", isSignal: true, isRequired: false, transformFunction: null }, transportTypeIcon: { classPropertyName: "transportTypeIcon", publicName: "transportTypeIcon", isSignal: true, isRequired: false, transformFunction: null }, logoChat: { classPropertyName: "logoChat", publicName: "logoChat", isSignal: true, isRequired: false, transformFunction: null }, mobileMode: { classPropertyName: "mobileMode", publicName: "mobileMode", isSignal: true, isRequired: false, transformFunction: null }, quickActionsResolver: { classPropertyName: "quickActionsResolver", publicName: "quickActionsResolver", isSignal: true, isRequired: false, transformFunction: null }, quickActionClick: { classPropertyName: "quickActionClick", publicName: "quickActionClick", isSignal: true, isRequired: false, transformFunction: null }, quickActionsAutoSend: { classPropertyName: "quickActionsAutoSend", publicName: "quickActionsAutoSend", isSignal: true, isRequired: false, transformFunction: null }, hideHandler: { classPropertyName: "hideHandler", publicName: "hideHandler", isSignal: true, isRequired: false, transformFunction: null }, closeHandler: { classPropertyName: "closeHandler", publicName: "closeHandler", isSignal: true, isRequired: false, transformFunction: null }, scrollToBottomTrigger: { classPropertyName: "scrollToBottomTrigger", publicName: "scrollToBottomTrigger", isSignal: true, isRequired: false, transformFunction: null }, loadHistory: { classPropertyName: "loadHistory", publicName: "loadHistory", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragActive: "dragActiveChange", messageList: "messageListChange", messageUpdate: "messageUpdateChange", selectedForEdit: "selectedForEditChange", messageAction: "messageActionChange", quickActionClick: "quickActionClickChange", scrollToBottomTrigger: "scrollToBottomTriggerChange", loadHistory: "loadHistoryChange" }, providers: [], viewQueries: [{ propertyName: "chatFlow", first: true, predicate: ChatFlowComponent, descendants: true }, { propertyName: "inputMessage", first: true, predicate: InputMessageComponent, descendants: true }], ngImport: i0, template: "<div class=\"modal-chat\" [ngClass]=\"'flow-theme-' + theme()\">\r\n <div class=\"modal-chat__body\">\r\n @if (header()) {\r\n <header class=\"modal-chat__header\" mat-dialog-title>\r\n <div class=\"modal-chat__hide-block\"></div>\r\n\r\n <div class=\"modal-chat__title\">\r\n <h1 class=\"modal-chat__heading\" id=\"modal-chat__heading\">\r\n @if (transportTypeIconSrc()) {\r\n <img [ngSrc]=\"transportTypeIconSrc()\"\r\n class=\"modal-chat__heading-icon\"\r\n width=\"20\"\r\n height=\"20\"\r\n [attr.alt]=\"transportType() || 'transport icon'\"/>\r\n }\r\n <span class=\"modal-chat__heading-text\">\r\n {{ transportType() }} {{ incomingUser() }}\r\n </span>\r\n </h1>\r\n </div>\r\n\r\n <div class=\"modal-chat__actions\">\r\n <img ngSrc=\"assets/ngx-parl/icons/hide.svg\" class=\"modal-chat__icon modal-chat__icon--hide\"\r\n width=\"24\" height=\"24\" alt=\"hide\"\r\n (click)=\"onHideClick()\"/>\r\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\" class=\"modal-chat__icon modal-chat__icon--close\"\r\n width=\"24\" height=\"24\" alt=\"close\"\r\n (click)=\"onCloseClick()\"/>\r\n </div>\r\n </header>\r\n }\r\n\r\n <mat-dialog-content class=\"modal-chat__content\"\r\n [class.modal-chat__content--header]=\"header() === false\"\r\n [class.modal-chat__content--dragover]=\"dragActive()\"\r\n (dragenter)=\"onDragEnter($event)\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\">\r\n @if (dragActive()) {\r\n <div class=\"modal-chat__drag-overlay\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n [attr.aria-label]=\"'chat.drag_title' | transloco\">\r\n <div class=\"modal-chat__drag-card\">\r\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\r\n class=\"modal-chat__drag-icon\"\r\n alt=\"\"\r\n width=\"56\"\r\n height=\"56\"/>\r\n\r\n <div class=\"modal-chat__drag-title\">\r\n {{ 'chat.drag_title' | transloco }}\r\n </div>\r\n <div class=\"modal-chat__drag-subtitle\">\r\n {{ 'chat.drag_subtitle' | transloco }}\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n <app-chat-flow [messageListInput]=\"messageList()\"\r\n [(selectedForEdit)]=\"selectedForEdit\"\r\n (requestDeleteChange)=\"onRequestDelete($event)\"\r\n [logoChat]=\"logoChat()\"\r\n [mobileMode]=\"mobileMode()\"\r\n [quickActionsResolver]=\"quickActionsResolver()\"\r\n [quickActionClick]=\"quickActionClick()\"\r\n (quickActionClickChange)=\"onQuickActionClick($event)\"\r\n [(scrollToBottomTrigger)]=\"scrollToBottomTrigger\"\r\n [(loadHistory)]=\"loadHistory\">\r\n </app-chat-flow>\r\n\r\n <app-input-message [editMessage]=\"selectedForEdit()\"\r\n (cancelEditChange)=\"onCancelEdit($event)\"\r\n (input_textChange)=\"sendMessage($event)\">\r\n @if (ai_run_in_progress) {\r\n <mat-spinner [diameter]=\"30\"></mat-spinner>\r\n }\r\n </app-input-message>\r\n </mat-dialog-content>\r\n </div>\r\n</div>\r\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.modal-chat{width:800px;height:600px;border-radius:16px}.modal-chat__body{display:flex;flex-direction:column;height:100%}.modal-chat__header{height:56px;min-height:56px;max-height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;gap:12px;border-top-left-radius:16px;border-top-right-radius:16px;flex-direction:row}.modal-chat__hide-block{width:48px;color:#5a72d7}.modal-chat__title #modal-chat__heading{color:#fff;font:600 16px/20px inter,sans-serif;display:inline-flex;align-items:center;gap:8px}.modal-chat__heading-icon{width:20px;height:20px;border-radius:1000px;flex:0 0 auto}.modal-chat__actions{display:flex;gap:8px}.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;background:#fff;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:background-color .16s ease,box-shadow .16s ease;position:relative}.modal-chat__content--header{border-top-left-radius:16px;border-top-right-radius:16px}.modal-chat__content--dragover:after{content:\"\";position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 2px #e9ecef inset;background:#fff0;pointer-events:none;z-index:1000}.modal-chat__content app-chat-flow{flex:1 1 auto;min-height:0px;overflow:auto;display:flex;align-items:flex-end}.modal-chat__drag-overlay{position:absolute;inset:16px;display:flex;align-items:center;justify-content:center;border-radius:16px;border:2px dashed #7A95E0;background:#ffffffeb;z-index:1000;pointer-events:none}.modal-chat__drag-card{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 24px;border-radius:16px;background:#fff;box-shadow:0 2px 4px #0000001a;text-align:center}.modal-chat__drag-icon{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.modal-chat__drag-title{font:600 20px/24px inter,sans-serif;color:#4656ca}.modal-chat__drag-subtitle{font:400 14px/18px inter,sans-serif;color:#6c757d}.modal-chat__input{flex:0px 0px auto;border-bottom-left-radius:16px;border-bottom-right-radius:16px}:host ::ng-deep .mat-mdc-dialog-content.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;padding:0;max-height:none;overflow:hidden}img{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: ChatFlowComponent, selector: "app-chat-flow", inputs: ["scrollToBottomTrigger", "loadHistory", "messageListInput", "selectedForEdit", "requestDelete", "mobileMode", "logoChat", "quickActionsResolver", "quickActionClick"], outputs: ["scrollToBottomTriggerChange", "loadHistoryChange", "messageListInputChange", "selectedForEditChange", "requestDeleteChange", "quickActionClickChange"] }, { kind: "component", type: InputMessageComponent, selector: "app-input-message", inputs: ["editMessage", "cancelEdit", "input_text", "files", "previews", "messageEvent"], outputs: ["cancelEditChange", "input_textChange", "filesChange", "previewsChange", "messageEventChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
1486
1558
  }
1487
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NgxParlComponent, decorators: [{
1559
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: NgxParlComponent, decorators: [{
1488
1560
  type: Component,
1489
1561
  args: [{ selector: 'ngx-parl', standalone: true, imports: [
1490
1562
  NgOptimizedImage, NgClass, MatDialogContent, MatDialogTitle, MatProgressSpinner, ChatFlowComponent, InputMessageComponent,
1491
1563
  TranslocoModule,
1492
1564
  TranslocoPipe
1493
- ], providers: [], template: "<div class=\"modal-chat\" [ngClass]=\"'flow-theme-' + theme()\">\n <div class=\"modal-chat__body\">\n @if (header()) {\n <header class=\"modal-chat__header\" mat-dialog-title>\n <div class=\"modal-chat__hide-block\"></div>\n\n <div class=\"modal-chat__title\">\n <h1 class=\"modal-chat__heading\" id=\"modal-chat__heading\">\n @if (transportTypeIconSrc()) {\n <img [ngSrc]=\"transportTypeIconSrc()\"\n class=\"modal-chat__heading-icon\"\n width=\"20\"\n height=\"20\"\n [attr.alt]=\"transportType() || 'transport icon'\"/>\n }\n <span class=\"modal-chat__heading-text\">\n {{ transportType() }} {{ incomingUser() }}\n </span>\n </h1>\n </div>\n\n <div class=\"modal-chat__actions\">\n <img ngSrc=\"assets/ngx-parl/icons/hide.svg\" class=\"modal-chat__icon modal-chat__icon--hide\"\n width=\"24\" height=\"24\" alt=\"hide\"\n (click)=\"onHideClick()\"/>\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\" class=\"modal-chat__icon modal-chat__icon--close\"\n width=\"24\" height=\"24\" alt=\"close\"\n (click)=\"onCloseClick()\"/>\n </div>\n </header>\n }\n\n <mat-dialog-content class=\"modal-chat__content\"\n [class.modal-chat__content--header]=\"header() === false\"\n [class.modal-chat__content--dragover]=\"dragActive()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n @if (dragActive()) {\n <div class=\"modal-chat__drag-overlay\"\n role=\"status\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'chat.drag_title' | transloco\">\n <div class=\"modal-chat__drag-card\">\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\n class=\"modal-chat__drag-icon\"\n alt=\"\"\n width=\"56\"\n height=\"56\"/>\n\n <div class=\"modal-chat__drag-title\">\n {{ 'chat.drag_title' | transloco }}\n </div>\n <div class=\"modal-chat__drag-subtitle\">\n {{ 'chat.drag_subtitle' | transloco }}\n </div>\n </div>\n </div>\n }\n <app-chat-flow [messageListInput]=\"messageList()\"\n [(selectedForEdit)]=\"selectedForEdit\"\n (requestDeleteChange)=\"onRequestDelete($event)\"\n [mobileMode]=\"mobileMode()\"\n [quickActionsResolver]=\"quickActionsResolver()\"\n [(quickActionClick)]=\"quickActionClick\"\n [(scrollToBottomTrigger)]=\"scrollToBottomTrigger\"\n [(loadHistory)]=\"loadHistory\">\n </app-chat-flow>\n\n <app-input-message [editMessage]=\"selectedForEdit()\"\n (cancelEditChange)=\"onCancelEdit($event)\"\n (input_textChange)=\"sendMessage($event)\">\n @if (ai_run_in_progress) {\n <mat-spinner [diameter]=\"30\"></mat-spinner>\n }\n </app-input-message>\n </mat-dialog-content>\n </div>\n</div>\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.modal-chat{width:800px;height:600px;border-radius:16px}.modal-chat__body{display:flex;flex-direction:column;height:100%}.modal-chat__header{height:56px;min-height:56px;max-height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;gap:12px;border-top-left-radius:16px;border-top-right-radius:16px;flex-direction:row}.modal-chat__hide-block{width:48px;color:#5a72d7}.modal-chat__title #modal-chat__heading{color:#fff;font:600 16px/20px inter,sans-serif;display:inline-flex;align-items:center;gap:8px}.modal-chat__heading-icon{width:20px;height:20px;border-radius:1000px;flex:0 0 auto}.modal-chat__actions{display:flex;gap:8px}.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;background:#fff;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:background-color .16s ease,box-shadow .16s ease;position:relative}.modal-chat__content--header{border-top-left-radius:16px;border-top-right-radius:16px}.modal-chat__content--dragover:after{content:\"\";position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 2px #e9ecef inset;background:#fff0;pointer-events:none;z-index:1000}.modal-chat__content app-chat-flow{flex:1 1 auto;min-height:0px;overflow:auto;display:flex;align-items:flex-end}.modal-chat__drag-overlay{position:absolute;inset:16px;display:flex;align-items:center;justify-content:center;border-radius:16px;border:2px dashed #7A95E0;background:#ffffffeb;z-index:1000;pointer-events:none}.modal-chat__drag-card{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 24px;border-radius:16px;background:#fff;box-shadow:0 2px 4px #0000001a;text-align:center}.modal-chat__drag-icon{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.modal-chat__drag-title{font:600 20px/24px inter,sans-serif;color:#4656ca}.modal-chat__drag-subtitle{font:400 14px/18px inter,sans-serif;color:#6c757d}.modal-chat__input{flex:0px 0px auto;border-bottom-left-radius:16px;border-bottom-right-radius:16px}:host ::ng-deep .mat-mdc-dialog-content.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;padding:0;max-height:none;overflow:hidden}img{cursor:pointer}\n"] }]
1565
+ ], providers: [], template: "<div class=\"modal-chat\" [ngClass]=\"'flow-theme-' + theme()\">\r\n <div class=\"modal-chat__body\">\r\n @if (header()) {\r\n <header class=\"modal-chat__header\" mat-dialog-title>\r\n <div class=\"modal-chat__hide-block\"></div>\r\n\r\n <div class=\"modal-chat__title\">\r\n <h1 class=\"modal-chat__heading\" id=\"modal-chat__heading\">\r\n @if (transportTypeIconSrc()) {\r\n <img [ngSrc]=\"transportTypeIconSrc()\"\r\n class=\"modal-chat__heading-icon\"\r\n width=\"20\"\r\n height=\"20\"\r\n [attr.alt]=\"transportType() || 'transport icon'\"/>\r\n }\r\n <span class=\"modal-chat__heading-text\">\r\n {{ transportType() }} {{ incomingUser() }}\r\n </span>\r\n </h1>\r\n </div>\r\n\r\n <div class=\"modal-chat__actions\">\r\n <img ngSrc=\"assets/ngx-parl/icons/hide.svg\" class=\"modal-chat__icon modal-chat__icon--hide\"\r\n width=\"24\" height=\"24\" alt=\"hide\"\r\n (click)=\"onHideClick()\"/>\r\n <img ngSrc=\"assets/ngx-parl/icons/close.svg\" class=\"modal-chat__icon modal-chat__icon--close\"\r\n width=\"24\" height=\"24\" alt=\"close\"\r\n (click)=\"onCloseClick()\"/>\r\n </div>\r\n </header>\r\n }\r\n\r\n <mat-dialog-content class=\"modal-chat__content\"\r\n [class.modal-chat__content--header]=\"header() === false\"\r\n [class.modal-chat__content--dragover]=\"dragActive()\"\r\n (dragenter)=\"onDragEnter($event)\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\">\r\n @if (dragActive()) {\r\n <div class=\"modal-chat__drag-overlay\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n [attr.aria-label]=\"'chat.drag_title' | transloco\">\r\n <div class=\"modal-chat__drag-card\">\r\n <img ngSrc=\"assets/ngx-parl/icons/attach-filled.svg\"\r\n class=\"modal-chat__drag-icon\"\r\n alt=\"\"\r\n width=\"56\"\r\n height=\"56\"/>\r\n\r\n <div class=\"modal-chat__drag-title\">\r\n {{ 'chat.drag_title' | transloco }}\r\n </div>\r\n <div class=\"modal-chat__drag-subtitle\">\r\n {{ 'chat.drag_subtitle' | transloco }}\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n <app-chat-flow [messageListInput]=\"messageList()\"\r\n [(selectedForEdit)]=\"selectedForEdit\"\r\n (requestDeleteChange)=\"onRequestDelete($event)\"\r\n [logoChat]=\"logoChat()\"\r\n [mobileMode]=\"mobileMode()\"\r\n [quickActionsResolver]=\"quickActionsResolver()\"\r\n [quickActionClick]=\"quickActionClick()\"\r\n (quickActionClickChange)=\"onQuickActionClick($event)\"\r\n [(scrollToBottomTrigger)]=\"scrollToBottomTrigger\"\r\n [(loadHistory)]=\"loadHistory\">\r\n </app-chat-flow>\r\n\r\n <app-input-message [editMessage]=\"selectedForEdit()\"\r\n (cancelEditChange)=\"onCancelEdit($event)\"\r\n (input_textChange)=\"sendMessage($event)\">\r\n @if (ai_run_in_progress) {\r\n <mat-spinner [diameter]=\"30\"></mat-spinner>\r\n }\r\n </app-input-message>\r\n </mat-dialog-content>\r\n </div>\r\n</div>\r\n", styles: [".flow-theme-primary ::ng-deep .modal-chat__header{background-color:#5a72d7;color:#fff}.flow-theme-primary ::ng-deep .message--incoming .message__body{background:#e9ecef;color:#343a40}.flow-theme-primary ::ng-deep .message--outgoing .message__body{background:#4656ca;color:#fff}:root{--shadow-sm: 0px 1px 2px 0px rgba(0, 0, 0, .05);--shadow-md: 0px 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0px 8px 24px rgba(0, 0, 0, .12);--shadow-soft: 0px 0px 6px 0px rgba(46, 46, 46, .12) }.flow-theme-secondary ::ng-deep .modal-chat__header{background-color:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--incoming .message__body{background:#848af5;color:#fefefe}.flow-theme-secondary ::ng-deep .message--outgoing .message__body{background:#efefef;color:#464646}.modal-chat{width:800px;height:600px;border-radius:16px}.modal-chat__body{display:flex;flex-direction:column;height:100%}.modal-chat__header{height:56px;min-height:56px;max-height:56px;display:flex;align-items:center;justify-content:space-between;padding:0 16px;gap:12px;border-top-left-radius:16px;border-top-right-radius:16px;flex-direction:row}.modal-chat__hide-block{width:48px;color:#5a72d7}.modal-chat__title #modal-chat__heading{color:#fff;font:600 16px/20px inter,sans-serif;display:inline-flex;align-items:center;gap:8px}.modal-chat__heading-icon{width:20px;height:20px;border-radius:1000px;flex:0 0 auto}.modal-chat__actions{display:flex;gap:8px}.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;background:#fff;border-bottom-left-radius:16px;border-bottom-right-radius:16px;transition:background-color .16s ease,box-shadow .16s ease;position:relative}.modal-chat__content--header{border-top-left-radius:16px;border-top-right-radius:16px}.modal-chat__content--dragover:after{content:\"\";position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 2px #e9ecef inset;background:#fff0;pointer-events:none;z-index:1000}.modal-chat__content app-chat-flow{flex:1 1 auto;min-height:0px;overflow:auto;display:flex;align-items:flex-end}.modal-chat__drag-overlay{position:absolute;inset:16px;display:flex;align-items:center;justify-content:center;border-radius:16px;border:2px dashed #7A95E0;background:#ffffffeb;z-index:1000;pointer-events:none}.modal-chat__drag-card{display:flex;flex-direction:column;align-items:center;gap:8px;padding:20px 24px;border-radius:16px;background:#fff;box-shadow:0 2px 4px #0000001a;text-align:center}.modal-chat__drag-icon{filter:drop-shadow(0 2px 4px rgba(0,0,0,.2))}.modal-chat__drag-title{font:600 20px/24px inter,sans-serif;color:#4656ca}.modal-chat__drag-subtitle{font:400 14px/18px inter,sans-serif;color:#6c757d}.modal-chat__input{flex:0px 0px auto;border-bottom-left-radius:16px;border-bottom-right-radius:16px}:host ::ng-deep .mat-mdc-dialog-content.modal-chat__content{flex:1 1 auto;display:flex;flex-direction:column;padding:0;max-height:none;overflow:hidden}img{cursor:pointer}\n"] }]
1494
1566
  }], ctorParameters: () => [{ type: UtilsService }, { type: i2.TranslocoService }, { type: i3.MatDialogRef, decorators: [{
1495
1567
  type: Optional
1496
1568
  }] }], propDecorators: { chatFlow: [{
@@ -1499,7 +1571,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
1499
1571
  }], inputMessage: [{
1500
1572
  type: ViewChild,
1501
1573
  args: [InputMessageComponent]
1502
- }], dragActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragActive", required: false }] }, { type: i0.Output, args: ["dragActiveChange"] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], messageList: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageList", required: false }] }, { type: i0.Output, args: ["messageListChange"] }], messageUpdate: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageUpdate", required: false }] }, { type: i0.Output, args: ["messageUpdateChange"] }], selectedForEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedForEdit", required: false }] }, { type: i0.Output, args: ["selectedForEditChange"] }], messageAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageAction", required: false }] }, { type: i0.Output, args: ["messageActionChange"] }], incomingUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "incomingUser", required: false }] }], transportType: [{ type: i0.Input, args: [{ isSignal: true, alias: "transportType", required: false }] }], transportTypeIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "transportTypeIcon", required: false }] }], mobileMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileMode", required: false }] }], quickActionsResolver: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionsResolver", required: false }] }], quickActionClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionClick", required: false }] }, { type: i0.Output, args: ["quickActionClickChange"] }], quickActionsAutoSend: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionsAutoSend", required: false }] }], hideHandler: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHandler", required: false }] }], closeHandler: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeHandler", required: false }] }], scrollToBottomTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToBottomTrigger", required: false }] }, { type: i0.Output, args: ["scrollToBottomTriggerChange"] }], loadHistory: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadHistory", required: false }] }, { type: i0.Output, args: ["loadHistoryChange"] }] } });
1574
+ }], dragActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragActive", required: false }] }, { type: i0.Output, args: ["dragActiveChange"] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], messageList: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageList", required: false }] }, { type: i0.Output, args: ["messageListChange"] }], messageUpdate: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageUpdate", required: false }] }, { type: i0.Output, args: ["messageUpdateChange"] }], selectedForEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedForEdit", required: false }] }, { type: i0.Output, args: ["selectedForEditChange"] }], messageAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageAction", required: false }] }, { type: i0.Output, args: ["messageActionChange"] }], incomingUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "incomingUser", required: false }] }], transportType: [{ type: i0.Input, args: [{ isSignal: true, alias: "transportType", required: false }] }], transportTypeIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "transportTypeIcon", required: false }] }], logoChat: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoChat", required: false }] }], mobileMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileMode", required: false }] }], quickActionsResolver: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionsResolver", required: false }] }], quickActionClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionClick", required: false }] }, { type: i0.Output, args: ["quickActionClickChange"] }], quickActionsAutoSend: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickActionsAutoSend", required: false }] }], hideHandler: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideHandler", required: false }] }], closeHandler: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeHandler", required: false }] }], scrollToBottomTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollToBottomTrigger", required: false }] }, { type: i0.Output, args: ["scrollToBottomTriggerChange"] }], loadHistory: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadHistory", required: false }] }, { type: i0.Output, args: ["loadHistoryChange"] }] } });
1503
1575
 
1504
1576
  var chat$1 = {
1505
1577
  title: "Telegram",
@@ -1569,10 +1641,10 @@ class ParlTranslocoLoader {
1569
1641
  return of(en);
1570
1642
  }
1571
1643
  }
1572
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ParlTranslocoLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1573
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ParlTranslocoLoader });
1644
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ParlTranslocoLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1645
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ParlTranslocoLoader });
1574
1646
  }
1575
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ParlTranslocoLoader, decorators: [{
1647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.12", ngImport: i0, type: ParlTranslocoLoader, decorators: [{
1576
1648
  type: Injectable
1577
1649
  }] });
1578
1650
 
@@ -1592,5 +1664,5 @@ function provideNgxParl() {
1592
1664
  * Generated bundle index. Do not edit.
1593
1665
  */
1594
1666
 
1595
- export { ChatMessage, MessageType, NgxParlComponent, provideNgxParl };
1667
+ export { ChatMessage, MessageType, NgxParlComponent, defaultParlQuickActionsResolver, messageHasActionButtons, provideNgxParl, resolveParlQuickActions };
1596
1668
  //# sourceMappingURL=trixwell-ngx-parl.mjs.map