@rt-tools/ui-kit-v2 0.20.0 → 0.21.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.
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-rich-editor.mjs","sources":["../../../projects/ui-kit-v2/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/message-composer/rt-message-composer.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/message-composer/rt-message-composer.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-message-actions.directive.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-message-actions.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-message-actions.pipe.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat.model.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/pipes/rt-chat-status-label.pipe.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-files.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-thread.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-typing.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/to-rt-message.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/rt-ai-chat.directives.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.html","../../../projects/ui-kit-v2/src/rich-editor/public-api.ts","../../../projects/ui-kit-v2/src/rich-editor/rt-tools-ui-kit-v2-rich-editor.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n InputSignal,\n OnDestroy,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport type Quill from 'quill';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { coerceQuillDeltaOutput, IQuillDelta, IQuillDeltaOp, RtFormControlBase } from '@rt-tools/ui-kit-v2';\n\nconst BEM_BLOCK: string = 'rt-rich-editor';\n\n/**\n * Режим тулбара: `full` — весь whitelist, `minimal` — жирный + два списка\n * (G113: чаты оператора/админа/саппорта).\n */\nexport type TRtRichEditorToolbar = 'full' | 'minimal';\n\n/** Модули тулбара — строго whitelist (без link/image/color/script). */\nconst TOOLBAR: Record<TRtRichEditorToolbar, readonly unknown[]> = {\n full: [\n ['bold', 'italic', 'underline', 'strike'],\n [{ header: 1 }, { header: 2 }, { header: 3 }],\n [{ list: 'ordered' }, { list: 'bullet' }],\n ['blockquote', 'code-block'],\n ],\n minimal: [['bold'], [{ list: 'ordered' }, { list: 'bullet' }]],\n};\n\n/** Форматы, которые Quill вообще примет (вставленное из буфера лишнее вырезается). */\nconst FORMATS: Record<TRtRichEditorToolbar, readonly string[]> = {\n full: ['bold', 'italic', 'underline', 'strike', 'header', 'list', 'blockquote', 'code-block'],\n minimal: ['bold', 'list'],\n};\n\ntype TQuillContentsArg = Parameters<Quill['setContents']>[0];\n\n/**\n * Rich-редактор чата на Quill. Наследует CVA-ядро input-семейства\n * (`RtFormControlBase`) — плагается в reactive-форму. Quill грузится **лениво**\n * (`import(\"quill\")` в `ngAfterViewInit`), тип импортируется `import type` и в\n * бандл не попадает. Значение CVA — `IQuillDelta` (или `null`, когда пусто).\n */\n@Component({\n selector: 'rt-rich-editor',\n templateUrl: './rt-rich-editor.component.html',\n styleUrl: './rt-rich-editor.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ],\n providers: [\n // Алиас базового токена — чтобы rt-field мог найти контрол через\n // contentChild(RtFormControlBase) (query по абстрактному классу).\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtRichEditorComponent) },\n ],\n host: {\n class: BEM_BLOCK,\n // Пока начинка редактора не смонтирована, хост несёт признак недостроенности: снаружи\n // недостроенный редактор ничем не отличается от достроенного пустого, и съёмка витрины\n // ловила именно этот промежуток — кадр выходил втрое ниже эталона.\n '[attr.data-rt-pending]': 'mounted() ? null : \"\"',\n },\n})\nexport class RtRichEditorComponent extends RtFormControlBase<IQuillDelta | null> implements AfterViewInit, OnDestroy {\n // `viewChild` не работает на ES-private (`#`) поле — держим `protected`.\n protected readonly editorHost: Signal<ElementRef<HTMLElement>> = viewChild.required<ElementRef<HTMLElement>>('editor');\n\n #quill: Quill | null = null;\n\n /** Значение, пришедшее через writeValue до готовности Quill. */\n #pending: IQuillDelta | null = null;\n\n /**\n * Смонтирована ли начинка редактора. Пока нет, хост несёт признак недостроенности: съёмке\n * витрины и любой другой проверке снаружи иначе нечем отличить недостроенный редактор от\n * достроенного пустого — оба выглядят пустым местом.\n */\n protected readonly mounted: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value() !== null);\n\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Набор кнопок форматирования; сужает и принимаемые форматы (вставка из буфера). */\n public readonly toolbar: InputSignal<TRtRichEditorToolbar> = input<TRtRichEditorToolbar>('full');\n\n /** Enter без Shift в редакторе — сигнал отправки (Shift+Enter остаётся переносом). */\n public readonly enterPressed: OutputEmitterRef<void> = output<void>();\n\n public readonly displayText: Signal<string> = computed((): string => {\n const delta: IQuillDelta | null = this.value();\n if (delta === null) {\n return '';\n }\n return delta.ops.map((op: IQuillDeltaOp): string => op.insert).join('');\n });\n\n public async ngAfterViewInit(): Promise<void> {\n const QuillCtor: typeof Quill = (await import('quill')).default;\n const quill: Quill = new QuillCtor(this.editorHost().nativeElement, {\n theme: 'snow',\n placeholder: this.placeholder(),\n formats: [...FORMATS[this.toolbar()]],\n modules: {\n toolbar: [...TOOLBAR[this.toolbar()]],\n keyboard: {\n bindings: {\n // Enter без Shift — отправка (перенос гасим возвратом false);\n // Shift+Enter не совпадает с биндингом и уходит в дефолт (перенос).\n enterSubmit: {\n key: 'Enter',\n shiftKey: false,\n handler: (): boolean => {\n this.enterPressed.emit();\n return false;\n },\n },\n },\n },\n },\n });\n this.#quill = quill;\n if (this.#pending !== null) {\n quill.setContents(this.#pending as unknown as TQuillContentsArg);\n this.#pending = null;\n }\n if (this.isDisabled()) {\n quill.disable();\n }\n quill.on('text-change', (): void => this.#onEditorChange());\n this.mounted.set(true);\n }\n\n /** Ставит фокус в редактор; до загрузки Quill ничего не делает. */\n public focus(): void {\n this.#quill?.focus();\n }\n\n public ngOnDestroy(): void {\n this.#quill = null;\n this.mounted.set(false);\n }\n\n public override writeValue(value: IQuillDelta | null): void {\n super.writeValue(value);\n if (this.#quill === null) {\n this.#pending = value;\n return;\n }\n this.#quill.setContents((value ?? { ops: [] }) as unknown as TQuillContentsArg);\n }\n\n public override setDisabledState(isDisabled: boolean): void {\n super.setDisabledState(isDisabled);\n if (this.#quill === null) {\n return;\n }\n if (isDisabled) {\n this.#quill.disable();\n return;\n }\n this.#quill.enable();\n }\n\n protected getEmptyValue(): IQuillDelta | null {\n return null;\n }\n\n protected focusAfterClear(): void {\n this.#quill?.focus();\n }\n\n /** Text-change: пустой слепок → null-канал; иначе delta. */\n #onEditorChange(): void {\n if (this.#quill === null) {\n return;\n }\n const blank: boolean = this.#quill.getText().trim().length === 0;\n const next: IQuillDelta | null = blank\n ? null\n : coerceQuillDeltaOutput({\n ops: this.#quill.getContents().ops as unknown as IQuillDeltaOp[],\n });\n this.value.set(next);\n this.emitChange(next);\n this.markTouched();\n }\n}\n","<ng-container rtBlock=\"rt-rich-editor\">\n <div #editor rtElem=\"surface\" qa-dataid=\"rich-editor-surface\"></div>\n</ng-container>\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { CdkTextareaAutosize } from '@angular/cdk/text-field';\nimport {\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n numberAttribute,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IQuillDelta, RT_KIT_LABELS, RtFileCardComponent, RtIconButtonComponent, rtKitLabel, TRtKitLabelMap } from '@rt-tools/ui-kit-v2';\n\nimport { RtRichEditorComponent, TRtRichEditorToolbar } from '../rich-editor/rt-rich-editor.component';\nimport { IRtMessageComposer } from './rt-message-composer.model';\n\nconst BEM_BLOCK: string = 'rt-message-composer';\n\n/** Текст в поле выше полутора строк — он перенёсся, и капсула берёт скругление высокой. */\nfunction rtComposerWraps(node: HTMLTextAreaElement): boolean {\n const style: CSSStyleDeclaration = getComputedStyle(node);\n const line: number = parseFloat(style.lineHeight) || parseFloat(style.fontSize) * 1.5;\n const text: number = node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);\n return text > line * 1.5;\n}\n\ninterface IComposerFormShape {\n message: FormControl<string>;\n files: FormControl<File[]>;\n delta: FormControl<IQuillDelta | null>;\n}\n\n/**\n * Композер сообщения — капсула: слева круглая кнопка вложения, по центру авто-растущая\n * textarea, справа круглая кнопка отправки; вложения стоят внутри капсулы над строкой.\n * Презентационный, без data-access: наружу торчит только `submitted` с текстом и файлами.\n *\n * Отправка — `Enter` (без Shift) или клик по иконке; `Shift+Enter` — перенос\n * строки. Кнопка отправки активна, пока есть непустой текст или вложения.\n *\n * Со `stoppable` во время `sending` вместо стрелки стоит кнопка «Стоп», а поле\n * остаётся открытым: следующий вопрос набирается, пока идёт ответ.\n */\n@Component({\n selector: 'rt-message-composer',\n templateUrl: './rt-message-composer.component.html',\n styleUrl: './rt-message-composer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n ReactiveFormsModule,\n\n // cdk\n CdkTextareaAutosize,\n\n // standalone components / directives\n RtFileCardComponent,\n RtIconButtonComponent,\n RtRichEditorComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtMessageComposerComponent {\n readonly #formValue: Signal<Partial<{ message: string; files: File[]; delta: IQuillDelta | null }>>;\n\n readonly #t_chatPlaceholder: Signal<string> = rtKitLabel('chatPlaceholder');\n\n /** Текст перенёсся на вторую строку — меряется по высоте textarea после отрисовки. */\n readonly #multiRow: WritableSignal<boolean> = signal(false);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.#t_chatPlaceholder());\n\n protected readonly fileInput: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fileEl');\n\n protected readonly textInput: Signal<ElementRef<HTMLTextAreaElement> | undefined> =\n viewChild<ElementRef<HTMLTextAreaElement>>('textEl');\n\n protected readonly richEditor: Signal<RtRichEditorComponent | undefined> = viewChild(RtRichEditorComponent);\n\n protected readonly form: FormGroup<IComposerFormShape> = new FormGroup<IComposerFormShape>({\n message: new FormControl<string>('', { nonNullable: true }),\n files: new FormControl<File[]>([], { nonNullable: true }),\n delta: new FormControl<IQuillDelta | null>(null),\n });\n\n protected readonly files: Signal<readonly File[]> = computed((): readonly File[] => this.#formValue().files ?? []);\n\n /** Отправка доступна: есть контент (текст/delta/файлы), композер не занят. */\n protected readonly canSend: Signal<boolean> = computed((): boolean => {\n if (this.sending() || this.disabled()) {\n return false;\n }\n const value: Partial<{ message: string; files: File[]; delta: IQuillDelta | null }> = this.#formValue();\n const hasFiles: boolean = this.attachments() && (value.files?.length ?? 0) > 0;\n if (this.formatting()) {\n return (value.delta ?? null) !== null || hasFiles;\n }\n const hasText: boolean = (value.message ?? '').trim().length > 0;\n return hasText || hasFiles;\n });\n\n /** Капсула выше одной строки: перенос текста, вложения или режим форматирования. */\n protected readonly tall: Signal<boolean> = computed(\n (): boolean => this.#multiRow() || this.formatting() || (this.attachments() && this.files().length > 0)\n );\n\n /** Идёт ответ, который можно остановить: вместо стрелки — «Стоп», поле открыто. */\n protected readonly isStoppable: Signal<boolean> = computed((): boolean => this.stoppable() && this.sending() && !this.disabled());\n\n protected readonly capsuleMods: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n tall: this.tall(),\n disabled: this.disabled(),\n }));\n\n /** Текст-подсказка textarea. Пусто — берётся переведённое умолчание. */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Фильтр типов для file-input (`.pdf,.doc,...`). */\n public readonly accept: InputSignal<string> = input<string>('');\n\n /** Строка под капсулой про Enter и Shift + Enter. */\n public readonly hint: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку вложения и список файлов. */\n public readonly attachments: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Отправка в процессе — блокирует submit, кнопка отправки крутит индикатор. */\n public readonly sending: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Ответ на сообщение можно остановить. Во время `sending` стрелку сменяет кнопка\n * «Стоп», а поле не блокируется; без входа `sending` блокирует поле, как раньше.\n */\n public readonly stoppable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Полная блокировка композера. */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Rich-режим: вместо textarea — Quill-редактор, отправка уходит delta-каналом. */\n public readonly formatting: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Набор кнопок rich-редактора (проброс в `rt-rich-editor`). */\n public readonly toolbar: InputSignal<TRtRichEditorToolbar> = input<TRtRichEditorToolbar>('full');\n\n /** Минимальная высота textarea в строках. */\n public readonly minRows: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(1, { transform: numberAttribute });\n\n /** Максимальная высота textarea в строках (дальше — скролл). */\n public readonly maxRows: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(6, { transform: numberAttribute });\n\n /**\n * Файлы, выброшенные drag-n-drop'ом в обёртку чата: пробрасываются сюда как\n * вложения. Каждый физический drop даёт новый массив, поэтому effect\n * перезапускается на каждое перетаскивание; файлы добавляются к уже выбранным.\n */\n public readonly droppedFiles: InputSignal<File[] | null> = input<File[] | null>(null);\n\n /** Отправка сообщения: текст + файлы (последние — только при `attachments`). */\n public readonly submitted: OutputEmitterRef<IRtMessageComposer.SubmitPayload> = output<IRtMessageComposer.SubmitPayload>();\n\n /** Черновик поля без форматирования: задаётся снаружи, правки уходят наружу, после отправки пуст. */\n public readonly text: ModelSignal<string> = model<string>('');\n\n /** Клик по кнопке «Стоп» во время ответа, который можно остановить. */\n public readonly stopped: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n this.#formValue = toSignal(this.form.valueChanges, {\n initialValue: this.form.value,\n });\n\n effect((): void => {\n const draft: string = this.text();\n if (this.form.controls.message.value !== draft) {\n this.form.controls.message.setValue(draft);\n }\n });\n\n this.form.controls.message.valueChanges.pipe(takeUntilDestroyed()).subscribe((value: string): void => this.text.set(value));\n\n effect((): void => {\n const blocked: boolean = this.disabled() || (this.sending() && !this.stoppable());\n if (blocked && this.form.enabled) {\n this.form.disable({ emitEvent: false });\n }\n if (!blocked && this.form.disabled) {\n this.form.enable({ emitEvent: false });\n }\n });\n\n // Поле пересоздаётся при смене режима форматирования: наблюдатель идёт за текущим узлом.\n effect((onCleanup: (fn: () => void) => void): void => {\n const node: HTMLTextAreaElement | undefined = this.textInput()?.nativeElement;\n if (!node || typeof ResizeObserver === 'undefined') {\n this.#multiRow.set(false);\n return;\n }\n const observer: ResizeObserver = new ResizeObserver((): void => this.#multiRow.set(rtComposerWraps(node)));\n observer.observe(node);\n onCleanup((): void => observer.disconnect());\n });\n\n effect((): void => {\n const dropped: File[] | null = this.droppedFiles();\n if (dropped !== null && dropped.length > 0 && this.attachments()) {\n this.form.controls.files.setValue([...this.form.controls.files.value, ...dropped]);\n }\n });\n }\n\n /** Ставит фокус в поле: в textarea, а в режиме форматирования — в rich-редактор. */\n public focus(): void {\n if (this.formatting()) {\n this.richEditor()?.focus();\n return;\n }\n this.textInput()?.nativeElement.focus();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n // Enter без модификаторов — отправка; Shift+Enter оставляем переносом строки.\n // isComposing — не перехватываем подтверждение IME-композиции.\n if (event.key === 'Enter' && !event.shiftKey && !event.isComposing) {\n event.preventDefault();\n this.submit();\n }\n }\n\n protected stop(): void {\n if (this.isStoppable()) {\n this.stopped.emit();\n }\n }\n\n protected openPicker(): void {\n if (this.disabled() || this.sending()) {\n return;\n }\n this.fileInput()?.nativeElement.click();\n }\n\n protected onFilesPicked(event: Event): void {\n const el: HTMLInputElement = event.target as HTMLInputElement;\n const picked: File[] = el.files ? Array.from(el.files) : [];\n if (picked.length) {\n this.form.controls.files.setValue([...this.form.controls.files.value, ...picked]);\n }\n // Сброс value — чтобы повторный выбор того же файла снова дал change-событие.\n el.value = '';\n }\n\n protected removeFile(index: number): void {\n const next: File[] = this.form.controls.files.value.filter((_: File, i: number): boolean => i !== index);\n this.form.controls.files.setValue(next);\n }\n\n protected submit(): void {\n if (!this.canSend()) {\n return;\n }\n const files: File[] = this.attachments() ? this.form.controls.files.value : [];\n if (this.formatting()) {\n const delta: IQuillDelta | null = this.form.controls.delta.value;\n this.submitted.emit({\n text: '',\n delta: delta === null ? null : JSON.stringify(delta),\n files,\n });\n } else {\n const text: string = this.form.controls.message.value.trim();\n this.submitted.emit({ text, files });\n }\n this.form.reset({ message: '', files: [], delta: null });\n }\n}\n","<ng-container rtBlock=\"rt-message-composer\" [formGroup]=\"form\">\n <div rtElem=\"capsule\" qa-dataid=\"message-composer-capsule\" [rtMod]=\"capsuleMods()\">\n @if (attachments() && files().length) {\n <div rtElem=\"files\" qa-dataid=\"message-composer-files\">\n @for (file of files(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"message-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"disabled() || sending()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n\n @if (formatting()) {\n <rt-rich-editor\n rtElem=\"rich\"\n qa-dataid=\"message-composer-rich\"\n formControlName=\"delta\"\n [placeholder]=\"placeholderText()\"\n [toolbar]=\"toolbar()\"\n (enterPressed)=\"submit()\" />\n }\n\n <div rtElem=\"row\">\n @if (attachments()) {\n <input\n #fileEl\n qa-dataid=\"message-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"message-composer-attach\"\n icon=\"paperclip\"\n iconColor=\"muted\"\n radius=\"full\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"disabled() || sending()\"\n (clicked)=\"openPicker()\" />\n }\n\n @if (!formatting()) {\n <textarea\n #textEl\n rtElem=\"input\"\n qa-dataid=\"message-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholderText()\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (keydown)=\"onKeydown($event)\"></textarea>\n }\n\n @if (isStoppable()) {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-stop\"\n icon=\"stop\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatStopAria\"\n [tooltip]=\"t().chatStopLabel\"\n (clicked)=\"stop()\" />\n } @else {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-send\"\n icon=\"arrow-up\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatSendAria\"\n [tooltip]=\"t().chatSendLabel\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"\n (clicked)=\"submit()\" />\n }\n </div>\n </div>\n\n @if (hint()) {\n <p rtElem=\"hint\" qa-dataid=\"message-composer-hint\">{{ t().chatComposerHint }}</p>\n }\n</ng-container>\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { IRtChat } from './rt-chat.model';\n\n/**\n * Контекст шаблона `[rtChatMessageActions]`: `$implicit` — реплика треда.\n */\nexport interface IRtChatMessageActionsContext {\n $implicit: IRtChat.Message;\n}\n\n/**\n * Захватывает `<ng-template rtChatMessageActions let-message>` — содержимое «…»-меню\n * действий у реплики. `rt-chat` рисует этот шаблон рядом с точечными действиями реплики,\n * прокидывая её через `$implicit`.\n *\n * Точечные действия остаются на месте: удаление, повтор отправки и скачивание общи для\n * любой переписки. Шаблон нужен тем действиям, которых кит не знает и знать не должен, —\n * без него потребителю оставалось ждать правки кита либо ставить кнопку над диалогом, то\n * есть не там, где читают реплику.\n *\n * Дженерика у контекста нет: тип реплики у переписки один, и type-carrier, который у\n * строки таблицы несёт тип строки, здесь не нужен.\n *\n * @example\n * ```html\n * <rt-chat [messages]=\"messages()\" [messageHasActions]=\"canAct\">\n * <ng-template rtChatMessageActions let-message>\n * <rt-menu-item icon=\"link\" label=\"Скопировать ссылку\" (selected)=\"copy(message)\" />\n * </ng-template>\n * </rt-chat>\n * ```\n */\n@Directive({\n selector: 'ng-template[rtChatMessageActions]',\n})\nexport class RtChatMessageActionsDirective {\n public readonly template: TemplateRef<IRtChatMessageActionsContext> = inject<TemplateRef<IRtChatMessageActionsContext>>(TemplateRef);\n\n /** Type-guard: сужает контекст шаблона до реплики при проверке шаблонов. */\n public static ngTemplateContextGuard(\n _directive: RtChatMessageActionsDirective,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtChatMessageActionsContext {\n return true;\n }\n}\n","import { IRtChat } from './rt-chat.model';\n\n/**\n * Есть ли у реплики хотя бы одно доступное действие потребителя.\n *\n * Признак приходит предикатом от экрана, а не подсчётом отрисованных пунктов меню:\n * содержимое спроецированного шаблона известно только после отрисовки, и кнопка\n * успевала бы мигнуть на первом кадре.\n *\n * Предикат не задан — у реплики есть действия: экран, который ничего не гейтит,\n * показывает кнопку меню. Так же это устроено у строки таблицы, и расхождение между\n * двумя точками проекции одного кита читалось бы дефектом.\n */\nexport function messageHasAvailableActions(message: IRtChat.Message, hasActions: IRtChat.MessageActionsPredicate | null): boolean {\n return hasActions === null ? true : hasActions(message);\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { messageHasAvailableActions } from './rt-chat-message-actions.logic';\nimport { IRtChat } from './rt-chat.model';\n\n/**\n * Есть ли у реплики доступные действия — гейт кнопки «…» у неё.\n *\n * Pure-pipe: пересчитывается только при смене реплики или предиката, а не на каждом\n * цикле проверки. Значение приходит из контекста шаблона (реплика треда), поэтому\n * `computed()` здесь неприменим.\n */\n@Pipe({ name: 'rtChatMessageHasActions' })\nexport class RtChatMessageHasActionsPipe implements PipeTransform {\n public transform(message: IRtChat.Message, hasActions: IRtChat.MessageActionsPredicate | null): boolean {\n return messageHasAvailableActions(message, hasActions);\n }\n}\n","import { IQuillDelta } from '@rt-tools/ui-kit-v2';\n\n/**\n * Модель общего чат-компонента `rt-chat`: один корневой неймспейс\n * с префиксом `I`. Доменные стора маппят свою модель сообщения в `Message`, а сам\n * `rt-chat` ничего не знает о доменных сущностях — только рисует тред и композер.\n */\n/**\n * Судьба своего сообщения в ленте: пока летит на сервер — часы, после записи —\n * двойной чек, после того как собеседник открыл переписку — тот же чек синим,\n * при обрыве — «!» с повтором. Входящие сообщения статуса не имеют.\n */\nexport enum ERtChatMessageStatus {\n Sending = 'sending',\n Sent = 'sent',\n Read = 'read',\n Failed = 'failed',\n}\n\nexport namespace IRtChat {\n /** Алиас enum'а для доменных мапперов, работающих через неймспейс. */\n export type MessageStatus = ERtChatMessageStatus;\n\n /**\n * Есть ли у реплики доступные действия потребителя — гейт кнопки «…» у неё.\n *\n * Признак приходит предикатом, а не полем модели: действие, которого кит не знает,\n * его моделью и не описывается.\n */\n export type MessageActionsPredicate = (message: Message) => boolean;\n\n /** Вложение сообщения — домен маппит свой ресурс, скачивание по `public_id`. */\n export interface Attachment {\n id: number;\n /** Обезличенное имя для карточки файла. */\n name: string;\n /** Непрозрачный идентификатор файла — консюмер качает blob по нему. */\n publicId: string;\n }\n\n /**\n * Одно сообщение треда в уже подготовленной для отображения форме: автор —\n * готовый лейбл (домен решает, как его собрать), `own`/`system` — флаги\n * выравнивания и стиля, дата — ISO-строка (форматируется `DatePipe` внутри).\n */\n export interface Message {\n /** Идентификатор сообщения — ключ `@for track`. */\n id: number | string;\n /** Клиентский временный id оптимистичного сообщения (до ответа сервера). */\n tempId?: string;\n /**\n * Статус своего сообщения. Отсутствует у входящих: чужому сообщению\n * нечего сообщать о доставке.\n */\n status?: MessageStatus;\n /** Готовый лейбл автора (доменный authorLabel). */\n author: string;\n /** Сообщение текущего пользователя — выравнивается вправо, акцентный фон. */\n own: boolean;\n /** Признак системного сообщения (рендерится обычным входящим пузырём). */\n system?: boolean;\n text: string;\n /**\n * Rich-тело (Quill delta) — при наличии рендерится вместо plain `text`\n * через `rt-delta-view`. `null`/отсутствует ⇒ показываем `text`.\n */\n delta?: IQuillDelta | null;\n /** ISO-дата создания. */\n createdAt: string;\n /** URL вложения (если есть) — наличие включает карточку файла. */\n fileUrl?: string | null;\n /** Имя вложения для отображения в карточке. */\n fileName?: string | null;\n /**\n * Вложения сообщения (несколько файлов). Непустой массив имеет приоритет\n * над legacy-парой `fileUrl`/`fileName` (та равна первому вложению).\n */\n attachments?: readonly Attachment[];\n /** Внешняя ссылка-призыв (привязка Telegram) — наличие включает кнопку-ссылку. */\n deepLink?: string | null;\n /** Подпись кнопки-ссылки `deepLink` (домен решает текст по состоянию). */\n deepLinkLabel?: string | null;\n /** Сообщение помечено удалённым — рендерится плейсхолдером вместо содержимого. */\n deleted?: boolean;\n /** Показать действие «удалить» на этом сообщении (домен решает по правам/направлению). */\n canDelete?: boolean;\n /**\n * Текст подтверждения перед удалением. Задан — клик по корзине открывает\n * confirm-попап с этим текстом, удаление уходит только после подтверждения.\n * Пусто/undefined — удаление сразу по клику (домен без confirm-семантики).\n */\n deleteConfirm?: string;\n }\n\n /** Payload отправки: текст + файлы (пусто/undefined, если вложения выключены). */\n export interface SendPayload {\n text: string;\n files?: File[];\n /**\n * Rich-тело строкой JSON (`JSON.stringify(getContents())`) — взаимоисключимо\n * с непустым `text`. При наличии домен шлёт delta-канал (`message:\"\"`).\n */\n delta?: string | null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { ERtChatMessageStatus } from '../components/chat/rt-chat.model';\n\n/**\n * Ключи подписей статусов для скринридера: сам индикатор — иконка, и без текста\n * различие «доставлено/прочитано» слышно не будет.\n *\n * Пайп отдаёт ключ, а переводит его `transloco` следующим звеном цепочки.\n * Готовый текст здесь застыл бы на языке, активном в момент загрузки модуля.\n */\nconst STATUS_KEYS: Readonly<Record<ERtChatMessageStatus, string>> = {\n [ERtChatMessageStatus.Sending]: 'rtKit.chatStatusSending',\n [ERtChatMessageStatus.Sent]: 'rtKit.chatStatusSent',\n [ERtChatMessageStatus.Read]: 'rtKit.chatStatusRead',\n [ERtChatMessageStatus.Failed]: 'rtKit.chatStatusFailed',\n};\n\n/** Ключ текстовой расшифровки иконки статуса сообщения. */\n@Pipe({ name: 'rtChatStatusLabel' })\nexport class RtChatStatusLabelPipe implements PipeTransform {\n public transform(status: ERtChatMessageStatus): string {\n return STATUS_KEYS[status];\n }\n}\n","/** Выбранные файлы вместе с только что добавленными. Список всегда новый: его читает сигнал. */\nexport function withAppendedFiles(current: ReadonlyArray<File>, added: ReadonlyArray<File>): File[] {\n return [...current, ...added];\n}\n\n/** Выбранные файлы без того, что стоит на этом месте. */\nexport function withoutFileAt(current: ReadonlyArray<File>, index: number): File[] {\n return current.filter((_: File, position: number): boolean => position !== index);\n}\n\n/** Файлы, названные полем выбора. Поле без выбора отдаёт пустой список, а не отсутствие. */\nexport function pickedFiles(files: FileList | null): File[] {\n return Array.from(files ?? []);\n}\n","/** Замеры прокрутки треда: столько, сколько нужно решению о прилипании к низу. */\nexport interface IRtChatThreadMetrics {\n scrollTop: number;\n scrollHeight: number;\n clientHeight: number;\n}\n\n/** Зазор от низа треда, в пределах которого читатель считается стоящим у нижнего края. */\nexport const RT_CHAT_NEAR_BOTTOM_THRESHOLD_PX: number = 64;\n\n/**\n * Задержки повторных подтягиваний ленты к низу после первой прокрутки. Присланное\n * содержимое дорисовывается несколькими проходами уже после того, как лента встала по\n * промежуточной высоте, и набор тиков покрывает окно, за которое высота устаканивается.\n */\nexport const RT_CHAT_PIN_RETRY_DELAYS_MS: ReadonlyArray<number> = [50, 150, 300, 500, 800];\n\n/** Стоит ли читатель у нижнего края треда. */\nexport function isNearBottom(metrics: IRtChatThreadMetrics): boolean {\n return metrics.scrollHeight - metrics.clientHeight - metrics.scrollTop <= RT_CHAT_NEAR_BOTTOM_THRESHOLD_PX;\n}\n\n/**\n * Прилипает ли лента к низу после этой прокрутки.\n *\n * Прилипание снимается только тогда, когда читатель уехал вверх сам. Прокрутка, сделанная\n * самим компонентом, и рост содержимого приходят с тем же или большим положением — на них\n * прилипание лишь подтверждается: иначе позднее событие от собственной прокрутки читалось бы\n * отрывом от низа, и лента переставала бы догонять последнее сообщение.\n */\nexport function nextAtBottom(previous: boolean, lastScrollTop: number, metrics: IRtChatThreadMetrics): boolean {\n const nearBottom: boolean = isNearBottom(metrics);\n\n return metrics.scrollTop < lastScrollTop - 1 ? nearBottom : previous || nearBottom;\n}\n","import { inject, DestroyRef } from '@angular/core';\n\n/** Пауза без ввода, после которой отрезок набора считается законченным. */\nexport const RT_CHAT_TYPING_PAUSE_MS: number = 3000;\n\n/**\n * Текст поля ответа из узла, где случился ввод. Поле обычного режима — textarea, поле с\n * оформлением — редактируемый узел; всё прочее, например выбор файла, набором не считается и\n * даёт `null`.\n */\nexport function typingDraft(target: EventTarget | null): string | null {\n if (target instanceof HTMLTextAreaElement) {\n return target.value;\n }\n const editor: Element | null = target instanceof HTMLElement ? target.closest('[contenteditable=\"true\"]') : null;\n return editor === null ? null : (editor.textContent ?? '');\n}\n\n/**\n * Отрезок набора: одно «начал» и одно «перестал» на отрезок, а не событие на каждую клавишу.\n * Отрезок кончается пустым полем, отправкой или паузой без ввода. Создаётся в контексте\n * внедрения: таймер паузы снимается вместе с компонентом, и выход уничтоженного компонента не\n * зовётся.\n */\nexport class RtChatTypingTracker {\n #typing: boolean = false;\n\n #timer: ReturnType<typeof setTimeout> | null = null;\n\n readonly #notify: (typing: boolean) => void;\n\n readonly #pauseMs: number;\n\n constructor(notify: (typing: boolean) => void, pauseMs: number = RT_CHAT_TYPING_PAUSE_MS) {\n this.#notify = notify;\n this.#pauseMs = pauseMs;\n inject(DestroyRef).onDestroy((): void => this.#clearTimer());\n }\n\n /** Ввод в поле ответа с его текущим текстом: пустой текст кончает отрезок. */\n public input(draft: string): void {\n if (draft.trim().length === 0) {\n this.stop();\n return;\n }\n if (!this.#typing) {\n this.#typing = true;\n this.#notify(true);\n }\n this.#clearTimer();\n this.#timer = setTimeout((): void => this.stop(), this.#pauseMs);\n }\n\n /** Конец отрезка; отрезок, который уже кончился, ничего не шлёт. */\n public stop(): void {\n this.#clearTimer();\n if (this.#typing) {\n this.#typing = false;\n this.#notify(false);\n }\n }\n\n #clearTimer(): void {\n if (this.#timer !== null) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { CdkTextareaAutosize } from '@angular/cdk/text-field';\nimport { DatePipe } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\n\nimport { NgTemplateOutlet } from '@angular/common';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport {\n RtButtonDirective,\n RtConfirmDirective,\n RtDeltaViewComponent,\n RtFileCardComponent,\n RtFileDropComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtMenuComponent,\n RtNoteComponent,\n RtSkeletonWrapperComponent,\n RtSpinnerComponent,\n RtToolbarComponent,\n RtToolbarLeftDirective,\n RtToolbarRightDirective,\n} from '@rt-tools/ui-kit-v2';\nimport { RT_KIT_LABELS, RT_KIT_LOCALE, rtKitLabel, TRtKitLabelKey, TRtKitLabelMap } from '@rt-tools/ui-kit-v2';\nimport { RtChatMessageActionsDirective } from './rt-chat-message-actions.directive';\nimport { RtChatMessageHasActionsPipe } from './rt-chat-message-actions.pipe';\nimport { RtChatStatusLabelPipe } from '../../pipes/rt-chat-status-label.pipe';\nimport { RtMessageComposerComponent } from '../message-composer/rt-message-composer.component';\nimport { IRtMessageComposer } from '../message-composer/rt-message-composer.model';\nimport { TRtRichEditorToolbar } from '../rich-editor/rt-rich-editor.component';\nimport { pickedFiles, withAppendedFiles, withoutFileAt } from './rt-chat-files.logic';\nimport { nextAtBottom, RT_CHAT_PIN_RETRY_DELAYS_MS } from './rt-chat-thread.logic';\nimport { typingDraft, RtChatTypingTracker } from './rt-chat-typing.logic';\nimport { ERtChatMessageStatus, IRtChat } from './rt-chat.model';\n\nconst BEM_BLOCK: string = 'rt-chat';\n\n/** Ключ заглушки имени вложения, когда домен не отдал `fileName` (только URL). */\nconst ATTACHMENT_FALLBACK_KEY: TRtKitLabelKey = 'chatAttachmentFallback';\n\n/**\n * Общий презентационный чат: тред сообщений + композер. История приходит готовым массивом\n * `IRtChat.Message[]`, отправка, обновление, скачивание и набор текста уходят наружу выходами;\n * стор и blob-загрузка остаются у потребителя. Композер держит свой `FormGroup`. Полноэкранный\n * режим — overlay внутри компонента (`--expanded`). Шапка рисуется, только когда включена хотя бы\n * одна из иконок `showRefresh`/`showExpand`: в диалогах своя header-обёртка.\n */\n@Component({\n selector: 'rt-chat',\n templateUrl: './rt-chat.component.html',\n styleUrls: ['./rt-chat.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n CdkTextareaAutosize,\n DatePipe,\n NgTemplateOutlet,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtButtonDirective,\n RtChatStatusLabelPipe,\n RtConfirmDirective,\n RtDeltaViewComponent,\n RtFileCardComponent,\n RtFileDropComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtChatMessageHasActionsPipe,\n RtMenuComponent,\n RtMessageComposerComponent,\n RtNoteComponent,\n RtSkeletonWrapperComponent,\n RtSpinnerComponent,\n RtToolbarComponent,\n RtToolbarLeftDirective,\n RtToolbarRightDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-chat--expanded]': 'expanded()',\n '[class.rt-chat--fill]': 'fill()',\n },\n})\nexport class RtChatComponent {\n /**\n * Дата форматируется по активной локали приложения, а не по `LOCALE_ID`: тот вычисляется на\n * подъёме и при смене языка на ходу оставил бы прежний формат. Данные локали для `DatePipe`\n * регистрирует приложение: без них пайп падает `Missing locale data`.\n */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly locale: Signal<string> = inject(RT_KIT_LOCALE);\n\n /** Читатель у нижнего края. Плоское поле, не сигнал: afterRenderEffect не перезапускается на scroll. */\n #atBottom: boolean = true;\n\n /** Прошлый scrollTop треда — для различения прокрутки вверх и роста контента. */\n #lastScrollTop: number = 0;\n\n /** One-shot: своё отправленное сообщение всегда прокручивает тред вниз. */\n #forceScroll: boolean = false;\n\n /** Отрезок набора в поле ответа: наружу уходит одно «начал» и одно «перестал» на отрезок. */\n readonly #typingTracker: RtChatTypingTracker = new RtChatTypingTracker((typing: boolean): void => this.typing.emit(typing));\n\n /** Текущее значение композера — источник реактивности для `canSend`. */\n readonly #formValue: Signal<Partial<{ message: string; files: File[] }>>;\n\n /**\n * Скролл-контейнер треда — для автопрокрутки к последнему сообщению.\n * `viewChild` не работает на ES-private (`#`) поле, поэтому `protected`.\n */\n protected readonly thread: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('thread');\n\n /** Скрытый нативный input — открывается кнопкой-скрепкой внутри поля ввода. */\n protected readonly composerFileEl: Signal<ElementRef<HTMLInputElement> | undefined> =\n viewChild<ElementRef<HTMLInputElement>>('composerFileEl');\n\n protected readonly attachmentFallbackName: Signal<string> = rtKitLabel(ATTACHMENT_FALLBACK_KEY);\n\n /** Подписи с учётом того, что передал хозяин компонента: своё важнее умолчания */\n protected readonly titleText: Signal<string> = computed((): string => this.title() || this.#defaultTitle());\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.#defaultPlaceholder());\n protected readonly emptyHintText: Signal<string> = computed((): string => this.emptyHint() || this.#defaultEmptyHint());\n\n readonly #defaultTitle: Signal<string> = rtKitLabel('chatTitle');\n readonly #defaultPlaceholder: Signal<string> = rtKitLabel('chatPlaceholder');\n readonly #defaultEmptyHint: Signal<string> = rtKitLabel('chatEmptyHint');\n\n protected readonly MessageStatus: typeof ERtChatMessageStatus = ERtChatMessageStatus;\n\n /** Плейсхолдеры скелетонов треда при первичной загрузке. */\n protected readonly skeletonRows: readonly number[] = [1, 2, 3];\n\n /** Полноэкранный режим (overlay поверх страницы). */\n protected readonly expanded: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly replyForm: FormGroup<{\n message: FormControl<string>;\n files: FormControl<File[]>;\n }> = new FormGroup({\n message: new FormControl<string>('', { nonNullable: true }),\n files: new FormControl<File[]>([], { nonNullable: true }),\n });\n\n /** Композер заблокирован при загрузке/рефреше треда или отправке in-flight. */\n protected readonly composerDisabled: Signal<boolean> = computed((): boolean => this.loading() || this.fetching() || this.sending());\n\n /**\n * Можно ли отправить: композер активен и есть содержимое — непустой текст или\n * (при включённых вложениях) хотя бы один файл. Сообщение само по себе не\n * бывает «невалидным» — пустоту гасим дизейблом кнопки, а не подсветкой поля.\n */\n protected readonly canSend: Signal<boolean> = computed((): boolean => {\n if (this.composerDisabled()) {\n return false;\n }\n const value: Partial<{ message: string; files: File[] }> = this.#formValue();\n const hasText: boolean = (value.message ?? '').trim().length > 0;\n const hasFiles: boolean = this.attachments() && (value.files?.length ?? 0) > 0;\n return hasText || hasFiles;\n });\n\n /** Показывать ли шапку: только когда включена хотя бы одна иконка. */\n protected readonly showHeader: Signal<boolean> = computed((): boolean => this.showRefresh() || this.showExpand());\n\n /** Подпись кнопки fullscreen: тернарник в шаблоне переводом не покрыть. */\n protected readonly expandLabel: Signal<string> = rtKitLabel(\n computed((): TRtKitLabelKey => (this.expanded() ? 'chatCollapse' : 'chatExpand'))\n );\n\n /** Выбранные, но ещё не отправленные файлы — карточки над полем ввода. */\n protected readonly selectedFiles: Signal<File[]> = computed((): File[] => this.#formValue().files ?? []);\n\n /**\n * Drop-зона активна только когда вложения включены, ответ доступен и композер\n * не занят (загрузка/рефреш/отправка). Иначе обёртка `rt-file-drop` просто\n * пропускает контент без оверлея.\n */\n protected readonly dropDisabled: Signal<boolean> = computed(\n (): boolean => !this.attachments() || !this.canReply() || this.composerDisabled()\n );\n\n /**\n * Файл из drag-n-drop для rich-композера: каждый drop кладёт новый `File`,\n * пробрасывается в `rt-message-composer` через input. Классический композер\n * принимает drop напрямую в свой `replyForm`.\n */\n protected readonly droppedFiles: WritableSignal<File[] | null> = signal<File[] | null>(null);\n\n /**\n * Шаблон действий у реплики: `<ng-template rtChatMessageActions let-message>`.\n *\n * Не объявлен — разметка реплики прежняя, и лишней кнопки у неё не появляется.\n */\n protected readonly messageActions: Signal<RtChatMessageActionsDirective | undefined> = contentChild(RtChatMessageActionsDirective);\n\n /** История сообщений (consumer уже смаппил из доменной модели). */\n public readonly messages: InputSignal<readonly IRtChat.Message[]> = input<readonly IRtChat.Message[]>([]);\n\n /** Первичная загрузка — скелетоны вместо треда. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Рефреш при наличии данных — тред остаётся, композер дизейблится. */\n public readonly fetching: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Доступна ли отправка (иначе вместо композера — note с причиной). */\n public readonly canReply: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Причина блокировки ответа — note под тредом. */\n public readonly replyBlockReason: InputSignal<string | null> = input<string | null>(null);\n\n /** Отправка in-flight — спиннер/дизейбл на кнопке. */\n public readonly sending: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Подписи по умолчанию приходят пустыми и переводятся ниже: значение\n * `input()` вычисляется при создании компонента, и готовый перевод застыл бы\n * на языке, активном в этот момент.\n */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n public readonly title: InputSignal<string> = input<string>('');\n\n /** Текст, когда треда ещё нет (заявка не создана). */\n public readonly emptyHint: InputSignal<string> = input<string>('');\n\n /** Есть ли тред (иначе показываем `emptyHint`). */\n public readonly hasThread: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Включить загрузку файлов в композере. */\n public readonly attachments: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** `accept` для file-input (`.pdf,.doc,...`). */\n public readonly accept: InputSignal<string> = input<string>('');\n\n /**\n * Компактный композер (`rt-message-composer`): авто-растущая textarea над\n * разделителем + ряд иконок (прикрепить слева, отправить справа) вместо\n * классического вертикального стека. По умолчанию выключен.\n */\n public readonly richComposer: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Rich-текст в композере (Quill delta). Требует `richComposer` — форматирование\n * живёт только в компактном композере. Отправка уходит delta-каналом.\n */\n public readonly formatting: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Набор кнопок rich-редактора (проброс до `rt-rich-editor` через композер). */\n public readonly formattingToolbar: InputSignal<TRtRichEditorToolbar> = input<TRtRichEditorToolbar>('full');\n\n /**\n * Растягивать чат на всю высоту контейнера: тред занимает свободное место,\n * композер прижат к низу. По умолчанию выключен (тред с фикс. max-height).\n * Требует, чтобы родитель давал высоту (flex-цепочка).\n */\n public readonly fill: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показать иконку refresh в шапке. */\n public readonly showRefresh: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показать иконку expand (fullscreen) в шапке. */\n public readonly showExpand: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Отправка сообщения (+файлы) — consumer вызывает свой store/api. */\n public readonly send: OutputEmitterRef<IRtChat.SendPayload> = output<IRtChat.SendPayload>();\n\n /** Клик refresh — consumer перетягивает тред. */\n public readonly refresh: OutputEmitterRef<void> = output<void>();\n\n /** Клик по вложению — consumer качает blob своим api; шаблон зовёт выход прямо, без релея. */\n public readonly downloadFile: OutputEmitterRef<IRtChat.Message> = output<IRtChat.Message>();\n\n /** Клик по карточке вложения из `attachments[]` — консюмер качает по `publicId`. */\n public readonly downloadAttachment: OutputEmitterRef<IRtChat.Attachment> = output<IRtChat.Attachment>();\n\n /** Набор текста в поле ответа: `true` — отрезок начался, `false` — кончился. */\n public readonly typing: OutputEmitterRef<boolean> = output<boolean>();\n\n /** Строка о том, что печатает вторая сторона, поверх низа ленты; пустая прячет плашку. */\n public readonly typingText: InputSignal<string> = input<string>('');\n\n /** Смена fullscreen-состояния. */\n public readonly expandedChange: OutputEmitterRef<boolean> = output<boolean>();\n\n public readonly deleteMessage: OutputEmitterRef<IRtChat.Message> = output<IRtChat.Message>();\n\n /** Повторная отправка своего сообщения со статусом `failed`. */\n public readonly retryMessage: OutputEmitterRef<IRtChat.Message> = output<IRtChat.Message>();\n\n /**\n * Есть ли у реплики действия потребителя — гейт кнопки «…» у неё.\n *\n * Не задан — точка действий показывается у каждой реплики: экран, который ничего не\n * гейтит, показывает её так же, как это делает строка таблицы.\n */\n public readonly messageHasActions: InputSignal<IRtChat.MessageActionsPredicate | null> = input<IRtChat.MessageActionsPredicate | null>(\n null\n );\n\n constructor() {\n this.#formValue = toSignal(this.replyForm.valueChanges, {\n initialValue: this.replyForm.value,\n });\n\n // После рендера, зависящего от треда, лента прокручивается к последнему сообщению — если оно\n // своё (forceScroll) или читатель у нижнего края; ушедшего читать историю входящее не дёргает.\n afterRenderEffect((): void => {\n this.messages();\n this.loading();\n this.fetching();\n this.expanded();\n const el: HTMLElement | undefined = this.thread()?.nativeElement;\n if (el === undefined) {\n return;\n }\n if (this.#forceScroll || this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n this.#atBottom = true;\n this.#pinToBottomDeferred();\n }\n this.#forceScroll = false;\n });\n\n // `formControlName`-инпуты игнорируют атрибут `disabled` — состояние ввода\n // держим через сам контрол: блок при рефреше треда или отправке in-flight.\n effect((): void => {\n const blocked: boolean = this.composerDisabled();\n if (blocked && this.replyForm.enabled) {\n this.replyForm.disable({ emitEvent: false });\n return;\n }\n if (!blocked && this.replyForm.disabled) {\n this.replyForm.enable({ emitEvent: false });\n }\n });\n }\n\n protected onSubmit(): void {\n // Кнопка уже дизейблится по `canSend` — guard лишь страхует от submit в\n // обход кнопки (программный/Enter), молча и без подсветки поля.\n if (!this.canSend()) {\n return;\n }\n const text: string = this.replyForm.controls.message.value.trim();\n const files: File[] = this.replyForm.controls.files.value;\n // Своё сообщение всегда прокручивает тред вниз — независимо от позиции.\n this.#forceScroll = true;\n this.#typingTracker.stop();\n this.send.emit({ text, files: this.attachments() ? files : undefined });\n this.replyForm.reset({ message: '', files: [] });\n }\n\n protected onComposerKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' && !event.shiftKey && !event.isComposing) {\n event.preventDefault();\n this.onSubmit();\n }\n }\n\n /** Релей submit'а от `rt-message-composer` (rich-режим) наружу как `send`. */\n protected onComposerSubmit(payload: IRtMessageComposer.SubmitPayload): void {\n // Своё сообщение всегда прокручивает тред вниз — независимо от позиции.\n this.#forceScroll = true;\n this.#typingTracker.stop();\n this.send.emit({\n text: payload.text,\n files: this.attachments() ? payload.files : undefined,\n delta: payload.delta,\n });\n }\n\n /** Ввод в поле ответа любого из двух режимов; выбор файла набором не считается. */\n protected onReplyInput(event: Event): void {\n const draft: string | null = typingDraft(event.target);\n if (draft !== null) {\n this.#typingTracker.input(draft);\n }\n }\n\n /**\n * Файлы выброшены в обёртку чата: в rich-режиме отдаём массив композеру через\n * input, в классическом — добавляем к уже выбранным в собственном `replyForm`.\n */\n protected onFilesDropped(files: File[]): void {\n if (files.length === 0) {\n return;\n }\n if (this.richComposer()) {\n // Новый массив на каждый drop — effect композера видит каждое перетаскивание.\n this.droppedFiles.set([...files]);\n return;\n }\n this.replyForm.controls.files.setValue(withAppendedFiles(this.replyForm.controls.files.value, files));\n }\n\n protected openFilePicker(): void {\n this.composerFileEl()?.nativeElement.click();\n }\n\n protected onFilesPicked(event: Event): void {\n const inputEl: HTMLInputElement = event.target as HTMLInputElement;\n const picked: File[] = pickedFiles(inputEl.files);\n if (picked.length > 0) {\n this.replyForm.controls.files.setValue(withAppendedFiles(this.replyForm.controls.files.value, picked));\n }\n // Сброс значения: без него повторный выбор того же файла не даёт `change`.\n inputEl.value = '';\n }\n\n protected removeFile(index: number): void {\n this.replyForm.controls.files.setValue(withoutFileAt(this.replyForm.controls.files.value, index));\n }\n\n /** Признак «читатель у нижнего края» обновляется по прокрутке: на нём стоит автопрокрутка. */\n protected onThreadScroll(): void {\n const el: HTMLElement | undefined = this.thread()?.nativeElement;\n if (el === undefined) {\n return;\n }\n\n this.#atBottom = nextAtBottom(this.#atBottom, this.#lastScrollTop, el);\n this.#lastScrollTop = el.scrollTop;\n }\n\n /**\n * Серия отложенных подтягиваний ленты к низу: присланное содержимое дорисовывается несколькими\n * проходами, и одной прокрутки мало. Каждый тик берёт тред заново — он бывает пересоздан — и\n * дотягивает ленту, пока читатель стоит у нижнего края.\n */\n #pinToBottomDeferred(): void {\n for (const delay of RT_CHAT_PIN_RETRY_DELAYS_MS) {\n setTimeout((): void => {\n const el: HTMLElement | undefined = this.thread()?.nativeElement;\n if (el !== undefined && this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n }\n }, delay);\n }\n }\n\n protected toggleExpand(): void {\n const next: boolean = !this.expanded();\n this.expanded.set(next);\n this.expandedChange.emit(next);\n }\n}\n","<ng-container rtBlock=\"rt-chat\">\n <rt-file-drop\n [overlayLabel]=\"t().chatDropOverlay\"\n [accept]=\"accept()\"\n [disabled]=\"dropDisabled()\"\n (filesDropped)=\"onFilesDropped($event)\">\n @if (showHeader()) {\n <rt-toolbar rtElem=\"header\" dense>\n <ng-template rtToolbarLeft>\n <h3 rtElem=\"title\" qa-dataid=\"chat-title\">{{ title() }}</h3>\n </ng-template>\n <ng-template rtToolbarRight>\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"chat-refresh\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRefreshAria\"\n [tooltip]=\"t().chatRefreshTooltip\"\n [loading]=\"fetching()\"\n [disabled]=\"!hasThread()\"\n (clicked)=\"refresh.emit()\" />\n }\n @if (showExpand()) {\n <rt-icon-button\n qa-dataid=\"chat-expand\"\n variant=\"ghost\"\n [icon]=\"expanded() ? 'window-minimize' : 'window-maximize'\"\n [ariaLabel]=\"expandLabel()\"\n [tooltip]=\"expandLabel()\"\n (clicked)=\"toggleExpand()\" />\n }\n <ng-content select=\"[rtChatHeaderActions]\" />\n </ng-template>\n </rt-toolbar>\n }\n\n @if (!hasThread()) {\n <rt-note qa-dataid=\"chat-empty-hint\">{{ emptyHint() }}</rt-note>\n } @else {\n <div rtElem=\"thread-viewport\" qa-dataid=\"chat-thread-viewport\">\n @if (loading()) {\n <!-- Скелетон повторяет структуру сообщения (автор → текст → дата),\n чередуя выравнивание, чтобы тред не «прыгал» при подмене на реальные. -->\n <div rtElem=\"thread\" qa-dataid=\"chat-thread-skeleton\">\n @for (row of skeletonRows; track row; let even = $even) {\n <div rtElem=\"message-skeleton\" qa-dataid=\"chat-message-skeleton\" [rtMod]=\"{ own: even }\">\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"72px\" height=\"10px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"100%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"55%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"56px\" height=\"10px\" [isLoading]=\"true\" />\n </div>\n }\n </div>\n } @else {\n <div\n #thread\n rtElem=\"thread\"\n qa-dataid=\"chat-thread\"\n [rtMod]=\"{ frozen: fetching() }\"\n [attr.aria-busy]=\"fetching() ? 'true' : null\"\n (scroll)=\"onThreadScroll()\">\n @for (m of messages(); track m.id) {\n <div\n rtElem=\"message-row\"\n qa-dataid=\"chat-message\"\n [attr.data-own]=\"m.own\"\n [attr.data-status]=\"m.status || null\"\n [attr.data-deleted]=\"m.deleted || null\"\n [rtMod]=\"{ own: m.own }\">\n @if (m.canDelete && !m.deleted) {\n @if (m.deleteConfirm) {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n [rtConfirm]=\"m.deleteConfirm\"\n (confirmed)=\"deleteMessage.emit(m)\" />\n } @else {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n (clicked)=\"deleteMessage.emit(m)\" />\n }\n }\n @if (messageActions()?.template; as actionsTpl) {\n @if (m | rtChatMessageHasActions: messageHasActions()) {\n <div rtElem=\"message-actions\" qa-dataid=\"chat-message-actions\">\n <rt-menu>\n <ng-container\n [ngTemplateOutlet]=\"actionsTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: m }\" />\n </rt-menu>\n </div>\n }\n }\n <div rtElem=\"message\" [rtMod]=\"{ own: m.own, deleted: m.deleted }\">\n <p rtElem=\"message-author\" qa-dataid=\"chat-message-author\">{{ m.author }}</p>\n @if (m.deleted) {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-deleted\" rtMod=\"deleted\">\n {{ t().chatMessageDeleted }}\n </p>\n } @else {\n @if (m.delta) {\n <rt-delta-view rtElem=\"message-text\" qa-dataid=\"chat-message-text\" [delta]=\"m.delta\" />\n } @else {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-text\">{{ m.text }}</p>\n }\n @if (m.attachments?.length) {\n @for (att of m.attachments; track att.id) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"att.name || attachmentFallbackName()\"\n (download)=\"downloadAttachment.emit(att)\" />\n </span>\n }\n } @else if (m.fileUrl) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"m.fileName || attachmentFallbackName()\"\n (download)=\"downloadFile.emit(m)\" />\n </span>\n }\n @if (m.deepLink) {\n <span rtElem=\"message-deeplink\">\n <a\n rtButton\n qa-dataid=\"chat-message-deeplink\"\n appearance=\"outlined\"\n icon=\"send\"\n rel=\"noopener\"\n target=\"_blank\"\n [href]=\"m.deepLink\"\n [label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"\n [attr.aria-label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"></a>\n </span>\n }\n }\n <span rtElem=\"message-footer\">\n <span rtElem=\"message-date\" qa-dataid=\"chat-message-date\">\n {{ m.createdAt | date: 'short' : undefined : locale() }}\n </span>\n @if (m.status) {\n <span\n rtElem=\"message-status\"\n qa-dataid=\"chat-message-status\"\n [attr.data-status]=\"m.status\"\n [rtMod]=\"{ status: m.status }\"\n [attr.aria-label]=\"m.status | rtChatStatusLabel\">\n @if (m.status === MessageStatus.Failed) {\n <rt-icon rtElem=\"status-icon\" name=\"exclamation-circle\" size=\"sm\" />\n <rt-icon-button\n qa-dataid=\"chat-message-retry\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRetryAria\"\n [tooltip]=\"t().chatRetryTooltip\"\n (clicked)=\"retryMessage.emit(m)\" />\n } @else {\n <!-- Часы, пока сообщение в пути; дальше двойной чек, цвет которого\n (серый/синий) различает доставлено и прочитано. -->\n <rt-icon\n rtElem=\"status-icon\"\n size=\"sm\"\n [name]=\"m.status === MessageStatus.Sending ? 'clock' : 'check-double'\" />\n }\n </span>\n }\n </span>\n </div>\n </div>\n } @empty {\n <rt-note qa-dataid=\"chat-empty-thread\">{{ t().chatEmptyThread }}</rt-note>\n }\n </div>\n }\n @if (!loading() && fetching()) {\n <div rtElem=\"thread-overlay\" qa-dataid=\"chat-thread-overlay\" role=\"status\" [attr.aria-label]=\"t().chatRefreshAria\">\n <rt-spinner diameter=\"32\" />\n </div>\n }\n <div rtElem=\"typing\" qa-dataid=\"chat-typing\" aria-live=\"polite\" [rtMod]=\"{ shown: typingText() !== '' }\">\n {{ typingText() }}\n </div>\n </div>\n\n @if (canReply()) {\n @if (richComposer()) {\n <rt-message-composer\n rtElem=\"composer-rich\"\n qa-dataid=\"chat-composer-rich\"\n [placeholder]=\"placeholder()\"\n [accept]=\"accept()\"\n [attachments]=\"attachments()\"\n [formatting]=\"formatting()\"\n [toolbar]=\"formattingToolbar()\"\n [sending]=\"sending()\"\n [disabled]=\"loading() || fetching()\"\n [droppedFiles]=\"droppedFiles()\"\n (submitted)=\"onComposerSubmit($event)\"\n (input)=\"onReplyInput($event)\" />\n } @else {\n <form\n rtElem=\"composer\"\n qa-dataid=\"chat-composer\"\n [formGroup]=\"replyForm\"\n (ngSubmit)=\"onSubmit()\"\n (input)=\"onReplyInput($event)\">\n @if (attachments() && selectedFiles().length > 0) {\n <div rtElem=\"composer-files\" qa-dataid=\"chat-composer-files\">\n @for (file of selectedFiles(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"chat-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"composerDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n <div rtElem=\"composer-field\" [rtMod]=\"{ attach: attachments() }\">\n @if (attachments()) {\n <input\n #composerFileEl\n qa-dataid=\"chat-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"chat-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"composerDisabled()\"\n (clicked)=\"openFilePicker()\" />\n }\n <textarea\n rtElem=\"composer-input\"\n qa-dataid=\"chat-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"4\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"onComposerKeydown($event)\"></textarea>\n </div>\n <button\n rtButton\n rtElem=\"composer-send\"\n qa-dataid=\"chat-composer-send\"\n type=\"submit\"\n theme=\"primary\"\n appearance=\"filled\"\n [label]=\"t().chatSendLabel\"\n [attr.aria-label]=\"t().chatSendAria\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"></button>\n </form>\n }\n } @else if (replyBlockReason()) {\n <rt-note rtElem=\"reply-block\" qa-dataid=\"chat-reply-block\">{{ replyBlockReason() }}</rt-note>\n }\n\n <!-- Слот доменных действий потребителя под композером: в fullscreen\n попадает внутрь overlay, поэтому кнопки остаются видны. -->\n <div rtElem=\"footer-slot\" qa-dataid=\"chat-footer\" [rtMod]=\"{ blocked: fetching() }\" [attr.inert]=\"fetching() ? '' : null\">\n <ng-content select=\"[rtChatFooter]\" />\n </div>\n }\n </rt-file-drop>\n</ng-container>\n","import { fileNameFromUrl, IQuillDelta } from '@rt-tools/ui-kit-v2';\n\nimport { ERtChatMessageStatus, IRtChat } from './rt-chat.model';\n\n/**\n * Статус уже сохранённого своего сообщения: сервер знает только, дошло ли оно до\n * собеседника. Часы и ошибка — состояния клиентской очереди, сюда не попадают.\n */\nexport function deliveryStatus(read: boolean): ERtChatMessageStatus {\n return read ? ERtChatMessageStatus.Read : ERtChatMessageStatus.Sent;\n}\n\n/**\n * Сообщение, ещё не подтверждённое сервером. Серверного id и ссылок на вложения\n * у него нет: есть клиентский ключ, текст и выбранные файлы.\n *\n * Rich-тело приходит уже разобранным — доменная форма его хранения тут ни при\n * чём, а хранят его стороны по-разному: одна шлёт обычный текст, другая —\n * строку композера, которая в том же виде уходит на сервер.\n */\nexport interface IRtPendingMessage {\n tempId: string;\n text: string;\n delta?: IQuillDelta | null;\n createdAt: string;\n status: IRtChat.MessageStatus;\n files: readonly File[];\n}\n\n/**\n * Неподтверждённое сообщение → строка ленты. Показывается сразу после отправки:\n * ждать ответа сервера, глядя в пустоту, незачем ни одной из сторон.\n *\n * Скрыть такое сообщение нельзя: на сервере его ещё нет, и удалять нечего.\n */\nexport function pendingToRtMessage(pending: IRtPendingMessage, authorLabel: string): IRtChat.Message {\n return {\n id: pending.tempId,\n tempId: pending.tempId,\n author: authorLabel,\n own: true,\n text: pending.text,\n delta: pending.delta ?? null,\n createdAt: pending.createdAt,\n status: pending.status,\n canDelete: false,\n attachments: pending.files.map((file: File, index: number): IRtChat.Attachment => ({\n id: index,\n name: file.name,\n // Файл ещё не на сервере — скачивать нечего, карточка только именует.\n publicId: '',\n })),\n };\n}\n\n/**\n * Структурный контракт доменного сообщения, достаточный для маппинга в\n * `IRtChat.Message`. Доменные модели удовлетворяют ему по форме;\n * роль-специфика (автор/own/system) задаётся опциями.\n */\nexport interface IRtMappableMessage {\n id: string | number;\n tempId?: string;\n status?: IRtChat.MessageStatus;\n message: string;\n messageDelta: IQuillDelta | null;\n createdAt: string;\n fileUrl: string | null;\n attachments: readonly { id: number; name: string; publicId: string }[];\n}\n\n/**\n * Опции маппинга: роль-специфичные куски, которые не вывести из общего контракта.\n *\n * - `roleLabel` — подпись автора (обычно ярлык роли).\n * - `isOwn` — своё ли это сообщение (правый пузырь).\n * - `isSystem` — системное ли (нейтральный стиль); по умолчанию нет.\n * - `fileName` — имя файла вложения; по умолчанию выводится из `fileUrl`.\n * - `optimistic` — включить `tempId`/`status` (оптимистичная отправка); по умолчанию да.\n * Для read-only тредов (агент) — `false`: тогда `id` берётся из серверного `id`.\n */\nexport interface IToRtMessageOptions<TMessage extends IRtMappableMessage> {\n roleLabel: (message: TMessage) => string;\n isOwn: (message: TMessage) => boolean;\n isSystem?: (message: TMessage) => boolean;\n fileName?: (message: TMessage) => string | null;\n optimistic?: boolean;\n}\n\n/**\n * Собрать `IRtChat.Message` из доменного сообщения. Общие поля (текст, delta,\n * дата, вложения, файл) берутся из контракта; автор/own/system/имя файла —\n * из опций. Ключ `id` — `tempId ?? id` в оптимистичном режиме (пока сервер не\n * подтвердил), иначе серверный `id`.\n */\nexport function toRtMessage<TMessage extends IRtMappableMessage>(\n message: TMessage,\n options: IToRtMessageOptions<TMessage>\n): IRtChat.Message {\n const optimistic: boolean = options.optimistic ?? true;\n const fileNameFromUrlOrNull: string | null = message.fileUrl ? fileNameFromUrl(message.fileUrl) : null;\n return {\n id: optimistic ? (message.tempId ?? message.id) : message.id,\n tempId: optimistic ? message.tempId : undefined,\n status: optimistic ? message.status : undefined,\n author: options.roleLabel(message),\n own: options.isOwn(message),\n system: options.isSystem?.(message) ?? false,\n text: message.message,\n delta: message.messageDelta,\n createdAt: message.createdAt,\n fileUrl: message.fileUrl,\n fileName: options.fileName ? options.fileName(message) : fileNameFromUrlOrNull,\n attachments: message.attachments.map((attachment: { id: number; name: string; publicId: string }): IRtChat.Attachment => ({\n id: attachment.id,\n name: attachment.name,\n publicId: attachment.publicId,\n })),\n };\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n InputSignal,\n model,\n ModelSignal,\n output,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, RtAiRunStatusComponent, RtIconButtonComponent, RtMarkdownTextComponent, TRtKitLabelMap } from '@rt-tools/ui-kit-v2';\n\nimport { IRtAiChat } from '../rt-ai-chat.model';\n\nconst BEM_BLOCK: string = 'rt-ai-chat-answer';\n\n/**\n * Ответ ассистента в ленте `rt-ai-chat`: ход работы, текст в markdown, вложения приложения и оценка.\n * Оценка появляется, когда текст дописан.\n */\n@Component({\n selector: 'rt-ai-chat-answer',\n templateUrl: './rt-ai-chat-answer.component.html',\n styleUrl: './rt-ai-chat-answer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n NgTemplateOutlet,\n\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n RtAiRunStatusComponent,\n RtIconButtonComponent,\n RtMarkdownTextComponent,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'article',\n '[attr.data-id]': 'message().id',\n },\n})\nexport class RtAiChatAnswerComponent {\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly isRated: Signal<boolean> = computed((): boolean => !!this.message().text && !this.message().streaming);\n\n public readonly message: InputSignal<IRtAiChat.Message> = input.required<IRtAiChat.Message>();\n\n /** Шаблон вложений ответа; `null` — вложений нет. */\n public readonly extra: InputSignal<TemplateRef<IRtAiChat.ExtraContext> | null> = input<TemplateRef<IRtAiChat.ExtraContext> | null>(\n null\n );\n\n /** Шаги хода работы раскрыты. */\n public readonly expanded: ModelSignal<boolean> = model<boolean>(false);\n\n /** Нажата оценка; повторное нажатие той же снимает её — решает родитель. */\n public readonly feedbackChange: OutputEmitterRef<Exclude<IRtAiChat.Feedback, null>> = output<Exclude<IRtAiChat.Feedback, null>>();\n}\n","<ng-container rtBlock=\"rt-ai-chat-answer\">\n @if (message().run; as run) {\n <rt-ai-run-status\n qa-dataid=\"ai-chat-run\"\n [state]=\"run.state\"\n [label]=\"run.label\"\n [meta]=\"run.meta ?? ''\"\n [steps]=\"run.steps ?? []\"\n [(expanded)]=\"expanded\" />\n }\n @if (message().text) {\n <rt-markdown-text rtElem=\"text\" qa-dataid=\"ai-chat-answer-text\" [text]=\"message().text\" />\n }\n @if (extra(); as extraTemplate) {\n <ng-container [ngTemplateOutlet]=\"extraTemplate\" [ngTemplateOutletContext]=\"{ $implicit: message() }\" />\n }\n @if (isRated()) {\n <div rtElem=\"feedback\" qa-dataid=\"ai-chat-feedback\">\n <rt-icon-button\n qa-dataid=\"ai-chat-like\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"thumb-up\"\n [active]=\"message().feedback === 'liked'\"\n [ariaLabel]=\"t().aiLike\"\n [tooltip]=\"t().aiLike\"\n (clicked)=\"feedbackChange.emit('liked')\" />\n <rt-icon-button\n qa-dataid=\"ai-chat-dislike\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"thumb-down\"\n [active]=\"message().feedback === 'disliked'\"\n [ariaLabel]=\"t().aiDislike\"\n [tooltip]=\"t().aiDislike\"\n (clicked)=\"feedbackChange.emit('disliked')\" />\n </div>\n }\n</ng-container>\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { IRtAiChat } from './rt-ai-chat.model';\n\n/**\n * Вложения ответа ассистента: то, что рисует приложение под текстом ответа — график, таблица,\n * карточка. Шаблон получает сообщение.\n */\n@Directive({\n selector: 'ng-template[rtAiChatMessageExtra]',\n})\nexport class RtAiChatMessageExtraDirective {\n public readonly templateRef: TemplateRef<IRtAiChat.ExtraContext> = inject<TemplateRef<IRtAiChat.ExtraContext>>(TemplateRef);\n\n public static ngTemplateContextGuard(\n _directive: RtAiChatMessageExtraDirective,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате\n context: unknown\n ): context is IRtAiChat.ExtraContext {\n return true;\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n ElementRef,\n inject,\n Injector,\n input,\n InputSignal,\n InputSignalWithTransform,\n booleanAttribute,\n model,\n ModelSignal,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { BooleanInput } from '@angular/cdk/coercion';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport {\n IRtIcon,\n IRtSideMenu,\n IRtThreadList,\n RT_KIT_LABELS,\n RtButtonDirective,\n RtCopyValueComponent,\n RtEmptyStateComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtMessageComponent,\n RtPromptSuggestionComponent,\n RtSpinnerComponent,\n RtThreadListComponent,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n splitSideMenuTitle,\n TRtKitLabelMap,\n} from '@rt-tools/ui-kit-v2';\n\nimport { nextAtBottom, RT_CHAT_PIN_RETRY_DELAYS_MS } from '../chat/rt-chat-thread.logic';\nimport { IRtMessageComposer } from '../message-composer/rt-message-composer.model';\nimport { RtMessageComposerComponent } from '../message-composer/rt-message-composer.component';\nimport { RtAiChatAnswerComponent } from './answer/rt-ai-chat-answer.component';\nimport { RtAiChatMessageExtraDirective } from './rt-ai-chat.directives';\nimport { IRtAiChat } from './rt-ai-chat.model';\n\nconst BEM_BLOCK: string = 'rt-ai-chat';\n\n/** Значки строк-превью пустого списка бесед по умолчанию: беседы идут с ассистентом. */\nconst PREVIEW_ICONS: readonly IRtIcon.Name[] = ['sparkle', 'bot', 'sparkle'];\n\n/** Строка беседы для списка бесед: `rt-thread-list` ждёт `id` и `hasUnread`. */\ninterface IThreadRow extends IRtThreadList.Row {\n readonly id: string;\n readonly hasUnread: boolean;\n readonly title: string;\n readonly titleParts: readonly IRtSideMenu.TitlePart[];\n readonly time: string;\n readonly unreadCount: number;\n}\n\n/**\n * Панель ИИ-ассистента одним компонентом: шапка с действиями, лента вопросов и ответов с ходом\n * работы, пустой экран с подсказками, ошибка с номером обращения, поле сообщения и подпись под\n * ним; по кнопке «Conversations» — список бесед.\n *\n * Компонент презентационный: сообщения, ход работы, беседы и ошибка приходят входами, действия\n * уходят выходами. Вложения ответа — графики и прочее — приложение отдаёт шаблоном\n * `rtAiChatMessageExtra`.\n */\n@Component({\n selector: 'rt-ai-chat',\n templateUrl: './rt-ai-chat.component.html',\n styleUrl: './rt-ai-chat.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n NgTemplateOutlet,\n\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n RtAiChatAnswerComponent,\n RtButtonDirective,\n RtCopyValueComponent,\n RtEmptyStateComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtMessageComponent,\n RtMessageComposerComponent,\n RtPromptSuggestionComponent,\n RtSpinnerComponent,\n RtThreadListComponent,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtAiChatComponent {\n #atBottom: boolean = true;\n #lastScrollTop: number = 0;\n #forceScroll: boolean = false;\n\n readonly #injector: Injector = inject(Injector);\n\n protected readonly composer: Signal<RtMessageComposerComponent | undefined> = viewChild(RtMessageComposerComponent);\n protected readonly backButton: Signal<ElementRef<HTMLElement> | undefined> = viewChild('back', { read: ElementRef });\n protected readonly feed: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('feed');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly extraTemplate: Signal<RtAiChatMessageExtraDirective | undefined> = contentChild(RtAiChatMessageExtraDirective);\n\n /** Ответы, у которых человек раскрыл шаги. */\n protected readonly openRuns: WritableSignal<ReadonlySet<string>> = signal<ReadonlySet<string>>(new Set<string>());\n\n protected readonly titleText: Signal<string> = computed((): string => this.title() || this.t().aiTitle);\n protected readonly emptyTitleText: Signal<string> = computed((): string => this.emptyTitle() || this.t().aiEmptyTitle);\n protected readonly emptyDescriptionText: Signal<string> = computed((): string => this.emptyDescription() || this.t().aiEmptyText);\n protected readonly disclaimerText: Signal<string> = computed((): string => this.disclaimer() ?? this.t().aiDisclaimer);\n\n protected readonly hasThreads: Signal<boolean> = computed((): boolean => this.threads() !== null);\n\n /** Список бесед стоит колонкой слева: на весь экран, когда беседы есть. */\n protected readonly isThreadColumn: Signal<boolean> = computed((): boolean => this.fullScreen() && this.hasThreads());\n\n /** Список бесед стоит на месте ленты: в узкой панели по кнопке «Conversations». */\n protected readonly isThreadPage: Signal<boolean> = computed(\n (): boolean => this.threadsOpen() && this.hasThreads() && !this.isThreadColumn()\n );\n\n protected readonly isEmpty: Signal<boolean> = computed(\n (): boolean => !this.loading() && !this.messages().length && this.error() === null\n );\n\n /** Строка поиска по беседам: подсвечивает совпадения и меняет подпись пустого списка. */\n protected readonly threadQuery: WritableSignal<string> = signal<string>('');\n\n protected readonly threadRows: Signal<readonly IThreadRow[]> = computed((): readonly IThreadRow[] => {\n const query: string = this.threadQuery();\n\n return (this.threads() ?? []).map((thread: IRtAiChat.Thread): IThreadRow => ({\n id: thread.id,\n hasUnread: (thread.unreadCount ?? 0) > 0,\n title: thread.title,\n titleParts: splitSideMenuTitle(thread.title, query),\n time: thread.time ?? '',\n unreadCount: thread.unreadCount ?? 0,\n }));\n });\n\n /** Пустой список: без поиска — «бесед нет», с поиском — подпись списка «ничего не найдено». */\n protected readonly threadsEmptyText: Signal<string> = computed((): string => (this.threadQuery() ? '' : this.t().aiNoThreads));\n\n /** Заголовок беседы над лентой; пусто — строки нет. */\n public readonly title: InputSignal<string> = input<string>('');\n\n /** Вторая строка шапки — обычно название беседы. Пусто — не рисуется. */\n public readonly subtitle: InputSignal<string> = input<string>('');\n\n public readonly messages: InputSignal<readonly IRtAiChat.Message[]> = input<readonly IRtAiChat.Message[]>([]);\n\n /** Готовые вопросы пустого экрана. */\n public readonly suggestions: InputSignal<readonly string[]> = input<readonly string[]>([]);\n\n public readonly emptyTitle: InputSignal<string> = input<string>('');\n\n public readonly emptyDescription: InputSignal<string> = input<string>('');\n\n /** Подсказка в поле сообщения; пусто — подпись поля кита. */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Подпись под полем сообщения; `null` — подпись кита, пустая строка — без подписи. */\n public readonly disclaimer: InputSignal<string | null> = input<string | null>(null);\n\n /** Ответ пишется: поле сообщения в режиме остановки, подсказки и новая беседа выключены. */\n public readonly sending: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Беседа загружается: крутилка, пока сообщений нет. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly error: InputSignal<IRtAiChat.RunError | null> = input<IRtAiChat.RunError | null>(null);\n\n /** Беседы; `null` — кнопки «Conversations» нет. */\n public readonly threads: InputSignal<readonly IRtAiChat.Thread[] | null> = input<readonly IRtAiChat.Thread[] | null>(null);\n\n public readonly activeThreadId: InputSignal<string | null> = input<string | null>(null);\n\n public readonly threadsLoading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly threadsFetching: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly threadsHasMore: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Значки декоративных строк-превью пустого списка бесед, по строке на значок. */\n public readonly emptyPreviewIcons: InputSignal<readonly IRtIcon.Name[]> = input<readonly IRtIcon.Name[]>(PREVIEW_ICONS);\n\n /** Кнопка «Full screen» в шапке. */\n public readonly fullScreenable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Кнопка закрытия в шапке. */\n public readonly closable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Черновик в поле сообщения. */\n public readonly draft: ModelSignal<string> = model<string>('');\n\n /** Список бесед открыт на месте ленты. */\n public readonly threadsOpen: ModelSignal<boolean> = model<boolean>(false);\n\n public readonly fullScreen: ModelSignal<boolean> = model<boolean>(false);\n\n /** Вопрос ушёл: набранный или выбранная подсказка. */\n public readonly send: OutputEmitterRef<string> = output<string>();\n\n public readonly stop: OutputEmitterRef<void> = output<void>();\n\n public readonly retry: OutputEmitterRef<void> = output<void>();\n\n public readonly newThread: OutputEmitterRef<void> = output<void>();\n\n public readonly closed: OutputEmitterRef<void> = output<void>();\n\n public readonly selectThread: OutputEmitterRef<string> = output<string>();\n\n public readonly deleteThread: OutputEmitterRef<string> = output<string>();\n\n public readonly searchThreads: OutputEmitterRef<string> = output<string>();\n\n public readonly loadMoreThreads: OutputEmitterRef<void> = output<void>();\n\n public readonly feedbackChange: OutputEmitterRef<IRtAiChat.FeedbackChange> = output<IRtAiChat.FeedbackChange>();\n\n constructor() {\n afterRenderEffect((): void => {\n this.messages();\n this.error();\n this.loading();\n this.isThreadPage();\n const el: HTMLElement | undefined = this.feed()?.nativeElement;\n if (el === undefined) {\n return;\n }\n if (this.#forceScroll || this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n this.#atBottom = true;\n this.#pinToBottomDeferred();\n }\n this.#forceScroll = false;\n });\n }\n\n /** Фокус в поле сообщения после отрисовки: приложению — после своих действий вне панели. */\n public focusComposer(): void {\n afterNextRender((): void => this.composer()?.focus(), { injector: this.#injector });\n }\n\n protected onFeedScroll(): void {\n const el: HTMLElement | undefined = this.feed()?.nativeElement;\n if (el === undefined) {\n return;\n }\n this.#atBottom = nextAtBottom(this.#atBottom, this.#lastScrollTop, el);\n this.#lastScrollTop = el.scrollTop;\n }\n\n protected onSubmitted(value: IRtMessageComposer.SubmitPayload): void {\n const text: string = value.text.trim();\n if (!text) {\n return;\n }\n this.#forceScroll = true;\n this.send.emit(text);\n }\n\n protected onSuggestion(text: string): void {\n this.#forceScroll = true;\n this.send.emit(text);\n }\n\n protected onToggleRun(messageId: string, open: boolean): void {\n this.openRuns.update((ids: ReadonlySet<string>): ReadonlySet<string> => {\n const next: Set<string> = new Set<string>(ids);\n if (open) {\n next.add(messageId);\n } else {\n next.delete(messageId);\n }\n return next;\n });\n }\n\n protected onFeedback(message: IRtAiChat.Message, feedback: Exclude<IRtAiChat.Feedback, null>): void {\n this.feedbackChange.emit({ messageId: message.id, feedback: message.feedback === feedback ? null : feedback });\n }\n\n protected onToggleThreads(): void {\n this.threadsOpen.set(!this.threadsOpen());\n\n if (this.threadsOpen()) {\n afterNextRender((): void => this.backButton()?.nativeElement.querySelector('button')?.focus(), { injector: this.#injector });\n } else {\n this.focusComposer();\n }\n }\n\n protected onNewThread(): void {\n this.newThread.emit();\n this.focusComposer();\n }\n\n protected onStop(): void {\n this.stop.emit();\n this.focusComposer();\n }\n\n protected onToggleFullScreen(): void {\n this.fullScreen.set(!this.fullScreen());\n }\n\n protected onSearchThreads(query: string): void {\n this.threadQuery.set(query);\n this.searchThreads.emit(query);\n }\n\n protected onSelectThread(id: IRtThreadList.TRowId): void {\n this.threadsOpen.set(false);\n this.#forceScroll = true;\n this.selectThread.emit(String(id));\n this.focusComposer();\n }\n\n #pinToBottomDeferred(): void {\n for (const delay of RT_CHAT_PIN_RETRY_DELAYS_MS) {\n setTimeout((): void => {\n const el: HTMLElement | undefined = this.feed()?.nativeElement;\n if (el !== undefined && this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n }\n }, delay);\n }\n }\n}\n","<ng-container rtBlock=\"rt-ai-chat\">\n @if (isThreadColumn()) {\n <aside rtElem=\"thread-column\" qa-dataid=\"ai-chat-thread-column\" [attr.aria-label]=\"t().aiThreads\">\n <div rtElem=\"column-head\">\n <span rtElem=\"column-title\">{{ t().aiThreads }}</span>\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n </div>\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n </aside>\n }\n\n <section rtElem=\"conversation\" qa-dataid=\"ai-chat\" [attr.aria-label]=\"titleText()\">\n <header rtElem=\"header\">\n @if (isThreadPage()) {\n <rt-icon-button\n #back\n qa-dataid=\"ai-chat-back\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"arrow-left\"\n [ariaLabel]=\"t().aiBackToChat\"\n [tooltip]=\"t().aiBackToChat\"\n (clicked)=\"onToggleThreads()\" />\n }\n\n <div rtElem=\"heading\">\n <span rtElem=\"title\" qa-dataid=\"ai-chat-title\">\n @if (!isThreadPage()) {\n <rt-icon name=\"sparkle\" size=\"sm\" color=\"primary\" aria-hidden=\"true\" />\n }\n {{ isThreadPage() ? t().aiThreads : titleText() }}\n </span>\n @if (!isThreadPage() && subtitle()) {\n <span rtElem=\"subtitle\" qa-dataid=\"ai-chat-subtitle\">{{ subtitle() }}</span>\n }\n </div>\n\n <div rtElem=\"actions\">\n @if (fullScreenable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-full-screen\"\n size=\"sm\"\n iconSize=\"sm\"\n [icon]=\"fullScreen() ? 'window-minimize' : 'fullscreen'\"\n [active]=\"fullScreen()\"\n [ariaLabel]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n [tooltip]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n (clicked)=\"onToggleFullScreen()\" />\n }\n @if (hasThreads() && !isThreadPage() && !isThreadColumn()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-threads\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"history\"\n [ariaLabel]=\"t().aiThreads\"\n [tooltip]=\"t().aiThreads\"\n (clicked)=\"onToggleThreads()\" />\n }\n @if (!isThreadColumn()) {\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n }\n @if (closable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-close\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"close\"\n [ariaLabel]=\"t().aiClose\"\n [tooltip]=\"t().aiClose\"\n (clicked)=\"closed.emit()\" />\n }\n </div>\n </header>\n\n @if (isThreadPage()) {\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n } @else {\n <div #feed rtElem=\"feed\" qa-dataid=\"ai-chat-feed\" aria-live=\"polite\" (scroll)=\"onFeedScroll()\">\n @if (loading() && !messages().length) {\n <rt-spinner rtElem=\"spinner\" appearance=\"arc\" [diameter]=\"32\" />\n } @else if (isEmpty()) {\n <div rtElem=\"empty\" qa-dataid=\"ai-chat-empty\">\n <rt-empty-state icon=\"comments\" [title]=\"emptyTitleText()\" [description]=\"emptyDescriptionText()\" />\n @if (suggestions().length) {\n <div rtElem=\"suggestions\">\n @for (suggestion of suggestions(); track suggestion) {\n <rt-prompt-suggestion\n qa-dataid=\"ai-chat-suggestion\"\n [label]=\"suggestion\"\n [disabled]=\"sending()\"\n (picked)=\"onSuggestion($event)\" />\n }\n </div>\n }\n </div>\n }\n\n @for (message of messages(); track message.id) {\n @if (message.role === 'user') {\n <div rtElem=\"question\" qa-dataid=\"ai-chat-question\">\n <div rtElem=\"bubble\">\n <span rtElem=\"author\">{{ t().aiYou }}</span>\n <p rtElem=\"bubble-text\">{{ message.text }}</p>\n @if (message.time) {\n <span rtElem=\"time\">{{ message.time }}</span>\n }\n </div>\n </div>\n } @else {\n <rt-ai-chat-answer\n qa-dataid=\"ai-chat-answer\"\n [message]=\"message\"\n [extra]=\"extraTemplate()?.templateRef ?? null\"\n [expanded]=\"openRuns().has(message.id)\"\n (expandedChange)=\"onToggleRun(message.id, $event)\"\n (feedbackChange)=\"onFeedback(message, $event)\" />\n }\n }\n\n @if (error(); as runError) {\n <div rtElem=\"error\" qa-dataid=\"ai-chat-error\" role=\"alert\">\n <rt-message severity=\"danger\">{{ runError.message }}</rt-message>\n @if (runError.referenceId) {\n <rt-copy-value [label]=\"t().aiReference\" [value]=\"runError.referenceId\" [copyLabel]=\"t().aiCopyReference\" />\n }\n @if (runError.retryable) {\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"ai-chat-retry\"\n appearance=\"text\"\n icon=\"sync\"\n size=\"sm\"\n [label]=\"t().aiRetry\"\n [attr.aria-label]=\"t().aiRetry\"\n [disabled]=\"sending()\"\n (click)=\"retry.emit()\"></button>\n }\n </div>\n }\n </div>\n\n <rt-message-composer\n rtElem=\"composer\"\n qa-dataid=\"ai-chat-composer\"\n stoppable\n [placeholder]=\"placeholder()\"\n [sending]=\"sending()\"\n [(text)]=\"draft\"\n (submitted)=\"onSubmitted($event)\"\n (stopped)=\"onStop()\" />\n\n @if (disclaimerText()) {\n <p rtElem=\"disclaimer\" qa-dataid=\"ai-chat-disclaimer\">{{ disclaimerText() }}</p>\n }\n }\n </section>\n</ng-container>\n\n<ng-template #newThreadButton>\n <rt-icon-button\n qa-dataid=\"ai-chat-new-thread\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"ico-plus\"\n [disabled]=\"sending()\"\n [ariaLabel]=\"t().aiNewThread\"\n [tooltip]=\"t().aiNewThread\"\n (clicked)=\"onNewThread()\" />\n</ng-template>\n\n<ng-template #threadList>\n <ng-container rtBlock=\"rt-ai-chat\">\n <rt-thread-list\n rtElem=\"threads\"\n qa-dataid=\"ai-chat-thread-list\"\n [rows]=\"threadRows()\"\n [activeId]=\"activeThreadId()\"\n [searchPlaceholder]=\"t().aiSearchThreads\"\n [emptyText]=\"threadsEmptyText()\"\n [emptyPreviewIcons]=\"emptyPreviewIcons()\"\n [loading]=\"threadsLoading()\"\n [fetching]=\"threadsFetching()\"\n [hasMore]=\"threadsHasMore()\"\n (selectRow)=\"onSelectThread($event)\"\n (searchChange)=\"onSearchThreads($event)\"\n (loadMore)=\"loadMoreThreads.emit()\">\n <ng-template let-row [rtThreadListRow]=\"threadRows()\">\n <span rtElem=\"thread-title\" qa-dataid=\"ai-chat-thread-title\" [attr.title]=\"row.title\">\n @for (part of row.titleParts; track $index) {\n <span rtElem=\"thread-part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n <span rtElem=\"thread-meta\">\n @if (row.unreadCount) {\n <span rtElem=\"thread-unread\" qa-dataid=\"ai-chat-thread-unread\">{{ row.unreadCount }}</span>\n }\n @if (row.time) {\n <span rtElem=\"thread-time\">{{ row.time }}</span>\n }\n </span>\n </ng-template>\n <ng-template let-row [rtThreadListRowActions]=\"threadRows()\">\n <rt-icon-button\n qa-dataid=\"ai-chat-delete-thread\"\n size=\"xs\"\n iconSize=\"sm\"\n icon=\"trash\"\n [disabled]=\"sending() && row.id === activeThreadId()\"\n [ariaLabel]=\"t().aiDeleteThread\"\n [tooltip]=\"t().aiDeleteThread\"\n (clicked)=\"deleteThread.emit(row.id)\" />\n </ng-template>\n </rt-thread-list>\n </ng-container>\n</ng-template>\n","/*\n * Вход @rt-tools/ui-kit-v2/rich-editor — компоненты, которые работают на библиотеке quill: редактор\n * текста, поле ввода сообщения и чат. Они стоят отдельным входом, чтобы приложение без них\n * собиралось без quill: из основного входа сборщик разрешал бы import('quill') всегда.\n */\n\nexport * from './lib/components/rich-editor';\nexport * from './lib/components/message-composer';\nexport * from './lib/components/chat';\nexport * from './lib/components/ai-chat';\nexport * from './lib/pipes';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["BEM_BLOCK"],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-rich-editor.mjs","sources":["../../../projects/ui-kit-v2/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/message-composer/rt-message-composer.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/message-composer/rt-message-composer.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-message-actions.directive.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-message-actions.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-message-actions.pipe.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat.model.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/pipes/rt-chat-status-label.pipe.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-files.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-thread.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat-typing.logic.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/rt-chat.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/chat/to-rt-message.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/copy/rt-ai-chat-copy.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/copy/rt-ai-chat-copy.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.html","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/rt-ai-chat.directives.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.ts","../../../projects/ui-kit-v2/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.html","../../../projects/ui-kit-v2/src/rich-editor/public-api.ts","../../../projects/ui-kit-v2/src/rich-editor/rt-tools-ui-kit-v2-rich-editor.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n InputSignal,\n OnDestroy,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport type Quill from 'quill';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { coerceQuillDeltaOutput, IQuillDelta, IQuillDeltaOp, RtFormControlBase } from '@rt-tools/ui-kit-v2';\n\nconst BEM_BLOCK: string = 'rt-rich-editor';\n\n/**\n * Режим тулбара: `full` — весь whitelist, `minimal` — жирный + два списка\n * (G113: чаты оператора/админа/саппорта).\n */\nexport type TRtRichEditorToolbar = 'full' | 'minimal';\n\n/** Модули тулбара — строго whitelist (без link/image/color/script). */\nconst TOOLBAR: Record<TRtRichEditorToolbar, readonly unknown[]> = {\n full: [\n ['bold', 'italic', 'underline', 'strike'],\n [{ header: 1 }, { header: 2 }, { header: 3 }],\n [{ list: 'ordered' }, { list: 'bullet' }],\n ['blockquote', 'code-block'],\n ],\n minimal: [['bold'], [{ list: 'ordered' }, { list: 'bullet' }]],\n};\n\n/** Форматы, которые Quill вообще примет (вставленное из буфера лишнее вырезается). */\nconst FORMATS: Record<TRtRichEditorToolbar, readonly string[]> = {\n full: ['bold', 'italic', 'underline', 'strike', 'header', 'list', 'blockquote', 'code-block'],\n minimal: ['bold', 'list'],\n};\n\ntype TQuillContentsArg = Parameters<Quill['setContents']>[0];\n\n/**\n * Rich-редактор чата на Quill. Наследует CVA-ядро input-семейства\n * (`RtFormControlBase`) — плагается в reactive-форму. Quill грузится **лениво**\n * (`import(\"quill\")` в `ngAfterViewInit`), тип импортируется `import type` и в\n * бандл не попадает. Значение CVA — `IQuillDelta` (или `null`, когда пусто).\n */\n@Component({\n selector: 'rt-rich-editor',\n templateUrl: './rt-rich-editor.component.html',\n styleUrl: './rt-rich-editor.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ],\n providers: [\n // Алиас базового токена — чтобы rt-field мог найти контрол через\n // contentChild(RtFormControlBase) (query по абстрактному классу).\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtRichEditorComponent) },\n ],\n host: {\n class: BEM_BLOCK,\n // Пока начинка редактора не смонтирована, хост несёт признак недостроенности: снаружи\n // недостроенный редактор ничем не отличается от достроенного пустого, и съёмка витрины\n // ловила именно этот промежуток — кадр выходил втрое ниже эталона.\n '[attr.data-rt-pending]': 'mounted() ? null : \"\"',\n },\n})\nexport class RtRichEditorComponent extends RtFormControlBase<IQuillDelta | null> implements AfterViewInit, OnDestroy {\n // `viewChild` не работает на ES-private (`#`) поле — держим `protected`.\n protected readonly editorHost: Signal<ElementRef<HTMLElement>> = viewChild.required<ElementRef<HTMLElement>>('editor');\n\n #quill: Quill | null = null;\n\n /** Значение, пришедшее через writeValue до готовности Quill. */\n #pending: IQuillDelta | null = null;\n\n /**\n * Смонтирована ли начинка редактора. Пока нет, хост несёт признак недостроенности: съёмке\n * витрины и любой другой проверке снаружи иначе нечем отличить недостроенный редактор от\n * достроенного пустого — оба выглядят пустым местом.\n */\n protected readonly mounted: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value() !== null);\n\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Набор кнопок форматирования; сужает и принимаемые форматы (вставка из буфера). */\n public readonly toolbar: InputSignal<TRtRichEditorToolbar> = input<TRtRichEditorToolbar>('full');\n\n /** Enter без Shift в редакторе — сигнал отправки (Shift+Enter остаётся переносом). */\n public readonly enterPressed: OutputEmitterRef<void> = output<void>();\n\n public readonly displayText: Signal<string> = computed((): string => {\n const delta: IQuillDelta | null = this.value();\n if (delta === null) {\n return '';\n }\n return delta.ops.map((op: IQuillDeltaOp): string => op.insert).join('');\n });\n\n public async ngAfterViewInit(): Promise<void> {\n const QuillCtor: typeof Quill = (await import('quill')).default;\n const quill: Quill = new QuillCtor(this.editorHost().nativeElement, {\n theme: 'snow',\n placeholder: this.placeholder(),\n formats: [...FORMATS[this.toolbar()]],\n modules: {\n toolbar: [...TOOLBAR[this.toolbar()]],\n keyboard: {\n bindings: {\n // Enter без Shift — отправка (перенос гасим возвратом false);\n // Shift+Enter не совпадает с биндингом и уходит в дефолт (перенос).\n enterSubmit: {\n key: 'Enter',\n shiftKey: false,\n handler: (): boolean => {\n this.enterPressed.emit();\n return false;\n },\n },\n },\n },\n },\n });\n this.#quill = quill;\n if (this.#pending !== null) {\n quill.setContents(this.#pending as unknown as TQuillContentsArg);\n this.#pending = null;\n }\n if (this.isDisabled()) {\n quill.disable();\n }\n quill.on('text-change', (): void => this.#onEditorChange());\n this.mounted.set(true);\n }\n\n /** Ставит фокус в редактор; до загрузки Quill ничего не делает. */\n public focus(): void {\n this.#quill?.focus();\n }\n\n public ngOnDestroy(): void {\n this.#quill = null;\n this.mounted.set(false);\n }\n\n public override writeValue(value: IQuillDelta | null): void {\n super.writeValue(value);\n if (this.#quill === null) {\n this.#pending = value;\n return;\n }\n this.#quill.setContents((value ?? { ops: [] }) as unknown as TQuillContentsArg);\n }\n\n public override setDisabledState(isDisabled: boolean): void {\n super.setDisabledState(isDisabled);\n if (this.#quill === null) {\n return;\n }\n if (isDisabled) {\n this.#quill.disable();\n return;\n }\n this.#quill.enable();\n }\n\n protected getEmptyValue(): IQuillDelta | null {\n return null;\n }\n\n protected focusAfterClear(): void {\n this.#quill?.focus();\n }\n\n /** Text-change: пустой слепок → null-канал; иначе delta. */\n #onEditorChange(): void {\n if (this.#quill === null) {\n return;\n }\n const blank: boolean = this.#quill.getText().trim().length === 0;\n const next: IQuillDelta | null = blank\n ? null\n : coerceQuillDeltaOutput({\n ops: this.#quill.getContents().ops as unknown as IQuillDeltaOp[],\n });\n this.value.set(next);\n this.emitChange(next);\n this.markTouched();\n }\n}\n","<ng-container rtBlock=\"rt-rich-editor\">\n <div #editor rtElem=\"surface\" qa-dataid=\"rich-editor-surface\"></div>\n</ng-container>\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { CdkTextareaAutosize } from '@angular/cdk/text-field';\nimport {\n booleanAttribute,\n computed,\n effect,\n inject,\n input,\n model,\n numberAttribute,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { IQuillDelta, RT_KIT_LABELS, RtFileCardComponent, RtIconButtonComponent, rtKitLabel, TRtKitLabelMap } from '@rt-tools/ui-kit-v2';\n\nimport { RtRichEditorComponent, TRtRichEditorToolbar } from '../rich-editor/rt-rich-editor.component';\nimport { IRtMessageComposer } from './rt-message-composer.model';\n\nconst BEM_BLOCK: string = 'rt-message-composer';\n\n/** Текст в поле выше полутора строк — он перенёсся, и капсула берёт скругление высокой. */\nfunction rtComposerWraps(node: HTMLTextAreaElement): boolean {\n const style: CSSStyleDeclaration = getComputedStyle(node);\n const line: number = parseFloat(style.lineHeight) || parseFloat(style.fontSize) * 1.5;\n const text: number = node.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);\n return text > line * 1.5;\n}\n\ninterface IComposerFormShape {\n message: FormControl<string>;\n files: FormControl<File[]>;\n delta: FormControl<IQuillDelta | null>;\n}\n\n/**\n * Композер сообщения — капсула: слева круглая кнопка вложения, по центру авто-растущая\n * textarea, справа круглая кнопка отправки; вложения стоят внутри капсулы над строкой.\n * Презентационный, без data-access: наружу торчит только `submitted` с текстом и файлами.\n *\n * Отправка — `Enter` (без Shift) или клик по иконке; `Shift+Enter` — перенос\n * строки. Кнопка отправки активна, пока есть непустой текст или вложения.\n *\n * Со `stoppable` во время `sending` вместо стрелки стоит кнопка «Стоп», а поле\n * остаётся открытым: следующий вопрос набирается, пока идёт ответ.\n */\n@Component({\n selector: 'rt-message-composer',\n templateUrl: './rt-message-composer.component.html',\n styleUrl: './rt-message-composer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n ReactiveFormsModule,\n\n // cdk\n CdkTextareaAutosize,\n\n // standalone components / directives\n RtFileCardComponent,\n RtIconButtonComponent,\n RtRichEditorComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtMessageComposerComponent {\n readonly #formValue: Signal<Partial<{ message: string; files: File[]; delta: IQuillDelta | null }>>;\n\n readonly #t_chatPlaceholder: Signal<string> = rtKitLabel('chatPlaceholder');\n\n /** Текст перенёсся на вторую строку — меряется по высоте textarea после отрисовки. */\n readonly #multiRow: WritableSignal<boolean> = signal(false);\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.#t_chatPlaceholder());\n\n protected readonly fileInput: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fileEl');\n\n protected readonly textInput: Signal<ElementRef<HTMLTextAreaElement> | undefined> =\n viewChild<ElementRef<HTMLTextAreaElement>>('textEl');\n\n protected readonly richEditor: Signal<RtRichEditorComponent | undefined> = viewChild(RtRichEditorComponent);\n\n protected readonly form: FormGroup<IComposerFormShape> = new FormGroup<IComposerFormShape>({\n message: new FormControl<string>('', { nonNullable: true }),\n files: new FormControl<File[]>([], { nonNullable: true }),\n delta: new FormControl<IQuillDelta | null>(null),\n });\n\n protected readonly files: Signal<readonly File[]> = computed((): readonly File[] => this.#formValue().files ?? []);\n\n /** Отправка доступна: есть контент (текст/delta/файлы), композер не занят. */\n protected readonly canSend: Signal<boolean> = computed((): boolean => {\n if (this.sending() || this.disabled()) {\n return false;\n }\n const value: Partial<{ message: string; files: File[]; delta: IQuillDelta | null }> = this.#formValue();\n const hasFiles: boolean = this.attachments() && (value.files?.length ?? 0) > 0;\n if (this.formatting()) {\n return (value.delta ?? null) !== null || hasFiles;\n }\n const hasText: boolean = (value.message ?? '').trim().length > 0;\n return hasText || hasFiles;\n });\n\n /** Капсула выше одной строки: перенос текста, вложения или режим форматирования. */\n protected readonly tall: Signal<boolean> = computed(\n (): boolean => this.#multiRow() || this.formatting() || (this.attachments() && this.files().length > 0)\n );\n\n /** Идёт ответ, который можно остановить: вместо стрелки — «Стоп», поле открыто. */\n protected readonly isStoppable: Signal<boolean> = computed((): boolean => this.stoppable() && this.sending() && !this.disabled());\n\n protected readonly capsuleMods: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n tall: this.tall(),\n disabled: this.disabled(),\n }));\n\n /** Текст-подсказка textarea. Пусто — берётся переведённое умолчание. */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Фильтр типов для file-input (`.pdf,.doc,...`). */\n public readonly accept: InputSignal<string> = input<string>('');\n\n /** Строка под капсулой про Enter и Shift + Enter. */\n public readonly hint: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку вложения и список файлов. */\n public readonly attachments: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Отправка в процессе — блокирует submit, кнопка отправки крутит индикатор. */\n public readonly sending: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Ответ на сообщение можно остановить. Во время `sending` стрелку сменяет кнопка\n * «Стоп», а поле не блокируется; без входа `sending` блокирует поле, как раньше.\n */\n public readonly stoppable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Полная блокировка композера. */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Rich-режим: вместо textarea — Quill-редактор, отправка уходит delta-каналом. */\n public readonly formatting: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Набор кнопок rich-редактора (проброс в `rt-rich-editor`). */\n public readonly toolbar: InputSignal<TRtRichEditorToolbar> = input<TRtRichEditorToolbar>('full');\n\n /** Минимальная высота textarea в строках. */\n public readonly minRows: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(1, { transform: numberAttribute });\n\n /** Максимальная высота textarea в строках (дальше — скролл). */\n public readonly maxRows: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(6, { transform: numberAttribute });\n\n /**\n * Файлы, выброшенные drag-n-drop'ом в обёртку чата: пробрасываются сюда как\n * вложения. Каждый физический drop даёт новый массив, поэтому effect\n * перезапускается на каждое перетаскивание; файлы добавляются к уже выбранным.\n */\n public readonly droppedFiles: InputSignal<File[] | null> = input<File[] | null>(null);\n\n /** Отправка сообщения: текст + файлы (последние — только при `attachments`). */\n public readonly submitted: OutputEmitterRef<IRtMessageComposer.SubmitPayload> = output<IRtMessageComposer.SubmitPayload>();\n\n /** Черновик поля без форматирования: задаётся снаружи, правки уходят наружу, после отправки пуст. */\n public readonly text: ModelSignal<string> = model<string>('');\n\n /** Клик по кнопке «Стоп» во время ответа, который можно остановить. */\n public readonly stopped: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n this.#formValue = toSignal(this.form.valueChanges, {\n initialValue: this.form.value,\n });\n\n effect((): void => {\n const draft: string = this.text();\n if (this.form.controls.message.value !== draft) {\n this.form.controls.message.setValue(draft);\n }\n });\n\n this.form.controls.message.valueChanges.pipe(takeUntilDestroyed()).subscribe((value: string): void => this.text.set(value));\n\n effect((): void => {\n const blocked: boolean = this.disabled() || (this.sending() && !this.stoppable());\n if (blocked && this.form.enabled) {\n this.form.disable({ emitEvent: false });\n }\n if (!blocked && this.form.disabled) {\n this.form.enable({ emitEvent: false });\n }\n });\n\n // Поле пересоздаётся при смене режима форматирования: наблюдатель идёт за текущим узлом.\n effect((onCleanup: (fn: () => void) => void): void => {\n const node: HTMLTextAreaElement | undefined = this.textInput()?.nativeElement;\n if (!node || typeof ResizeObserver === 'undefined') {\n this.#multiRow.set(false);\n return;\n }\n const observer: ResizeObserver = new ResizeObserver((): void => this.#multiRow.set(rtComposerWraps(node)));\n observer.observe(node);\n onCleanup((): void => observer.disconnect());\n });\n\n effect((): void => {\n const dropped: File[] | null = this.droppedFiles();\n if (dropped !== null && dropped.length > 0 && this.attachments()) {\n this.form.controls.files.setValue([...this.form.controls.files.value, ...dropped]);\n }\n });\n }\n\n /** Ставит фокус в поле: в textarea, а в режиме форматирования — в rich-редактор. */\n public focus(): void {\n if (this.formatting()) {\n this.richEditor()?.focus();\n return;\n }\n this.textInput()?.nativeElement.focus();\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n // Enter без модификаторов — отправка; Shift+Enter оставляем переносом строки.\n // isComposing — не перехватываем подтверждение IME-композиции.\n if (event.key === 'Enter' && !event.shiftKey && !event.isComposing) {\n event.preventDefault();\n this.submit();\n }\n }\n\n protected stop(): void {\n if (this.isStoppable()) {\n this.stopped.emit();\n }\n }\n\n protected openPicker(): void {\n if (this.disabled() || this.sending()) {\n return;\n }\n this.fileInput()?.nativeElement.click();\n }\n\n protected onFilesPicked(event: Event): void {\n const el: HTMLInputElement = event.target as HTMLInputElement;\n const picked: File[] = el.files ? Array.from(el.files) : [];\n if (picked.length) {\n this.form.controls.files.setValue([...this.form.controls.files.value, ...picked]);\n }\n // Сброс value — чтобы повторный выбор того же файла снова дал change-событие.\n el.value = '';\n }\n\n protected removeFile(index: number): void {\n const next: File[] = this.form.controls.files.value.filter((_: File, i: number): boolean => i !== index);\n this.form.controls.files.setValue(next);\n }\n\n protected submit(): void {\n if (!this.canSend()) {\n return;\n }\n const files: File[] = this.attachments() ? this.form.controls.files.value : [];\n if (this.formatting()) {\n const delta: IQuillDelta | null = this.form.controls.delta.value;\n this.submitted.emit({\n text: '',\n delta: delta === null ? null : JSON.stringify(delta),\n files,\n });\n } else {\n const text: string = this.form.controls.message.value.trim();\n this.submitted.emit({ text, files });\n }\n this.form.reset({ message: '', files: [], delta: null });\n }\n}\n","<ng-container rtBlock=\"rt-message-composer\" [formGroup]=\"form\">\n <div rtElem=\"capsule\" qa-dataid=\"message-composer-capsule\" [rtMod]=\"capsuleMods()\">\n @if (attachments() && files().length) {\n <div rtElem=\"files\" qa-dataid=\"message-composer-files\">\n @for (file of files(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"message-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"disabled() || sending()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n\n @if (formatting()) {\n <rt-rich-editor\n rtElem=\"rich\"\n qa-dataid=\"message-composer-rich\"\n formControlName=\"delta\"\n [placeholder]=\"placeholderText()\"\n [toolbar]=\"toolbar()\"\n (enterPressed)=\"submit()\" />\n }\n\n <div rtElem=\"row\">\n @if (attachments()) {\n <input\n #fileEl\n qa-dataid=\"message-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"message-composer-attach\"\n icon=\"paperclip\"\n iconColor=\"muted\"\n radius=\"full\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"disabled() || sending()\"\n (clicked)=\"openPicker()\" />\n }\n\n @if (!formatting()) {\n <textarea\n #textEl\n rtElem=\"input\"\n qa-dataid=\"message-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholderText()\"\n [cdkAutosizeMinRows]=\"minRows()\"\n [cdkAutosizeMaxRows]=\"maxRows()\"\n (keydown)=\"onKeydown($event)\"></textarea>\n }\n\n @if (isStoppable()) {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-stop\"\n icon=\"stop\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatStopAria\"\n [tooltip]=\"t().chatStopLabel\"\n (clicked)=\"stop()\" />\n } @else {\n <rt-icon-button\n rtElem=\"send\"\n qa-dataid=\"message-composer-send\"\n icon=\"arrow-up\"\n radius=\"full\"\n variant=\"primary\"\n [ariaLabel]=\"t().chatSendAria\"\n [tooltip]=\"t().chatSendLabel\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"\n (clicked)=\"submit()\" />\n }\n </div>\n </div>\n\n @if (hint()) {\n <p rtElem=\"hint\" qa-dataid=\"message-composer-hint\">{{ t().chatComposerHint }}</p>\n }\n</ng-container>\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { IRtChat } from './rt-chat.model';\n\n/**\n * Контекст шаблона `[rtChatMessageActions]`: `$implicit` — реплика треда.\n */\nexport interface IRtChatMessageActionsContext {\n $implicit: IRtChat.Message;\n}\n\n/**\n * Захватывает `<ng-template rtChatMessageActions let-message>` — содержимое «…»-меню\n * действий у реплики. `rt-chat` рисует этот шаблон рядом с точечными действиями реплики,\n * прокидывая её через `$implicit`.\n *\n * Точечные действия остаются на месте: удаление, повтор отправки и скачивание общи для\n * любой переписки. Шаблон нужен тем действиям, которых кит не знает и знать не должен, —\n * без него потребителю оставалось ждать правки кита либо ставить кнопку над диалогом, то\n * есть не там, где читают реплику.\n *\n * Дженерика у контекста нет: тип реплики у переписки один, и type-carrier, который у\n * строки таблицы несёт тип строки, здесь не нужен.\n *\n * @example\n * ```html\n * <rt-chat [messages]=\"messages()\" [messageHasActions]=\"canAct\">\n * <ng-template rtChatMessageActions let-message>\n * <rt-menu-item icon=\"link\" label=\"Скопировать ссылку\" (selected)=\"copy(message)\" />\n * </ng-template>\n * </rt-chat>\n * ```\n */\n@Directive({\n selector: 'ng-template[rtChatMessageActions]',\n})\nexport class RtChatMessageActionsDirective {\n public readonly template: TemplateRef<IRtChatMessageActionsContext> = inject<TemplateRef<IRtChatMessageActionsContext>>(TemplateRef);\n\n /** Type-guard: сужает контекст шаблона до реплики при проверке шаблонов. */\n public static ngTemplateContextGuard(\n _directive: RtChatMessageActionsDirective,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtChatMessageActionsContext {\n return true;\n }\n}\n","import { IRtChat } from './rt-chat.model';\n\n/**\n * Есть ли у реплики хотя бы одно доступное действие потребителя.\n *\n * Признак приходит предикатом от экрана, а не подсчётом отрисованных пунктов меню:\n * содержимое спроецированного шаблона известно только после отрисовки, и кнопка\n * успевала бы мигнуть на первом кадре.\n *\n * Предикат не задан — у реплики есть действия: экран, который ничего не гейтит,\n * показывает кнопку меню. Так же это устроено у строки таблицы, и расхождение между\n * двумя точками проекции одного кита читалось бы дефектом.\n */\nexport function messageHasAvailableActions(message: IRtChat.Message, hasActions: IRtChat.MessageActionsPredicate | null): boolean {\n return hasActions === null ? true : hasActions(message);\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { messageHasAvailableActions } from './rt-chat-message-actions.logic';\nimport { IRtChat } from './rt-chat.model';\n\n/**\n * Есть ли у реплики доступные действия — гейт кнопки «…» у неё.\n *\n * Pure-pipe: пересчитывается только при смене реплики или предиката, а не на каждом\n * цикле проверки. Значение приходит из контекста шаблона (реплика треда), поэтому\n * `computed()` здесь неприменим.\n */\n@Pipe({ name: 'rtChatMessageHasActions' })\nexport class RtChatMessageHasActionsPipe implements PipeTransform {\n public transform(message: IRtChat.Message, hasActions: IRtChat.MessageActionsPredicate | null): boolean {\n return messageHasAvailableActions(message, hasActions);\n }\n}\n","import { IQuillDelta } from '@rt-tools/ui-kit-v2';\n\n/**\n * Модель общего чат-компонента `rt-chat`: один корневой неймспейс\n * с префиксом `I`. Доменные стора маппят свою модель сообщения в `Message`, а сам\n * `rt-chat` ничего не знает о доменных сущностях — только рисует тред и композер.\n */\n/**\n * Судьба своего сообщения в ленте: пока летит на сервер — часы, после записи —\n * двойной чек, после того как собеседник открыл переписку — тот же чек синим,\n * при обрыве — «!» с повтором. Входящие сообщения статуса не имеют.\n */\nexport enum ERtChatMessageStatus {\n Sending = 'sending',\n Sent = 'sent',\n Read = 'read',\n Failed = 'failed',\n}\n\nexport namespace IRtChat {\n /** Алиас enum'а для доменных мапперов, работающих через неймспейс. */\n export type MessageStatus = ERtChatMessageStatus;\n\n /**\n * Есть ли у реплики доступные действия потребителя — гейт кнопки «…» у неё.\n *\n * Признак приходит предикатом, а не полем модели: действие, которого кит не знает,\n * его моделью и не описывается.\n */\n export type MessageActionsPredicate = (message: Message) => boolean;\n\n /** Вложение сообщения — домен маппит свой ресурс, скачивание по `public_id`. */\n export interface Attachment {\n id: number;\n /** Обезличенное имя для карточки файла. */\n name: string;\n /** Непрозрачный идентификатор файла — консюмер качает blob по нему. */\n publicId: string;\n }\n\n /**\n * Одно сообщение треда в уже подготовленной для отображения форме: автор —\n * готовый лейбл (домен решает, как его собрать), `own`/`system` — флаги\n * выравнивания и стиля, дата — ISO-строка (форматируется `DatePipe` внутри).\n */\n export interface Message {\n /** Идентификатор сообщения — ключ `@for track`. */\n id: number | string;\n /** Клиентский временный id оптимистичного сообщения (до ответа сервера). */\n tempId?: string;\n /**\n * Статус своего сообщения. Отсутствует у входящих: чужому сообщению\n * нечего сообщать о доставке.\n */\n status?: MessageStatus;\n /** Готовый лейбл автора (доменный authorLabel). */\n author: string;\n /** Сообщение текущего пользователя — выравнивается вправо, акцентный фон. */\n own: boolean;\n /** Признак системного сообщения (рендерится обычным входящим пузырём). */\n system?: boolean;\n text: string;\n /**\n * Rich-тело (Quill delta) — при наличии рендерится вместо plain `text`\n * через `rt-delta-view`. `null`/отсутствует ⇒ показываем `text`.\n */\n delta?: IQuillDelta | null;\n /** ISO-дата создания. */\n createdAt: string;\n /** URL вложения (если есть) — наличие включает карточку файла. */\n fileUrl?: string | null;\n /** Имя вложения для отображения в карточке. */\n fileName?: string | null;\n /**\n * Вложения сообщения (несколько файлов). Непустой массив имеет приоритет\n * над legacy-парой `fileUrl`/`fileName` (та равна первому вложению).\n */\n attachments?: readonly Attachment[];\n /** Внешняя ссылка-призыв (привязка Telegram) — наличие включает кнопку-ссылку. */\n deepLink?: string | null;\n /** Подпись кнопки-ссылки `deepLink` (домен решает текст по состоянию). */\n deepLinkLabel?: string | null;\n /** Сообщение помечено удалённым — рендерится плейсхолдером вместо содержимого. */\n deleted?: boolean;\n /** Показать действие «удалить» на этом сообщении (домен решает по правам/направлению). */\n canDelete?: boolean;\n /**\n * Текст подтверждения перед удалением. Задан — клик по корзине открывает\n * confirm-попап с этим текстом, удаление уходит только после подтверждения.\n * Пусто/undefined — удаление сразу по клику (домен без confirm-семантики).\n */\n deleteConfirm?: string;\n }\n\n /** Payload отправки: текст + файлы (пусто/undefined, если вложения выключены). */\n export interface SendPayload {\n text: string;\n files?: File[];\n /**\n * Rich-тело строкой JSON (`JSON.stringify(getContents())`) — взаимоисключимо\n * с непустым `text`. При наличии домен шлёт delta-канал (`message:\"\"`).\n */\n delta?: string | null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { ERtChatMessageStatus } from '../components/chat/rt-chat.model';\n\n/**\n * Ключи подписей статусов для скринридера: сам индикатор — иконка, и без текста\n * различие «доставлено/прочитано» слышно не будет.\n *\n * Пайп отдаёт ключ, а переводит его `transloco` следующим звеном цепочки.\n * Готовый текст здесь застыл бы на языке, активном в момент загрузки модуля.\n */\nconst STATUS_KEYS: Readonly<Record<ERtChatMessageStatus, string>> = {\n [ERtChatMessageStatus.Sending]: 'rtKit.chatStatusSending',\n [ERtChatMessageStatus.Sent]: 'rtKit.chatStatusSent',\n [ERtChatMessageStatus.Read]: 'rtKit.chatStatusRead',\n [ERtChatMessageStatus.Failed]: 'rtKit.chatStatusFailed',\n};\n\n/** Ключ текстовой расшифровки иконки статуса сообщения. */\n@Pipe({ name: 'rtChatStatusLabel' })\nexport class RtChatStatusLabelPipe implements PipeTransform {\n public transform(status: ERtChatMessageStatus): string {\n return STATUS_KEYS[status];\n }\n}\n","/** Выбранные файлы вместе с только что добавленными. Список всегда новый: его читает сигнал. */\nexport function withAppendedFiles(current: ReadonlyArray<File>, added: ReadonlyArray<File>): File[] {\n return [...current, ...added];\n}\n\n/** Выбранные файлы без того, что стоит на этом месте. */\nexport function withoutFileAt(current: ReadonlyArray<File>, index: number): File[] {\n return current.filter((_: File, position: number): boolean => position !== index);\n}\n\n/** Файлы, названные полем выбора. Поле без выбора отдаёт пустой список, а не отсутствие. */\nexport function pickedFiles(files: FileList | null): File[] {\n return Array.from(files ?? []);\n}\n","/** Замеры прокрутки треда: столько, сколько нужно решению о прилипании к низу. */\nexport interface IRtChatThreadMetrics {\n scrollTop: number;\n scrollHeight: number;\n clientHeight: number;\n}\n\n/** Зазор от низа треда, в пределах которого читатель считается стоящим у нижнего края. */\nexport const RT_CHAT_NEAR_BOTTOM_THRESHOLD_PX: number = 64;\n\n/**\n * Задержки повторных подтягиваний ленты к низу после первой прокрутки. Присланное\n * содержимое дорисовывается несколькими проходами уже после того, как лента встала по\n * промежуточной высоте, и набор тиков покрывает окно, за которое высота устаканивается.\n */\nexport const RT_CHAT_PIN_RETRY_DELAYS_MS: ReadonlyArray<number> = [50, 150, 300, 500, 800];\n\n/** Стоит ли читатель у нижнего края треда. */\nexport function isNearBottom(metrics: IRtChatThreadMetrics): boolean {\n return metrics.scrollHeight - metrics.clientHeight - metrics.scrollTop <= RT_CHAT_NEAR_BOTTOM_THRESHOLD_PX;\n}\n\n/**\n * Прилипает ли лента к низу после этой прокрутки.\n *\n * Прилипание снимается только тогда, когда читатель уехал вверх сам. Прокрутка, сделанная\n * самим компонентом, и рост содержимого приходят с тем же или большим положением — на них\n * прилипание лишь подтверждается: иначе позднее событие от собственной прокрутки читалось бы\n * отрывом от низа, и лента переставала бы догонять последнее сообщение.\n */\nexport function nextAtBottom(previous: boolean, lastScrollTop: number, metrics: IRtChatThreadMetrics): boolean {\n const nearBottom: boolean = isNearBottom(metrics);\n\n return metrics.scrollTop < lastScrollTop - 1 ? nearBottom : previous || nearBottom;\n}\n","import { inject, DestroyRef } from '@angular/core';\n\n/** Пауза без ввода, после которой отрезок набора считается законченным. */\nexport const RT_CHAT_TYPING_PAUSE_MS: number = 3000;\n\n/**\n * Текст поля ответа из узла, где случился ввод. Поле обычного режима — textarea, поле с\n * оформлением — редактируемый узел; всё прочее, например выбор файла, набором не считается и\n * даёт `null`.\n */\nexport function typingDraft(target: EventTarget | null): string | null {\n if (target instanceof HTMLTextAreaElement) {\n return target.value;\n }\n const editor: Element | null = target instanceof HTMLElement ? target.closest('[contenteditable=\"true\"]') : null;\n return editor === null ? null : (editor.textContent ?? '');\n}\n\n/**\n * Отрезок набора: одно «начал» и одно «перестал» на отрезок, а не событие на каждую клавишу.\n * Отрезок кончается пустым полем, отправкой или паузой без ввода. Создаётся в контексте\n * внедрения: таймер паузы снимается вместе с компонентом, и выход уничтоженного компонента не\n * зовётся.\n */\nexport class RtChatTypingTracker {\n #typing: boolean = false;\n\n #timer: ReturnType<typeof setTimeout> | null = null;\n\n readonly #notify: (typing: boolean) => void;\n\n readonly #pauseMs: number;\n\n constructor(notify: (typing: boolean) => void, pauseMs: number = RT_CHAT_TYPING_PAUSE_MS) {\n this.#notify = notify;\n this.#pauseMs = pauseMs;\n inject(DestroyRef).onDestroy((): void => this.#clearTimer());\n }\n\n /** Ввод в поле ответа с его текущим текстом: пустой текст кончает отрезок. */\n public input(draft: string): void {\n if (draft.trim().length === 0) {\n this.stop();\n return;\n }\n if (!this.#typing) {\n this.#typing = true;\n this.#notify(true);\n }\n this.#clearTimer();\n this.#timer = setTimeout((): void => this.stop(), this.#pauseMs);\n }\n\n /** Конец отрезка; отрезок, который уже кончился, ничего не шлёт. */\n public stop(): void {\n this.#clearTimer();\n if (this.#typing) {\n this.#typing = false;\n this.#notify(false);\n }\n }\n\n #clearTimer(): void {\n if (this.#timer !== null) {\n clearTimeout(this.#timer);\n this.#timer = null;\n }\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { CdkTextareaAutosize } from '@angular/cdk/text-field';\nimport { DatePipe } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\n\nimport { NgTemplateOutlet } from '@angular/common';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport {\n RtButtonDirective,\n RtConfirmDirective,\n RtDeltaViewComponent,\n RtFileCardComponent,\n RtFileDropComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtMenuComponent,\n RtNoteComponent,\n RtSkeletonWrapperComponent,\n RtSpinnerComponent,\n RtToolbarComponent,\n RtToolbarLeftDirective,\n RtToolbarRightDirective,\n} from '@rt-tools/ui-kit-v2';\nimport { RT_KIT_LABELS, RT_KIT_LOCALE, rtKitLabel, TRtKitLabelKey, TRtKitLabelMap } from '@rt-tools/ui-kit-v2';\nimport { RtChatMessageActionsDirective } from './rt-chat-message-actions.directive';\nimport { RtChatMessageHasActionsPipe } from './rt-chat-message-actions.pipe';\nimport { RtChatStatusLabelPipe } from '../../pipes/rt-chat-status-label.pipe';\nimport { RtMessageComposerComponent } from '../message-composer/rt-message-composer.component';\nimport { IRtMessageComposer } from '../message-composer/rt-message-composer.model';\nimport { TRtRichEditorToolbar } from '../rich-editor/rt-rich-editor.component';\nimport { pickedFiles, withAppendedFiles, withoutFileAt } from './rt-chat-files.logic';\nimport { nextAtBottom, RT_CHAT_PIN_RETRY_DELAYS_MS } from './rt-chat-thread.logic';\nimport { typingDraft, RtChatTypingTracker } from './rt-chat-typing.logic';\nimport { ERtChatMessageStatus, IRtChat } from './rt-chat.model';\n\nconst BEM_BLOCK: string = 'rt-chat';\n\n/** Ключ заглушки имени вложения, когда домен не отдал `fileName` (только URL). */\nconst ATTACHMENT_FALLBACK_KEY: TRtKitLabelKey = 'chatAttachmentFallback';\n\n/**\n * Общий презентационный чат: тред сообщений + композер. История приходит готовым массивом\n * `IRtChat.Message[]`, отправка, обновление, скачивание и набор текста уходят наружу выходами;\n * стор и blob-загрузка остаются у потребителя. Композер держит свой `FormGroup`. Полноэкранный\n * режим — overlay внутри компонента (`--expanded`). Шапка рисуется, только когда включена хотя бы\n * одна из иконок `showRefresh`/`showExpand`: в диалогах своя header-обёртка.\n */\n@Component({\n selector: 'rt-chat',\n templateUrl: './rt-chat.component.html',\n styleUrls: ['./rt-chat.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n CdkTextareaAutosize,\n DatePipe,\n NgTemplateOutlet,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtButtonDirective,\n RtChatStatusLabelPipe,\n RtConfirmDirective,\n RtDeltaViewComponent,\n RtFileCardComponent,\n RtFileDropComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtChatMessageHasActionsPipe,\n RtMenuComponent,\n RtMessageComposerComponent,\n RtNoteComponent,\n RtSkeletonWrapperComponent,\n RtSpinnerComponent,\n RtToolbarComponent,\n RtToolbarLeftDirective,\n RtToolbarRightDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-chat--expanded]': 'expanded()',\n '[class.rt-chat--fill]': 'fill()',\n },\n})\nexport class RtChatComponent {\n /**\n * Дата форматируется по активной локали приложения, а не по `LOCALE_ID`: тот вычисляется на\n * подъёме и при смене языка на ходу оставил бы прежний формат. Данные локали для `DatePipe`\n * регистрирует приложение: без них пайп падает `Missing locale data`.\n */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly locale: Signal<string> = inject(RT_KIT_LOCALE);\n\n /** Читатель у нижнего края. Плоское поле, не сигнал: afterRenderEffect не перезапускается на scroll. */\n #atBottom: boolean = true;\n\n /** Прошлый scrollTop треда — для различения прокрутки вверх и роста контента. */\n #lastScrollTop: number = 0;\n\n /** One-shot: своё отправленное сообщение всегда прокручивает тред вниз. */\n #forceScroll: boolean = false;\n\n /** Отрезок набора в поле ответа: наружу уходит одно «начал» и одно «перестал» на отрезок. */\n readonly #typingTracker: RtChatTypingTracker = new RtChatTypingTracker((typing: boolean): void => this.typing.emit(typing));\n\n /** Текущее значение композера — источник реактивности для `canSend`. */\n readonly #formValue: Signal<Partial<{ message: string; files: File[] }>>;\n\n /**\n * Скролл-контейнер треда — для автопрокрутки к последнему сообщению.\n * `viewChild` не работает на ES-private (`#`) поле, поэтому `protected`.\n */\n protected readonly thread: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('thread');\n\n /** Скрытый нативный input — открывается кнопкой-скрепкой внутри поля ввода. */\n protected readonly composerFileEl: Signal<ElementRef<HTMLInputElement> | undefined> =\n viewChild<ElementRef<HTMLInputElement>>('composerFileEl');\n\n protected readonly attachmentFallbackName: Signal<string> = rtKitLabel(ATTACHMENT_FALLBACK_KEY);\n\n /** Подписи с учётом того, что передал хозяин компонента: своё важнее умолчания */\n protected readonly titleText: Signal<string> = computed((): string => this.title() || this.#defaultTitle());\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.#defaultPlaceholder());\n protected readonly emptyHintText: Signal<string> = computed((): string => this.emptyHint() || this.#defaultEmptyHint());\n\n readonly #defaultTitle: Signal<string> = rtKitLabel('chatTitle');\n readonly #defaultPlaceholder: Signal<string> = rtKitLabel('chatPlaceholder');\n readonly #defaultEmptyHint: Signal<string> = rtKitLabel('chatEmptyHint');\n\n protected readonly MessageStatus: typeof ERtChatMessageStatus = ERtChatMessageStatus;\n\n /** Плейсхолдеры скелетонов треда при первичной загрузке. */\n protected readonly skeletonRows: readonly number[] = [1, 2, 3];\n\n /** Полноэкранный режим (overlay поверх страницы). */\n protected readonly expanded: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly replyForm: FormGroup<{\n message: FormControl<string>;\n files: FormControl<File[]>;\n }> = new FormGroup({\n message: new FormControl<string>('', { nonNullable: true }),\n files: new FormControl<File[]>([], { nonNullable: true }),\n });\n\n /** Композер заблокирован при загрузке/рефреше треда или отправке in-flight. */\n protected readonly composerDisabled: Signal<boolean> = computed((): boolean => this.loading() || this.fetching() || this.sending());\n\n /**\n * Можно ли отправить: композер активен и есть содержимое — непустой текст или\n * (при включённых вложениях) хотя бы один файл. Сообщение само по себе не\n * бывает «невалидным» — пустоту гасим дизейблом кнопки, а не подсветкой поля.\n */\n protected readonly canSend: Signal<boolean> = computed((): boolean => {\n if (this.composerDisabled()) {\n return false;\n }\n const value: Partial<{ message: string; files: File[] }> = this.#formValue();\n const hasText: boolean = (value.message ?? '').trim().length > 0;\n const hasFiles: boolean = this.attachments() && (value.files?.length ?? 0) > 0;\n return hasText || hasFiles;\n });\n\n /** Показывать ли шапку: только когда включена хотя бы одна иконка. */\n protected readonly showHeader: Signal<boolean> = computed((): boolean => this.showRefresh() || this.showExpand());\n\n /** Подпись кнопки fullscreen: тернарник в шаблоне переводом не покрыть. */\n protected readonly expandLabel: Signal<string> = rtKitLabel(\n computed((): TRtKitLabelKey => (this.expanded() ? 'chatCollapse' : 'chatExpand'))\n );\n\n /** Выбранные, но ещё не отправленные файлы — карточки над полем ввода. */\n protected readonly selectedFiles: Signal<File[]> = computed((): File[] => this.#formValue().files ?? []);\n\n /**\n * Drop-зона активна только когда вложения включены, ответ доступен и композер\n * не занят (загрузка/рефреш/отправка). Иначе обёртка `rt-file-drop` просто\n * пропускает контент без оверлея.\n */\n protected readonly dropDisabled: Signal<boolean> = computed(\n (): boolean => !this.attachments() || !this.canReply() || this.composerDisabled()\n );\n\n /**\n * Файл из drag-n-drop для rich-композера: каждый drop кладёт новый `File`,\n * пробрасывается в `rt-message-composer` через input. Классический композер\n * принимает drop напрямую в свой `replyForm`.\n */\n protected readonly droppedFiles: WritableSignal<File[] | null> = signal<File[] | null>(null);\n\n /**\n * Шаблон действий у реплики: `<ng-template rtChatMessageActions let-message>`.\n *\n * Не объявлен — разметка реплики прежняя, и лишней кнопки у неё не появляется.\n */\n protected readonly messageActions: Signal<RtChatMessageActionsDirective | undefined> = contentChild(RtChatMessageActionsDirective);\n\n /** История сообщений (consumer уже смаппил из доменной модели). */\n public readonly messages: InputSignal<readonly IRtChat.Message[]> = input<readonly IRtChat.Message[]>([]);\n\n /** Первичная загрузка — скелетоны вместо треда. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Рефреш при наличии данных — тред остаётся, композер дизейблится. */\n public readonly fetching: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Доступна ли отправка (иначе вместо композера — note с причиной). */\n public readonly canReply: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Причина блокировки ответа — note под тредом. */\n public readonly replyBlockReason: InputSignal<string | null> = input<string | null>(null);\n\n /** Отправка in-flight — спиннер/дизейбл на кнопке. */\n public readonly sending: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Подписи по умолчанию приходят пустыми и переводятся ниже: значение\n * `input()` вычисляется при создании компонента, и готовый перевод застыл бы\n * на языке, активном в этот момент.\n */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n public readonly title: InputSignal<string> = input<string>('');\n\n /** Текст, когда треда ещё нет (заявка не создана). */\n public readonly emptyHint: InputSignal<string> = input<string>('');\n\n /** Есть ли тред (иначе показываем `emptyHint`). */\n public readonly hasThread: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Включить загрузку файлов в композере. */\n public readonly attachments: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** `accept` для file-input (`.pdf,.doc,...`). */\n public readonly accept: InputSignal<string> = input<string>('');\n\n /**\n * Компактный композер (`rt-message-composer`): авто-растущая textarea над\n * разделителем + ряд иконок (прикрепить слева, отправить справа) вместо\n * классического вертикального стека. По умолчанию выключен.\n */\n public readonly richComposer: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Rich-текст в композере (Quill delta). Требует `richComposer` — форматирование\n * живёт только в компактном композере. Отправка уходит delta-каналом.\n */\n public readonly formatting: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Набор кнопок rich-редактора (проброс до `rt-rich-editor` через композер). */\n public readonly formattingToolbar: InputSignal<TRtRichEditorToolbar> = input<TRtRichEditorToolbar>('full');\n\n /**\n * Растягивать чат на всю высоту контейнера: тред занимает свободное место,\n * композер прижат к низу. По умолчанию выключен (тред с фикс. max-height).\n * Требует, чтобы родитель давал высоту (flex-цепочка).\n */\n public readonly fill: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показать иконку refresh в шапке. */\n public readonly showRefresh: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показать иконку expand (fullscreen) в шапке. */\n public readonly showExpand: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Отправка сообщения (+файлы) — consumer вызывает свой store/api. */\n public readonly send: OutputEmitterRef<IRtChat.SendPayload> = output<IRtChat.SendPayload>();\n\n /** Клик refresh — consumer перетягивает тред. */\n public readonly refresh: OutputEmitterRef<void> = output<void>();\n\n /** Клик по вложению — consumer качает blob своим api; шаблон зовёт выход прямо, без релея. */\n public readonly downloadFile: OutputEmitterRef<IRtChat.Message> = output<IRtChat.Message>();\n\n /** Клик по карточке вложения из `attachments[]` — консюмер качает по `publicId`. */\n public readonly downloadAttachment: OutputEmitterRef<IRtChat.Attachment> = output<IRtChat.Attachment>();\n\n /** Набор текста в поле ответа: `true` — отрезок начался, `false` — кончился. */\n public readonly typing: OutputEmitterRef<boolean> = output<boolean>();\n\n /** Строка о том, что печатает вторая сторона, поверх низа ленты; пустая прячет плашку. */\n public readonly typingText: InputSignal<string> = input<string>('');\n\n /** Смена fullscreen-состояния. */\n public readonly expandedChange: OutputEmitterRef<boolean> = output<boolean>();\n\n public readonly deleteMessage: OutputEmitterRef<IRtChat.Message> = output<IRtChat.Message>();\n\n /** Повторная отправка своего сообщения со статусом `failed`. */\n public readonly retryMessage: OutputEmitterRef<IRtChat.Message> = output<IRtChat.Message>();\n\n /**\n * Есть ли у реплики действия потребителя — гейт кнопки «…» у неё.\n *\n * Не задан — точка действий показывается у каждой реплики: экран, который ничего не\n * гейтит, показывает её так же, как это делает строка таблицы.\n */\n public readonly messageHasActions: InputSignal<IRtChat.MessageActionsPredicate | null> = input<IRtChat.MessageActionsPredicate | null>(\n null\n );\n\n constructor() {\n this.#formValue = toSignal(this.replyForm.valueChanges, {\n initialValue: this.replyForm.value,\n });\n\n // После рендера, зависящего от треда, лента прокручивается к последнему сообщению — если оно\n // своё (forceScroll) или читатель у нижнего края; ушедшего читать историю входящее не дёргает.\n afterRenderEffect((): void => {\n this.messages();\n this.loading();\n this.fetching();\n this.expanded();\n const el: HTMLElement | undefined = this.thread()?.nativeElement;\n if (el === undefined) {\n return;\n }\n if (this.#forceScroll || this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n this.#atBottom = true;\n this.#pinToBottomDeferred();\n }\n this.#forceScroll = false;\n });\n\n // `formControlName`-инпуты игнорируют атрибут `disabled` — состояние ввода\n // держим через сам контрол: блок при рефреше треда или отправке in-flight.\n effect((): void => {\n const blocked: boolean = this.composerDisabled();\n if (blocked && this.replyForm.enabled) {\n this.replyForm.disable({ emitEvent: false });\n return;\n }\n if (!blocked && this.replyForm.disabled) {\n this.replyForm.enable({ emitEvent: false });\n }\n });\n }\n\n protected onSubmit(): void {\n // Кнопка уже дизейблится по `canSend` — guard лишь страхует от submit в\n // обход кнопки (программный/Enter), молча и без подсветки поля.\n if (!this.canSend()) {\n return;\n }\n const text: string = this.replyForm.controls.message.value.trim();\n const files: File[] = this.replyForm.controls.files.value;\n // Своё сообщение всегда прокручивает тред вниз — независимо от позиции.\n this.#forceScroll = true;\n this.#typingTracker.stop();\n this.send.emit({ text, files: this.attachments() ? files : undefined });\n this.replyForm.reset({ message: '', files: [] });\n }\n\n protected onComposerKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' && !event.shiftKey && !event.isComposing) {\n event.preventDefault();\n this.onSubmit();\n }\n }\n\n /** Релей submit'а от `rt-message-composer` (rich-режим) наружу как `send`. */\n protected onComposerSubmit(payload: IRtMessageComposer.SubmitPayload): void {\n // Своё сообщение всегда прокручивает тред вниз — независимо от позиции.\n this.#forceScroll = true;\n this.#typingTracker.stop();\n this.send.emit({\n text: payload.text,\n files: this.attachments() ? payload.files : undefined,\n delta: payload.delta,\n });\n }\n\n /** Ввод в поле ответа любого из двух режимов; выбор файла набором не считается. */\n protected onReplyInput(event: Event): void {\n const draft: string | null = typingDraft(event.target);\n if (draft !== null) {\n this.#typingTracker.input(draft);\n }\n }\n\n /**\n * Файлы выброшены в обёртку чата: в rich-режиме отдаём массив композеру через\n * input, в классическом — добавляем к уже выбранным в собственном `replyForm`.\n */\n protected onFilesDropped(files: File[]): void {\n if (files.length === 0) {\n return;\n }\n if (this.richComposer()) {\n // Новый массив на каждый drop — effect композера видит каждое перетаскивание.\n this.droppedFiles.set([...files]);\n return;\n }\n this.replyForm.controls.files.setValue(withAppendedFiles(this.replyForm.controls.files.value, files));\n }\n\n protected openFilePicker(): void {\n this.composerFileEl()?.nativeElement.click();\n }\n\n protected onFilesPicked(event: Event): void {\n const inputEl: HTMLInputElement = event.target as HTMLInputElement;\n const picked: File[] = pickedFiles(inputEl.files);\n if (picked.length > 0) {\n this.replyForm.controls.files.setValue(withAppendedFiles(this.replyForm.controls.files.value, picked));\n }\n // Сброс значения: без него повторный выбор того же файла не даёт `change`.\n inputEl.value = '';\n }\n\n protected removeFile(index: number): void {\n this.replyForm.controls.files.setValue(withoutFileAt(this.replyForm.controls.files.value, index));\n }\n\n /** Признак «читатель у нижнего края» обновляется по прокрутке: на нём стоит автопрокрутка. */\n protected onThreadScroll(): void {\n const el: HTMLElement | undefined = this.thread()?.nativeElement;\n if (el === undefined) {\n return;\n }\n\n this.#atBottom = nextAtBottom(this.#atBottom, this.#lastScrollTop, el);\n this.#lastScrollTop = el.scrollTop;\n }\n\n /**\n * Серия отложенных подтягиваний ленты к низу: присланное содержимое дорисовывается несколькими\n * проходами, и одной прокрутки мало. Каждый тик берёт тред заново — он бывает пересоздан — и\n * дотягивает ленту, пока читатель стоит у нижнего края.\n */\n #pinToBottomDeferred(): void {\n for (const delay of RT_CHAT_PIN_RETRY_DELAYS_MS) {\n setTimeout((): void => {\n const el: HTMLElement | undefined = this.thread()?.nativeElement;\n if (el !== undefined && this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n }\n }, delay);\n }\n }\n\n protected toggleExpand(): void {\n const next: boolean = !this.expanded();\n this.expanded.set(next);\n this.expandedChange.emit(next);\n }\n}\n","<ng-container rtBlock=\"rt-chat\">\n <rt-file-drop\n [overlayLabel]=\"t().chatDropOverlay\"\n [accept]=\"accept()\"\n [disabled]=\"dropDisabled()\"\n (filesDropped)=\"onFilesDropped($event)\">\n @if (showHeader()) {\n <rt-toolbar rtElem=\"header\" dense>\n <ng-template rtToolbarLeft>\n <h3 rtElem=\"title\" qa-dataid=\"chat-title\">{{ title() }}</h3>\n </ng-template>\n <ng-template rtToolbarRight>\n @if (showRefresh()) {\n <rt-icon-button\n qa-dataid=\"chat-refresh\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRefreshAria\"\n [tooltip]=\"t().chatRefreshTooltip\"\n [loading]=\"fetching()\"\n [disabled]=\"!hasThread()\"\n (clicked)=\"refresh.emit()\" />\n }\n @if (showExpand()) {\n <rt-icon-button\n qa-dataid=\"chat-expand\"\n variant=\"ghost\"\n [icon]=\"expanded() ? 'window-minimize' : 'window-maximize'\"\n [ariaLabel]=\"expandLabel()\"\n [tooltip]=\"expandLabel()\"\n (clicked)=\"toggleExpand()\" />\n }\n <ng-content select=\"[rtChatHeaderActions]\" />\n </ng-template>\n </rt-toolbar>\n }\n\n @if (!hasThread()) {\n <rt-note qa-dataid=\"chat-empty-hint\">{{ emptyHint() }}</rt-note>\n } @else {\n <div rtElem=\"thread-viewport\" qa-dataid=\"chat-thread-viewport\">\n @if (loading()) {\n <!-- Скелетон повторяет структуру сообщения (автор → текст → дата),\n чередуя выравнивание, чтобы тред не «прыгал» при подмене на реальные. -->\n <div rtElem=\"thread\" qa-dataid=\"chat-thread-skeleton\">\n @for (row of skeletonRows; track row; let even = $even) {\n <div rtElem=\"message-skeleton\" qa-dataid=\"chat-message-skeleton\" [rtMod]=\"{ own: even }\">\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"72px\" height=\"10px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"100%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"55%\" height=\"13px\" [isLoading]=\"true\" />\n <rt-skeleton-wrapper rtElem=\"skeleton-line\" width=\"56px\" height=\"10px\" [isLoading]=\"true\" />\n </div>\n }\n </div>\n } @else {\n <div\n #thread\n rtElem=\"thread\"\n qa-dataid=\"chat-thread\"\n [rtMod]=\"{ frozen: fetching() }\"\n [attr.aria-busy]=\"fetching() ? 'true' : null\"\n (scroll)=\"onThreadScroll()\">\n @for (m of messages(); track m.id) {\n <div\n rtElem=\"message-row\"\n qa-dataid=\"chat-message\"\n [attr.data-own]=\"m.own\"\n [attr.data-status]=\"m.status || null\"\n [attr.data-deleted]=\"m.deleted || null\"\n [rtMod]=\"{ own: m.own }\">\n @if (m.canDelete && !m.deleted) {\n @if (m.deleteConfirm) {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n [rtConfirm]=\"m.deleteConfirm\"\n (confirmed)=\"deleteMessage.emit(m)\" />\n } @else {\n <rt-icon-button\n rtElem=\"message-delete\"\n qa-dataid=\"chat-message-delete\"\n icon=\"trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatDeleteAria\"\n [tooltip]=\"t().chatDeleteTooltip\"\n (clicked)=\"deleteMessage.emit(m)\" />\n }\n }\n @if (messageActions()?.template; as actionsTpl) {\n @if (m | rtChatMessageHasActions: messageHasActions()) {\n <div rtElem=\"message-actions\" qa-dataid=\"chat-message-actions\">\n <rt-menu>\n <ng-container\n [ngTemplateOutlet]=\"actionsTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: m }\" />\n </rt-menu>\n </div>\n }\n }\n <div rtElem=\"message\" [rtMod]=\"{ own: m.own, deleted: m.deleted }\">\n <p rtElem=\"message-author\" qa-dataid=\"chat-message-author\">{{ m.author }}</p>\n @if (m.deleted) {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-deleted\" rtMod=\"deleted\">\n {{ t().chatMessageDeleted }}\n </p>\n } @else {\n @if (m.delta) {\n <rt-delta-view rtElem=\"message-text\" qa-dataid=\"chat-message-text\" [delta]=\"m.delta\" />\n } @else {\n <p rtElem=\"message-text\" qa-dataid=\"chat-message-text\">{{ m.text }}</p>\n }\n @if (m.attachments?.length) {\n @for (att of m.attachments; track att.id) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"att.name || attachmentFallbackName()\"\n (download)=\"downloadAttachment.emit(att)\" />\n </span>\n }\n } @else if (m.fileUrl) {\n <span rtElem=\"message-attachment\" qa-dataid=\"chat-message-attachment\">\n <rt-file-card\n showDownload\n size=\"sm\"\n [name]=\"m.fileName || attachmentFallbackName()\"\n (download)=\"downloadFile.emit(m)\" />\n </span>\n }\n @if (m.deepLink) {\n <span rtElem=\"message-deeplink\">\n <a\n rtButton\n qa-dataid=\"chat-message-deeplink\"\n appearance=\"outlined\"\n icon=\"send\"\n rel=\"noopener\"\n target=\"_blank\"\n [href]=\"m.deepLink\"\n [label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"\n [attr.aria-label]=\"m.deepLinkLabel || t().uiSubscribeNotifications\"></a>\n </span>\n }\n }\n <span rtElem=\"message-footer\">\n <span rtElem=\"message-date\" qa-dataid=\"chat-message-date\">\n {{ m.createdAt | date: 'short' : undefined : locale() }}\n </span>\n @if (m.status) {\n <span\n rtElem=\"message-status\"\n qa-dataid=\"chat-message-status\"\n [attr.data-status]=\"m.status\"\n [rtMod]=\"{ status: m.status }\"\n [attr.aria-label]=\"m.status | rtChatStatusLabel\">\n @if (m.status === MessageStatus.Failed) {\n <rt-icon rtElem=\"status-icon\" name=\"exclamation-circle\" size=\"sm\" />\n <rt-icon-button\n qa-dataid=\"chat-message-retry\"\n icon=\"sync\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatRetryAria\"\n [tooltip]=\"t().chatRetryTooltip\"\n (clicked)=\"retryMessage.emit(m)\" />\n } @else {\n <!-- Часы, пока сообщение в пути; дальше двойной чек, цвет которого\n (серый/синий) различает доставлено и прочитано. -->\n <rt-icon\n rtElem=\"status-icon\"\n size=\"sm\"\n [name]=\"m.status === MessageStatus.Sending ? 'clock' : 'check-double'\" />\n }\n </span>\n }\n </span>\n </div>\n </div>\n } @empty {\n <rt-note qa-dataid=\"chat-empty-thread\">{{ t().chatEmptyThread }}</rt-note>\n }\n </div>\n }\n @if (!loading() && fetching()) {\n <div rtElem=\"thread-overlay\" qa-dataid=\"chat-thread-overlay\" role=\"status\" [attr.aria-label]=\"t().chatRefreshAria\">\n <rt-spinner diameter=\"32\" />\n </div>\n }\n <div rtElem=\"typing\" qa-dataid=\"chat-typing\" aria-live=\"polite\" [rtMod]=\"{ shown: typingText() !== '' }\">\n {{ typingText() }}\n </div>\n </div>\n\n @if (canReply()) {\n @if (richComposer()) {\n <rt-message-composer\n rtElem=\"composer-rich\"\n qa-dataid=\"chat-composer-rich\"\n [placeholder]=\"placeholder()\"\n [accept]=\"accept()\"\n [attachments]=\"attachments()\"\n [formatting]=\"formatting()\"\n [toolbar]=\"formattingToolbar()\"\n [sending]=\"sending()\"\n [disabled]=\"loading() || fetching()\"\n [droppedFiles]=\"droppedFiles()\"\n (submitted)=\"onComposerSubmit($event)\"\n (input)=\"onReplyInput($event)\" />\n } @else {\n <form\n rtElem=\"composer\"\n qa-dataid=\"chat-composer\"\n [formGroup]=\"replyForm\"\n (ngSubmit)=\"onSubmit()\"\n (input)=\"onReplyInput($event)\">\n @if (attachments() && selectedFiles().length > 0) {\n <div rtElem=\"composer-files\" qa-dataid=\"chat-composer-files\">\n @for (file of selectedFiles(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"chat-composer-file\"\n size=\"sm\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"composerDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </div>\n }\n <div rtElem=\"composer-field\" [rtMod]=\"{ attach: attachments() }\">\n @if (attachments()) {\n <input\n #composerFileEl\n qa-dataid=\"chat-composer-file-input\"\n type=\"file\"\n hidden\n multiple\n [attr.accept]=\"accept() || null\"\n (change)=\"onFilesPicked($event)\" />\n <rt-icon-button\n qa-dataid=\"chat-composer-attach\"\n icon=\"paperclip\"\n variant=\"ghost\"\n [ariaLabel]=\"t().chatAttachAria\"\n [tooltip]=\"t().chatAttachTooltip\"\n [disabled]=\"composerDisabled()\"\n (clicked)=\"openFilePicker()\" />\n }\n <textarea\n rtElem=\"composer-input\"\n qa-dataid=\"chat-composer-input\"\n cdkTextareaAutosize\n formControlName=\"message\"\n cdkAutosizeMinRows=\"1\"\n cdkAutosizeMaxRows=\"4\"\n [attr.aria-label]=\"t().chatComposerAria\"\n [placeholder]=\"placeholder()\"\n (keydown)=\"onComposerKeydown($event)\"></textarea>\n </div>\n <button\n rtButton\n rtElem=\"composer-send\"\n qa-dataid=\"chat-composer-send\"\n type=\"submit\"\n theme=\"primary\"\n appearance=\"filled\"\n [label]=\"t().chatSendLabel\"\n [attr.aria-label]=\"t().chatSendAria\"\n [loading]=\"sending()\"\n [disabled]=\"!canSend()\"></button>\n </form>\n }\n } @else if (replyBlockReason()) {\n <rt-note rtElem=\"reply-block\" qa-dataid=\"chat-reply-block\">{{ replyBlockReason() }}</rt-note>\n }\n\n <!-- Слот доменных действий потребителя под композером: в fullscreen\n попадает внутрь overlay, поэтому кнопки остаются видны. -->\n <div rtElem=\"footer-slot\" qa-dataid=\"chat-footer\" [rtMod]=\"{ blocked: fetching() }\" [attr.inert]=\"fetching() ? '' : null\">\n <ng-content select=\"[rtChatFooter]\" />\n </div>\n }\n </rt-file-drop>\n</ng-container>\n","import { fileNameFromUrl, IQuillDelta } from '@rt-tools/ui-kit-v2';\n\nimport { ERtChatMessageStatus, IRtChat } from './rt-chat.model';\n\n/**\n * Статус уже сохранённого своего сообщения: сервер знает только, дошло ли оно до\n * собеседника. Часы и ошибка — состояния клиентской очереди, сюда не попадают.\n */\nexport function deliveryStatus(read: boolean): ERtChatMessageStatus {\n return read ? ERtChatMessageStatus.Read : ERtChatMessageStatus.Sent;\n}\n\n/**\n * Сообщение, ещё не подтверждённое сервером. Серверного id и ссылок на вложения\n * у него нет: есть клиентский ключ, текст и выбранные файлы.\n *\n * Rich-тело приходит уже разобранным — доменная форма его хранения тут ни при\n * чём, а хранят его стороны по-разному: одна шлёт обычный текст, другая —\n * строку композера, которая в том же виде уходит на сервер.\n */\nexport interface IRtPendingMessage {\n tempId: string;\n text: string;\n delta?: IQuillDelta | null;\n createdAt: string;\n status: IRtChat.MessageStatus;\n files: readonly File[];\n}\n\n/**\n * Неподтверждённое сообщение → строка ленты. Показывается сразу после отправки:\n * ждать ответа сервера, глядя в пустоту, незачем ни одной из сторон.\n *\n * Скрыть такое сообщение нельзя: на сервере его ещё нет, и удалять нечего.\n */\nexport function pendingToRtMessage(pending: IRtPendingMessage, authorLabel: string): IRtChat.Message {\n return {\n id: pending.tempId,\n tempId: pending.tempId,\n author: authorLabel,\n own: true,\n text: pending.text,\n delta: pending.delta ?? null,\n createdAt: pending.createdAt,\n status: pending.status,\n canDelete: false,\n attachments: pending.files.map((file: File, index: number): IRtChat.Attachment => ({\n id: index,\n name: file.name,\n // Файл ещё не на сервере — скачивать нечего, карточка только именует.\n publicId: '',\n })),\n };\n}\n\n/**\n * Структурный контракт доменного сообщения, достаточный для маппинга в\n * `IRtChat.Message`. Доменные модели удовлетворяют ему по форме;\n * роль-специфика (автор/own/system) задаётся опциями.\n */\nexport interface IRtMappableMessage {\n id: string | number;\n tempId?: string;\n status?: IRtChat.MessageStatus;\n message: string;\n messageDelta: IQuillDelta | null;\n createdAt: string;\n fileUrl: string | null;\n attachments: readonly { id: number; name: string; publicId: string }[];\n}\n\n/**\n * Опции маппинга: роль-специфичные куски, которые не вывести из общего контракта.\n *\n * - `roleLabel` — подпись автора (обычно ярлык роли).\n * - `isOwn` — своё ли это сообщение (правый пузырь).\n * - `isSystem` — системное ли (нейтральный стиль); по умолчанию нет.\n * - `fileName` — имя файла вложения; по умолчанию выводится из `fileUrl`.\n * - `optimistic` — включить `tempId`/`status` (оптимистичная отправка); по умолчанию да.\n * Для read-only тредов (агент) — `false`: тогда `id` берётся из серверного `id`.\n */\nexport interface IToRtMessageOptions<TMessage extends IRtMappableMessage> {\n roleLabel: (message: TMessage) => string;\n isOwn: (message: TMessage) => boolean;\n isSystem?: (message: TMessage) => boolean;\n fileName?: (message: TMessage) => string | null;\n optimistic?: boolean;\n}\n\n/**\n * Собрать `IRtChat.Message` из доменного сообщения. Общие поля (текст, delta,\n * дата, вложения, файл) берутся из контракта; автор/own/system/имя файла —\n * из опций. Ключ `id` — `tempId ?? id` в оптимистичном режиме (пока сервер не\n * подтвердил), иначе серверный `id`.\n */\nexport function toRtMessage<TMessage extends IRtMappableMessage>(\n message: TMessage,\n options: IToRtMessageOptions<TMessage>\n): IRtChat.Message {\n const optimistic: boolean = options.optimistic ?? true;\n const fileNameFromUrlOrNull: string | null = message.fileUrl ? fileNameFromUrl(message.fileUrl) : null;\n return {\n id: optimistic ? (message.tempId ?? message.id) : message.id,\n tempId: optimistic ? message.tempId : undefined,\n status: optimistic ? message.status : undefined,\n author: options.roleLabel(message),\n own: options.isOwn(message),\n system: options.isSystem?.(message) ?? false,\n text: message.message,\n delta: message.messageDelta,\n createdAt: message.createdAt,\n fileUrl: message.fileUrl,\n fileName: options.fileName ? options.fileName(message) : fileNameFromUrlOrNull,\n attachments: message.attachments.map((attachment: { id: number; name: string; publicId: string }): IRtChat.Attachment => ({\n id: attachment.id,\n name: attachment.name,\n publicId: attachment.publicId,\n })),\n };\n}\n","import { Clipboard } from '@angular/cdk/clipboard';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n inject,\n input,\n InputSignal,\n signal,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { IRtIcon, RtIconButtonComponent, rtKitLabel } from '@rt-tools/ui-kit-v2';\n\nconst BEM_BLOCK: string = 'rt-ai-chat-copy';\n\n/** Сколько держать состояние «скопировано» перед сбросом значка и подписи — как у `rt-copy-value`. */\nconst RESET_DELAY_MS: number = 2000;\n\n/**\n * Кнопка копирования текста сообщения `rt-ai-chat`: у вопроса под пузырём, у ответа первой в строке\n * оценки. После нажатия значок на две секунды меняется на галочку, подпись — на «Copied».\n */\n@Component({\n selector: 'rt-ai-chat-copy',\n templateUrl: './rt-ai-chat-copy.component.html',\n styleUrl: './rt-ai-chat-copy.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconButtonComponent,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtAiChatCopyComponent {\n readonly #clipboard: Clipboard = inject(Clipboard);\n\n #resetTimer: ReturnType<typeof setTimeout> | null = null;\n\n readonly #t_uiCopy: Signal<string> = rtKitLabel('uiCopy');\n readonly #t_uiCopied: Signal<string> = rtKitLabel('uiCopied');\n\n protected readonly copied: WritableSignal<boolean> = signal(false);\n\n protected readonly iconName: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => (this.copied() ? 'check' : 'copy'));\n\n protected readonly actionLabel: Signal<string> = computed((): string => (this.copied() ? this.#t_uiCopied() : this.#t_uiCopy()));\n\n /** Что уходит в буфер: у вопроса — его текст как есть, у ответа — видимый текст без знаков разметки. */\n public readonly text: InputSignal<string> = input.required<string>();\n\n constructor() {\n inject(DestroyRef).onDestroy((): void => this.#clearTimer());\n }\n\n protected onCopy(): void {\n this.#clipboard.copy(this.text());\n this.copied.set(true);\n\n this.#clearTimer();\n this.#resetTimer = setTimeout((): void => this.copied.set(false), RESET_DELAY_MS);\n }\n\n #clearTimer(): void {\n if (this.#resetTimer !== null) {\n clearTimeout(this.#resetTimer);\n this.#resetTimer = null;\n }\n }\n}\n","<rt-icon-button\n qa-dataid=\"ai-chat-copy\"\n size=\"sm\"\n iconSize=\"sm\"\n [icon]=\"iconName()\"\n [ariaLabel]=\"actionLabel()\"\n [tooltip]=\"actionLabel()\"\n (clicked)=\"onCopy()\" />\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n model,\n ModelSignal,\n output,\n OutputEmitterRef,\n Signal,\n TemplateRef,\n ViewEncapsulation,\n} from '@angular/core';\nimport { BooleanInput } from '@angular/cdk/coercion';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport {\n markdownToPlainText,\n RT_KIT_LABELS,\n RtAiRunStatusComponent,\n RtIconButtonComponent,\n RtMarkdownTextComponent,\n TRtKitLabelMap,\n} from '@rt-tools/ui-kit-v2';\n\nimport { RtAiChatCopyComponent } from '../copy/rt-ai-chat-copy.component';\nimport { IRtAiChat } from '../rt-ai-chat.model';\n\nconst BEM_BLOCK: string = 'rt-ai-chat-answer';\n\n/**\n * Ответ ассистента в ленте `rt-ai-chat`: ход работы, текст в markdown, вложения приложения и строка\n * действий — копирование и оценка. Строка появляется, когда текст дописан.\n */\n@Component({\n selector: 'rt-ai-chat-answer',\n templateUrl: './rt-ai-chat-answer.component.html',\n styleUrl: './rt-ai-chat-answer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n NgTemplateOutlet,\n\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n RtAiChatCopyComponent,\n RtAiRunStatusComponent,\n RtIconButtonComponent,\n RtMarkdownTextComponent,\n ],\n host: {\n class: BEM_BLOCK,\n role: 'article',\n '[attr.data-id]': 'message().id',\n },\n})\nexport class RtAiChatAnswerComponent {\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n /** Текст дописан: строка действий с копированием и оценкой. */\n protected readonly isWritten: Signal<boolean> = computed((): boolean => !!this.message().text && !this.message().streaming);\n\n /** Что копирует кнопка: видимый текст ответа без знаков разметки — без хода работы и вложений. */\n protected readonly plainText: Signal<string> = computed((): string => markdownToPlainText(this.message().text));\n\n public readonly message: InputSignal<IRtAiChat.Message> = input.required<IRtAiChat.Message>();\n\n /** Шаблон вложений ответа; `null` — вложений нет. */\n public readonly extra: InputSignal<TemplateRef<IRtAiChat.ExtraContext> | null> = input<TemplateRef<IRtAiChat.ExtraContext> | null>(\n null\n );\n\n /** Кнопка копирования текста первой в строке действий. */\n public readonly copyable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Шаги хода работы раскрыты. */\n public readonly expanded: ModelSignal<boolean> = model<boolean>(false);\n\n /** Нажата оценка; повторное нажатие той же снимает её — решает родитель. */\n public readonly feedbackChange: OutputEmitterRef<Exclude<IRtAiChat.Feedback, null>> = output<Exclude<IRtAiChat.Feedback, null>>();\n}\n","<ng-container rtBlock=\"rt-ai-chat-answer\">\n @if (message().run; as run) {\n <rt-ai-run-status\n qa-dataid=\"ai-chat-run\"\n [state]=\"run.state\"\n [label]=\"run.label\"\n [meta]=\"run.meta ?? ''\"\n [steps]=\"run.steps ?? []\"\n [(expanded)]=\"expanded\" />\n }\n @if (message().text) {\n <rt-markdown-text rtElem=\"text\" qa-dataid=\"ai-chat-answer-text\" [text]=\"message().text\" />\n }\n @if (extra(); as extraTemplate) {\n <ng-container [ngTemplateOutlet]=\"extraTemplate\" [ngTemplateOutletContext]=\"{ $implicit: message() }\" />\n }\n @if (isWritten()) {\n <div rtElem=\"feedback\" qa-dataid=\"ai-chat-feedback\">\n @if (copyable()) {\n <rt-ai-chat-copy [text]=\"plainText()\" />\n }\n <rt-icon-button\n qa-dataid=\"ai-chat-like\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"thumb-up\"\n [active]=\"message().feedback === 'liked'\"\n [ariaLabel]=\"t().aiLike\"\n [tooltip]=\"t().aiLike\"\n (clicked)=\"feedbackChange.emit('liked')\" />\n <rt-icon-button\n qa-dataid=\"ai-chat-dislike\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"thumb-down\"\n [active]=\"message().feedback === 'disliked'\"\n [ariaLabel]=\"t().aiDislike\"\n [tooltip]=\"t().aiDislike\"\n (clicked)=\"feedbackChange.emit('disliked')\" />\n </div>\n }\n</ng-container>\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { IRtAiChat } from './rt-ai-chat.model';\n\n/**\n * Вложения ответа ассистента: то, что рисует приложение под текстом ответа — график, таблица,\n * карточка. Шаблон получает сообщение.\n */\n@Directive({\n selector: 'ng-template[rtAiChatMessageExtra]',\n})\nexport class RtAiChatMessageExtraDirective {\n public readonly templateRef: TemplateRef<IRtAiChat.ExtraContext> = inject<TemplateRef<IRtAiChat.ExtraContext>>(TemplateRef);\n\n public static ngTemplateContextGuard(\n _directive: RtAiChatMessageExtraDirective,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате\n context: unknown\n ): context is IRtAiChat.ExtraContext {\n return true;\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n ElementRef,\n inject,\n Injector,\n input,\n InputSignal,\n InputSignalWithTransform,\n booleanAttribute,\n model,\n ModelSignal,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { BooleanInput } from '@angular/cdk/coercion';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport {\n IRtIcon,\n IRtSideMenu,\n IRtThreadList,\n RT_KIT_LABELS,\n RtButtonDirective,\n RtCopyValueComponent,\n RtEmptyStateComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtMessageComponent,\n RtPromptSuggestionComponent,\n RtSpinnerComponent,\n RtThreadListComponent,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n splitSideMenuTitle,\n TRtKitLabelMap,\n} from '@rt-tools/ui-kit-v2';\n\nimport { nextAtBottom, RT_CHAT_PIN_RETRY_DELAYS_MS } from '../chat/rt-chat-thread.logic';\nimport { IRtMessageComposer } from '../message-composer/rt-message-composer.model';\nimport { RtMessageComposerComponent } from '../message-composer/rt-message-composer.component';\nimport { RtAiChatAnswerComponent } from './answer/rt-ai-chat-answer.component';\nimport { RtAiChatCopyComponent } from './copy/rt-ai-chat-copy.component';\nimport { RtAiChatMessageExtraDirective } from './rt-ai-chat.directives';\nimport { IRtAiChat } from './rt-ai-chat.model';\n\nconst BEM_BLOCK: string = 'rt-ai-chat';\n\n/** Значки строк-превью пустого списка бесед по умолчанию: беседы идут с ассистентом. */\nconst PREVIEW_ICONS: readonly IRtIcon.Name[] = ['sparkle', 'bot', 'sparkle'];\n\n/** Строка беседы для списка бесед: `rt-thread-list` ждёт `id` и `hasUnread`. */\ninterface IThreadRow extends IRtThreadList.Row {\n readonly id: string;\n readonly hasUnread: boolean;\n readonly title: string;\n readonly titleParts: readonly IRtSideMenu.TitlePart[];\n readonly time: string;\n readonly unreadCount: number;\n}\n\n/**\n * Панель ИИ-ассистента одним компонентом: шапка с действиями, лента вопросов и ответов с ходом\n * работы, пустой экран с подсказками, ошибка с номером обращения, поле сообщения и подпись под\n * ним; по кнопке «Conversations» — список бесед.\n *\n * Компонент презентационный: сообщения, ход работы, беседы и ошибка приходят входами, действия\n * уходят выходами. Вложения ответа — графики и прочее — приложение отдаёт шаблоном\n * `rtAiChatMessageExtra`.\n */\n@Component({\n selector: 'rt-ai-chat',\n templateUrl: './rt-ai-chat.component.html',\n styleUrl: './rt-ai-chat.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n NgTemplateOutlet,\n\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n RtAiChatAnswerComponent,\n RtAiChatCopyComponent,\n RtButtonDirective,\n RtCopyValueComponent,\n RtEmptyStateComponent,\n RtIconButtonComponent,\n RtIconComponent,\n RtMessageComponent,\n RtMessageComposerComponent,\n RtPromptSuggestionComponent,\n RtSpinnerComponent,\n RtThreadListComponent,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtAiChatComponent {\n #atBottom: boolean = true;\n #lastScrollTop: number = 0;\n #forceScroll: boolean = false;\n\n readonly #injector: Injector = inject(Injector);\n\n protected readonly composer: Signal<RtMessageComposerComponent | undefined> = viewChild(RtMessageComposerComponent);\n protected readonly backButton: Signal<ElementRef<HTMLElement> | undefined> = viewChild('back', { read: ElementRef });\n protected readonly feed: Signal<ElementRef<HTMLElement> | undefined> = viewChild<ElementRef<HTMLElement>>('feed');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly extraTemplate: Signal<RtAiChatMessageExtraDirective | undefined> = contentChild(RtAiChatMessageExtraDirective);\n\n /** Ответы, у которых человек раскрыл шаги. */\n protected readonly openRuns: WritableSignal<ReadonlySet<string>> = signal<ReadonlySet<string>>(new Set<string>());\n\n protected readonly titleText: Signal<string> = computed((): string => this.title() || this.t().aiTitle);\n protected readonly emptyTitleText: Signal<string> = computed((): string => this.emptyTitle() || this.t().aiEmptyTitle);\n protected readonly emptyDescriptionText: Signal<string> = computed((): string => this.emptyDescription() || this.t().aiEmptyText);\n protected readonly disclaimerText: Signal<string> = computed((): string => this.disclaimer() ?? this.t().aiDisclaimer);\n\n /** Значение признака одних значков на шапке: только материальный набор, свой — без признака. */\n protected readonly headerIconSign: Signal<IRtIcon.Preset | null> = computed((): IRtIcon.Preset | null =>\n this.headerIconPreset() === 'material' ? 'material' : null\n );\n\n protected readonly hasThreads: Signal<boolean> = computed((): boolean => this.threads() !== null);\n\n /** Список бесед стоит колонкой слева: на весь экран, когда беседы есть. */\n protected readonly isThreadColumn: Signal<boolean> = computed((): boolean => this.fullScreen() && this.hasThreads());\n\n /** Список бесед стоит на месте ленты: в узкой панели по кнопке «Conversations». */\n protected readonly isThreadPage: Signal<boolean> = computed(\n (): boolean => this.threadsOpen() && this.hasThreads() && !this.isThreadColumn()\n );\n\n protected readonly isEmpty: Signal<boolean> = computed(\n (): boolean => !this.loading() && !this.messages().length && this.error() === null\n );\n\n /** Строка поиска по беседам: подсвечивает совпадения и меняет подпись пустого списка. */\n protected readonly threadQuery: WritableSignal<string> = signal<string>('');\n\n protected readonly threadRows: Signal<readonly IThreadRow[]> = computed((): readonly IThreadRow[] => {\n const query: string = this.threadQuery();\n\n return (this.threads() ?? []).map((thread: IRtAiChat.Thread): IThreadRow => ({\n id: thread.id,\n hasUnread: (thread.unreadCount ?? 0) > 0,\n title: thread.title,\n titleParts: splitSideMenuTitle(thread.title, query),\n time: thread.time ?? '',\n unreadCount: thread.unreadCount ?? 0,\n }));\n });\n\n /** Пустой список: без поиска — «бесед нет», с поиском — подпись списка «ничего не найдено». */\n protected readonly threadsEmptyText: Signal<string> = computed((): string => (this.threadQuery() ? '' : this.t().aiNoThreads));\n\n /** Заголовок беседы над лентой; пусто — строки нет. */\n public readonly title: InputSignal<string> = input<string>('');\n\n /** Вторая строка шапки — обычно название беседы. Пусто — не рисуется. */\n public readonly subtitle: InputSignal<string> = input<string>('');\n\n public readonly messages: InputSignal<readonly IRtAiChat.Message[]> = input<readonly IRtAiChat.Message[]>([]);\n\n /** Готовые вопросы пустого экрана. */\n public readonly suggestions: InputSignal<readonly string[]> = input<readonly string[]>([]);\n\n public readonly emptyTitle: InputSignal<string> = input<string>('');\n\n public readonly emptyDescription: InputSignal<string> = input<string>('');\n\n /** Подсказка в поле сообщения; пусто — подпись поля кита. */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Подпись под полем сообщения; `null` — подпись кита, пустая строка — без подписи. */\n public readonly disclaimer: InputSignal<string | null> = input<string | null>(null);\n\n /** Ответ пишется: поле сообщения в режиме остановки, подсказки и новая беседа выключены. */\n public readonly sending: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Беседа загружается: крутилка, пока сообщений нет. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly error: InputSignal<IRtAiChat.RunError | null> = input<IRtAiChat.RunError | null>(null);\n\n /** Беседы; `null` — кнопки «Conversations» нет. */\n public readonly threads: InputSignal<readonly IRtAiChat.Thread[] | null> = input<readonly IRtAiChat.Thread[] | null>(null);\n\n public readonly activeThreadId: InputSignal<string | null> = input<string | null>(null);\n\n public readonly threadsLoading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly threadsFetching: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly threadsHasMore: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Значки декоративных строк-превью пустого списка бесед, по строке на значок. */\n public readonly emptyPreviewIcons: InputSignal<readonly IRtIcon.Name[]> = input<readonly IRtIcon.Name[]>(PREVIEW_ICONS);\n\n /** Кнопка «Full screen» в шапке. */\n public readonly fullScreenable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Кнопка закрытия в шапке. */\n public readonly closable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Кнопка копирования текста под вопросом и в строке действий ответа. */\n public readonly copyable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /**\n * Набор рисунков значков шапки. `'material'` ставит на шапку признак одних значков\n * `data-rt-icon-preset`: значки рисуются материальным набором, токены и остальной вид — свои.\n * Признак значок читает после первой отрисовки, поэтому вход задаётся до неё. Дефолт `'base'`.\n */\n public readonly headerIconPreset: InputSignal<IRtIcon.Preset> = input<IRtIcon.Preset>('base');\n\n /** Черновик в поле сообщения. */\n public readonly draft: ModelSignal<string> = model<string>('');\n\n /** Список бесед открыт на месте ленты. */\n public readonly threadsOpen: ModelSignal<boolean> = model<boolean>(false);\n\n public readonly fullScreen: ModelSignal<boolean> = model<boolean>(false);\n\n /** Вопрос ушёл: набранный или выбранная подсказка. */\n public readonly send: OutputEmitterRef<string> = output<string>();\n\n public readonly stop: OutputEmitterRef<void> = output<void>();\n\n public readonly retry: OutputEmitterRef<void> = output<void>();\n\n public readonly newThread: OutputEmitterRef<void> = output<void>();\n\n public readonly closed: OutputEmitterRef<void> = output<void>();\n\n public readonly selectThread: OutputEmitterRef<string> = output<string>();\n\n public readonly deleteThread: OutputEmitterRef<string> = output<string>();\n\n public readonly searchThreads: OutputEmitterRef<string> = output<string>();\n\n public readonly loadMoreThreads: OutputEmitterRef<void> = output<void>();\n\n public readonly feedbackChange: OutputEmitterRef<IRtAiChat.FeedbackChange> = output<IRtAiChat.FeedbackChange>();\n\n constructor() {\n afterRenderEffect((): void => {\n this.messages();\n this.error();\n this.loading();\n this.isThreadPage();\n const el: HTMLElement | undefined = this.feed()?.nativeElement;\n if (el === undefined) {\n return;\n }\n if (this.#forceScroll || this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n this.#atBottom = true;\n this.#pinToBottomDeferred();\n }\n this.#forceScroll = false;\n });\n }\n\n /** Фокус в поле сообщения после отрисовки: приложению — после своих действий вне панели. */\n public focusComposer(): void {\n afterNextRender((): void => this.composer()?.focus(), { injector: this.#injector });\n }\n\n protected onFeedScroll(): void {\n const el: HTMLElement | undefined = this.feed()?.nativeElement;\n if (el === undefined) {\n return;\n }\n this.#atBottom = nextAtBottom(this.#atBottom, this.#lastScrollTop, el);\n this.#lastScrollTop = el.scrollTop;\n }\n\n protected onSubmitted(value: IRtMessageComposer.SubmitPayload): void {\n const text: string = value.text.trim();\n if (!text) {\n return;\n }\n this.#forceScroll = true;\n this.send.emit(text);\n }\n\n protected onSuggestion(text: string): void {\n this.#forceScroll = true;\n this.send.emit(text);\n }\n\n protected onToggleRun(messageId: string, open: boolean): void {\n this.openRuns.update((ids: ReadonlySet<string>): ReadonlySet<string> => {\n const next: Set<string> = new Set<string>(ids);\n if (open) {\n next.add(messageId);\n } else {\n next.delete(messageId);\n }\n return next;\n });\n }\n\n protected onFeedback(message: IRtAiChat.Message, feedback: Exclude<IRtAiChat.Feedback, null>): void {\n this.feedbackChange.emit({ messageId: message.id, feedback: message.feedback === feedback ? null : feedback });\n }\n\n protected onToggleThreads(): void {\n this.threadsOpen.set(!this.threadsOpen());\n\n if (this.threadsOpen()) {\n afterNextRender((): void => this.backButton()?.nativeElement.querySelector('button')?.focus(), { injector: this.#injector });\n } else {\n this.focusComposer();\n }\n }\n\n protected onNewThread(): void {\n this.newThread.emit();\n this.focusComposer();\n }\n\n protected onStop(): void {\n this.stop.emit();\n this.focusComposer();\n }\n\n protected onToggleFullScreen(): void {\n this.fullScreen.set(!this.fullScreen());\n }\n\n protected onSearchThreads(query: string): void {\n this.threadQuery.set(query);\n this.searchThreads.emit(query);\n }\n\n protected onSelectThread(id: IRtThreadList.TRowId): void {\n this.threadsOpen.set(false);\n this.#forceScroll = true;\n this.selectThread.emit(String(id));\n this.focusComposer();\n }\n\n #pinToBottomDeferred(): void {\n for (const delay of RT_CHAT_PIN_RETRY_DELAYS_MS) {\n setTimeout((): void => {\n const el: HTMLElement | undefined = this.feed()?.nativeElement;\n if (el !== undefined && this.#atBottom) {\n el.scrollTop = el.scrollHeight;\n }\n }, delay);\n }\n }\n}\n","<ng-container rtBlock=\"rt-ai-chat\">\n @if (isThreadColumn()) {\n <aside rtElem=\"thread-column\" qa-dataid=\"ai-chat-thread-column\" [attr.aria-label]=\"t().aiThreads\">\n <div rtElem=\"column-head\">\n <span rtElem=\"column-title\">{{ t().aiThreads }}</span>\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n </div>\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n </aside>\n }\n\n <section rtElem=\"conversation\" qa-dataid=\"ai-chat\" [attr.aria-label]=\"titleText()\">\n <header rtElem=\"header\" [attr.data-rt-icon-preset]=\"headerIconSign()\">\n @if (isThreadPage()) {\n <rt-icon-button\n #back\n qa-dataid=\"ai-chat-back\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"arrow-left\"\n [ariaLabel]=\"t().aiBackToChat\"\n [tooltip]=\"t().aiBackToChat\"\n (clicked)=\"onToggleThreads()\" />\n }\n\n <div rtElem=\"heading\">\n <span rtElem=\"title\" qa-dataid=\"ai-chat-title\">\n @if (!isThreadPage()) {\n <rt-icon name=\"sparkle\" size=\"sm\" color=\"primary\" aria-hidden=\"true\" />\n }\n {{ isThreadPage() ? t().aiThreads : titleText() }}\n </span>\n @if (!isThreadPage() && subtitle()) {\n <span rtElem=\"subtitle\" qa-dataid=\"ai-chat-subtitle\">{{ subtitle() }}</span>\n }\n </div>\n\n <div rtElem=\"actions\">\n @if (fullScreenable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-full-screen\"\n size=\"sm\"\n iconSize=\"sm\"\n [icon]=\"fullScreen() ? 'window-minimize' : 'fullscreen'\"\n [active]=\"fullScreen()\"\n [ariaLabel]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n [tooltip]=\"fullScreen() ? t().aiExitFullScreen : t().aiFullScreen\"\n (clicked)=\"onToggleFullScreen()\" />\n }\n @if (hasThreads() && !isThreadPage() && !isThreadColumn()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-threads\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"history\"\n [ariaLabel]=\"t().aiThreads\"\n [tooltip]=\"t().aiThreads\"\n (clicked)=\"onToggleThreads()\" />\n }\n @if (!isThreadColumn()) {\n <ng-container [ngTemplateOutlet]=\"newThreadButton\" />\n }\n @if (closable()) {\n <rt-icon-button\n qa-dataid=\"ai-chat-close\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"close\"\n [ariaLabel]=\"t().aiClose\"\n [tooltip]=\"t().aiClose\"\n (clicked)=\"closed.emit()\" />\n }\n </div>\n </header>\n\n @if (isThreadPage()) {\n <ng-container [ngTemplateOutlet]=\"threadList\" />\n } @else {\n <div #feed rtElem=\"feed\" qa-dataid=\"ai-chat-feed\" aria-live=\"polite\" (scroll)=\"onFeedScroll()\">\n @if (loading() && !messages().length) {\n <rt-spinner rtElem=\"spinner\" appearance=\"arc\" [diameter]=\"32\" />\n } @else if (isEmpty()) {\n <div rtElem=\"empty\" qa-dataid=\"ai-chat-empty\">\n <rt-empty-state icon=\"comments\" [title]=\"emptyTitleText()\" [description]=\"emptyDescriptionText()\" />\n @if (suggestions().length) {\n <div rtElem=\"suggestions\">\n @for (suggestion of suggestions(); track suggestion) {\n <rt-prompt-suggestion\n qa-dataid=\"ai-chat-suggestion\"\n [label]=\"suggestion\"\n [disabled]=\"sending()\"\n (picked)=\"onSuggestion($event)\" />\n }\n </div>\n }\n </div>\n }\n\n @for (message of messages(); track message.id) {\n @if (message.role === 'user') {\n <div rtElem=\"question\" qa-dataid=\"ai-chat-question\">\n <div rtElem=\"bubble\">\n <span rtElem=\"author\">{{ t().aiYou }}</span>\n <p rtElem=\"bubble-text\">{{ message.text }}</p>\n @if (message.time) {\n <span rtElem=\"time\">{{ message.time }}</span>\n }\n </div>\n @if (copyable() && message.text) {\n <div rtElem=\"question-actions\" qa-dataid=\"ai-chat-question-actions\">\n <rt-ai-chat-copy [text]=\"message.text\" />\n </div>\n }\n </div>\n } @else {\n <rt-ai-chat-answer\n qa-dataid=\"ai-chat-answer\"\n [message]=\"message\"\n [copyable]=\"copyable()\"\n [extra]=\"extraTemplate()?.templateRef ?? null\"\n [expanded]=\"openRuns().has(message.id)\"\n (expandedChange)=\"onToggleRun(message.id, $event)\"\n (feedbackChange)=\"onFeedback(message, $event)\" />\n }\n }\n\n @if (error(); as runError) {\n <div rtElem=\"error\" qa-dataid=\"ai-chat-error\" role=\"alert\">\n <rt-message severity=\"danger\">{{ runError.message }}</rt-message>\n @if (runError.referenceId) {\n <rt-copy-value [label]=\"t().aiReference\" [value]=\"runError.referenceId\" [copyLabel]=\"t().aiCopyReference\" />\n }\n @if (runError.retryable) {\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"ai-chat-retry\"\n appearance=\"text\"\n icon=\"sync\"\n size=\"sm\"\n [label]=\"t().aiRetry\"\n [attr.aria-label]=\"t().aiRetry\"\n [disabled]=\"sending()\"\n (click)=\"retry.emit()\"></button>\n }\n </div>\n }\n </div>\n\n <rt-message-composer\n rtElem=\"composer\"\n qa-dataid=\"ai-chat-composer\"\n stoppable\n [placeholder]=\"placeholder()\"\n [sending]=\"sending()\"\n [(text)]=\"draft\"\n (submitted)=\"onSubmitted($event)\"\n (stopped)=\"onStop()\" />\n\n @if (disclaimerText()) {\n <p rtElem=\"disclaimer\" qa-dataid=\"ai-chat-disclaimer\">{{ disclaimerText() }}</p>\n }\n }\n </section>\n</ng-container>\n\n<ng-template #newThreadButton>\n <rt-icon-button\n qa-dataid=\"ai-chat-new-thread\"\n size=\"sm\"\n iconSize=\"sm\"\n icon=\"ico-plus\"\n [disabled]=\"sending()\"\n [ariaLabel]=\"t().aiNewThread\"\n [tooltip]=\"t().aiNewThread\"\n (clicked)=\"onNewThread()\" />\n</ng-template>\n\n<ng-template #threadList>\n <ng-container rtBlock=\"rt-ai-chat\">\n <rt-thread-list\n rtElem=\"threads\"\n qa-dataid=\"ai-chat-thread-list\"\n [rows]=\"threadRows()\"\n [activeId]=\"activeThreadId()\"\n [searchPlaceholder]=\"t().aiSearchThreads\"\n [emptyText]=\"threadsEmptyText()\"\n [emptyPreviewIcons]=\"emptyPreviewIcons()\"\n [loading]=\"threadsLoading()\"\n [fetching]=\"threadsFetching()\"\n [hasMore]=\"threadsHasMore()\"\n (selectRow)=\"onSelectThread($event)\"\n (searchChange)=\"onSearchThreads($event)\"\n (loadMore)=\"loadMoreThreads.emit()\">\n <ng-template let-row [rtThreadListRow]=\"threadRows()\">\n <span rtElem=\"thread-title\" qa-dataid=\"ai-chat-thread-title\" [attr.title]=\"row.title\">\n @for (part of row.titleParts; track $index) {\n <span rtElem=\"thread-part\" [rtMod]=\"{ match: part.matched }\">{{ part.text }}</span>\n }\n </span>\n <span rtElem=\"thread-meta\">\n @if (row.unreadCount) {\n <span rtElem=\"thread-unread\" qa-dataid=\"ai-chat-thread-unread\">{{ row.unreadCount }}</span>\n }\n @if (row.time) {\n <span rtElem=\"thread-time\">{{ row.time }}</span>\n }\n </span>\n </ng-template>\n <ng-template let-row [rtThreadListRowActions]=\"threadRows()\">\n <rt-icon-button\n qa-dataid=\"ai-chat-delete-thread\"\n size=\"xs\"\n iconSize=\"sm\"\n icon=\"trash\"\n [disabled]=\"sending() && row.id === activeThreadId()\"\n [ariaLabel]=\"t().aiDeleteThread\"\n [tooltip]=\"t().aiDeleteThread\"\n (clicked)=\"deleteThread.emit(row.id)\" />\n </ng-template>\n </rt-thread-list>\n </ng-container>\n</ng-template>\n","/*\n * Вход @rt-tools/ui-kit-v2/rich-editor — компоненты, которые работают на библиотеке quill: редактор\n * текста, поле ввода сообщения и чат. Они стоят отдельным входом, чтобы приложение без них\n * собиралось без quill: из основного входа сборщик разрешал бы import('quill') всегда.\n */\n\nexport * from './lib/components/rich-editor';\nexport * from './lib/components/message-composer';\nexport * from './lib/components/chat';\nexport * from './lib/components/ai-chat';\nexport * from './lib/pipes';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["BEM_BLOCK"],"mappings":"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"}