@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.
- package/README.md +235 -228
- package/fesm2022/trixwell-ngx-parl.mjs +224 -152
- package/fesm2022/trixwell-ngx-parl.mjs.map +1 -1
- package/package.json +16 -8
- package/src/assets/icons/avatar_manager.svg +10 -10
- package/{index.d.ts → types/trixwell-ngx-parl.d.ts} +20 -3
|
@@ -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: "
|
|
213
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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: "
|
|
267
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
|
|
334
|
-
|
|
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
|
-
|
|
345
|
-
|
|
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
|
|
400
|
+
const title = (action.title ?? '').trim();
|
|
392
401
|
const value = (action.value ?? '').trim();
|
|
393
|
-
|
|
402
|
+
const content = value || title;
|
|
403
|
+
if (!content) {
|
|
394
404
|
return this;
|
|
395
405
|
}
|
|
396
|
-
this.
|
|
397
|
-
|
|
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
|
-
|
|
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: "
|
|
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: "
|
|
438
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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: "
|
|
468
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "
|
|
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: "
|
|
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
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
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.
|
|
552
|
+
text: this.translateChatKey('chat.cancel', 'Cancel'),
|
|
499
553
|
role: 'cancel',
|
|
500
554
|
handler: () => this.closeDeleteConfirm(),
|
|
501
555
|
},
|
|
502
556
|
{
|
|
503
|
-
text: this.
|
|
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 =
|
|
520
|
-
if (
|
|
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: "
|
|
736
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
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: "
|
|
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=\"
|
|
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: "
|
|
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: "
|
|
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
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
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: "
|
|
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: "
|
|
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 [
|
|
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: "
|
|
1573
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
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: "
|
|
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
|