@rtsee/ngx 0.0.120 → 0.0.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ngx/fesm2022/rtsee-ngx.mjs +1313 -86
- package/dist/ngx/fesm2022/rtsee-ngx.mjs.map +1 -1
- package/dist/ngx/index.d.ts +281 -14
- package/dist/ngx/src/lib/theme/containers/shell.scss +20 -0
- package/dist/ngx/src/lib/theme/events-manager/event-widgets.scss +133 -0
- package/dist/ngx/src/lib/theme/messenger/chat.scss +17 -0
- package/dist/ngx/src/lib/theme/messenger/chats-list.scss +4 -0
- package/dist/ngx/src/lib/theme/messenger/create-chat.scss +0 -5
- package/dist/ngx/src/lib/theme/messenger/messages-list.scss +19 -1
- package/dist/ngx/src/lib/theme/messenger/messenger-header.scss +16 -2
- package/dist/ngx/src/lib/theme/messenger/messenger.scss +26 -1
- package/package.json +11 -11
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, Input, Component, ViewChild, EventEmitter, Output, forwardRef, Directive, HostListener, reflectComponentType, DOCUMENT, Inject, ChangeDetectionStrategy, output, CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
|
3
|
-
import * as
|
|
3
|
+
import * as i1$3 from '@angular/common';
|
|
4
4
|
import { NgClass, NgIf, NgForOf, DecimalPipe, DatePipe, NgComponentOutlet, SlicePipe, JsonPipe, DOCUMENT as DOCUMENT$1, CommonModule, NgStyle, NgOptimizedImage } from '@angular/common';
|
|
5
5
|
import * as i1 from '@angular/forms';
|
|
6
6
|
import { FormsModule, FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
@@ -14,11 +14,11 @@ import { AuthEndpointsKeys, LS_TOKEN_LABEL, LS_USER_LABEL, DEFAULT_ROUTE_NAMES }
|
|
|
14
14
|
import * as i2 from '@angular/router';
|
|
15
15
|
import { RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
|
|
16
16
|
import * as i1$1 from '@angular/common/http';
|
|
17
|
-
import { RTSeeChatMemberRoles, RTSeeIllustratorEvents, RTSeeChatTypes, OzzyTaskStatus, getStoryTranslatorLanguage, STORY_TRANSLATOR_LANGUAGES } from '@rtsee/common';
|
|
17
|
+
import { RTSeeChatMemberRoles, RTSeeIllustratorEvents, RTSeeChatTypes, OzzyTaskStatus, CREATE_STORY_ACTION_NAME, EDIT_STORY_ACTION_NAME, CREATE_SLIDE_ACTION_NAME, EDIT_SLIDE_ACTION_NAME, getStoryTranslatorLanguage, STORY_TRANSLATOR_LANGUAGES } from '@rtsee/common';
|
|
18
18
|
import { sanitizeImageUrl, ManageAgentForm, RTSeeForm, RTSeeFormFieldRadioGroup, RTSeeFormField, RTSeeFormFieldImageUploader, fetchImageBlob, RTSeeRater } from '@rtsee/utilities-ui';
|
|
19
19
|
import { InputText } from 'primeng/inputtext';
|
|
20
20
|
import { InputGroup } from 'primeng/inputgroup';
|
|
21
|
-
import * as i2$
|
|
21
|
+
import * as i2$1 from 'primeng/message';
|
|
22
22
|
import { Message, MessageModule } from 'primeng/message';
|
|
23
23
|
import { Textarea } from 'primeng/textarea';
|
|
24
24
|
import { Checkbox } from 'primeng/checkbox';
|
|
@@ -31,7 +31,7 @@ import { ImageCropperComponent } from 'ngx-image-cropper';
|
|
|
31
31
|
import { Tooltip } from 'primeng/tooltip';
|
|
32
32
|
import { Fieldset } from 'primeng/fieldset';
|
|
33
33
|
import { DatePicker } from 'primeng/datepicker';
|
|
34
|
-
import { RTSeeManageChatInfo, RTSeeChatEvents, OzzyClientTaskEvents, OzzyWorkflowClientEvents, RTSeeMentionAutocomplete, RTSeeWorkflowAutocomplete } from '@rtsee/messenger';
|
|
34
|
+
import { RTSeeManageChatInfo, RTSeeChatEvents, OzzyClientTaskActionEvents, OzzyClientTaskEvents, OzzyWorkflowClientEvents, RTSeeMentionAutocomplete, RTSeeWorkflowAutocomplete } from '@rtsee/messenger';
|
|
35
35
|
import { InfiniteScrollDirective, InfiniteScrollModule } from 'ngx-infinite-scroll';
|
|
36
36
|
import dayjs from 'dayjs';
|
|
37
37
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
@@ -40,7 +40,7 @@ import { loadStripe } from '@stripe/stripe-js';
|
|
|
40
40
|
import { Card } from 'primeng/card';
|
|
41
41
|
import { CdkCopyToClipboard } from '@angular/cdk/clipboard';
|
|
42
42
|
import { Toast } from 'primeng/toast';
|
|
43
|
-
import * as i1$
|
|
43
|
+
import * as i1$4 from 'primeng/api';
|
|
44
44
|
import { MessageService } from 'primeng/api';
|
|
45
45
|
import Swiper from 'swiper';
|
|
46
46
|
import { Virtual, EffectCards } from 'swiper/modules';
|
|
@@ -1280,6 +1280,7 @@ class AddChatMemberComponent {
|
|
|
1280
1280
|
}
|
|
1281
1281
|
}
|
|
1282
1282
|
async copyLink() {
|
|
1283
|
+
this.messenger?.trackChatMemberInviteClicked?.(this.chatInfo?.chat, this.invitationLink);
|
|
1283
1284
|
try {
|
|
1284
1285
|
await navigator.clipboard.writeText(this.invitationLink);
|
|
1285
1286
|
this.linkCopied = true;
|
|
@@ -1403,6 +1404,7 @@ class ChatMembersComponent {
|
|
|
1403
1404
|
}
|
|
1404
1405
|
showAddMember() {
|
|
1405
1406
|
this.view = 'add';
|
|
1407
|
+
this.messenger?.trackChatMemberInviteClicked?.(this.chatInfo?.chat);
|
|
1406
1408
|
}
|
|
1407
1409
|
showEditAgent(memberId) {
|
|
1408
1410
|
this.editingAgentMemberId = memberId;
|
|
@@ -1573,6 +1575,9 @@ class ManageChatInfoComponent {
|
|
|
1573
1575
|
},
|
|
1574
1576
|
});
|
|
1575
1577
|
this.manageChatInfo.on('saved', (savedChat) => {
|
|
1578
|
+
if (!this.isEditMode) {
|
|
1579
|
+
this.messenger?.trackChatCreated?.(savedChat);
|
|
1580
|
+
}
|
|
1576
1581
|
this.chatSaved.emit(savedChat);
|
|
1577
1582
|
});
|
|
1578
1583
|
}
|
|
@@ -2444,6 +2449,808 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2444
2449
|
type: Input
|
|
2445
2450
|
}] } });
|
|
2446
2451
|
|
|
2452
|
+
/**
|
|
2453
|
+
* Full client-side representation of a single OzzyTaskAction.
|
|
2454
|
+
* Displays input, logs, output, and/or errors of the action.
|
|
2455
|
+
*/
|
|
2456
|
+
class RTSeeTaskActionComponent {
|
|
2457
|
+
constructor(cdr) {
|
|
2458
|
+
this.cdr = cdr;
|
|
2459
|
+
this.copied = null;
|
|
2460
|
+
this.subscribedAction = null;
|
|
2461
|
+
this.onChangedBound = () => this.onActionChanged();
|
|
2462
|
+
}
|
|
2463
|
+
ngOnInit() {
|
|
2464
|
+
this.subscribe();
|
|
2465
|
+
this.ensureLoaded();
|
|
2466
|
+
}
|
|
2467
|
+
ngOnChanges(changes) {
|
|
2468
|
+
if (changes['action'] && !changes['action'].firstChange) {
|
|
2469
|
+
this.subscribe();
|
|
2470
|
+
this.ensureLoaded();
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
ngOnDestroy() {
|
|
2474
|
+
this.unsubscribe();
|
|
2475
|
+
}
|
|
2476
|
+
get statusLabel() {
|
|
2477
|
+
switch (this.action?.status) {
|
|
2478
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2479
|
+
return 'Running';
|
|
2480
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2481
|
+
return 'Completed';
|
|
2482
|
+
case OzzyTaskStatus.FAIL:
|
|
2483
|
+
return 'Failed';
|
|
2484
|
+
default:
|
|
2485
|
+
return 'Ready';
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
get statusClass() {
|
|
2489
|
+
switch (this.action?.status) {
|
|
2490
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2491
|
+
return 'rts-task-action-status-running';
|
|
2492
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2493
|
+
return 'rts-task-action-status-success';
|
|
2494
|
+
case OzzyTaskStatus.FAIL:
|
|
2495
|
+
return 'rts-task-action-status-fail';
|
|
2496
|
+
default:
|
|
2497
|
+
return 'rts-task-action-status-ready';
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
get inputJson() {
|
|
2501
|
+
return this.toJson(this.action?.input);
|
|
2502
|
+
}
|
|
2503
|
+
get outputJson() {
|
|
2504
|
+
return this.toJson(this.action?.output);
|
|
2505
|
+
}
|
|
2506
|
+
get hasOutput() {
|
|
2507
|
+
return this.action?.output !== undefined && this.action?.output !== null;
|
|
2508
|
+
}
|
|
2509
|
+
get hasLogs() {
|
|
2510
|
+
return !!(this.action?.logs?.length || this.action?.liveText);
|
|
2511
|
+
}
|
|
2512
|
+
async copy(kind) {
|
|
2513
|
+
try {
|
|
2514
|
+
await navigator.clipboard.writeText(kind === 'input' ? this.inputJson : this.outputJson);
|
|
2515
|
+
this.copied = kind;
|
|
2516
|
+
this.cdr.detectChanges();
|
|
2517
|
+
setTimeout(() => {
|
|
2518
|
+
this.copied = null;
|
|
2519
|
+
this.cdr.detectChanges();
|
|
2520
|
+
}, 1500);
|
|
2521
|
+
}
|
|
2522
|
+
catch (e) {
|
|
2523
|
+
console.log('Failed to copy', e);
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
trackLog(index, log) {
|
|
2527
|
+
return `${index}-${log.level}`;
|
|
2528
|
+
}
|
|
2529
|
+
ensureLoaded() {
|
|
2530
|
+
if (this.action && !this.action.loaded && !this.action.isRunning) {
|
|
2531
|
+
void this.action.load();
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
toJson(value) {
|
|
2535
|
+
if (value === undefined || value === null) {
|
|
2536
|
+
return '';
|
|
2537
|
+
}
|
|
2538
|
+
try {
|
|
2539
|
+
return JSON.stringify(value, null, 2);
|
|
2540
|
+
}
|
|
2541
|
+
catch {
|
|
2542
|
+
return String(value);
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
subscribe() {
|
|
2546
|
+
if (this.subscribedAction === this.action) {
|
|
2547
|
+
return;
|
|
2548
|
+
}
|
|
2549
|
+
this.unsubscribe();
|
|
2550
|
+
if (this.action) {
|
|
2551
|
+
this.subscribedAction = this.action;
|
|
2552
|
+
this.action.on(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
unsubscribe() {
|
|
2556
|
+
this.subscribedAction?.off(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
2557
|
+
this.subscribedAction = null;
|
|
2558
|
+
}
|
|
2559
|
+
onActionChanged() {
|
|
2560
|
+
this.cdr.detectChanges();
|
|
2561
|
+
const el = this.logsContainer?.nativeElement;
|
|
2562
|
+
if (el) {
|
|
2563
|
+
el.scrollTop = el.scrollHeight;
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeTaskActionComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2567
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RTSeeTaskActionComponent, isStandalone: true, selector: "rtsee-task-action", inputs: { action: "action" }, viewQueries: [{ propertyName: "logsContainer", first: true, predicate: ["logsContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-task-action\" [ngClass]=\"statusClass\">\n @if (action) {\n <div class=\"rts-task-action-header\">\n <div class=\"rts-task-action-identity\">\n <span class=\"rts-task-action-icon\">\u26A1</span>\n <div class=\"rts-task-action-titles\">\n <span class=\"rts-task-action-name\">{{ action.name || 'Action' }}</span>\n <span class=\"rts-task-action-id\" [title]=\"action.id\">#{{ action.id }}</span>\n </div>\n </div>\n <span class=\"rts-task-action-status\">\n <span class=\"rts-task-action-status-dot\"></span>\n {{ statusLabel }}\n </span>\n </div>\n\n <!-- Input -->\n <div class=\"rts-task-action-section\">\n <div class=\"rts-task-action-section-head\">\n <span class=\"rts-task-action-section-label\">Input</span>\n @if (inputJson) {\n <button type=\"button\" class=\"rts-task-action-copy\" (click)=\"copy('input')\">\n {{ copied === 'input' ? 'Copied' : 'Copy' }}\n </button>\n }\n </div>\n @if (inputJson) {\n <pre class=\"rts-task-action-code\"><code>{{ inputJson }}</code></pre>\n } @else if (action.loading) {\n <div class=\"rts-task-action-placeholder\">Loading\u2026</div>\n } @else {\n <div class=\"rts-task-action-placeholder\">No input</div>\n }\n </div>\n\n <!-- Logs -->\n @if (hasLogs || action.isRunning || action.loading) {\n <div class=\"rts-task-action-section\">\n <div class=\"rts-task-action-section-head\">\n <span class=\"rts-task-action-section-label\">Logs</span>\n @if (action.isRunning) {\n <span class=\"rts-task-action-live\">LIVE</span>\n }\n </div>\n <div #logsContainer class=\"rts-task-action-terminal\">\n @for (log of action.logs; track $index) {\n <div class=\"rts-task-action-log\" [ngClass]=\"'rts-task-action-log-' + log.level\">\n <span class=\"rts-task-action-log-time\">{{ log.createdAt | date: 'HH:mm:ss' }}</span>\n <span class=\"rts-task-action-log-level\">{{ log.level }}</span>\n <span class=\"rts-task-action-log-message\">{{ log.message }}</span>\n </div>\n }\n @if (action.liveText) {\n <div class=\"rts-task-action-live-text\">{{ action.liveText }}@if (action.isRunning) {<span class=\"rts-task-action-cursor\"></span>}</div>\n } @else if (action.isRunning && !action.logs.length) {\n <div class=\"rts-task-action-log rts-task-action-log-info\">\n <span class=\"rts-task-action-log-message\">Waiting for logs\u2026</span>\n </div>\n } @else if (action.loading && !action.logs.length) {\n <div class=\"rts-task-action-log rts-task-action-log-info\">\n <span class=\"rts-task-action-log-message\">Loading logs\u2026</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Output -->\n @if (hasOutput) {\n <div class=\"rts-task-action-section rts-task-action-section-output\">\n <div class=\"rts-task-action-section-head\">\n <span class=\"rts-task-action-section-label\">Output</span>\n <button type=\"button\" class=\"rts-task-action-copy\" (click)=\"copy('output')\">\n {{ copied === 'output' ? 'Copied' : 'Copy' }}\n </button>\n </div>\n <pre class=\"rts-task-action-code\"><code>{{ outputJson }}</code></pre>\n </div>\n }\n\n @if (action.errors.length) {\n <div class=\"rts-task-action-errors\">\n @for (error of action.errors; track $index) {\n <div class=\"rts-task-action-error\">{{ error.message }}</div>\n }\n </div>\n }\n\n @if (action.requestError) {\n <div class=\"rts-task-action-errors\">\n <div class=\"rts-task-action-error\">{{ action.requestError }}</div>\n </div>\n }\n } @else {\n <div class=\"rts-task-action-placeholder\">Action is not available yet.</div>\n }\n</div>\n", styles: [":host{display:block;--rts-task-action-accent: #8b5cf6;--rts-task-action-accent-2: #6366f1;--rts-task-action-success: #10b981;--rts-task-action-fail: #f43f5e;--rts-task-action-warn: #f59e0b}.rts-task-action{position:relative;display:flex;flex-direction:column;gap:8px;padding:10px 12px;border-radius:10px;background:var(--rts-bg-secondary, #fff);border:1px solid rgba(139,92,246,.22);font-size:12.5px}.rts-task-action-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-task-action-identity{display:flex;align-items:center;gap:8px;min-width:0}.rts-task-action-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;flex-shrink:0;border-radius:6px;color:#fff;font-size:12px;background:linear-gradient(135deg,var(--rts-task-action-accent-2),var(--rts-task-action-accent))}.rts-task-action-titles{display:flex;flex-direction:column;min-width:0}.rts-task-action-name{font-weight:600;color:var(--rts-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-task-action-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-task-action-status{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0;color:var(--rts-task-action-accent);background:#8b5cf61f}.rts-task-action-status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.rts-task-action-status-running .rts-task-action-status-dot{animation:rts-task-action-pulse 1s ease-in-out infinite}.rts-task-action-status-success .rts-task-action-status{color:var(--rts-task-action-success);background:#10b9811f}.rts-task-action-status-fail .rts-task-action-status{color:var(--rts-task-action-fail);background:#f43f5e1f}.rts-task-action-section{display:flex;flex-direction:column;gap:4px}.rts-task-action-section-head{display:flex;align-items:center;justify-content:space-between}.rts-task-action-section-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-task-action-copy{border:none;background:transparent;color:var(--rts-task-action-accent);font-size:11px;cursor:pointer;padding:0 2px}.rts-task-action-copy:hover{text-decoration:underline}.rts-task-action-live{font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--rts-task-action-fail);animation:rts-task-action-pulse 1.2s ease-in-out infinite}.rts-task-action-code,.rts-task-action-terminal{margin:0;padding:8px 10px;border-radius:7px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.5;max-height:180px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid rgba(139,92,246,.18)}.rts-task-action-section-output .rts-task-action-code{border-color:#10b98159}.rts-task-action-log{display:flex;gap:8px;align-items:baseline}.rts-task-action-log-time{color:#6b6f8a;flex-shrink:0}.rts-task-action-log-level{flex-shrink:0;min-width:34px;text-transform:uppercase;font-size:9.5px;font-weight:700;color:#a78bfa}.rts-task-action-log-warn .rts-task-action-log-level{color:var(--rts-task-action-warn)}.rts-task-action-log-error .rts-task-action-log-level,.rts-task-action-log-error .rts-task-action-log-message{color:#fb7185}.rts-task-action-live-text{margin-top:6px;padding-top:6px;border-top:1px dashed rgba(139,92,246,.25);color:#c4b5fd;white-space:pre-wrap}.rts-task-action-cursor{display:inline-block;width:6px;height:12px;margin-left:1px;vertical-align:text-bottom;background:#a78bfa;animation:rts-task-action-blink .8s step-end infinite}.rts-task-action-placeholder{font-size:11.5px;color:var(--rts-text-secondary, #8a8fa3);font-style:italic}.rts-task-action-errors{display:flex;flex-direction:column;gap:4px}.rts-task-action-error{padding:6px 10px;border-radius:6px;font-size:11.5px;color:var(--rts-task-action-fail);background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}@keyframes rts-task-action-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rts-task-action-blink{0%,to{opacity:1}50%{opacity:0}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: DatePipe, name: "date" }] }); }
|
|
2568
|
+
}
|
|
2569
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeTaskActionComponent, decorators: [{
|
|
2570
|
+
type: Component,
|
|
2571
|
+
args: [{ selector: 'rtsee-task-action', standalone: true, imports: [NgClass, DatePipe], template: "<div class=\"rts-task-action\" [ngClass]=\"statusClass\">\n @if (action) {\n <div class=\"rts-task-action-header\">\n <div class=\"rts-task-action-identity\">\n <span class=\"rts-task-action-icon\">\u26A1</span>\n <div class=\"rts-task-action-titles\">\n <span class=\"rts-task-action-name\">{{ action.name || 'Action' }}</span>\n <span class=\"rts-task-action-id\" [title]=\"action.id\">#{{ action.id }}</span>\n </div>\n </div>\n <span class=\"rts-task-action-status\">\n <span class=\"rts-task-action-status-dot\"></span>\n {{ statusLabel }}\n </span>\n </div>\n\n <!-- Input -->\n <div class=\"rts-task-action-section\">\n <div class=\"rts-task-action-section-head\">\n <span class=\"rts-task-action-section-label\">Input</span>\n @if (inputJson) {\n <button type=\"button\" class=\"rts-task-action-copy\" (click)=\"copy('input')\">\n {{ copied === 'input' ? 'Copied' : 'Copy' }}\n </button>\n }\n </div>\n @if (inputJson) {\n <pre class=\"rts-task-action-code\"><code>{{ inputJson }}</code></pre>\n } @else if (action.loading) {\n <div class=\"rts-task-action-placeholder\">Loading\u2026</div>\n } @else {\n <div class=\"rts-task-action-placeholder\">No input</div>\n }\n </div>\n\n <!-- Logs -->\n @if (hasLogs || action.isRunning || action.loading) {\n <div class=\"rts-task-action-section\">\n <div class=\"rts-task-action-section-head\">\n <span class=\"rts-task-action-section-label\">Logs</span>\n @if (action.isRunning) {\n <span class=\"rts-task-action-live\">LIVE</span>\n }\n </div>\n <div #logsContainer class=\"rts-task-action-terminal\">\n @for (log of action.logs; track $index) {\n <div class=\"rts-task-action-log\" [ngClass]=\"'rts-task-action-log-' + log.level\">\n <span class=\"rts-task-action-log-time\">{{ log.createdAt | date: 'HH:mm:ss' }}</span>\n <span class=\"rts-task-action-log-level\">{{ log.level }}</span>\n <span class=\"rts-task-action-log-message\">{{ log.message }}</span>\n </div>\n }\n @if (action.liveText) {\n <div class=\"rts-task-action-live-text\">{{ action.liveText }}@if (action.isRunning) {<span class=\"rts-task-action-cursor\"></span>}</div>\n } @else if (action.isRunning && !action.logs.length) {\n <div class=\"rts-task-action-log rts-task-action-log-info\">\n <span class=\"rts-task-action-log-message\">Waiting for logs\u2026</span>\n </div>\n } @else if (action.loading && !action.logs.length) {\n <div class=\"rts-task-action-log rts-task-action-log-info\">\n <span class=\"rts-task-action-log-message\">Loading logs\u2026</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Output -->\n @if (hasOutput) {\n <div class=\"rts-task-action-section rts-task-action-section-output\">\n <div class=\"rts-task-action-section-head\">\n <span class=\"rts-task-action-section-label\">Output</span>\n <button type=\"button\" class=\"rts-task-action-copy\" (click)=\"copy('output')\">\n {{ copied === 'output' ? 'Copied' : 'Copy' }}\n </button>\n </div>\n <pre class=\"rts-task-action-code\"><code>{{ outputJson }}</code></pre>\n </div>\n }\n\n @if (action.errors.length) {\n <div class=\"rts-task-action-errors\">\n @for (error of action.errors; track $index) {\n <div class=\"rts-task-action-error\">{{ error.message }}</div>\n }\n </div>\n }\n\n @if (action.requestError) {\n <div class=\"rts-task-action-errors\">\n <div class=\"rts-task-action-error\">{{ action.requestError }}</div>\n </div>\n }\n } @else {\n <div class=\"rts-task-action-placeholder\">Action is not available yet.</div>\n }\n</div>\n", styles: [":host{display:block;--rts-task-action-accent: #8b5cf6;--rts-task-action-accent-2: #6366f1;--rts-task-action-success: #10b981;--rts-task-action-fail: #f43f5e;--rts-task-action-warn: #f59e0b}.rts-task-action{position:relative;display:flex;flex-direction:column;gap:8px;padding:10px 12px;border-radius:10px;background:var(--rts-bg-secondary, #fff);border:1px solid rgba(139,92,246,.22);font-size:12.5px}.rts-task-action-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-task-action-identity{display:flex;align-items:center;gap:8px;min-width:0}.rts-task-action-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;flex-shrink:0;border-radius:6px;color:#fff;font-size:12px;background:linear-gradient(135deg,var(--rts-task-action-accent-2),var(--rts-task-action-accent))}.rts-task-action-titles{display:flex;flex-direction:column;min-width:0}.rts-task-action-name{font-weight:600;color:var(--rts-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-task-action-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-task-action-status{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0;color:var(--rts-task-action-accent);background:#8b5cf61f}.rts-task-action-status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.rts-task-action-status-running .rts-task-action-status-dot{animation:rts-task-action-pulse 1s ease-in-out infinite}.rts-task-action-status-success .rts-task-action-status{color:var(--rts-task-action-success);background:#10b9811f}.rts-task-action-status-fail .rts-task-action-status{color:var(--rts-task-action-fail);background:#f43f5e1f}.rts-task-action-section{display:flex;flex-direction:column;gap:4px}.rts-task-action-section-head{display:flex;align-items:center;justify-content:space-between}.rts-task-action-section-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-task-action-copy{border:none;background:transparent;color:var(--rts-task-action-accent);font-size:11px;cursor:pointer;padding:0 2px}.rts-task-action-copy:hover{text-decoration:underline}.rts-task-action-live{font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--rts-task-action-fail);animation:rts-task-action-pulse 1.2s ease-in-out infinite}.rts-task-action-code,.rts-task-action-terminal{margin:0;padding:8px 10px;border-radius:7px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.5;max-height:180px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid rgba(139,92,246,.18)}.rts-task-action-section-output .rts-task-action-code{border-color:#10b98159}.rts-task-action-log{display:flex;gap:8px;align-items:baseline}.rts-task-action-log-time{color:#6b6f8a;flex-shrink:0}.rts-task-action-log-level{flex-shrink:0;min-width:34px;text-transform:uppercase;font-size:9.5px;font-weight:700;color:#a78bfa}.rts-task-action-log-warn .rts-task-action-log-level{color:var(--rts-task-action-warn)}.rts-task-action-log-error .rts-task-action-log-level,.rts-task-action-log-error .rts-task-action-log-message{color:#fb7185}.rts-task-action-live-text{margin-top:6px;padding-top:6px;border-top:1px dashed rgba(139,92,246,.25);color:#c4b5fd;white-space:pre-wrap}.rts-task-action-cursor{display:inline-block;width:6px;height:12px;margin-left:1px;vertical-align:text-bottom;background:#a78bfa;animation:rts-task-action-blink .8s step-end infinite}.rts-task-action-placeholder{font-size:11.5px;color:var(--rts-text-secondary, #8a8fa3);font-style:italic}.rts-task-action-errors{display:flex;flex-direction:column;gap:4px}.rts-task-action-error{padding:6px 10px;border-radius:6px;font-size:11.5px;color:var(--rts-task-action-fail);background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}@keyframes rts-task-action-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rts-task-action-blink{0%,to{opacity:1}50%{opacity:0}}\n"] }]
|
|
2572
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { action: [{
|
|
2573
|
+
type: Input
|
|
2574
|
+
}], logsContainer: [{
|
|
2575
|
+
type: ViewChild,
|
|
2576
|
+
args: ['logsContainer']
|
|
2577
|
+
}] } });
|
|
2578
|
+
|
|
2579
|
+
class DefaultTaskActionThumbnailComponent {
|
|
2580
|
+
constructor() {
|
|
2581
|
+
this.expanded = false;
|
|
2582
|
+
}
|
|
2583
|
+
get statusClass() {
|
|
2584
|
+
switch (this.action?.status) {
|
|
2585
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2586
|
+
return 'rts-action-thumb-status-success';
|
|
2587
|
+
case OzzyTaskStatus.FAIL:
|
|
2588
|
+
return 'rts-action-thumb-status-fail';
|
|
2589
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2590
|
+
return 'rts-action-thumb-status-running';
|
|
2591
|
+
default:
|
|
2592
|
+
return 'rts-action-thumb-status-ready';
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
onToggle() {
|
|
2596
|
+
this.toggleExpand?.();
|
|
2597
|
+
}
|
|
2598
|
+
onButtonClick(event) {
|
|
2599
|
+
event.stopPropagation();
|
|
2600
|
+
this.toggleExpand?.();
|
|
2601
|
+
}
|
|
2602
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionThumbnailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2603
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: DefaultTaskActionThumbnailComponent, isStandalone: true, selector: "rtsee-default-task-action-thumbnail", inputs: { action: "action", task: "task", expanded: "expanded", toggleExpand: "toggleExpand" }, ngImport: i0, template: `
|
|
2604
|
+
<div class="rts-action-thumb-default" [ngClass]="statusClass" (click)="onToggle()">
|
|
2605
|
+
<div class="rts-action-thumb-left">
|
|
2606
|
+
<span class="rts-action-thumb-dot"></span>
|
|
2607
|
+
<span class="rts-action-thumb-name" [title]="action?.name || 'Action'">
|
|
2608
|
+
{{ action?.name || 'Action' }}
|
|
2609
|
+
</span>
|
|
2610
|
+
</div>
|
|
2611
|
+
<button type="button"
|
|
2612
|
+
class="rts-action-thumb-expand"
|
|
2613
|
+
(click)="onButtonClick($event)"
|
|
2614
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2615
|
+
>
|
|
2616
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2617
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2618
|
+
</button>
|
|
2619
|
+
</div>
|
|
2620
|
+
`, isInline: true, styles: [".rts-action-thumb-default{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 10px;border-radius:8px;background:#8b5cf60f;border:1px solid rgba(139,92,246,.18);cursor:pointer;transition:background .15s ease,border-color .15s ease}.rts-action-thumb-default:hover{background:#8b5cf61c;border-color:#8b5cf652}.rts-action-thumb-left{display:flex;align-items:center;gap:8px;min-width:0}.rts-action-thumb-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;background:#8b5cf6}.rts-action-thumb-status-success .rts-action-thumb-dot{background:#10b981}.rts-action-thumb-status-fail .rts-action-thumb-dot{background:#f43f5e}.rts-action-thumb-status-running .rts-action-thumb-dot{background:#8b5cf6;animation:rts-thumb-pulse 1s ease-in-out infinite}.rts-action-thumb-name{font-size:12px;font-weight:600;color:var(--rts-text-primary, #1f2430);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-action-thumb-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#8b5cf61f;color:#8b5cf6;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;flex-shrink:0}.rts-action-thumb-expand:hover{background:#8b5cf638}@keyframes rts-thumb-pulse{0%,to{opacity:1}50%{opacity:.35}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
2621
|
+
}
|
|
2622
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionThumbnailComponent, decorators: [{
|
|
2623
|
+
type: Component,
|
|
2624
|
+
args: [{ selector: 'rtsee-default-task-action-thumbnail', standalone: true, imports: [NgClass], template: `
|
|
2625
|
+
<div class="rts-action-thumb-default" [ngClass]="statusClass" (click)="onToggle()">
|
|
2626
|
+
<div class="rts-action-thumb-left">
|
|
2627
|
+
<span class="rts-action-thumb-dot"></span>
|
|
2628
|
+
<span class="rts-action-thumb-name" [title]="action?.name || 'Action'">
|
|
2629
|
+
{{ action?.name || 'Action' }}
|
|
2630
|
+
</span>
|
|
2631
|
+
</div>
|
|
2632
|
+
<button type="button"
|
|
2633
|
+
class="rts-action-thumb-expand"
|
|
2634
|
+
(click)="onButtonClick($event)"
|
|
2635
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2636
|
+
>
|
|
2637
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2638
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2639
|
+
</button>
|
|
2640
|
+
</div>
|
|
2641
|
+
`, styles: [".rts-action-thumb-default{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 10px;border-radius:8px;background:#8b5cf60f;border:1px solid rgba(139,92,246,.18);cursor:pointer;transition:background .15s ease,border-color .15s ease}.rts-action-thumb-default:hover{background:#8b5cf61c;border-color:#8b5cf652}.rts-action-thumb-left{display:flex;align-items:center;gap:8px;min-width:0}.rts-action-thumb-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;background:#8b5cf6}.rts-action-thumb-status-success .rts-action-thumb-dot{background:#10b981}.rts-action-thumb-status-fail .rts-action-thumb-dot{background:#f43f5e}.rts-action-thumb-status-running .rts-action-thumb-dot{background:#8b5cf6;animation:rts-thumb-pulse 1s ease-in-out infinite}.rts-action-thumb-name{font-size:12px;font-weight:600;color:var(--rts-text-primary, #1f2430);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-action-thumb-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#8b5cf61f;color:#8b5cf6;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;flex-shrink:0}.rts-action-thumb-expand:hover{background:#8b5cf638}@keyframes rts-thumb-pulse{0%,to{opacity:1}50%{opacity:.35}}\n"] }]
|
|
2642
|
+
}], propDecorators: { action: [{
|
|
2643
|
+
type: Input
|
|
2644
|
+
}], task: [{
|
|
2645
|
+
type: Input
|
|
2646
|
+
}], expanded: [{
|
|
2647
|
+
type: Input
|
|
2648
|
+
}], toggleExpand: [{
|
|
2649
|
+
type: Input
|
|
2650
|
+
}] } });
|
|
2651
|
+
|
|
2652
|
+
/**
|
|
2653
|
+
* Custom task-action thumbnail widget for Story creation / update actions.
|
|
2654
|
+
* Displays story-name, recommendedAge, friendlyUrl, and 2-line truncated
|
|
2655
|
+
* description, moralMeaning, and history with full text tooltip on hover.
|
|
2656
|
+
*/
|
|
2657
|
+
class StoryTaskActionThumbnailComponent {
|
|
2658
|
+
constructor() {
|
|
2659
|
+
this.expanded = false;
|
|
2660
|
+
}
|
|
2661
|
+
get storyData() {
|
|
2662
|
+
return {
|
|
2663
|
+
...(this.action?.input || {}),
|
|
2664
|
+
...(this.action?.output || {}),
|
|
2665
|
+
};
|
|
2666
|
+
}
|
|
2667
|
+
get storyName() {
|
|
2668
|
+
return this.storyData.name || this.action?.name || 'Story';
|
|
2669
|
+
}
|
|
2670
|
+
get recommendedAge() {
|
|
2671
|
+
return this.storyData.recommendedAge || '';
|
|
2672
|
+
}
|
|
2673
|
+
get friendlyUrl() {
|
|
2674
|
+
return this.storyData.friendlyUrl || '';
|
|
2675
|
+
}
|
|
2676
|
+
get description() {
|
|
2677
|
+
return this.storyData.description || '';
|
|
2678
|
+
}
|
|
2679
|
+
get moralMeaning() {
|
|
2680
|
+
return this.storyData.moralMeaning || '';
|
|
2681
|
+
}
|
|
2682
|
+
get history() {
|
|
2683
|
+
return this.storyData.history || '';
|
|
2684
|
+
}
|
|
2685
|
+
get statusClass() {
|
|
2686
|
+
switch (this.action?.status) {
|
|
2687
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2688
|
+
return 'rts-story-thumb-status-success';
|
|
2689
|
+
case OzzyTaskStatus.FAIL:
|
|
2690
|
+
return 'rts-story-thumb-status-fail';
|
|
2691
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2692
|
+
return 'rts-story-thumb-status-running';
|
|
2693
|
+
default:
|
|
2694
|
+
return 'rts-story-thumb-status-ready';
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
onToggle() {
|
|
2698
|
+
this.toggleExpand?.();
|
|
2699
|
+
}
|
|
2700
|
+
onButtonClick(event) {
|
|
2701
|
+
event.stopPropagation();
|
|
2702
|
+
this.toggleExpand?.();
|
|
2703
|
+
}
|
|
2704
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryTaskActionThumbnailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2705
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryTaskActionThumbnailComponent, isStandalone: true, selector: "rtsee-story-task-action-thumbnail", inputs: { action: "action", task: "task", expanded: "expanded", toggleExpand: "toggleExpand" }, ngImport: i0, template: `
|
|
2706
|
+
<div class="rts-story-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2707
|
+
<div class="rts-story-thumb-header">
|
|
2708
|
+
<div class="rts-story-thumb-title-wrap">
|
|
2709
|
+
<span class="rts-story-thumb-dot"></span>
|
|
2710
|
+
<span class="rts-story-thumb-badge">Story</span>
|
|
2711
|
+
<span class="rts-story-thumb-name" [title]="storyName">{{ storyName }}</span>
|
|
2712
|
+
@if (recommendedAge) {
|
|
2713
|
+
<span class="rts-story-thumb-age" [title]="'Recommended age: ' + recommendedAge">
|
|
2714
|
+
{{ recommendedAge }}
|
|
2715
|
+
</span>
|
|
2716
|
+
}
|
|
2717
|
+
@if (friendlyUrl) {
|
|
2718
|
+
<span class="rts-story-thumb-url" [title]="friendlyUrl">/{{ friendlyUrl }}</span>
|
|
2719
|
+
}
|
|
2720
|
+
</div>
|
|
2721
|
+
<button type="button"
|
|
2722
|
+
class="rts-story-thumb-expand"
|
|
2723
|
+
(click)="onButtonClick($event)"
|
|
2724
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2725
|
+
>
|
|
2726
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2727
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2728
|
+
</button>
|
|
2729
|
+
</div>
|
|
2730
|
+
|
|
2731
|
+
@if (description || moralMeaning || history) {
|
|
2732
|
+
<div class="rts-story-thumb-fields">
|
|
2733
|
+
@if (description) {
|
|
2734
|
+
<div class="rts-story-thumb-field">
|
|
2735
|
+
<span class="rts-story-thumb-field-label">Description</span>
|
|
2736
|
+
<p class="rts-story-thumb-truncated" [title]="description">{{ description }}</p>
|
|
2737
|
+
</div>
|
|
2738
|
+
}
|
|
2739
|
+
@if (moralMeaning) {
|
|
2740
|
+
<div class="rts-story-thumb-field">
|
|
2741
|
+
<span class="rts-story-thumb-field-label">Moral Meaning</span>
|
|
2742
|
+
<p class="rts-story-thumb-truncated" [title]="moralMeaning">{{ moralMeaning }}</p>
|
|
2743
|
+
</div>
|
|
2744
|
+
}
|
|
2745
|
+
@if (history) {
|
|
2746
|
+
<div class="rts-story-thumb-field">
|
|
2747
|
+
<span class="rts-story-thumb-field-label">History</span>
|
|
2748
|
+
<p class="rts-story-thumb-truncated" [title]="history">{{ history }}</p>
|
|
2749
|
+
</div>
|
|
2750
|
+
}
|
|
2751
|
+
</div>
|
|
2752
|
+
}
|
|
2753
|
+
</div>
|
|
2754
|
+
`, isInline: true, styles: [".rts-story-thumb{display:flex;flex-direction:column;gap:6px;padding:9px 11px;border-radius:9px;background:#6366f10f;border:1px solid rgba(99,102,241,.22);cursor:pointer;transition:background .15s ease,border-color .15s ease}.rts-story-thumb:hover{background:#6366f11c;border-color:#6366f15c}.rts-story-thumb-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-story-thumb-title-wrap{display:flex;align-items:center;gap:6px;min-width:0;flex-wrap:wrap}.rts-story-thumb-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;background:#8b5cf6}.rts-story-thumb-status-success .rts-story-thumb-dot{background:#10b981}.rts-story-thumb-status-fail .rts-story-thumb-dot{background:#f43f5e}.rts-story-thumb-badge{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:1px 6px;border-radius:4px;background:#6366f126;color:#6366f1;flex-shrink:0}.rts-story-thumb-name{font-size:12.5px;font-weight:700;color:var(--rts-text-primary, #1f2430);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-story-thumb-age{font-size:10.5px;font-weight:700;padding:1px 6px;border-radius:999px;background:#10b98124;color:#10b981;flex-shrink:0}.rts-story-thumb-url{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.rts-story-thumb-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#8b5cf61f;color:#8b5cf6;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;flex-shrink:0}.rts-story-thumb-expand:hover{background:#8b5cf638}.rts-story-thumb-fields{display:flex;flex-direction:column;gap:5px;padding-top:2px}.rts-story-thumb-field{display:flex;flex-direction:column;gap:1px}.rts-story-thumb-field-label{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-thumb-truncated{margin:0;font-size:11.5px;line-height:1.4;color:var(--rts-text-primary, #1f2430);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;word-break:break-word}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
2755
|
+
}
|
|
2756
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryTaskActionThumbnailComponent, decorators: [{
|
|
2757
|
+
type: Component,
|
|
2758
|
+
args: [{ selector: 'rtsee-story-task-action-thumbnail', standalone: true, imports: [NgClass], template: `
|
|
2759
|
+
<div class="rts-story-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2760
|
+
<div class="rts-story-thumb-header">
|
|
2761
|
+
<div class="rts-story-thumb-title-wrap">
|
|
2762
|
+
<span class="rts-story-thumb-dot"></span>
|
|
2763
|
+
<span class="rts-story-thumb-badge">Story</span>
|
|
2764
|
+
<span class="rts-story-thumb-name" [title]="storyName">{{ storyName }}</span>
|
|
2765
|
+
@if (recommendedAge) {
|
|
2766
|
+
<span class="rts-story-thumb-age" [title]="'Recommended age: ' + recommendedAge">
|
|
2767
|
+
{{ recommendedAge }}
|
|
2768
|
+
</span>
|
|
2769
|
+
}
|
|
2770
|
+
@if (friendlyUrl) {
|
|
2771
|
+
<span class="rts-story-thumb-url" [title]="friendlyUrl">/{{ friendlyUrl }}</span>
|
|
2772
|
+
}
|
|
2773
|
+
</div>
|
|
2774
|
+
<button type="button"
|
|
2775
|
+
class="rts-story-thumb-expand"
|
|
2776
|
+
(click)="onButtonClick($event)"
|
|
2777
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2778
|
+
>
|
|
2779
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2780
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2781
|
+
</button>
|
|
2782
|
+
</div>
|
|
2783
|
+
|
|
2784
|
+
@if (description || moralMeaning || history) {
|
|
2785
|
+
<div class="rts-story-thumb-fields">
|
|
2786
|
+
@if (description) {
|
|
2787
|
+
<div class="rts-story-thumb-field">
|
|
2788
|
+
<span class="rts-story-thumb-field-label">Description</span>
|
|
2789
|
+
<p class="rts-story-thumb-truncated" [title]="description">{{ description }}</p>
|
|
2790
|
+
</div>
|
|
2791
|
+
}
|
|
2792
|
+
@if (moralMeaning) {
|
|
2793
|
+
<div class="rts-story-thumb-field">
|
|
2794
|
+
<span class="rts-story-thumb-field-label">Moral Meaning</span>
|
|
2795
|
+
<p class="rts-story-thumb-truncated" [title]="moralMeaning">{{ moralMeaning }}</p>
|
|
2796
|
+
</div>
|
|
2797
|
+
}
|
|
2798
|
+
@if (history) {
|
|
2799
|
+
<div class="rts-story-thumb-field">
|
|
2800
|
+
<span class="rts-story-thumb-field-label">History</span>
|
|
2801
|
+
<p class="rts-story-thumb-truncated" [title]="history">{{ history }}</p>
|
|
2802
|
+
</div>
|
|
2803
|
+
}
|
|
2804
|
+
</div>
|
|
2805
|
+
}
|
|
2806
|
+
</div>
|
|
2807
|
+
`, styles: [".rts-story-thumb{display:flex;flex-direction:column;gap:6px;padding:9px 11px;border-radius:9px;background:#6366f10f;border:1px solid rgba(99,102,241,.22);cursor:pointer;transition:background .15s ease,border-color .15s ease}.rts-story-thumb:hover{background:#6366f11c;border-color:#6366f15c}.rts-story-thumb-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-story-thumb-title-wrap{display:flex;align-items:center;gap:6px;min-width:0;flex-wrap:wrap}.rts-story-thumb-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;background:#8b5cf6}.rts-story-thumb-status-success .rts-story-thumb-dot{background:#10b981}.rts-story-thumb-status-fail .rts-story-thumb-dot{background:#f43f5e}.rts-story-thumb-badge{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:1px 6px;border-radius:4px;background:#6366f126;color:#6366f1;flex-shrink:0}.rts-story-thumb-name{font-size:12.5px;font-weight:700;color:var(--rts-text-primary, #1f2430);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-story-thumb-age{font-size:10.5px;font-weight:700;padding:1px 6px;border-radius:999px;background:#10b98124;color:#10b981;flex-shrink:0}.rts-story-thumb-url{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.rts-story-thumb-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#8b5cf61f;color:#8b5cf6;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;flex-shrink:0}.rts-story-thumb-expand:hover{background:#8b5cf638}.rts-story-thumb-fields{display:flex;flex-direction:column;gap:5px;padding-top:2px}.rts-story-thumb-field{display:flex;flex-direction:column;gap:1px}.rts-story-thumb-field-label{font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-thumb-truncated{margin:0;font-size:11.5px;line-height:1.4;color:var(--rts-text-primary, #1f2430);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;word-break:break-word}\n"] }]
|
|
2808
|
+
}], propDecorators: { action: [{
|
|
2809
|
+
type: Input
|
|
2810
|
+
}], task: [{
|
|
2811
|
+
type: Input
|
|
2812
|
+
}], expanded: [{
|
|
2813
|
+
type: Input
|
|
2814
|
+
}], toggleExpand: [{
|
|
2815
|
+
type: Input
|
|
2816
|
+
}] } });
|
|
2817
|
+
|
|
2818
|
+
/**
|
|
2819
|
+
* Custom task-action thumbnail widget for Slide creation / update actions.
|
|
2820
|
+
* Displays slide number and 2 first truncated lines of slide text with full text tooltip on hover.
|
|
2821
|
+
*/
|
|
2822
|
+
class SlideTaskActionThumbnailComponent {
|
|
2823
|
+
constructor() {
|
|
2824
|
+
this.expanded = false;
|
|
2825
|
+
}
|
|
2826
|
+
get slideData() {
|
|
2827
|
+
return {
|
|
2828
|
+
...(this.action?.input || {}),
|
|
2829
|
+
...(this.action?.output || {}),
|
|
2830
|
+
};
|
|
2831
|
+
}
|
|
2832
|
+
get slideNumber() {
|
|
2833
|
+
return this.slideData.slideNumber ?? '-';
|
|
2834
|
+
}
|
|
2835
|
+
get slideText() {
|
|
2836
|
+
return this.slideData.text || '';
|
|
2837
|
+
}
|
|
2838
|
+
get statusClass() {
|
|
2839
|
+
switch (this.action?.status) {
|
|
2840
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2841
|
+
return 'rts-slide-thumb-status-success';
|
|
2842
|
+
case OzzyTaskStatus.FAIL:
|
|
2843
|
+
return 'rts-slide-thumb-status-fail';
|
|
2844
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2845
|
+
return 'rts-slide-thumb-status-running';
|
|
2846
|
+
default:
|
|
2847
|
+
return 'rts-slide-thumb-status-ready';
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
onToggle() {
|
|
2851
|
+
this.toggleExpand?.();
|
|
2852
|
+
}
|
|
2853
|
+
onButtonClick(event) {
|
|
2854
|
+
event.stopPropagation();
|
|
2855
|
+
this.toggleExpand?.();
|
|
2856
|
+
}
|
|
2857
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SlideTaskActionThumbnailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2858
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SlideTaskActionThumbnailComponent, isStandalone: true, selector: "rtsee-slide-task-action-thumbnail", inputs: { action: "action", task: "task", expanded: "expanded", toggleExpand: "toggleExpand" }, ngImport: i0, template: `
|
|
2859
|
+
<div class="rts-slide-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2860
|
+
<div class="rts-slide-thumb-header">
|
|
2861
|
+
<div class="rts-slide-thumb-title-wrap">
|
|
2862
|
+
<span class="rts-slide-thumb-dot"></span>
|
|
2863
|
+
<span class="rts-slide-thumb-number">Slide #{{ slideNumber }}</span>
|
|
2864
|
+
<span class="rts-slide-thumb-action-name">{{ action?.name }}</span>
|
|
2865
|
+
</div>
|
|
2866
|
+
<button type="button"
|
|
2867
|
+
class="rts-slide-thumb-expand"
|
|
2868
|
+
(click)="onButtonClick($event)"
|
|
2869
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2870
|
+
>
|
|
2871
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2872
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2873
|
+
</button>
|
|
2874
|
+
</div>
|
|
2875
|
+
|
|
2876
|
+
@if (slideText) {
|
|
2877
|
+
<p class="rts-slide-thumb-text" [title]="slideText">{{ slideText }}</p>
|
|
2878
|
+
}
|
|
2879
|
+
</div>
|
|
2880
|
+
`, isInline: true, styles: [".rts-slide-thumb{display:flex;flex-direction:column;gap:5px;padding:8px 11px;border-radius:8px;background:#8b5cf60d;border:1px solid rgba(139,92,246,.18);cursor:pointer;transition:background .15s ease,border-color .15s ease}.rts-slide-thumb:hover{background:#8b5cf61a;border-color:#8b5cf652}.rts-slide-thumb-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-slide-thumb-title-wrap{display:flex;align-items:center;gap:6px;min-width:0}.rts-slide-thumb-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;background:#8b5cf6}.rts-slide-thumb-status-success .rts-slide-thumb-dot{background:#10b981}.rts-slide-thumb-status-fail .rts-slide-thumb-dot{background:#f43f5e}.rts-slide-thumb-number{font-size:11px;font-weight:700;padding:1px 7px;border-radius:999px;background:#8b5cf626;color:#8b5cf6;flex-shrink:0}.rts-slide-thumb-action-name{font-size:11px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-slide-thumb-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#8b5cf61f;color:#8b5cf6;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;flex-shrink:0}.rts-slide-thumb-expand:hover{background:#8b5cf638}.rts-slide-thumb-text{margin:0;font-size:12px;line-height:1.45;color:var(--rts-text-primary, #1f2430);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;word-break:break-word}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
2881
|
+
}
|
|
2882
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SlideTaskActionThumbnailComponent, decorators: [{
|
|
2883
|
+
type: Component,
|
|
2884
|
+
args: [{ selector: 'rtsee-slide-task-action-thumbnail', standalone: true, imports: [NgClass], template: `
|
|
2885
|
+
<div class="rts-slide-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2886
|
+
<div class="rts-slide-thumb-header">
|
|
2887
|
+
<div class="rts-slide-thumb-title-wrap">
|
|
2888
|
+
<span class="rts-slide-thumb-dot"></span>
|
|
2889
|
+
<span class="rts-slide-thumb-number">Slide #{{ slideNumber }}</span>
|
|
2890
|
+
<span class="rts-slide-thumb-action-name">{{ action?.name }}</span>
|
|
2891
|
+
</div>
|
|
2892
|
+
<button type="button"
|
|
2893
|
+
class="rts-slide-thumb-expand"
|
|
2894
|
+
(click)="onButtonClick($event)"
|
|
2895
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2896
|
+
>
|
|
2897
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2898
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2899
|
+
</button>
|
|
2900
|
+
</div>
|
|
2901
|
+
|
|
2902
|
+
@if (slideText) {
|
|
2903
|
+
<p class="rts-slide-thumb-text" [title]="slideText">{{ slideText }}</p>
|
|
2904
|
+
}
|
|
2905
|
+
</div>
|
|
2906
|
+
`, styles: [".rts-slide-thumb{display:flex;flex-direction:column;gap:5px;padding:8px 11px;border-radius:8px;background:#8b5cf60d;border:1px solid rgba(139,92,246,.18);cursor:pointer;transition:background .15s ease,border-color .15s ease}.rts-slide-thumb:hover{background:#8b5cf61a;border-color:#8b5cf652}.rts-slide-thumb-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-slide-thumb-title-wrap{display:flex;align-items:center;gap:6px;min-width:0}.rts-slide-thumb-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;background:#8b5cf6}.rts-slide-thumb-status-success .rts-slide-thumb-dot{background:#10b981}.rts-slide-thumb-status-fail .rts-slide-thumb-dot{background:#f43f5e}.rts-slide-thumb-number{font-size:11px;font-weight:700;padding:1px 7px;border-radius:999px;background:#8b5cf626;color:#8b5cf6;flex-shrink:0}.rts-slide-thumb-action-name{font-size:11px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-slide-thumb-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#8b5cf61f;color:#8b5cf6;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer;flex-shrink:0}.rts-slide-thumb-expand:hover{background:#8b5cf638}.rts-slide-thumb-text{margin:0;font-size:12px;line-height:1.45;color:var(--rts-text-primary, #1f2430);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;word-break:break-word}\n"] }]
|
|
2907
|
+
}], propDecorators: { action: [{
|
|
2908
|
+
type: Input
|
|
2909
|
+
}], task: [{
|
|
2910
|
+
type: Input
|
|
2911
|
+
}], expanded: [{
|
|
2912
|
+
type: Input
|
|
2913
|
+
}], toggleExpand: [{
|
|
2914
|
+
type: Input
|
|
2915
|
+
}] } });
|
|
2916
|
+
|
|
2917
|
+
class DefaultTaskActionPromptComponent {
|
|
2918
|
+
constructor() {
|
|
2919
|
+
this.expanded = false;
|
|
2920
|
+
this.responseValue = '';
|
|
2921
|
+
this.submitting = false;
|
|
2922
|
+
}
|
|
2923
|
+
get promptDataJson() {
|
|
2924
|
+
if (this.prompt?.data === undefined || this.prompt?.data === null) {
|
|
2925
|
+
return '';
|
|
2926
|
+
}
|
|
2927
|
+
try {
|
|
2928
|
+
return JSON.stringify(this.prompt.data, null, 2);
|
|
2929
|
+
}
|
|
2930
|
+
catch {
|
|
2931
|
+
return String(this.prompt.data);
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
onToggle() {
|
|
2935
|
+
this.toggleExpand?.();
|
|
2936
|
+
}
|
|
2937
|
+
onButtonClick(event) {
|
|
2938
|
+
event.stopPropagation();
|
|
2939
|
+
this.toggleExpand?.();
|
|
2940
|
+
}
|
|
2941
|
+
async submit() {
|
|
2942
|
+
if (!this.task || !this.prompt || this.submitting) {
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
this.submitting = true;
|
|
2946
|
+
try {
|
|
2947
|
+
await this.task.respondToPrompt(this.prompt.id, this.responseValue);
|
|
2948
|
+
}
|
|
2949
|
+
finally {
|
|
2950
|
+
this.submitting = false;
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionPromptComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2954
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DefaultTaskActionPromptComponent, isStandalone: true, selector: "rtsee-default-task-action-prompt", inputs: { prompt: "prompt", task: "task", expanded: "expanded", toggleExpand: "toggleExpand" }, ngImport: i0, template: `
|
|
2955
|
+
<div class="rts-prompt-default">
|
|
2956
|
+
<div class="rts-prompt-header" (click)="onToggle()">
|
|
2957
|
+
<div class="rts-prompt-left">
|
|
2958
|
+
<span class="rts-prompt-badge">Prompt</span>
|
|
2959
|
+
<span class="rts-prompt-name" [title]="prompt?.name || 'Prompt'">
|
|
2960
|
+
{{ prompt?.name || 'Prompt' }}
|
|
2961
|
+
</span>
|
|
2962
|
+
</div>
|
|
2963
|
+
<button type="button"
|
|
2964
|
+
class="rts-prompt-expand"
|
|
2965
|
+
(click)="onButtonClick($event)"
|
|
2966
|
+
>
|
|
2967
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2968
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2969
|
+
</button>
|
|
2970
|
+
</div>
|
|
2971
|
+
|
|
2972
|
+
@if (expanded && prompt) {
|
|
2973
|
+
<div class="rts-prompt-body">
|
|
2974
|
+
@if (promptDataJson) {
|
|
2975
|
+
<pre class="rts-prompt-code"><code>{{ promptDataJson }}</code></pre>
|
|
2976
|
+
}
|
|
2977
|
+
@if (!prompt.resolved) {
|
|
2978
|
+
<div class="rts-prompt-Controls">
|
|
2979
|
+
<input type="text"
|
|
2980
|
+
class="rts-prompt-input"
|
|
2981
|
+
[(ngModel)]="responseValue"
|
|
2982
|
+
placeholder="Provide response…"
|
|
2983
|
+
/>
|
|
2984
|
+
<button type="button"
|
|
2985
|
+
class="rts-prompt-submit"
|
|
2986
|
+
[disabled]="submitting"
|
|
2987
|
+
(click)="submit()"
|
|
2988
|
+
>
|
|
2989
|
+
Send
|
|
2990
|
+
</button>
|
|
2991
|
+
</div>
|
|
2992
|
+
} @else {
|
|
2993
|
+
<div class="rts-prompt-resolved">Prompt answered.</div>
|
|
2994
|
+
}
|
|
2995
|
+
</div>
|
|
2996
|
+
}
|
|
2997
|
+
</div>
|
|
2998
|
+
`, isInline: true, styles: [".rts-prompt-default{display:flex;flex-direction:column;gap:6px;padding:8px 10px;border-radius:8px;background:#f59e0b14;border:1px solid rgba(245,158,11,.28)}.rts-prompt-header{display:flex;align-items:center;justify-content:space-between;gap:8px;cursor:pointer}.rts-prompt-left{display:flex;align-items:center;gap:6px;min-width:0}.rts-prompt-badge{font-size:10px;font-weight:700;text-transform:uppercase;padding:1px 6px;border-radius:4px;background:#f59e0b33;color:#d97706}.rts-prompt-name{font-size:12px;font-weight:600;color:var(--rts-text-primary, #1f2430);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-prompt-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#f59e0b29;color:#d97706;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer}.rts-prompt-body{display:flex;flex-direction:column;gap:6px;padding-top:4px}.rts-prompt-code{margin:0;padding:8px 10px;border-radius:6px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;max-height:140px;overflow:auto;white-space:pre-wrap}.rts-prompt-Controls{display:flex;gap:6px}.rts-prompt-input{flex:1;padding:5px 8px;border-radius:6px;border:1px solid rgba(139,92,246,.3);font-size:12px;background:var(--rts-bg-primary, #fff);color:var(--rts-text-primary, #1f2430)}.rts-prompt-submit{padding:5px 12px;border:none;border-radius:6px;background:#8b5cf6;color:#fff;font-size:11.5px;font-weight:600;cursor:pointer}.rts-prompt-resolved{font-size:11px;color:#10b981;font-weight:600}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
|
|
2999
|
+
}
|
|
3000
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionPromptComponent, decorators: [{
|
|
3001
|
+
type: Component,
|
|
3002
|
+
args: [{ selector: 'rtsee-default-task-action-prompt', standalone: true, imports: [NgClass, FormsModule], template: `
|
|
3003
|
+
<div class="rts-prompt-default">
|
|
3004
|
+
<div class="rts-prompt-header" (click)="onToggle()">
|
|
3005
|
+
<div class="rts-prompt-left">
|
|
3006
|
+
<span class="rts-prompt-badge">Prompt</span>
|
|
3007
|
+
<span class="rts-prompt-name" [title]="prompt?.name || 'Prompt'">
|
|
3008
|
+
{{ prompt?.name || 'Prompt' }}
|
|
3009
|
+
</span>
|
|
3010
|
+
</div>
|
|
3011
|
+
<button type="button"
|
|
3012
|
+
class="rts-prompt-expand"
|
|
3013
|
+
(click)="onButtonClick($event)"
|
|
3014
|
+
>
|
|
3015
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
3016
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
3017
|
+
</button>
|
|
3018
|
+
</div>
|
|
3019
|
+
|
|
3020
|
+
@if (expanded && prompt) {
|
|
3021
|
+
<div class="rts-prompt-body">
|
|
3022
|
+
@if (promptDataJson) {
|
|
3023
|
+
<pre class="rts-prompt-code"><code>{{ promptDataJson }}</code></pre>
|
|
3024
|
+
}
|
|
3025
|
+
@if (!prompt.resolved) {
|
|
3026
|
+
<div class="rts-prompt-Controls">
|
|
3027
|
+
<input type="text"
|
|
3028
|
+
class="rts-prompt-input"
|
|
3029
|
+
[(ngModel)]="responseValue"
|
|
3030
|
+
placeholder="Provide response…"
|
|
3031
|
+
/>
|
|
3032
|
+
<button type="button"
|
|
3033
|
+
class="rts-prompt-submit"
|
|
3034
|
+
[disabled]="submitting"
|
|
3035
|
+
(click)="submit()"
|
|
3036
|
+
>
|
|
3037
|
+
Send
|
|
3038
|
+
</button>
|
|
3039
|
+
</div>
|
|
3040
|
+
} @else {
|
|
3041
|
+
<div class="rts-prompt-resolved">Prompt answered.</div>
|
|
3042
|
+
}
|
|
3043
|
+
</div>
|
|
3044
|
+
}
|
|
3045
|
+
</div>
|
|
3046
|
+
`, styles: [".rts-prompt-default{display:flex;flex-direction:column;gap:6px;padding:8px 10px;border-radius:8px;background:#f59e0b14;border:1px solid rgba(245,158,11,.28)}.rts-prompt-header{display:flex;align-items:center;justify-content:space-between;gap:8px;cursor:pointer}.rts-prompt-left{display:flex;align-items:center;gap:6px;min-width:0}.rts-prompt-badge{font-size:10px;font-weight:700;text-transform:uppercase;padding:1px 6px;border-radius:4px;background:#f59e0b33;color:#d97706}.rts-prompt-name{font-size:12px;font-weight:600;color:var(--rts-text-primary, #1f2430);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-prompt-expand{display:inline-flex;align-items:center;gap:4px;border:none;background:#f59e0b29;color:#d97706;font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;cursor:pointer}.rts-prompt-body{display:flex;flex-direction:column;gap:6px;padding-top:4px}.rts-prompt-code{margin:0;padding:8px 10px;border-radius:6px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;max-height:140px;overflow:auto;white-space:pre-wrap}.rts-prompt-Controls{display:flex;gap:6px}.rts-prompt-input{flex:1;padding:5px 8px;border-radius:6px;border:1px solid rgba(139,92,246,.3);font-size:12px;background:var(--rts-bg-primary, #fff);color:var(--rts-text-primary, #1f2430)}.rts-prompt-submit{padding:5px 12px;border:none;border-radius:6px;background:#8b5cf6;color:#fff;font-size:11.5px;font-weight:600;cursor:pointer}.rts-prompt-resolved{font-size:11px;color:#10b981;font-weight:600}\n"] }]
|
|
3047
|
+
}], propDecorators: { prompt: [{
|
|
3048
|
+
type: Input
|
|
3049
|
+
}], task: [{
|
|
3050
|
+
type: Input
|
|
3051
|
+
}], expanded: [{
|
|
3052
|
+
type: Input
|
|
3053
|
+
}], toggleExpand: [{
|
|
3054
|
+
type: Input
|
|
3055
|
+
}] } });
|
|
3056
|
+
|
|
3057
|
+
/**
|
|
3058
|
+
* Registry of custom client-side widgets for task-action-thumbnails and task-action-prompts.
|
|
3059
|
+
* Falls back to DefaultTaskActionThumbnailComponent / DefaultTaskActionPromptComponent.
|
|
3060
|
+
*/
|
|
3061
|
+
class TaskActionWidgetsService {
|
|
3062
|
+
constructor() {
|
|
3063
|
+
this.thumbnailsMap = [
|
|
3064
|
+
{ name: CREATE_STORY_ACTION_NAME, component: StoryTaskActionThumbnailComponent },
|
|
3065
|
+
{ name: EDIT_STORY_ACTION_NAME, component: StoryTaskActionThumbnailComponent },
|
|
3066
|
+
{ name: CREATE_SLIDE_ACTION_NAME, component: SlideTaskActionThumbnailComponent },
|
|
3067
|
+
{ name: EDIT_SLIDE_ACTION_NAME, component: SlideTaskActionThumbnailComponent },
|
|
3068
|
+
];
|
|
3069
|
+
this.promptsMap = [];
|
|
3070
|
+
}
|
|
3071
|
+
registerThumbnail(widget) {
|
|
3072
|
+
this.thumbnailsMap = [
|
|
3073
|
+
...this.thumbnailsMap.filter((e) => e.name !== widget.name),
|
|
3074
|
+
widget,
|
|
3075
|
+
];
|
|
3076
|
+
}
|
|
3077
|
+
registerPrompt(widget) {
|
|
3078
|
+
this.promptsMap = [
|
|
3079
|
+
...this.promptsMap.filter((e) => e.name !== widget.name),
|
|
3080
|
+
widget,
|
|
3081
|
+
];
|
|
3082
|
+
}
|
|
3083
|
+
getThumbnailComponentByName(name) {
|
|
3084
|
+
if (!name) {
|
|
3085
|
+
return DefaultTaskActionThumbnailComponent;
|
|
3086
|
+
}
|
|
3087
|
+
return (this.thumbnailsMap.find((e) => e.name === name)?.component ||
|
|
3088
|
+
DefaultTaskActionThumbnailComponent);
|
|
3089
|
+
}
|
|
3090
|
+
getPromptComponentByName(name) {
|
|
3091
|
+
if (!name) {
|
|
3092
|
+
return DefaultTaskActionPromptComponent;
|
|
3093
|
+
}
|
|
3094
|
+
return (this.promptsMap.find((e) => e.name === name)?.component ||
|
|
3095
|
+
DefaultTaskActionPromptComponent);
|
|
3096
|
+
}
|
|
3097
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionWidgetsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3098
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionWidgetsService, providedIn: 'root' }); }
|
|
3099
|
+
}
|
|
3100
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionWidgetsService, decorators: [{
|
|
3101
|
+
type: Injectable,
|
|
3102
|
+
args: [{
|
|
3103
|
+
providedIn: 'root',
|
|
3104
|
+
}]
|
|
3105
|
+
}] });
|
|
3106
|
+
|
|
3107
|
+
/**
|
|
3108
|
+
* Minified thumbnail representation of an OzzyClientTaskAction.
|
|
3109
|
+
* Renders the registered custom thumbnail widget (or DefaultTaskActionThumbnailComponent)
|
|
3110
|
+
* and expands into the full RTSeeTaskActionComponent view on toggle.
|
|
3111
|
+
*/
|
|
3112
|
+
class TaskActionThumbnailComponent {
|
|
3113
|
+
constructor(cdr, actionWidgets) {
|
|
3114
|
+
this.cdr = cdr;
|
|
3115
|
+
this.actionWidgets = actionWidgets;
|
|
3116
|
+
this.expanded = false;
|
|
3117
|
+
this.subscribedAction = null;
|
|
3118
|
+
this.onChangedBound = () => this.cdr.detectChanges();
|
|
3119
|
+
this.toggleExpandBound = () => this.toggleExpand();
|
|
3120
|
+
}
|
|
3121
|
+
ngOnInit() {
|
|
3122
|
+
this.subscribe();
|
|
3123
|
+
}
|
|
3124
|
+
ngOnChanges(changes) {
|
|
3125
|
+
if (changes['action'] && !changes['action'].firstChange) {
|
|
3126
|
+
this.subscribe();
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
ngOnDestroy() {
|
|
3130
|
+
this.unsubscribe();
|
|
3131
|
+
}
|
|
3132
|
+
get thumbnailComponent() {
|
|
3133
|
+
return this.actionWidgets.getThumbnailComponentByName(this.action?.name);
|
|
3134
|
+
}
|
|
3135
|
+
get thumbnailInputs() {
|
|
3136
|
+
return {
|
|
3137
|
+
action: this.action,
|
|
3138
|
+
task: this.task,
|
|
3139
|
+
expanded: this.expanded,
|
|
3140
|
+
toggleExpand: this.toggleExpandBound,
|
|
3141
|
+
};
|
|
3142
|
+
}
|
|
3143
|
+
toggleExpand() {
|
|
3144
|
+
this.expanded = !this.expanded;
|
|
3145
|
+
if (this.expanded && this.action && !this.action.loaded && !this.action.isRunning) {
|
|
3146
|
+
void this.action.load();
|
|
3147
|
+
}
|
|
3148
|
+
this.cdr.detectChanges();
|
|
3149
|
+
}
|
|
3150
|
+
subscribe() {
|
|
3151
|
+
if (this.subscribedAction === this.action) {
|
|
3152
|
+
return;
|
|
3153
|
+
}
|
|
3154
|
+
this.unsubscribe();
|
|
3155
|
+
if (this.action) {
|
|
3156
|
+
this.subscribedAction = this.action;
|
|
3157
|
+
this.action.on(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
unsubscribe() {
|
|
3161
|
+
this.subscribedAction?.off(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
3162
|
+
this.subscribedAction = null;
|
|
3163
|
+
}
|
|
3164
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionThumbnailComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: TaskActionWidgetsService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3165
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: TaskActionThumbnailComponent, isStandalone: true, selector: "rtsee-task-action-thumbnail, task-action-thumbnail", inputs: { action: "action", task: "task" }, usesOnChanges: true, ngImport: i0, template: `
|
|
3166
|
+
<div class="rts-action-thumbnail-host">
|
|
3167
|
+
@if (action) {
|
|
3168
|
+
<ng-container
|
|
3169
|
+
*ngComponentOutlet="thumbnailComponent; inputs: thumbnailInputs"
|
|
3170
|
+
></ng-container>
|
|
3171
|
+
|
|
3172
|
+
@if (expanded) {
|
|
3173
|
+
<div class="rts-action-thumbnail-expanded">
|
|
3174
|
+
<rtsee-task-action [action]="action"></rtsee-task-action>
|
|
3175
|
+
</div>
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
</div>
|
|
3179
|
+
`, isInline: true, styles: [":host{display:block}.rts-action-thumbnail-host{display:flex;flex-direction:column;gap:6px}.rts-action-thumbnail-expanded{padding-left:8px;border-left:2px solid rgba(139,92,246,.35)}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: RTSeeTaskActionComponent, selector: "rtsee-task-action", inputs: ["action"] }] }); }
|
|
3180
|
+
}
|
|
3181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionThumbnailComponent, decorators: [{
|
|
3182
|
+
type: Component,
|
|
3183
|
+
args: [{ selector: 'rtsee-task-action-thumbnail, task-action-thumbnail', standalone: true, imports: [NgComponentOutlet, RTSeeTaskActionComponent], template: `
|
|
3184
|
+
<div class="rts-action-thumbnail-host">
|
|
3185
|
+
@if (action) {
|
|
3186
|
+
<ng-container
|
|
3187
|
+
*ngComponentOutlet="thumbnailComponent; inputs: thumbnailInputs"
|
|
3188
|
+
></ng-container>
|
|
3189
|
+
|
|
3190
|
+
@if (expanded) {
|
|
3191
|
+
<div class="rts-action-thumbnail-expanded">
|
|
3192
|
+
<rtsee-task-action [action]="action"></rtsee-task-action>
|
|
3193
|
+
</div>
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
</div>
|
|
3197
|
+
`, styles: [":host{display:block}.rts-action-thumbnail-host{display:flex;flex-direction:column;gap:6px}.rts-action-thumbnail-expanded{padding-left:8px;border-left:2px solid rgba(139,92,246,.35)}\n"] }]
|
|
3198
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: TaskActionWidgetsService }], propDecorators: { action: [{
|
|
3199
|
+
type: Input
|
|
3200
|
+
}], task: [{
|
|
3201
|
+
type: Input
|
|
3202
|
+
}] } });
|
|
3203
|
+
|
|
3204
|
+
/**
|
|
3205
|
+
* Host component for a task action prompt.
|
|
3206
|
+
* Renders the registered custom prompt widget (or DefaultTaskActionPromptComponent).
|
|
3207
|
+
*/
|
|
3208
|
+
class TaskActionPromptComponent {
|
|
3209
|
+
constructor(cdr, actionWidgets) {
|
|
3210
|
+
this.cdr = cdr;
|
|
3211
|
+
this.actionWidgets = actionWidgets;
|
|
3212
|
+
this.expanded = false;
|
|
3213
|
+
this.toggleExpandBound = () => this.toggleExpand();
|
|
3214
|
+
}
|
|
3215
|
+
get promptComponent() {
|
|
3216
|
+
return this.actionWidgets.getPromptComponentByName(this.prompt?.name);
|
|
3217
|
+
}
|
|
3218
|
+
get promptInputs() {
|
|
3219
|
+
return {
|
|
3220
|
+
prompt: this.prompt,
|
|
3221
|
+
task: this.task,
|
|
3222
|
+
expanded: this.expanded,
|
|
3223
|
+
toggleExpand: this.toggleExpandBound,
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
toggleExpand() {
|
|
3227
|
+
this.expanded = !this.expanded;
|
|
3228
|
+
this.cdr.detectChanges();
|
|
3229
|
+
}
|
|
3230
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionPromptComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: TaskActionWidgetsService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3231
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: TaskActionPromptComponent, isStandalone: true, selector: "rtsee-task-action-prompt, task-action-prompt", inputs: { prompt: "prompt", task: "task" }, ngImport: i0, template: `
|
|
3232
|
+
@if (prompt) {
|
|
3233
|
+
<ng-container
|
|
3234
|
+
*ngComponentOutlet="promptComponent; inputs: promptInputs"
|
|
3235
|
+
></ng-container>
|
|
3236
|
+
}
|
|
3237
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] }); }
|
|
3238
|
+
}
|
|
3239
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionPromptComponent, decorators: [{
|
|
3240
|
+
type: Component,
|
|
3241
|
+
args: [{ selector: 'rtsee-task-action-prompt, task-action-prompt', standalone: true, imports: [NgComponentOutlet], template: `
|
|
3242
|
+
@if (prompt) {
|
|
3243
|
+
<ng-container
|
|
3244
|
+
*ngComponentOutlet="promptComponent; inputs: promptInputs"
|
|
3245
|
+
></ng-container>
|
|
3246
|
+
}
|
|
3247
|
+
`, styles: [":host{display:block}\n"] }]
|
|
3248
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: TaskActionWidgetsService }], propDecorators: { prompt: [{
|
|
3249
|
+
type: Input
|
|
3250
|
+
}], task: [{
|
|
3251
|
+
type: Input
|
|
3252
|
+
}] } });
|
|
3253
|
+
|
|
2447
3254
|
/**
|
|
2448
3255
|
* Default client-side representation of a server-side OzzyTask.
|
|
2449
3256
|
* Can be used directly (`[task]`) or as a message widget (`message.data.taskId`).
|
|
@@ -2462,10 +3269,12 @@ class RTSeeTaskComponent {
|
|
|
2462
3269
|
this.task = this.messenger.ozzy.getTask(this.message.data.taskId);
|
|
2463
3270
|
}
|
|
2464
3271
|
this.subscribe();
|
|
3272
|
+
this.ensureActions();
|
|
2465
3273
|
}
|
|
2466
3274
|
ngOnChanges(changes) {
|
|
2467
3275
|
if (changes['task'] && !changes['task'].firstChange) {
|
|
2468
3276
|
this.subscribe();
|
|
3277
|
+
this.ensureActions();
|
|
2469
3278
|
}
|
|
2470
3279
|
}
|
|
2471
3280
|
ngOnDestroy() {
|
|
@@ -2504,12 +3313,27 @@ class RTSeeTaskComponent {
|
|
|
2504
3313
|
get hasOutput() {
|
|
2505
3314
|
return this.task?.output !== undefined && this.task?.output !== null;
|
|
2506
3315
|
}
|
|
2507
|
-
get
|
|
2508
|
-
return !!(this.task?.
|
|
3316
|
+
get hasActions() {
|
|
3317
|
+
return !!(this.task?.actions?.length || this.task?.actionsLoading);
|
|
3318
|
+
}
|
|
3319
|
+
get hasPrompts() {
|
|
3320
|
+
return !!(this.task?.prompts?.length);
|
|
2509
3321
|
}
|
|
2510
3322
|
execute() {
|
|
2511
3323
|
void this.task?.execute();
|
|
2512
3324
|
}
|
|
3325
|
+
loadMoreActions() {
|
|
3326
|
+
void this.task?.loadMoreActions();
|
|
3327
|
+
}
|
|
3328
|
+
onActionsScroll(event) {
|
|
3329
|
+
const el = event.target;
|
|
3330
|
+
if (!el || !this.task?.hasMoreActions || this.task.actionsLoading) {
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 40) {
|
|
3334
|
+
void this.task.loadMoreActions();
|
|
3335
|
+
}
|
|
3336
|
+
}
|
|
2513
3337
|
async copy(kind) {
|
|
2514
3338
|
try {
|
|
2515
3339
|
await navigator.clipboard.writeText(kind === 'input' ? this.inputJson : this.outputJson);
|
|
@@ -2524,8 +3348,19 @@ class RTSeeTaskComponent {
|
|
|
2524
3348
|
console.log('Failed to copy', e);
|
|
2525
3349
|
}
|
|
2526
3350
|
}
|
|
2527
|
-
|
|
2528
|
-
return
|
|
3351
|
+
trackAction(_index, action) {
|
|
3352
|
+
return action.id;
|
|
3353
|
+
}
|
|
3354
|
+
trackPrompt(_index, prompt) {
|
|
3355
|
+
return prompt.id;
|
|
3356
|
+
}
|
|
3357
|
+
ensureActions() {
|
|
3358
|
+
if (!this.task) {
|
|
3359
|
+
return;
|
|
3360
|
+
}
|
|
3361
|
+
if (this.task.status !== OzzyTaskStatus.CREATED) {
|
|
3362
|
+
this.task.ensureActionsLoaded();
|
|
3363
|
+
}
|
|
2529
3364
|
}
|
|
2530
3365
|
toJson(value) {
|
|
2531
3366
|
if (value === undefined || value === null) {
|
|
@@ -2553,18 +3388,21 @@ class RTSeeTaskComponent {
|
|
|
2553
3388
|
this.subscribedTask = null;
|
|
2554
3389
|
}
|
|
2555
3390
|
onTaskChanged() {
|
|
3391
|
+
this.ensureActions();
|
|
2556
3392
|
this.cdr.detectChanges();
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
el
|
|
3393
|
+
if (this.task?.isRunning) {
|
|
3394
|
+
const el = this.actionsContainer?.nativeElement;
|
|
3395
|
+
if (el) {
|
|
3396
|
+
el.scrollTop = el.scrollHeight;
|
|
3397
|
+
}
|
|
2560
3398
|
}
|
|
2561
3399
|
}
|
|
2562
3400
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeTaskComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2563
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RTSeeTaskComponent, isStandalone: true, selector: "rtsee-task", inputs: { task: "task", message: "message", messenger: "messenger", chat: "chat", allowExecute: "allowExecute" }, viewQueries: [{ propertyName: "logsContainer", first: true, predicate: ["logsContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-task\" [ngClass]=\"statusClass\">\n @if (task) {\n <div class=\"rts-task-header\">\n <div class=\"rts-task-identity\">\n <span class=\"rts-task-icon\">\u2699</span>\n <div class=\"rts-task-titles\">\n <span class=\"rts-task-name\">{{ task.name || 'Task' }}</span>\n <span class=\"rts-task-id\" [title]=\"task.id\">#{{ task.id }}</span>\n </div>\n </div>\n <span class=\"rts-task-status\">\n <span class=\"rts-task-status-dot\"></span>\n {{ statusLabel }}\n </span>\n </div>\n\n <!-- Input -->\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Input</span>\n @if (inputJson) {\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('input')\">\n {{ copied === 'input' ? 'Copied' : 'Copy' }}\n </button>\n }\n </div>\n @if (inputJson) {\n <pre class=\"rts-task-code\"><code>{{ inputJson }}</code></pre>\n } @else if (task.loading) {\n <div class=\"rts-task-placeholder\">Loading\u2026</div>\n } @else {\n <div class=\"rts-task-placeholder\">No input</div>\n }\n </div>\n\n @if (allowExecute) {\n <div class=\"rts-task-actions\">\n <button type=\"button\"\n class=\"rts-task-execute\"\n [disabled]=\"!task.canExecute\"\n (click)=\"execute()\"\n >\n @if (task.isRunning || task.executeInProgress) {\n <span class=\"rts-task-spinner\"></span> Executing\u2026\n } @else if (task.isFailed) {\n <span class=\"pi pi-refresh\"></span> Retry\n } @else if (task.isFinished) {\n <span class=\"pi pi-check\"></span> Executed\n } @else {\n <span class=\"pi pi-play\"></span> Execute\n }\n </button>\n </div>\n }\n\n <!-- Logs -->\n @if (hasLogs || task.isRunning) {\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Logs</span>\n @if (task.isRunning) {\n <span class=\"rts-task-live\">LIVE</span>\n }\n </div>\n <div #logsContainer class=\"rts-task-terminal\">\n @for (log of task.logs; track $index) {\n <div class=\"rts-task-log\" [ngClass]=\"'rts-task-log-' + log.level\">\n <span class=\"rts-task-log-time\">{{ log.createdAt | date: 'HH:mm:ss' }}</span>\n <span class=\"rts-task-log-level\">{{ log.level }}</span>\n <span class=\"rts-task-log-message\">{{ log.message }}</span>\n </div>\n }\n @if (task.liveText) {\n <div class=\"rts-task-live-text\">{{ task.liveText }}@if (task.isRunning) {<span class=\"rts-task-cursor\"></span>}</div>\n } @else if (task.isRunning && !task.logs.length) {\n <div class=\"rts-task-log rts-task-log-info\">\n <span class=\"rts-task-log-message\">Waiting for logs\u2026</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Output -->\n @if (hasOutput) {\n <div class=\"rts-task-section rts-task-section-output\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Output</span>\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('output')\">\n {{ copied === 'output' ? 'Copied' : 'Copy' }}\n </button>\n </div>\n <pre class=\"rts-task-code\"><code>{{ outputJson }}</code></pre>\n </div>\n }\n\n @if (task.errors.length) {\n <div class=\"rts-task-errors\">\n @for (error of task.errors; track $index) {\n <div class=\"rts-task-error\">{{ error.message }}</div>\n }\n </div>\n }\n\n @if (task.requestError) {\n <div class=\"rts-task-errors\">\n <div class=\"rts-task-error\">{{ task.requestError }}</div>\n </div>\n }\n } @else {\n <div class=\"rts-task-placeholder\">Task is not available yet.</div>\n }\n</div>\n", styles: [":host{display:block;--rts-task-accent: #8b5cf6;--rts-task-accent-2: #6366f1;--rts-task-success: #10b981;--rts-task-fail: #f43f5e;--rts-task-warn: #f59e0b}.rts-task{position:relative;display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:12px;background:linear-gradient(var(--rts-bg-secondary, #fff),var(--rts-bg-secondary, #fff)) padding-box,linear-gradient(135deg,#6366f173,#8b5cf626 60%,#a78bfa59) border-box;border:1px solid transparent;box-shadow:0 6px 24px -12px #6366f159;min-width:260px;max-width:100%;font-size:13px;transition:box-shadow .25s ease}.rts-task.rts-task-status-running{animation:rts-task-glow 2.2s ease-in-out infinite}@keyframes rts-task-glow{0%,to{box-shadow:0 6px 24px -12px #6366f159}50%{box-shadow:0 6px 28px -8px #8b5cf699}}.rts-task-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-task-identity{display:flex;align-items:center;gap:8px;min-width:0}.rts-task-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:8px;color:#fff;font-size:14px;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent))}.rts-task-status-running .rts-task-icon{animation:rts-task-spin 2.4s linear infinite}.rts-task-titles{display:flex;flex-direction:column;min-width:0}.rts-task-name{font-weight:600;color:var(--rts-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-task-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-task-status{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0;color:var(--rts-task-accent);background:#8b5cf61f}.rts-task-status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.rts-task-status-running .rts-task-status-dot{animation:rts-task-pulse 1s ease-in-out infinite}.rts-task-status-success .rts-task-status{color:var(--rts-task-success);background:#10b9811f}.rts-task-status-fail .rts-task-status{color:var(--rts-task-fail);background:#f43f5e1f}.rts-task-section{display:flex;flex-direction:column;gap:4px;animation:rts-task-fade-in .3s ease}.rts-task-section-head{display:flex;align-items:center;justify-content:space-between}.rts-task-section-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-task-copy{border:none;background:transparent;color:var(--rts-task-accent);font-size:11px;cursor:pointer;padding:0 2px}.rts-task-copy:hover{text-decoration:underline}.rts-task-live{font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--rts-task-fail);animation:rts-task-pulse 1.2s ease-in-out infinite}.rts-task-code,.rts-task-terminal{margin:0;padding:10px 12px;border-radius:8px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;line-height:1.55;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid rgba(139,92,246,.18)}.rts-task-section-output .rts-task-code{border-color:#10b98159}.rts-task-log{display:flex;gap:8px;align-items:baseline}.rts-task-log-time{color:#6b6f8a;flex-shrink:0}.rts-task-log-level{flex-shrink:0;min-width:34px;text-transform:uppercase;font-size:9.5px;font-weight:700;color:#a78bfa}.rts-task-log-warn .rts-task-log-level{color:var(--rts-task-warn)}.rts-task-log-error .rts-task-log-level,.rts-task-log-error .rts-task-log-message{color:#fb7185}.rts-task-live-text{margin-top:6px;padding-top:6px;border-top:1px dashed rgba(139,92,246,.25);color:#c4b5fd;white-space:pre-wrap}.rts-task-cursor{display:inline-block;width:6px;height:12px;margin-left:1px;vertical-align:text-bottom;background:#a78bfa;animation:rts-task-blink .8s step-end infinite}.rts-task-actions{display:flex;justify-content:flex-end}.rts-task-execute{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border:none;border-radius:8px;color:#fff;font-weight:600;font-size:12px;cursor:pointer;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent));box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.rts-task-execute:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 6px 18px -4px #6366f1bf}.rts-task-execute:disabled{cursor:default;opacity:.6;box-shadow:none}.rts-task-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-task-spin .8s linear infinite}.rts-task-placeholder{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);font-style:italic}.rts-task-errors{display:flex;flex-direction:column;gap:4px}.rts-task-error{padding:6px 10px;border-radius:6px;font-size:12px;color:var(--rts-task-fail);background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}@keyframes rts-task-spin{to{transform:rotate(360deg)}}@keyframes rts-task-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rts-task-blink{0%,to{opacity:1}50%{opacity:0}}@keyframes rts-task-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: DatePipe, name: "date" }] }); }
|
|
3401
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RTSeeTaskComponent, isStandalone: true, selector: "rtsee-task", inputs: { task: "task", message: "message", messenger: "messenger", chat: "chat", allowExecute: "allowExecute" }, viewQueries: [{ propertyName: "actionsContainer", first: true, predicate: ["actionsContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-task\" [ngClass]=\"statusClass\">\n @if (task) {\n <div class=\"rts-task-header\">\n <div class=\"rts-task-identity\">\n <span class=\"rts-task-icon\">\u2699</span>\n <div class=\"rts-task-titles\">\n <span class=\"rts-task-name\">{{ task.name || 'Task' }}</span>\n <span class=\"rts-task-id\" [title]=\"task.id\">#{{ task.id }}</span>\n </div>\n </div>\n <span class=\"rts-task-status\">\n <span class=\"rts-task-status-dot\"></span>\n {{ statusLabel }}\n </span>\n </div>\n\n <!-- Input -->\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Input</span>\n @if (inputJson) {\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('input')\">\n {{ copied === 'input' ? 'Copied' : 'Copy' }}\n </button>\n }\n </div>\n @if (inputJson) {\n <pre class=\"rts-task-code\"><code>{{ inputJson }}</code></pre>\n } @else if (task.loading) {\n <div class=\"rts-task-placeholder\">Loading\u2026</div>\n } @else {\n <div class=\"rts-task-placeholder\">No input</div>\n }\n </div>\n\n @if (allowExecute) {\n <div class=\"rts-task-actions\">\n <button type=\"button\"\n class=\"rts-task-execute\"\n [disabled]=\"!task.canExecute\"\n (click)=\"execute()\"\n >\n @if (task.isRunning || task.executeInProgress) {\n <span class=\"rts-task-spinner\"></span> Executing\u2026\n } @else if (task.isFailed) {\n <span class=\"pi pi-refresh\"></span> Retry\n } @else if (task.isFinished) {\n <span class=\"pi pi-check\"></span> Executed\n } @else {\n <span class=\"pi pi-play\"></span> Execute\n }\n </button>\n </div>\n }\n\n <!-- Prompts -->\n @if (hasPrompts) {\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Prompts</span>\n </div>\n <div class=\"rts-task-prompts-list\">\n @for (prompt of task.prompts; track prompt.id) {\n <rtsee-task-action-prompt\n [prompt]=\"prompt\"\n [task]=\"task\"\n ></rtsee-task-action-prompt>\n }\n </div>\n </div>\n }\n\n <!-- Actions (replaces Logs list) -->\n @if (hasActions || task.isRunning) {\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">\n Actions @if (task.actionsTotal) { ({{ task.actions.length }}/{{ task.actionsTotal }}) }\n </span>\n @if (task.isRunning) {\n <span class=\"rts-task-live\">LIVE</span>\n }\n </div>\n <div #actionsContainer class=\"rts-task-actions-list\" (scroll)=\"onActionsScroll($event)\">\n @for (action of task.actions; track action.id) {\n <rtsee-task-action-thumbnail\n [action]=\"action\"\n [task]=\"task\"\n ></rtsee-task-action-thumbnail>\n }\n @if (task.isRunning && !task.actions.length) {\n <div class=\"rts-task-placeholder\">Starting actions\u2026</div>\n }\n @if (task.actionsLoading) {\n <div class=\"rts-task-placeholder\">Loading actions\u2026</div>\n }\n @if (task.hasMoreActions && !task.actionsLoading) {\n <button type=\"button\" class=\"rts-task-load-more\" (click)=\"loadMoreActions()\">\n Load more actions ({{ task.actions.length }}/{{ task.actionsTotal }})\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Output -->\n @if (hasOutput) {\n <div class=\"rts-task-section rts-task-section-output\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Output</span>\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('output')\">\n {{ copied === 'output' ? 'Copied' : 'Copy' }}\n </button>\n </div>\n <pre class=\"rts-task-code\"><code>{{ outputJson }}</code></pre>\n </div>\n }\n\n @if (task.errors.length) {\n <div class=\"rts-task-errors\">\n @for (error of task.errors; track $index) {\n <div class=\"rts-task-error\">{{ error.message }}</div>\n }\n </div>\n }\n\n @if (task.requestError) {\n <div class=\"rts-task-errors\">\n <div class=\"rts-task-error\">{{ task.requestError }}</div>\n </div>\n }\n } @else {\n <div class=\"rts-task-placeholder\">Task is not available yet.</div>\n }\n</div>\n", styles: [":host{display:block;--rts-task-accent: #8b5cf6;--rts-task-accent-2: #6366f1;--rts-task-success: #10b981;--rts-task-fail: #f43f5e;--rts-task-warn: #f59e0b}.rts-task{position:relative;display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:12px;background:linear-gradient(var(--rts-bg-secondary, #fff),var(--rts-bg-secondary, #fff)) padding-box,linear-gradient(135deg,#6366f173,#8b5cf626 60%,#a78bfa59) border-box;border:1px solid transparent;box-shadow:0 6px 24px -12px #6366f159;min-width:260px;max-width:100%;font-size:13px;transition:box-shadow .25s ease}.rts-task.rts-task-status-running{animation:rts-task-glow 2.2s ease-in-out infinite}@keyframes rts-task-glow{0%,to{box-shadow:0 6px 24px -12px #6366f159}50%{box-shadow:0 6px 28px -8px #8b5cf699}}.rts-task-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-task-identity{display:flex;align-items:center;gap:8px;min-width:0}.rts-task-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:8px;color:#fff;font-size:14px;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent))}.rts-task-status-running .rts-task-icon{animation:rts-task-spin 2.4s linear infinite}.rts-task-titles{display:flex;flex-direction:column;min-width:0}.rts-task-name{font-weight:600;color:var(--rts-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-task-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-task-status{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0;color:var(--rts-task-accent);background:#8b5cf61f}.rts-task-status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.rts-task-status-running .rts-task-status-dot{animation:rts-task-pulse 1s ease-in-out infinite}.rts-task-status-success .rts-task-status{color:var(--rts-task-success);background:#10b9811f}.rts-task-status-fail .rts-task-status{color:var(--rts-task-fail);background:#f43f5e1f}.rts-task-section{display:flex;flex-direction:column;gap:4px;animation:rts-task-fade-in .3s ease}.rts-task-section-head{display:flex;align-items:center;justify-content:space-between}.rts-task-section-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-task-copy{border:none;background:transparent;color:var(--rts-task-accent);font-size:11px;cursor:pointer;padding:0 2px}.rts-task-copy:hover{text-decoration:underline}.rts-task-live{font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--rts-task-fail);animation:rts-task-pulse 1.2s ease-in-out infinite}.rts-task-code,.rts-task-terminal{margin:0;padding:10px 12px;border-radius:8px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;line-height:1.55;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid rgba(139,92,246,.18)}.rts-task-section-output .rts-task-code{border-color:#10b98159}.rts-task-actions-list,.rts-task-prompts-list{display:flex;flex-direction:column;gap:6px;max-height:360px;overflow-y:auto;padding:2px}.rts-task-load-more{align-self:center;margin-top:4px;padding:5px 12px;border-radius:6px;border:1px solid rgba(139,92,246,.3);background:#8b5cf614;color:var(--rts-task-accent);font-size:11px;font-weight:600;cursor:pointer}.rts-task-load-more:hover{background:#8b5cf629}.rts-task-log{display:flex;gap:8px;align-items:baseline}.rts-task-log-time{color:#6b6f8a;flex-shrink:0}.rts-task-log-level{flex-shrink:0;min-width:34px;text-transform:uppercase;font-size:9.5px;font-weight:700;color:#a78bfa}.rts-task-log-warn .rts-task-log-level{color:var(--rts-task-warn)}.rts-task-log-error .rts-task-log-level,.rts-task-log-error .rts-task-log-message{color:#fb7185}.rts-task-live-text{margin-top:6px;padding-top:6px;border-top:1px dashed rgba(139,92,246,.25);color:#c4b5fd;white-space:pre-wrap}.rts-task-cursor{display:inline-block;width:6px;height:12px;margin-left:1px;vertical-align:text-bottom;background:#a78bfa;animation:rts-task-blink .8s step-end infinite}.rts-task-actions{display:flex;justify-content:flex-end}.rts-task-execute{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border:none;border-radius:8px;color:#fff;font-weight:600;font-size:12px;cursor:pointer;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent));box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.rts-task-execute:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 6px 18px -4px #6366f1bf}.rts-task-execute:disabled{cursor:default;opacity:.6;box-shadow:none}.rts-task-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-task-spin .8s linear infinite}.rts-task-placeholder{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);font-style:italic}.rts-task-errors{display:flex;flex-direction:column;gap:4px}.rts-task-error{padding:6px 10px;border-radius:6px;font-size:12px;color:var(--rts-task-fail);background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}@keyframes rts-task-spin{to{transform:rotate(360deg)}}@keyframes rts-task-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rts-task-blink{0%,to{opacity:1}50%{opacity:0}}@keyframes rts-task-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TaskActionThumbnailComponent, selector: "rtsee-task-action-thumbnail, task-action-thumbnail", inputs: ["action", "task"] }, { kind: "component", type: TaskActionPromptComponent, selector: "rtsee-task-action-prompt, task-action-prompt", inputs: ["prompt", "task"] }] }); }
|
|
2564
3402
|
}
|
|
2565
3403
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeTaskComponent, decorators: [{
|
|
2566
3404
|
type: Component,
|
|
2567
|
-
args: [{ selector: 'rtsee-task', standalone: true, imports: [NgClass, DatePipe], template: "<div class=\"rts-task\" [ngClass]=\"statusClass\">\n @if (task) {\n <div class=\"rts-task-header\">\n <div class=\"rts-task-identity\">\n <span class=\"rts-task-icon\">\u2699</span>\n <div class=\"rts-task-titles\">\n <span class=\"rts-task-name\">{{ task.name || 'Task' }}</span>\n <span class=\"rts-task-id\" [title]=\"task.id\">#{{ task.id }}</span>\n </div>\n </div>\n <span class=\"rts-task-status\">\n <span class=\"rts-task-status-dot\"></span>\n {{ statusLabel }}\n </span>\n </div>\n\n <!-- Input -->\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Input</span>\n @if (inputJson) {\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('input')\">\n {{ copied === 'input' ? 'Copied' : 'Copy' }}\n </button>\n }\n </div>\n @if (inputJson) {\n <pre class=\"rts-task-code\"><code>{{ inputJson }}</code></pre>\n } @else if (task.loading) {\n <div class=\"rts-task-placeholder\">Loading\u2026</div>\n } @else {\n <div class=\"rts-task-placeholder\">No input</div>\n }\n </div>\n\n @if (allowExecute) {\n <div class=\"rts-task-actions\">\n <button type=\"button\"\n class=\"rts-task-execute\"\n [disabled]=\"!task.canExecute\"\n (click)=\"execute()\"\n >\n @if (task.isRunning || task.executeInProgress) {\n <span class=\"rts-task-spinner\"></span> Executing\u2026\n } @else if (task.isFailed) {\n <span class=\"pi pi-refresh\"></span> Retry\n } @else if (task.isFinished) {\n <span class=\"pi pi-check\"></span> Executed\n } @else {\n <span class=\"pi pi-play\"></span> Execute\n }\n </button>\n </div>\n }\n\n <!-- Logs -->\n @if (hasLogs || task.isRunning) {\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Logs</span>\n @if (task.isRunning) {\n <span class=\"rts-task-live\">LIVE</span>\n }\n </div>\n <div #logsContainer class=\"rts-task-terminal\">\n @for (log of task.logs; track $index) {\n <div class=\"rts-task-log\" [ngClass]=\"'rts-task-log-' + log.level\">\n <span class=\"rts-task-log-time\">{{ log.createdAt | date: 'HH:mm:ss' }}</span>\n <span class=\"rts-task-log-level\">{{ log.level }}</span>\n <span class=\"rts-task-log-message\">{{ log.message }}</span>\n </div>\n }\n @if (task.liveText) {\n <div class=\"rts-task-live-text\">{{ task.liveText }}@if (task.isRunning) {<span class=\"rts-task-cursor\"></span>}</div>\n } @else if (task.isRunning && !task.logs.length) {\n <div class=\"rts-task-log rts-task-log-info\">\n <span class=\"rts-task-log-message\">Waiting for logs\u2026</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Output -->\n @if (hasOutput) {\n <div class=\"rts-task-section rts-task-section-output\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Output</span>\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('output')\">\n {{ copied === 'output' ? 'Copied' : 'Copy' }}\n </button>\n </div>\n <pre class=\"rts-task-code\"><code>{{ outputJson }}</code></pre>\n </div>\n }\n\n @if (task.errors.length) {\n <div class=\"rts-task-errors\">\n @for (error of task.errors; track $index) {\n <div class=\"rts-task-error\">{{ error.message }}</div>\n }\n </div>\n }\n\n @if (task.requestError) {\n <div class=\"rts-task-errors\">\n <div class=\"rts-task-error\">{{ task.requestError }}</div>\n </div>\n }\n } @else {\n <div class=\"rts-task-placeholder\">Task is not available yet.</div>\n }\n</div>\n", styles: [":host{display:block;--rts-task-accent: #8b5cf6;--rts-task-accent-2: #6366f1;--rts-task-success: #10b981;--rts-task-fail: #f43f5e;--rts-task-warn: #f59e0b}.rts-task{position:relative;display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:12px;background:linear-gradient(var(--rts-bg-secondary, #fff),var(--rts-bg-secondary, #fff)) padding-box,linear-gradient(135deg,#6366f173,#8b5cf626 60%,#a78bfa59) border-box;border:1px solid transparent;box-shadow:0 6px 24px -12px #6366f159;min-width:260px;max-width:100%;font-size:13px;transition:box-shadow .25s ease}.rts-task.rts-task-status-running{animation:rts-task-glow 2.2s ease-in-out infinite}@keyframes rts-task-glow{0%,to{box-shadow:0 6px 24px -12px #6366f159}50%{box-shadow:0 6px 28px -8px #8b5cf699}}.rts-task-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-task-identity{display:flex;align-items:center;gap:8px;min-width:0}.rts-task-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:8px;color:#fff;font-size:14px;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent))}.rts-task-status-running .rts-task-icon{animation:rts-task-spin 2.4s linear infinite}.rts-task-titles{display:flex;flex-direction:column;min-width:0}.rts-task-name{font-weight:600;color:var(--rts-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-task-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-task-status{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0;color:var(--rts-task-accent);background:#8b5cf61f}.rts-task-status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.rts-task-status-running .rts-task-status-dot{animation:rts-task-pulse 1s ease-in-out infinite}.rts-task-status-success .rts-task-status{color:var(--rts-task-success);background:#10b9811f}.rts-task-status-fail .rts-task-status{color:var(--rts-task-fail);background:#f43f5e1f}.rts-task-section{display:flex;flex-direction:column;gap:4px;animation:rts-task-fade-in .3s ease}.rts-task-section-head{display:flex;align-items:center;justify-content:space-between}.rts-task-section-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-task-copy{border:none;background:transparent;color:var(--rts-task-accent);font-size:11px;cursor:pointer;padding:0 2px}.rts-task-copy:hover{text-decoration:underline}.rts-task-live{font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--rts-task-fail);animation:rts-task-pulse 1.2s ease-in-out infinite}.rts-task-code,.rts-task-terminal{margin:0;padding:10px 12px;border-radius:8px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;line-height:1.55;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid rgba(139,92,246,.18)}.rts-task-section-output .rts-task-code{border-color:#10b98159}.rts-task-log{display:flex;gap:8px;align-items:baseline}.rts-task-log-time{color:#6b6f8a;flex-shrink:0}.rts-task-log-level{flex-shrink:0;min-width:34px;text-transform:uppercase;font-size:9.5px;font-weight:700;color:#a78bfa}.rts-task-log-warn .rts-task-log-level{color:var(--rts-task-warn)}.rts-task-log-error .rts-task-log-level,.rts-task-log-error .rts-task-log-message{color:#fb7185}.rts-task-live-text{margin-top:6px;padding-top:6px;border-top:1px dashed rgba(139,92,246,.25);color:#c4b5fd;white-space:pre-wrap}.rts-task-cursor{display:inline-block;width:6px;height:12px;margin-left:1px;vertical-align:text-bottom;background:#a78bfa;animation:rts-task-blink .8s step-end infinite}.rts-task-actions{display:flex;justify-content:flex-end}.rts-task-execute{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border:none;border-radius:8px;color:#fff;font-weight:600;font-size:12px;cursor:pointer;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent));box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.rts-task-execute:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 6px 18px -4px #6366f1bf}.rts-task-execute:disabled{cursor:default;opacity:.6;box-shadow:none}.rts-task-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-task-spin .8s linear infinite}.rts-task-placeholder{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);font-style:italic}.rts-task-errors{display:flex;flex-direction:column;gap:4px}.rts-task-error{padding:6px 10px;border-radius:6px;font-size:12px;color:var(--rts-task-fail);background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}@keyframes rts-task-spin{to{transform:rotate(360deg)}}@keyframes rts-task-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rts-task-blink{0%,to{opacity:1}50%{opacity:0}}@keyframes rts-task-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}\n"] }]
|
|
3405
|
+
args: [{ selector: 'rtsee-task', standalone: true, imports: [NgClass, TaskActionThumbnailComponent, TaskActionPromptComponent], template: "<div class=\"rts-task\" [ngClass]=\"statusClass\">\n @if (task) {\n <div class=\"rts-task-header\">\n <div class=\"rts-task-identity\">\n <span class=\"rts-task-icon\">\u2699</span>\n <div class=\"rts-task-titles\">\n <span class=\"rts-task-name\">{{ task.name || 'Task' }}</span>\n <span class=\"rts-task-id\" [title]=\"task.id\">#{{ task.id }}</span>\n </div>\n </div>\n <span class=\"rts-task-status\">\n <span class=\"rts-task-status-dot\"></span>\n {{ statusLabel }}\n </span>\n </div>\n\n <!-- Input -->\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Input</span>\n @if (inputJson) {\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('input')\">\n {{ copied === 'input' ? 'Copied' : 'Copy' }}\n </button>\n }\n </div>\n @if (inputJson) {\n <pre class=\"rts-task-code\"><code>{{ inputJson }}</code></pre>\n } @else if (task.loading) {\n <div class=\"rts-task-placeholder\">Loading\u2026</div>\n } @else {\n <div class=\"rts-task-placeholder\">No input</div>\n }\n </div>\n\n @if (allowExecute) {\n <div class=\"rts-task-actions\">\n <button type=\"button\"\n class=\"rts-task-execute\"\n [disabled]=\"!task.canExecute\"\n (click)=\"execute()\"\n >\n @if (task.isRunning || task.executeInProgress) {\n <span class=\"rts-task-spinner\"></span> Executing\u2026\n } @else if (task.isFailed) {\n <span class=\"pi pi-refresh\"></span> Retry\n } @else if (task.isFinished) {\n <span class=\"pi pi-check\"></span> Executed\n } @else {\n <span class=\"pi pi-play\"></span> Execute\n }\n </button>\n </div>\n }\n\n <!-- Prompts -->\n @if (hasPrompts) {\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Prompts</span>\n </div>\n <div class=\"rts-task-prompts-list\">\n @for (prompt of task.prompts; track prompt.id) {\n <rtsee-task-action-prompt\n [prompt]=\"prompt\"\n [task]=\"task\"\n ></rtsee-task-action-prompt>\n }\n </div>\n </div>\n }\n\n <!-- Actions (replaces Logs list) -->\n @if (hasActions || task.isRunning) {\n <div class=\"rts-task-section\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">\n Actions @if (task.actionsTotal) { ({{ task.actions.length }}/{{ task.actionsTotal }}) }\n </span>\n @if (task.isRunning) {\n <span class=\"rts-task-live\">LIVE</span>\n }\n </div>\n <div #actionsContainer class=\"rts-task-actions-list\" (scroll)=\"onActionsScroll($event)\">\n @for (action of task.actions; track action.id) {\n <rtsee-task-action-thumbnail\n [action]=\"action\"\n [task]=\"task\"\n ></rtsee-task-action-thumbnail>\n }\n @if (task.isRunning && !task.actions.length) {\n <div class=\"rts-task-placeholder\">Starting actions\u2026</div>\n }\n @if (task.actionsLoading) {\n <div class=\"rts-task-placeholder\">Loading actions\u2026</div>\n }\n @if (task.hasMoreActions && !task.actionsLoading) {\n <button type=\"button\" class=\"rts-task-load-more\" (click)=\"loadMoreActions()\">\n Load more actions ({{ task.actions.length }}/{{ task.actionsTotal }})\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Output -->\n @if (hasOutput) {\n <div class=\"rts-task-section rts-task-section-output\">\n <div class=\"rts-task-section-head\">\n <span class=\"rts-task-section-label\">Output</span>\n <button type=\"button\" class=\"rts-task-copy\" (click)=\"copy('output')\">\n {{ copied === 'output' ? 'Copied' : 'Copy' }}\n </button>\n </div>\n <pre class=\"rts-task-code\"><code>{{ outputJson }}</code></pre>\n </div>\n }\n\n @if (task.errors.length) {\n <div class=\"rts-task-errors\">\n @for (error of task.errors; track $index) {\n <div class=\"rts-task-error\">{{ error.message }}</div>\n }\n </div>\n }\n\n @if (task.requestError) {\n <div class=\"rts-task-errors\">\n <div class=\"rts-task-error\">{{ task.requestError }}</div>\n </div>\n }\n } @else {\n <div class=\"rts-task-placeholder\">Task is not available yet.</div>\n }\n</div>\n", styles: [":host{display:block;--rts-task-accent: #8b5cf6;--rts-task-accent-2: #6366f1;--rts-task-success: #10b981;--rts-task-fail: #f43f5e;--rts-task-warn: #f59e0b}.rts-task{position:relative;display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:12px;background:linear-gradient(var(--rts-bg-secondary, #fff),var(--rts-bg-secondary, #fff)) padding-box,linear-gradient(135deg,#6366f173,#8b5cf626 60%,#a78bfa59) border-box;border:1px solid transparent;box-shadow:0 6px 24px -12px #6366f159;min-width:260px;max-width:100%;font-size:13px;transition:box-shadow .25s ease}.rts-task.rts-task-status-running{animation:rts-task-glow 2.2s ease-in-out infinite}@keyframes rts-task-glow{0%,to{box-shadow:0 6px 24px -12px #6366f159}50%{box-shadow:0 6px 28px -8px #8b5cf699}}.rts-task-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rts-task-identity{display:flex;align-items:center;gap:8px;min-width:0}.rts-task-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:8px;color:#fff;font-size:14px;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent))}.rts-task-status-running .rts-task-icon{animation:rts-task-spin 2.4s linear infinite}.rts-task-titles{display:flex;flex-direction:column;min-width:0}.rts-task-name{font-weight:600;color:var(--rts-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.rts-task-id{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10px;color:var(--rts-text-secondary, #8a8fa3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px}.rts-task-status{display:inline-flex;align-items:center;gap:5px;padding:2px 8px;border-radius:999px;font-size:10px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;flex-shrink:0;color:var(--rts-task-accent);background:#8b5cf61f}.rts-task-status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.rts-task-status-running .rts-task-status-dot{animation:rts-task-pulse 1s ease-in-out infinite}.rts-task-status-success .rts-task-status{color:var(--rts-task-success);background:#10b9811f}.rts-task-status-fail .rts-task-status{color:var(--rts-task-fail);background:#f43f5e1f}.rts-task-section{display:flex;flex-direction:column;gap:4px;animation:rts-task-fade-in .3s ease}.rts-task-section-head{display:flex;align-items:center;justify-content:space-between}.rts-task-section-label{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-task-copy{border:none;background:transparent;color:var(--rts-task-accent);font-size:11px;cursor:pointer;padding:0 2px}.rts-task-copy:hover{text-decoration:underline}.rts-task-live{font-size:9px;font-weight:700;letter-spacing:.08em;color:var(--rts-task-fail);animation:rts-task-pulse 1.2s ease-in-out infinite}.rts-task-code,.rts-task-terminal{margin:0;padding:10px 12px;border-radius:8px;background:#0f1020;color:#e4e4f0;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;line-height:1.55;max-height:220px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid rgba(139,92,246,.18)}.rts-task-section-output .rts-task-code{border-color:#10b98159}.rts-task-actions-list,.rts-task-prompts-list{display:flex;flex-direction:column;gap:6px;max-height:360px;overflow-y:auto;padding:2px}.rts-task-load-more{align-self:center;margin-top:4px;padding:5px 12px;border-radius:6px;border:1px solid rgba(139,92,246,.3);background:#8b5cf614;color:var(--rts-task-accent);font-size:11px;font-weight:600;cursor:pointer}.rts-task-load-more:hover{background:#8b5cf629}.rts-task-log{display:flex;gap:8px;align-items:baseline}.rts-task-log-time{color:#6b6f8a;flex-shrink:0}.rts-task-log-level{flex-shrink:0;min-width:34px;text-transform:uppercase;font-size:9.5px;font-weight:700;color:#a78bfa}.rts-task-log-warn .rts-task-log-level{color:var(--rts-task-warn)}.rts-task-log-error .rts-task-log-level,.rts-task-log-error .rts-task-log-message{color:#fb7185}.rts-task-live-text{margin-top:6px;padding-top:6px;border-top:1px dashed rgba(139,92,246,.25);color:#c4b5fd;white-space:pre-wrap}.rts-task-cursor{display:inline-block;width:6px;height:12px;margin-left:1px;vertical-align:text-bottom;background:#a78bfa;animation:rts-task-blink .8s step-end infinite}.rts-task-actions{display:flex;justify-content:flex-end}.rts-task-execute{display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border:none;border-radius:8px;color:#fff;font-weight:600;font-size:12px;cursor:pointer;background:linear-gradient(135deg,var(--rts-task-accent-2),var(--rts-task-accent));box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,opacity .15s ease}.rts-task-execute:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 6px 18px -4px #6366f1bf}.rts-task-execute:disabled{cursor:default;opacity:.6;box-shadow:none}.rts-task-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-task-spin .8s linear infinite}.rts-task-placeholder{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);font-style:italic}.rts-task-errors{display:flex;flex-direction:column;gap:4px}.rts-task-error{padding:6px 10px;border-radius:6px;font-size:12px;color:var(--rts-task-fail);background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}@keyframes rts-task-spin{to{transform:rotate(360deg)}}@keyframes rts-task-pulse{0%,to{opacity:1}50%{opacity:.35}}@keyframes rts-task-blink{0%,to{opacity:1}50%{opacity:0}}@keyframes rts-task-fade-in{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}\n"] }]
|
|
2568
3406
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { task: [{
|
|
2569
3407
|
type: Input
|
|
2570
3408
|
}], message: [{
|
|
@@ -2575,9 +3413,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2575
3413
|
type: Input
|
|
2576
3414
|
}], allowExecute: [{
|
|
2577
3415
|
type: Input
|
|
2578
|
-
}],
|
|
3416
|
+
}], actionsContainer: [{
|
|
2579
3417
|
type: ViewChild,
|
|
2580
|
-
args: ['
|
|
3418
|
+
args: ['actionsContainer']
|
|
2581
3419
|
}] } });
|
|
2582
3420
|
|
|
2583
3421
|
/**
|
|
@@ -3581,17 +4419,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
3581
4419
|
}] } });
|
|
3582
4420
|
|
|
3583
4421
|
class MessagesListComponent {
|
|
3584
|
-
constructor(timeFormatService, scroller, document) {
|
|
4422
|
+
constructor(timeFormatService, scroller, hostRef, document) {
|
|
3585
4423
|
this.timeFormatService = timeFormatService;
|
|
3586
4424
|
this.scroller = scroller;
|
|
4425
|
+
this.hostRef = hostRef;
|
|
3587
4426
|
this.document = document;
|
|
3588
4427
|
this.messagesGroups = [];
|
|
3589
4428
|
this.firstGroupedMessage = null;
|
|
3590
4429
|
this.lastGroupedMessage = null;
|
|
3591
4430
|
this.shouldStickToBottom = true;
|
|
4431
|
+
this.isWindowScroll = false;
|
|
3592
4432
|
this.resizeObserver = null;
|
|
3593
4433
|
this.onMediaCapture = null;
|
|
3594
4434
|
this.initialScrollInterval = null;
|
|
4435
|
+
this.lastContainerScrollTop = 0;
|
|
4436
|
+
this.lastWindowScrollTop = 0;
|
|
4437
|
+
this.isFramed = false;
|
|
3595
4438
|
this.RTSeeChatTypes = RTSeeChatTypes;
|
|
3596
4439
|
this.bindScrollFunction = () => {
|
|
3597
4440
|
this.shouldStickToBottom = true;
|
|
@@ -3604,29 +4447,66 @@ class MessagesListComponent {
|
|
|
3604
4447
|
}
|
|
3605
4448
|
};
|
|
3606
4449
|
}
|
|
4450
|
+
get isStandalone() {
|
|
4451
|
+
return Boolean(this.chat?.isStandalone);
|
|
4452
|
+
}
|
|
3607
4453
|
onWindowScroll(event) {
|
|
3608
|
-
this.
|
|
4454
|
+
this.updateScrollMode();
|
|
4455
|
+
if (!this.isWindowScroll) {
|
|
4456
|
+
return;
|
|
4457
|
+
}
|
|
3609
4458
|
const verticalOffset = window.pageYOffset ||
|
|
3610
4459
|
this.document.documentElement.scrollTop ||
|
|
3611
4460
|
this.document.body.scrollTop ||
|
|
3612
4461
|
0;
|
|
3613
|
-
|
|
4462
|
+
const scrollingUp = verticalOffset < this.lastWindowScrollTop;
|
|
4463
|
+
const scrollingDown = verticalOffset > this.lastWindowScrollTop;
|
|
4464
|
+
this.lastWindowScrollTop = verticalOffset;
|
|
4465
|
+
if (this.isStandalone) {
|
|
4466
|
+
const el = this.contentBlock?.nativeElement || this.scrollContainer?.nativeElement;
|
|
4467
|
+
if (!el || el.getClientRects().length === 0) {
|
|
4468
|
+
return;
|
|
4469
|
+
}
|
|
4470
|
+
const rect = el.getBoundingClientRect();
|
|
4471
|
+
const viewportHeight = window.innerHeight || this.document.documentElement.clientHeight || 0;
|
|
4472
|
+
if (scrollingDown && rect.bottom - viewportHeight < 300) {
|
|
4473
|
+
this.onScroll();
|
|
4474
|
+
}
|
|
4475
|
+
else if (scrollingUp && rect.top > -300 && rect.top <= 300) {
|
|
4476
|
+
this.onScrolledToTop();
|
|
4477
|
+
}
|
|
4478
|
+
return;
|
|
4479
|
+
}
|
|
4480
|
+
if (!this.isShellMobileChatActive()) {
|
|
3614
4481
|
return;
|
|
3615
4482
|
}
|
|
3616
|
-
|
|
4483
|
+
this.checkScrollPosition();
|
|
4484
|
+
if (scrollingUp && verticalOffset < 300) {
|
|
3617
4485
|
this.onScrolledToTop();
|
|
3618
4486
|
}
|
|
4487
|
+
else if (scrollingDown) {
|
|
4488
|
+
const scrollHeight = Math.max(this.document.documentElement.scrollHeight, this.document.body.scrollHeight);
|
|
4489
|
+
const clientHeight = window.innerHeight;
|
|
4490
|
+
if (scrollHeight - (verticalOffset + clientHeight) < 300) {
|
|
4491
|
+
this.onScroll();
|
|
4492
|
+
}
|
|
4493
|
+
}
|
|
3619
4494
|
}
|
|
3620
4495
|
onWindowResize() {
|
|
4496
|
+
this.updateScrollMode();
|
|
3621
4497
|
if (this.shouldStickToBottom) {
|
|
3622
4498
|
this.scrollToBottom();
|
|
3623
4499
|
}
|
|
3624
4500
|
}
|
|
3625
4501
|
ngOnInit() {
|
|
4502
|
+
this.updateScrollMode();
|
|
3626
4503
|
this.bindChatEvents(this.chat);
|
|
3627
4504
|
this.groupMessages();
|
|
3628
4505
|
}
|
|
3629
4506
|
ngOnChanges(changes) {
|
|
4507
|
+
if (changes['chat'] || changes['isFramed']) {
|
|
4508
|
+
this.updateScrollMode();
|
|
4509
|
+
}
|
|
3630
4510
|
if (changes['chat'] && !changes['chat'].firstChange) {
|
|
3631
4511
|
const prevChat = changes['chat'].previousValue;
|
|
3632
4512
|
this.unbindChatEvents(prevChat);
|
|
@@ -3636,7 +4516,8 @@ class MessagesListComponent {
|
|
|
3636
4516
|
}
|
|
3637
4517
|
}
|
|
3638
4518
|
ngAfterViewInit() {
|
|
3639
|
-
|
|
4519
|
+
this.updateScrollMode();
|
|
4520
|
+
if (this.isStandalone) {
|
|
3640
4521
|
return;
|
|
3641
4522
|
}
|
|
3642
4523
|
this.enforceInitialScroll();
|
|
@@ -3681,8 +4562,25 @@ class MessagesListComponent {
|
|
|
3681
4562
|
}
|
|
3682
4563
|
}
|
|
3683
4564
|
onContainerScroll(event) {
|
|
4565
|
+
this.updateScrollMode();
|
|
4566
|
+
if (this.isWindowScroll) {
|
|
4567
|
+
return;
|
|
4568
|
+
}
|
|
3684
4569
|
this.checkScrollPosition();
|
|
3685
|
-
this.
|
|
4570
|
+
const el = this.scrollContainer?.nativeElement;
|
|
4571
|
+
if (!el) {
|
|
4572
|
+
return;
|
|
4573
|
+
}
|
|
4574
|
+
const scrollTop = el.scrollTop;
|
|
4575
|
+
const scrollingUp = scrollTop < this.lastContainerScrollTop;
|
|
4576
|
+
const scrollingDown = scrollTop > this.lastContainerScrollTop;
|
|
4577
|
+
this.lastContainerScrollTop = scrollTop;
|
|
4578
|
+
if (scrollingUp && scrollTop < 300) {
|
|
4579
|
+
this.onScrolledToTop();
|
|
4580
|
+
}
|
|
4581
|
+
else if (scrollingDown && el.scrollHeight - (scrollTop + el.clientHeight) < 300) {
|
|
4582
|
+
this.onScroll();
|
|
4583
|
+
}
|
|
3686
4584
|
}
|
|
3687
4585
|
onScrolledToTop() {
|
|
3688
4586
|
if (this.chat.messagesLoadInProgress || this.chat.firstMessageLoaded) {
|
|
@@ -3691,36 +4589,26 @@ class MessagesListComponent {
|
|
|
3691
4589
|
this.chat.loadRemoteMessages('back');
|
|
3692
4590
|
}
|
|
3693
4591
|
onScroll() {
|
|
3694
|
-
if (this.chat.messagesLoadInProgress) {
|
|
4592
|
+
if (this.chat.messagesLoadInProgress || this.chat.lastMessageLoaded) {
|
|
3695
4593
|
return;
|
|
3696
4594
|
}
|
|
3697
4595
|
this.chat.loadRemoteMessages('front');
|
|
3698
4596
|
}
|
|
3699
4597
|
scrollToBottom(immediate = false) {
|
|
3700
|
-
if (this.
|
|
4598
|
+
if (this.isStandalone) {
|
|
3701
4599
|
return;
|
|
3702
4600
|
}
|
|
4601
|
+
this.updateScrollMode();
|
|
3703
4602
|
const performScroll = () => {
|
|
3704
|
-
if (this.
|
|
3705
|
-
|
|
3706
|
-
this.bottomAnchor.nativeElement.scrollIntoView({
|
|
3707
|
-
block: 'end',
|
|
3708
|
-
inline: 'nearest',
|
|
3709
|
-
behavior: 'instant',
|
|
3710
|
-
});
|
|
3711
|
-
}
|
|
3712
|
-
catch {
|
|
3713
|
-
// ignore
|
|
3714
|
-
}
|
|
3715
|
-
}
|
|
3716
|
-
if (window.innerWidth < COMMON_CONSTANTS.mobileBreakpoint) {
|
|
3717
|
-
const target = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
|
4603
|
+
if (this.isShellMobileChatActive()) {
|
|
4604
|
+
const target = Math.max(this.document.documentElement.scrollHeight, this.document.body.scrollHeight);
|
|
3718
4605
|
window.scrollTo({ top: target, behavior: 'instant' });
|
|
3719
4606
|
this.scroller.scrollToPosition([0, target]);
|
|
3720
4607
|
}
|
|
3721
|
-
if (this.scrollContainer?.nativeElement) {
|
|
4608
|
+
else if (!this.isWindowScroll && this.scrollContainer?.nativeElement) {
|
|
3722
4609
|
const el = this.scrollContainer.nativeElement;
|
|
3723
4610
|
el.scrollTop = el.scrollHeight;
|
|
4611
|
+
this.lastContainerScrollTop = el.scrollTop;
|
|
3724
4612
|
}
|
|
3725
4613
|
};
|
|
3726
4614
|
performScroll();
|
|
@@ -3743,11 +4631,11 @@ class MessagesListComponent {
|
|
|
3743
4631
|
}
|
|
3744
4632
|
isAtBottom() {
|
|
3745
4633
|
const threshold = 150; // px threshold from bottom
|
|
3746
|
-
if (
|
|
3747
|
-
const scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
|
4634
|
+
if (this.isShellMobileChatActive()) {
|
|
4635
|
+
const scrollHeight = Math.max(this.document.documentElement.scrollHeight, this.document.body.scrollHeight);
|
|
3748
4636
|
const scrollTop = window.pageYOffset ||
|
|
3749
|
-
document.documentElement.scrollTop ||
|
|
3750
|
-
document.body.scrollTop ||
|
|
4637
|
+
this.document.documentElement.scrollTop ||
|
|
4638
|
+
this.document.body.scrollTop ||
|
|
3751
4639
|
0;
|
|
3752
4640
|
const clientHeight = window.innerHeight;
|
|
3753
4641
|
return scrollHeight - (scrollTop + clientHeight) <= threshold;
|
|
@@ -3759,6 +4647,36 @@ class MessagesListComponent {
|
|
|
3759
4647
|
return el.scrollHeight - (el.scrollTop + el.clientHeight) <= threshold;
|
|
3760
4648
|
}
|
|
3761
4649
|
}
|
|
4650
|
+
isMobileViewport() {
|
|
4651
|
+
return (typeof window !== 'undefined' &&
|
|
4652
|
+
window.innerWidth < COMMON_CONSTANTS.mobileBreakpoint);
|
|
4653
|
+
}
|
|
4654
|
+
isShellMobileChatActive() {
|
|
4655
|
+
if (this.isStandalone || this.isFramed || !this.isMobileViewport()) {
|
|
4656
|
+
return false;
|
|
4657
|
+
}
|
|
4658
|
+
const el = this.scrollContainer?.nativeElement || this.hostRef?.nativeElement;
|
|
4659
|
+
if (!el) {
|
|
4660
|
+
return false;
|
|
4661
|
+
}
|
|
4662
|
+
const shell = typeof el.closest === 'function' ? el.closest('.rtsee-shell') : null;
|
|
4663
|
+
if (shell && !shell.classList.contains('rtsee-shell-messenger-active')) {
|
|
4664
|
+
return false;
|
|
4665
|
+
}
|
|
4666
|
+
return el.getClientRects().length > 0;
|
|
4667
|
+
}
|
|
4668
|
+
computeIsWindowScroll() {
|
|
4669
|
+
if (this.isStandalone) {
|
|
4670
|
+
return true;
|
|
4671
|
+
}
|
|
4672
|
+
if (this.isFramed) {
|
|
4673
|
+
return false;
|
|
4674
|
+
}
|
|
4675
|
+
return this.isMobileViewport();
|
|
4676
|
+
}
|
|
4677
|
+
updateScrollMode() {
|
|
4678
|
+
this.isWindowScroll = this.computeIsWindowScroll();
|
|
4679
|
+
}
|
|
3762
4680
|
enforceInitialScroll() {
|
|
3763
4681
|
this.shouldStickToBottom = true;
|
|
3764
4682
|
this.scrollToBottom();
|
|
@@ -3834,19 +4752,21 @@ class MessagesListComponent {
|
|
|
3834
4752
|
this.firstGroupedMessage = this.chat.messages[0];
|
|
3835
4753
|
this.lastGroupedMessage = this.chat.messages[this.chat.messages.length - 1];
|
|
3836
4754
|
}
|
|
3837
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessagesListComponent, deps: [{ token: TimeFormatHelperService }, { token:
|
|
3838
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessagesListComponent, isStandalone: true, selector: "rtsee-messages-list", inputs: { chat: "chat", messenger: "messenger" }, host: { listeners: { "window:scroll": "onWindowScroll($event)", "window:resize": "onWindowResize()" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollBlock"], descendants: true }, { propertyName: "contentBlock", first: true, predicate: ["contentBlock"], descendants: true }, { propertyName: "bottomAnchor", first: true, predicate: ["bottomAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-messages-list\"\n #scrollBlock\n infiniteScroll\n [infiniteScrollUpDistance]=\"2\"\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n [scrollWindow]=\"
|
|
4755
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessagesListComponent, deps: [{ token: TimeFormatHelperService }, { token: i1$3.ViewportScroller }, { token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4756
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessagesListComponent, isStandalone: true, selector: "rtsee-messages-list", inputs: { chat: "chat", messenger: "messenger", isFramed: "isFramed" }, host: { listeners: { "window:scroll": "onWindowScroll($event)", "window:resize": "onWindowResize()" } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollBlock"], descendants: true }, { propertyName: "contentBlock", first: true, predicate: ["contentBlock"], descendants: true }, { propertyName: "bottomAnchor", first: true, predicate: ["bottomAnchor"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-messages-list\"\n #scrollBlock\n infiniteScroll\n [infiniteScrollUpDistance]=\"2\"\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n [scrollWindow]=\"isWindowScroll\"\n [infiniteScrollContainer]=\"isWindowScroll ? null : scrollBlock\"\n (scrolledUp)=\"onScrolledToTop()\"\n (scrolled)=\"onScroll()\"\n (scroll)=\"onContainerScroll($event)\"\n [ngClass]=\"{\n 'rts-messages-list-scrollable': !isWindowScroll\n }\"\n [style.padding-bottom]=\"messenger.chatInputHeight + 'px'\"\n>\n <div class=\"rts-messages-list-inner\" #contentBlock>\n @for (messageGroup of messagesGroups; track messageGroup.id) {\n <div\n class=\"rts-messenger-message-wrapper\"\n data-ugc=\"true\"\n rel=\"ugc\"\n [ngClass]=\"{\n 'rts-messenger-message-wrapper-with-sender': messageGroup.senderVisible\n }\"\n >\n <div class=\"rts-messenger-message-inset\">\n <img [src]=\"messageGroup.sender.imageUrl\"\n class=\"rts-messenger-message-sender-image\"\n >\n </div>\n\n <div\n class=\"rts-messenger-message-sender-name\"\n itemprop=\"author\"\n itemscope\n itemtype=\"https://schema.org/Person\"\n >\n <p itemprop=\"name\">{{messageGroup.sender.name}}</p>\n </div>\n\n @for (message of messageGroup.messages; track message.id) {\n <rtsee-message [message]=\"message\"\n [messenger]=\"messenger\"\n [chat]=\"chat\"\n ></rtsee-message>\n }\n </div>\n }\n <div class=\"rts-messages-list-bottom-anchor\" #bottomAnchor></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: MessageComponent, selector: "rtsee-message", inputs: ["chat", "message", "member", "messenger"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
3839
4757
|
}
|
|
3840
4758
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessagesListComponent, decorators: [{
|
|
3841
4759
|
type: Component,
|
|
3842
|
-
args: [{ selector: 'rtsee-messages-list', imports: [InfiniteScrollDirective, MessageComponent, NgClass], standalone: true, template: "<div class=\"rts-messages-list\"\n #scrollBlock\n infiniteScroll\n [infiniteScrollUpDistance]=\"2\"\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n [scrollWindow]=\"
|
|
3843
|
-
}], ctorParameters: () => [{ type: TimeFormatHelperService }, { type:
|
|
4760
|
+
args: [{ selector: 'rtsee-messages-list', imports: [InfiniteScrollDirective, MessageComponent, NgClass], standalone: true, template: "<div class=\"rts-messages-list\"\n #scrollBlock\n infiniteScroll\n [infiniteScrollUpDistance]=\"2\"\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n [scrollWindow]=\"isWindowScroll\"\n [infiniteScrollContainer]=\"isWindowScroll ? null : scrollBlock\"\n (scrolledUp)=\"onScrolledToTop()\"\n (scrolled)=\"onScroll()\"\n (scroll)=\"onContainerScroll($event)\"\n [ngClass]=\"{\n 'rts-messages-list-scrollable': !isWindowScroll\n }\"\n [style.padding-bottom]=\"messenger.chatInputHeight + 'px'\"\n>\n <div class=\"rts-messages-list-inner\" #contentBlock>\n @for (messageGroup of messagesGroups; track messageGroup.id) {\n <div\n class=\"rts-messenger-message-wrapper\"\n data-ugc=\"true\"\n rel=\"ugc\"\n [ngClass]=\"{\n 'rts-messenger-message-wrapper-with-sender': messageGroup.senderVisible\n }\"\n >\n <div class=\"rts-messenger-message-inset\">\n <img [src]=\"messageGroup.sender.imageUrl\"\n class=\"rts-messenger-message-sender-image\"\n >\n </div>\n\n <div\n class=\"rts-messenger-message-sender-name\"\n itemprop=\"author\"\n itemscope\n itemtype=\"https://schema.org/Person\"\n >\n <p itemprop=\"name\">{{messageGroup.sender.name}}</p>\n </div>\n\n @for (message of messageGroup.messages; track message.id) {\n <rtsee-message [message]=\"message\"\n [messenger]=\"messenger\"\n [chat]=\"chat\"\n ></rtsee-message>\n }\n </div>\n }\n <div class=\"rts-messages-list-bottom-anchor\" #bottomAnchor></div>\n </div>\n</div>\n" }]
|
|
4761
|
+
}], ctorParameters: () => [{ type: TimeFormatHelperService }, { type: i1$3.ViewportScroller }, { type: i0.ElementRef }, { type: Document, decorators: [{
|
|
3844
4762
|
type: Inject,
|
|
3845
4763
|
args: [DOCUMENT]
|
|
3846
4764
|
}] }], propDecorators: { chat: [{
|
|
3847
4765
|
type: Input
|
|
3848
4766
|
}], messenger: [{
|
|
3849
4767
|
type: Input
|
|
4768
|
+
}], isFramed: [{
|
|
4769
|
+
type: Input
|
|
3850
4770
|
}], scrollContainer: [{
|
|
3851
4771
|
type: ViewChild,
|
|
3852
4772
|
args: ['scrollBlock']
|
|
@@ -4320,6 +5240,10 @@ class InviteLinkComponent {
|
|
|
4320
5240
|
}
|
|
4321
5241
|
}
|
|
4322
5242
|
async copyToClipboard() {
|
|
5243
|
+
const targetChat = this.chatId
|
|
5244
|
+
? this.messenger?.getChatById?.(this.chatId) || this.messenger?.openedChat
|
|
5245
|
+
: this.messenger?.openedChat;
|
|
5246
|
+
this.messenger?.trackChatMemberInviteClicked?.(targetChat, this.inviteUrl);
|
|
4323
5247
|
try {
|
|
4324
5248
|
await navigator.clipboard.writeText(this.inviteUrl);
|
|
4325
5249
|
this.copied = true;
|
|
@@ -4398,6 +5322,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4398
5322
|
|
|
4399
5323
|
class ChatComponent {
|
|
4400
5324
|
constructor() {
|
|
5325
|
+
this.isFramed = false;
|
|
4401
5326
|
this.showInvite = false;
|
|
4402
5327
|
}
|
|
4403
5328
|
get isSoleAdmin() {
|
|
@@ -4443,7 +5368,7 @@ class ChatComponent {
|
|
|
4443
5368
|
}
|
|
4444
5369
|
}
|
|
4445
5370
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4446
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatComponent, isStandalone: true, selector: "rtsee-chat", inputs: { chat: "chat", chatData: "chatData", entity: "entity", messenger: "messenger" }, ngImport: i0, template: "<div class=\"rts-chat\"\n [ngClass]=\"{\n 'rts-chat-standalone': chat.isStandalone,\n 'rts-chat-in-viewport': chat.isInViewPort\n }\"\n rtseeViewportObserver\n (inViewport)=\"onInViewPortChange($event)\"\n>\n @if (isSoleAdmin) {\n <div class=\"rts-chat-sole-admin-banner\">\n <div class=\"rts-chat-sole-admin-header\">\n <div class=\"rts-chat-sole-admin-badge\">\n <span class=\"material-icons-outlined\">group_add</span>\n </div>\n <div class=\"rts-chat-sole-admin-info\">\n <h4>You are the only member in this chat</h4>\n <p>Invite people to start chatting</p>\n </div>\n <button class=\"rts-btn rts-btn-primary rts-chat-invite-toggle-btn\"\n (click)=\"toggleInvite()\"\n type=\"button\"\n >\n <span class=\"material-icons-outlined\">{{ showInvite ? 'expand_less' : 'person_add' }}</span>\n <span>{{ showInvite ? 'Hide Invite' : 'Invite to Chat' }}</span>\n </button>\n </div>\n\n @if (showInvite) {\n <div class=\"rts-chat-sole-admin-invite\">\n <rtsee-invite-link\n [chatId]=\"chat.id\"\n [messenger]=\"messenger\"\n ></rtsee-invite-link>\n </div>\n }\n </div>\n }\n\n <div class=\"rts-chat-footer-container\">\n <div class=\"rts-chat-footer-container-inner\">\n <rtsee-chat-input [messenger]=\"messenger\" [chat]=\"chat\"></rtsee-chat-input>\n </div>\n </div>\n <div class=\"rts-chat-body-container\">\n <rtsee-messages-list [messenger]=\"messenger\" [chat]=\"chat\"></rtsee-messages-list>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: MessagesListComponent, selector: "rtsee-messages-list", inputs: ["chat", "messenger"] }, { kind: "component", type: ChatInputComponent, selector: "rtsee-chat-input", inputs: ["messenger", "chat"] }, { kind: "component", type: InviteLinkComponent, selector: "rtsee-invite-link", inputs: ["inviteUrl", "chatId", "messenger", "disclaimer"] }, { kind: "directive", type: ViewportObserverDirective, selector: "[rtseeViewportObserver]", outputs: ["inViewport"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
5371
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatComponent, isStandalone: true, selector: "rtsee-chat", inputs: { chat: "chat", chatData: "chatData", entity: "entity", messenger: "messenger", isFramed: "isFramed" }, ngImport: i0, template: "<div class=\"rts-chat\"\n [ngClass]=\"{\n 'rts-chat-standalone': chat.isStandalone,\n 'rts-chat-in-viewport': chat.isInViewPort,\n 'rts-chat-framed': isFramed\n }\"\n rtseeViewportObserver\n (inViewport)=\"onInViewPortChange($event)\"\n>\n @if (isSoleAdmin) {\n <div class=\"rts-chat-sole-admin-banner\">\n <div class=\"rts-chat-sole-admin-header\">\n <div class=\"rts-chat-sole-admin-badge\">\n <span class=\"material-icons-outlined\">group_add</span>\n </div>\n <div class=\"rts-chat-sole-admin-info\">\n <h4>You are the only member in this chat</h4>\n <p>Invite people to start chatting</p>\n </div>\n <button class=\"rts-btn rts-btn-primary rts-chat-invite-toggle-btn\"\n (click)=\"toggleInvite()\"\n type=\"button\"\n >\n <span class=\"material-icons-outlined\">{{ showInvite ? 'expand_less' : 'person_add' }}</span>\n <span>{{ showInvite ? 'Hide Invite' : 'Invite to Chat' }}</span>\n </button>\n </div>\n\n @if (showInvite) {\n <div class=\"rts-chat-sole-admin-invite\">\n <rtsee-invite-link\n [chatId]=\"chat.id\"\n [messenger]=\"messenger\"\n ></rtsee-invite-link>\n </div>\n }\n </div>\n }\n\n <div class=\"rts-chat-footer-container\">\n <div class=\"rts-chat-footer-container-inner\">\n <rtsee-chat-input [messenger]=\"messenger\" [chat]=\"chat\"></rtsee-chat-input>\n </div>\n </div>\n <div class=\"rts-chat-body-container\">\n <rtsee-messages-list [messenger]=\"messenger\" [chat]=\"chat\" [isFramed]=\"isFramed\"></rtsee-messages-list>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: MessagesListComponent, selector: "rtsee-messages-list", inputs: ["chat", "messenger", "isFramed"] }, { kind: "component", type: ChatInputComponent, selector: "rtsee-chat-input", inputs: ["messenger", "chat"] }, { kind: "component", type: InviteLinkComponent, selector: "rtsee-invite-link", inputs: ["inviteUrl", "chatId", "messenger", "disclaimer"] }, { kind: "directive", type: ViewportObserverDirective, selector: "[rtseeViewportObserver]", outputs: ["inViewport"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
4447
5372
|
}
|
|
4448
5373
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatComponent, decorators: [{
|
|
4449
5374
|
type: Component,
|
|
@@ -4453,7 +5378,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4453
5378
|
InviteLinkComponent,
|
|
4454
5379
|
ViewportObserverDirective,
|
|
4455
5380
|
NgClass,
|
|
4456
|
-
], standalone: true, template: "<div class=\"rts-chat\"\n [ngClass]=\"{\n 'rts-chat-standalone': chat.isStandalone,\n 'rts-chat-in-viewport': chat.isInViewPort\n }\"\n rtseeViewportObserver\n (inViewport)=\"onInViewPortChange($event)\"\n>\n @if (isSoleAdmin) {\n <div class=\"rts-chat-sole-admin-banner\">\n <div class=\"rts-chat-sole-admin-header\">\n <div class=\"rts-chat-sole-admin-badge\">\n <span class=\"material-icons-outlined\">group_add</span>\n </div>\n <div class=\"rts-chat-sole-admin-info\">\n <h4>You are the only member in this chat</h4>\n <p>Invite people to start chatting</p>\n </div>\n <button class=\"rts-btn rts-btn-primary rts-chat-invite-toggle-btn\"\n (click)=\"toggleInvite()\"\n type=\"button\"\n >\n <span class=\"material-icons-outlined\">{{ showInvite ? 'expand_less' : 'person_add' }}</span>\n <span>{{ showInvite ? 'Hide Invite' : 'Invite to Chat' }}</span>\n </button>\n </div>\n\n @if (showInvite) {\n <div class=\"rts-chat-sole-admin-invite\">\n <rtsee-invite-link\n [chatId]=\"chat.id\"\n [messenger]=\"messenger\"\n ></rtsee-invite-link>\n </div>\n }\n </div>\n }\n\n <div class=\"rts-chat-footer-container\">\n <div class=\"rts-chat-footer-container-inner\">\n <rtsee-chat-input [messenger]=\"messenger\" [chat]=\"chat\"></rtsee-chat-input>\n </div>\n </div>\n <div class=\"rts-chat-body-container\">\n <rtsee-messages-list [messenger]=\"messenger\" [chat]=\"chat\"></rtsee-messages-list>\n </div>\n</div>\n" }]
|
|
5381
|
+
], standalone: true, template: "<div class=\"rts-chat\"\n [ngClass]=\"{\n 'rts-chat-standalone': chat.isStandalone,\n 'rts-chat-in-viewport': chat.isInViewPort,\n 'rts-chat-framed': isFramed\n }\"\n rtseeViewportObserver\n (inViewport)=\"onInViewPortChange($event)\"\n>\n @if (isSoleAdmin) {\n <div class=\"rts-chat-sole-admin-banner\">\n <div class=\"rts-chat-sole-admin-header\">\n <div class=\"rts-chat-sole-admin-badge\">\n <span class=\"material-icons-outlined\">group_add</span>\n </div>\n <div class=\"rts-chat-sole-admin-info\">\n <h4>You are the only member in this chat</h4>\n <p>Invite people to start chatting</p>\n </div>\n <button class=\"rts-btn rts-btn-primary rts-chat-invite-toggle-btn\"\n (click)=\"toggleInvite()\"\n type=\"button\"\n >\n <span class=\"material-icons-outlined\">{{ showInvite ? 'expand_less' : 'person_add' }}</span>\n <span>{{ showInvite ? 'Hide Invite' : 'Invite to Chat' }}</span>\n </button>\n </div>\n\n @if (showInvite) {\n <div class=\"rts-chat-sole-admin-invite\">\n <rtsee-invite-link\n [chatId]=\"chat.id\"\n [messenger]=\"messenger\"\n ></rtsee-invite-link>\n </div>\n }\n </div>\n }\n\n <div class=\"rts-chat-footer-container\">\n <div class=\"rts-chat-footer-container-inner\">\n <rtsee-chat-input [messenger]=\"messenger\" [chat]=\"chat\"></rtsee-chat-input>\n </div>\n </div>\n <div class=\"rts-chat-body-container\">\n <rtsee-messages-list [messenger]=\"messenger\" [chat]=\"chat\" [isFramed]=\"isFramed\"></rtsee-messages-list>\n </div>\n</div>\n" }]
|
|
4457
5382
|
}], propDecorators: { chat: [{
|
|
4458
5383
|
type: Input
|
|
4459
5384
|
}], chatData: [{
|
|
@@ -4462,6 +5387,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4462
5387
|
type: Input
|
|
4463
5388
|
}], messenger: [{
|
|
4464
5389
|
type: Input
|
|
5390
|
+
}], isFramed: [{
|
|
5391
|
+
type: Input
|
|
4465
5392
|
}] } });
|
|
4466
5393
|
|
|
4467
5394
|
class ManageProfileComponent {
|
|
@@ -4833,11 +5760,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4833
5760
|
}] } });
|
|
4834
5761
|
|
|
4835
5762
|
class MessengerComponent {
|
|
5763
|
+
constructor() {
|
|
5764
|
+
this.isFramed = false;
|
|
5765
|
+
}
|
|
4836
5766
|
onScroll() {
|
|
4837
5767
|
void this.messenger.loadChats();
|
|
4838
5768
|
}
|
|
4839
5769
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessengerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4840
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessengerComponent, isStandalone: true, selector: "rtsee-messenger", inputs: { messenger: "messenger" }, ngImport: i0, template: "<div class=\"rts-messenger rts-theme-dark\" [ngClass]=\"{\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails,\n 'rts-messenger-folded': messenger.folded,\n 'rts-messenger-overlay-window': messenger.isOverlayPageOpened\n}\">\n @if (messenger.manageProfile) {\n <div class=\"rts-manage-profile\">\n <rtsee-manage-profile [manageProfile]=\"messenger.manageProfile\"\n [messenger]=\"messenger\"\n ></rtsee-manage-profile>\n </div>\n }\n\n @if (messenger.isPaymentPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-page>\n </div>\n }\n\n @if (messenger.isPaymentValidationPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-validation-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-validation-page>\n </div>\n }\n\n @if (messenger.isManagePlanPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-manage-plan [messenger]=\"messenger\"></rtsee-manage-plan>\n </div>\n }\n
|
|
5770
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessengerComponent, isStandalone: true, selector: "rtsee-messenger", inputs: { messenger: "messenger", isFramed: "isFramed" }, ngImport: i0, template: "<div class=\"rts-messenger rts-theme-dark\" [ngClass]=\"{\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo,\n 'rts-messenger-folded': messenger.folded,\n 'rts-messenger-overlay-window': messenger.isOverlayPageOpened,\n 'rts-messenger-framed': isFramed\n}\">\n @if (messenger.manageProfile) {\n <div class=\"rts-manage-profile\">\n <rtsee-manage-profile [manageProfile]=\"messenger.manageProfile\"\n [messenger]=\"messenger\"\n ></rtsee-manage-profile>\n </div>\n }\n\n @if (messenger.isPaymentPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-page>\n </div>\n }\n\n @if (messenger.isPaymentValidationPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-validation-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-validation-page>\n </div>\n }\n\n @if (messenger.isManagePlanPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-manage-plan [messenger]=\"messenger\"></rtsee-manage-plan>\n </div>\n }\n <div class=\"rts-messenger-body-container\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n [scrollWindow]=\"false\"\n (scrolled)=\"onScroll()\"\n >\n @if (messenger.openedChat) {\n <rtsee-chat [messenger]=\"messenger\" [chat]=\"messenger.openedChat\" [isFramed]=\"isFramed\"></rtsee-chat>\n } @else if (!messenger.openedChat) {\n <rtsee-chats-list [chats]=\"messenger.chats\" [messenger]=\"messenger\"></rtsee-chats-list>\n } @else if (messenger.openedProfile) {\n <rtsee-profile></rtsee-profile>\n }\n @if (messenger.loadingChatsInProgress) {\n <rtsee-preloader [diameter]=\"50\" ></rtsee-preloader>\n }\n </div>\n <div class=\"rts-messenger-header-container\">\n <rtsee-messenger-header [messenger]=\"messenger\"\n ></rtsee-messenger-header>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: MessengerHeaderComponent, selector: "rtsee-messenger-header", inputs: ["messenger"] }, { kind: "directive", type: InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ChatsListComponent, selector: "rtsee-chats-list", inputs: ["messenger", "chats"] }, { kind: "component", type: ChatComponent, selector: "rtsee-chat", inputs: ["chat", "chatData", "entity", "messenger", "isFramed"] }, { kind: "component", type: PreloaderComponent, selector: "rtsee-preloader", inputs: ["diameter", "color"] }, { kind: "component", type: ProfileComponent, selector: "rtsee-profile", inputs: ["messenger", "peer"] }, { kind: "component", type: ManageProfileComponent, selector: "rtsee-manage-profile", inputs: ["messenger", "manageProfile"] }, { kind: "component", type: PaymentPageComponent, selector: "rtsee-payment-page", inputs: ["messenger", "theme"] }, { kind: "component", type: PaymentValidationPageComponent, selector: "rtsee-payment-validation-page", inputs: ["messenger", "theme"] }, { kind: "component", type: ManagePlanComponent, selector: "rtsee-manage-plan", inputs: ["messenger"] }] }); }
|
|
4841
5771
|
}
|
|
4842
5772
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessengerComponent, decorators: [{
|
|
4843
5773
|
type: Component,
|
|
@@ -4855,9 +5785,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4855
5785
|
PaymentPageComponent,
|
|
4856
5786
|
PaymentValidationPageComponent,
|
|
4857
5787
|
ManagePlanComponent,
|
|
4858
|
-
], standalone: true, template: "<div class=\"rts-messenger rts-theme-dark\" [ngClass]=\"{\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails,\n 'rts-messenger-folded': messenger.folded,\n 'rts-messenger-overlay-window': messenger.isOverlayPageOpened\n}\">\n @if (messenger.manageProfile) {\n <div class=\"rts-manage-profile\">\n <rtsee-manage-profile [manageProfile]=\"messenger.manageProfile\"\n [messenger]=\"messenger\"\n ></rtsee-manage-profile>\n </div>\n }\n\n @if (messenger.isPaymentPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-page>\n </div>\n }\n\n @if (messenger.isPaymentValidationPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-validation-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-validation-page>\n </div>\n }\n\n @if (messenger.isManagePlanPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-manage-plan [messenger]=\"messenger\"></rtsee-manage-plan>\n </div>\n }\n
|
|
5788
|
+
], standalone: true, template: "<div class=\"rts-messenger rts-theme-dark\" [ngClass]=\"{\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo,\n 'rts-messenger-folded': messenger.folded,\n 'rts-messenger-overlay-window': messenger.isOverlayPageOpened,\n 'rts-messenger-framed': isFramed\n}\">\n @if (messenger.manageProfile) {\n <div class=\"rts-manage-profile\">\n <rtsee-manage-profile [manageProfile]=\"messenger.manageProfile\"\n [messenger]=\"messenger\"\n ></rtsee-manage-profile>\n </div>\n }\n\n @if (messenger.isPaymentPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-page>\n </div>\n }\n\n @if (messenger.isPaymentValidationPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-payment-validation-page [messenger]=\"messenger\" theme=\"dark\"></rtsee-payment-validation-page>\n </div>\n }\n\n @if (messenger.isManagePlanPageOpened) {\n <div class=\"rts-payment-page-container\">\n <rtsee-manage-plan [messenger]=\"messenger\"></rtsee-manage-plan>\n </div>\n }\n <div class=\"rts-messenger-body-container\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n [scrollWindow]=\"false\"\n (scrolled)=\"onScroll()\"\n >\n @if (messenger.openedChat) {\n <rtsee-chat [messenger]=\"messenger\" [chat]=\"messenger.openedChat\" [isFramed]=\"isFramed\"></rtsee-chat>\n } @else if (!messenger.openedChat) {\n <rtsee-chats-list [chats]=\"messenger.chats\" [messenger]=\"messenger\"></rtsee-chats-list>\n } @else if (messenger.openedProfile) {\n <rtsee-profile></rtsee-profile>\n }\n @if (messenger.loadingChatsInProgress) {\n <rtsee-preloader [diameter]=\"50\" ></rtsee-preloader>\n }\n </div>\n <div class=\"rts-messenger-header-container\">\n <rtsee-messenger-header [messenger]=\"messenger\"\n ></rtsee-messenger-header>\n </div>\n</div>\n" }]
|
|
4859
5789
|
}], propDecorators: { messenger: [{
|
|
4860
5790
|
type: Input
|
|
5791
|
+
}], isFramed: [{
|
|
5792
|
+
type: Input
|
|
4861
5793
|
}] } });
|
|
4862
5794
|
|
|
4863
5795
|
class BaseEventWidgetComponent {
|
|
@@ -5087,6 +6019,245 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
5087
6019
|
args: [{ selector: 'rtsee-slide-number-changed-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget slide-number-changed-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge slide-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\"\n >view_carousel</span\n >\n <span class=\"widget-badge-label\">\n Slide {{ slideNumber }}\n @if (totalSlides) {\n / {{ totalSlides }}\n }\n </span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently viewing slide' : 'Time spent on this slide'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"slideText\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder slide-placeholder\">\n <span class=\"material-icons-outlined\">image</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"slideText\">{{ slideText }}</span>\n @if (storyName) {\n @if (storyUrl) {\n <a\n [href]=\"storyUrl\"\n target=\"_blank\"\n class=\"widget-story-link\"\n [title]=\"storyName\"\n >\n <span class=\"widget-story-name\">{{ storyName }}</span>\n <span class=\"material-icons-outlined external-icon\"\n >open_in_new</span\n >\n </a>\n } @else {\n <span class=\"widget-story-name\">{{ storyName }}</span>\n }\n }\n </div>\n </div>\n</div>\n" }]
|
|
5088
6020
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
5089
6021
|
|
|
6022
|
+
class ProfileOpenedWidgetComponent extends BaseEventWidgetComponent {
|
|
6023
|
+
constructor(cd) {
|
|
6024
|
+
super(cd);
|
|
6025
|
+
}
|
|
6026
|
+
get userName() {
|
|
6027
|
+
const raw = this.event?.payload?.text ||
|
|
6028
|
+
this.event?.payload?.data?.name ||
|
|
6029
|
+
'User Profile';
|
|
6030
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6031
|
+
}
|
|
6032
|
+
get imageUrl() {
|
|
6033
|
+
return (this.event?.payload?.url ||
|
|
6034
|
+
this.event?.payload?.imageUrl ||
|
|
6035
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6036
|
+
null);
|
|
6037
|
+
}
|
|
6038
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ProfileOpenedWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6039
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ProfileOpenedWidgetComponent, isStandalone: true, selector: "rtsee-profile-opened-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget profile-opened-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge profile-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">person</span>\n <span class=\"widget-badge-label\">Profile Opened</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"userName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder profile-placeholder\">\n <span class=\"material-icons-outlined\">person</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"userName\">{{ userName }}</span>\n <span class=\"widget-subtitle\">Viewing profile</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6040
|
+
}
|
|
6041
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ProfileOpenedWidgetComponent, decorators: [{
|
|
6042
|
+
type: Component,
|
|
6043
|
+
args: [{ selector: 'rtsee-profile-opened-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget profile-opened-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge profile-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">person</span>\n <span class=\"widget-badge-label\">Profile Opened</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"userName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder profile-placeholder\">\n <span class=\"material-icons-outlined\">person</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"userName\">{{ userName }}</span>\n <span class=\"widget-subtitle\">Viewing profile</span>\n </div>\n </div>\n</div>\n" }]
|
|
6044
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6045
|
+
|
|
6046
|
+
class ChatOpenedWidgetComponent extends BaseEventWidgetComponent {
|
|
6047
|
+
constructor(cd) {
|
|
6048
|
+
super(cd);
|
|
6049
|
+
}
|
|
6050
|
+
get chatName() {
|
|
6051
|
+
const raw = this.event?.payload?.text ||
|
|
6052
|
+
this.event?.payload?.data?.chatName ||
|
|
6053
|
+
'Chat';
|
|
6054
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6055
|
+
}
|
|
6056
|
+
get imageUrl() {
|
|
6057
|
+
return (this.event?.payload?.imageUrl ||
|
|
6058
|
+
this.event?.payload?.url ||
|
|
6059
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6060
|
+
null);
|
|
6061
|
+
}
|
|
6062
|
+
get chatTypeLabel() {
|
|
6063
|
+
const type = this.event?.payload?.data?.chatType;
|
|
6064
|
+
if (type === 'channel')
|
|
6065
|
+
return 'Channel conversation';
|
|
6066
|
+
if (type === 'group')
|
|
6067
|
+
return 'Group conversation';
|
|
6068
|
+
return 'Active conversation';
|
|
6069
|
+
}
|
|
6070
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatOpenedWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6071
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatOpenedWidgetComponent, isStandalone: true, selector: "rtsee-chat-opened-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget chat-opened-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge chat-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">forum</span>\n <span class=\"widget-badge-label\">Chat Opened</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder chat-placeholder\">\n <span class=\"material-icons-outlined\">chat_bubble_outline</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">{{ chatTypeLabel }}</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6072
|
+
}
|
|
6073
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatOpenedWidgetComponent, decorators: [{
|
|
6074
|
+
type: Component,
|
|
6075
|
+
args: [{ selector: 'rtsee-chat-opened-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget chat-opened-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge chat-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">forum</span>\n <span class=\"widget-badge-label\">Chat Opened</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder chat-placeholder\">\n <span class=\"material-icons-outlined\">chat_bubble_outline</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">{{ chatTypeLabel }}</span>\n </div>\n </div>\n</div>\n" }]
|
|
6076
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6077
|
+
|
|
6078
|
+
class ChatCreatedWidgetComponent extends BaseEventWidgetComponent {
|
|
6079
|
+
constructor(cd) {
|
|
6080
|
+
super(cd);
|
|
6081
|
+
}
|
|
6082
|
+
get chatName() {
|
|
6083
|
+
const raw = this.event?.payload?.text ||
|
|
6084
|
+
this.event?.payload?.data?.chatName ||
|
|
6085
|
+
'New Chat';
|
|
6086
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6087
|
+
}
|
|
6088
|
+
get imageUrl() {
|
|
6089
|
+
return (this.event?.payload?.imageUrl ||
|
|
6090
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6091
|
+
null);
|
|
6092
|
+
}
|
|
6093
|
+
get chatTypeLabel() {
|
|
6094
|
+
const type = this.event?.payload?.data?.chatType || this.event?.payload?.url;
|
|
6095
|
+
if (type === 'channel')
|
|
6096
|
+
return 'Created channel';
|
|
6097
|
+
if (type === 'group')
|
|
6098
|
+
return 'Created group chat';
|
|
6099
|
+
return 'Created new chat';
|
|
6100
|
+
}
|
|
6101
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatCreatedWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6102
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatCreatedWidgetComponent, isStandalone: true, selector: "rtsee-chat-created-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget chat-created-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge created-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">add_comment</span>\n <span class=\"widget-badge-label\">Chat Created</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder created-placeholder\">\n <span class=\"material-icons-outlined\">group_add</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">{{ chatTypeLabel }}</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6103
|
+
}
|
|
6104
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatCreatedWidgetComponent, decorators: [{
|
|
6105
|
+
type: Component,
|
|
6106
|
+
args: [{ selector: 'rtsee-chat-created-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget chat-created-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge created-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">add_comment</span>\n <span class=\"widget-badge-label\">Chat Created</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder created-placeholder\">\n <span class=\"material-icons-outlined\">group_add</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">{{ chatTypeLabel }}</span>\n </div>\n </div>\n</div>\n" }]
|
|
6107
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6108
|
+
|
|
6109
|
+
class ChatMemberInviteClickedWidgetComponent extends BaseEventWidgetComponent {
|
|
6110
|
+
constructor(cd) {
|
|
6111
|
+
super(cd);
|
|
6112
|
+
}
|
|
6113
|
+
get chatName() {
|
|
6114
|
+
const raw = this.event?.payload?.text ||
|
|
6115
|
+
this.event?.payload?.data?.chatName ||
|
|
6116
|
+
'Chat';
|
|
6117
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6118
|
+
}
|
|
6119
|
+
get imageUrl() {
|
|
6120
|
+
return (this.event?.payload?.imageUrl ||
|
|
6121
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6122
|
+
null);
|
|
6123
|
+
}
|
|
6124
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatMemberInviteClickedWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6125
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatMemberInviteClickedWidgetComponent, isStandalone: true, selector: "rtsee-chat-member-invite-clicked-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget chat-member-invite-clicked-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge invite-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">person_add</span>\n <span class=\"widget-badge-label\">Member Invite</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder invite-placeholder\">\n <span class=\"material-icons-outlined\">link</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">Invitation link</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6126
|
+
}
|
|
6127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatMemberInviteClickedWidgetComponent, decorators: [{
|
|
6128
|
+
type: Component,
|
|
6129
|
+
args: [{ selector: 'rtsee-chat-member-invite-clicked-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget chat-member-invite-clicked-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge invite-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">person_add</span>\n <span class=\"widget-badge-label\">Member Invite</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder invite-placeholder\">\n <span class=\"material-icons-outlined\">link</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">Invitation link</span>\n </div>\n </div>\n</div>\n" }]
|
|
6130
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6131
|
+
|
|
6132
|
+
class ChatAgentCreatedWidgetComponent extends BaseEventWidgetComponent {
|
|
6133
|
+
constructor(cd) {
|
|
6134
|
+
super(cd);
|
|
6135
|
+
}
|
|
6136
|
+
get agentName() {
|
|
6137
|
+
const raw = this.event?.payload?.text ||
|
|
6138
|
+
this.event?.payload?.data?.agentName ||
|
|
6139
|
+
'AI Agent';
|
|
6140
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6141
|
+
}
|
|
6142
|
+
get chatName() {
|
|
6143
|
+
const raw = this.event?.payload?.data?.chatName ||
|
|
6144
|
+
this.event?.payload?.url ||
|
|
6145
|
+
'';
|
|
6146
|
+
const cleaned = String(raw).replace(/\*/g, ' ').trim();
|
|
6147
|
+
return cleaned ? `Added to ${cleaned}` : 'AI Agent added to chat';
|
|
6148
|
+
}
|
|
6149
|
+
get imageUrl() {
|
|
6150
|
+
return (this.event?.payload?.imageUrl ||
|
|
6151
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6152
|
+
null);
|
|
6153
|
+
}
|
|
6154
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatAgentCreatedWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6155
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatAgentCreatedWidgetComponent, isStandalone: true, selector: "rtsee-chat-agent-created-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget chat-agent-created-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge agent-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">smart_toy</span>\n <span class=\"widget-badge-label\">Agent Created</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"agentName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder agent-placeholder\">\n <span class=\"material-icons-outlined\">smart_toy</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"agentName\">{{ agentName }}</span>\n <span class=\"widget-subtitle\" [title]=\"chatName\">{{ chatName }}</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6156
|
+
}
|
|
6157
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatAgentCreatedWidgetComponent, decorators: [{
|
|
6158
|
+
type: Component,
|
|
6159
|
+
args: [{ selector: 'rtsee-chat-agent-created-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget chat-agent-created-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge agent-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">smart_toy</span>\n <span class=\"widget-badge-label\">Agent Created</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"agentName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder agent-placeholder\">\n <span class=\"material-icons-outlined\">smart_toy</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"agentName\">{{ agentName }}</span>\n <span class=\"widget-subtitle\" [title]=\"chatName\">{{ chatName }}</span>\n </div>\n </div>\n</div>\n" }]
|
|
6160
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6161
|
+
|
|
6162
|
+
class ChatMessageSentWidgetComponent extends BaseEventWidgetComponent {
|
|
6163
|
+
constructor(cd) {
|
|
6164
|
+
super(cd);
|
|
6165
|
+
}
|
|
6166
|
+
get chatName() {
|
|
6167
|
+
const raw = this.event?.payload?.text ||
|
|
6168
|
+
this.event?.payload?.data?.chatName ||
|
|
6169
|
+
'Chat';
|
|
6170
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6171
|
+
}
|
|
6172
|
+
get imageUrl() {
|
|
6173
|
+
return (this.event?.payload?.imageUrl ||
|
|
6174
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6175
|
+
null);
|
|
6176
|
+
}
|
|
6177
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatMessageSentWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6178
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatMessageSentWidgetComponent, isStandalone: true, selector: "rtsee-chat-message-sent-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget chat-message-sent-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge message-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">send</span>\n <span class=\"widget-badge-label\">Message Sent</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder message-placeholder\">\n <span class=\"material-icons-outlined\">chat</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">Sent a message</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6179
|
+
}
|
|
6180
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatMessageSentWidgetComponent, decorators: [{
|
|
6181
|
+
type: Component,
|
|
6182
|
+
args: [{ selector: 'rtsee-chat-message-sent-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget chat-message-sent-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge message-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">send</span>\n <span class=\"widget-badge-label\">Message Sent</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media avatar-media\">\n @if (imageUrl) {\n <img\n [src]=\"imageUrl\"\n [alt]=\"chatName\"\n class=\"widget-thumbnail-image\"\n />\n } @else {\n <div class=\"widget-thumbnail-placeholder message-placeholder\">\n <span class=\"material-icons-outlined\">chat</span>\n </div>\n }\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"chatName\">{{ chatName }}</span>\n <span class=\"widget-subtitle\">Sent a message</span>\n </div>\n </div>\n</div>\n" }]
|
|
6183
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6184
|
+
|
|
6185
|
+
class ApplicationEventWidgetComponent extends BaseEventWidgetComponent {
|
|
6186
|
+
constructor(cd) {
|
|
6187
|
+
super(cd);
|
|
6188
|
+
}
|
|
6189
|
+
get eventAction() {
|
|
6190
|
+
const key = this.event?.widget || this.event?.name || '';
|
|
6191
|
+
if (key.includes('deleted'))
|
|
6192
|
+
return 'deleted';
|
|
6193
|
+
if (key.includes('updated'))
|
|
6194
|
+
return 'updated';
|
|
6195
|
+
return 'created';
|
|
6196
|
+
}
|
|
6197
|
+
get badgeLabel() {
|
|
6198
|
+
if (this.eventAction === 'deleted')
|
|
6199
|
+
return 'App Deleted';
|
|
6200
|
+
if (this.eventAction === 'updated')
|
|
6201
|
+
return 'App Updated';
|
|
6202
|
+
return 'App Created';
|
|
6203
|
+
}
|
|
6204
|
+
get badgeIcon() {
|
|
6205
|
+
if (this.eventAction === 'deleted')
|
|
6206
|
+
return 'delete_outline';
|
|
6207
|
+
if (this.eventAction === 'updated')
|
|
6208
|
+
return 'edit';
|
|
6209
|
+
return 'add_box';
|
|
6210
|
+
}
|
|
6211
|
+
get badgeClass() {
|
|
6212
|
+
if (this.eventAction === 'deleted')
|
|
6213
|
+
return 'app-deleted-badge';
|
|
6214
|
+
if (this.eventAction === 'updated')
|
|
6215
|
+
return 'app-updated-badge';
|
|
6216
|
+
return 'app-created-badge';
|
|
6217
|
+
}
|
|
6218
|
+
get placeholderClass() {
|
|
6219
|
+
if (this.eventAction === 'deleted')
|
|
6220
|
+
return 'app-deleted-placeholder';
|
|
6221
|
+
if (this.eventAction === 'updated')
|
|
6222
|
+
return 'app-updated-placeholder';
|
|
6223
|
+
return 'app-created-placeholder';
|
|
6224
|
+
}
|
|
6225
|
+
get appName() {
|
|
6226
|
+
return (this.event?.payload?.text ||
|
|
6227
|
+
this.event?.payload?.data?.name ||
|
|
6228
|
+
'Application');
|
|
6229
|
+
}
|
|
6230
|
+
get appUrl() {
|
|
6231
|
+
return (this.event?.payload?.url ||
|
|
6232
|
+
this.event?.payload?.data?.url ||
|
|
6233
|
+
null);
|
|
6234
|
+
}
|
|
6235
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ApplicationEventWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6236
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ApplicationEventWidgetComponent, isStandalone: true, selector: "rtsee-application-event-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget application-event-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge\" [ngClass]=\"badgeClass\">\n <span class=\"material-icons-outlined widget-badge-icon\">{{ badgeIcon }}</span>\n <span class=\"widget-badge-label\">{{ badgeLabel }}</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media\">\n <div class=\"widget-thumbnail-placeholder\" [ngClass]=\"placeholderClass\">\n <span class=\"material-icons-outlined\">apps</span>\n </div>\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"appName\">{{ appName }}</span>\n @if (appUrl) {\n <a\n [href]=\"appUrl\"\n target=\"_blank\"\n class=\"widget-story-link\"\n [title]=\"appUrl\"\n >\n <span class=\"widget-story-name\">{{ appUrl }}</span>\n <span class=\"material-icons-outlined external-icon\">open_in_new</span>\n </a>\n } @else {\n <span class=\"widget-subtitle\">Application settings</span>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
6237
|
+
}
|
|
6238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ApplicationEventWidgetComponent, decorators: [{
|
|
6239
|
+
type: Component,
|
|
6240
|
+
args: [{ selector: 'rtsee-application-event-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget application-event-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge\" [ngClass]=\"badgeClass\">\n <span class=\"material-icons-outlined widget-badge-icon\">{{ badgeIcon }}</span>\n <span class=\"widget-badge-label\">{{ badgeLabel }}</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media\">\n <div class=\"widget-thumbnail-placeholder\" [ngClass]=\"placeholderClass\">\n <span class=\"material-icons-outlined\">apps</span>\n </div>\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"appName\">{{ appName }}</span>\n @if (appUrl) {\n <a\n [href]=\"appUrl\"\n target=\"_blank\"\n class=\"widget-story-link\"\n [title]=\"appUrl\"\n >\n <span class=\"widget-story-name\">{{ appUrl }}</span>\n <span class=\"material-icons-outlined external-icon\">open_in_new</span>\n </a>\n } @else {\n <span class=\"widget-subtitle\">Application settings</span>\n }\n </div>\n </div>\n</div>\n" }]
|
|
6241
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6242
|
+
|
|
6243
|
+
class RequestDemoClickedWidgetComponent extends BaseEventWidgetComponent {
|
|
6244
|
+
constructor(cd) {
|
|
6245
|
+
super(cd);
|
|
6246
|
+
}
|
|
6247
|
+
get title() {
|
|
6248
|
+
return this.event?.payload?.text || 'Request A Demo';
|
|
6249
|
+
}
|
|
6250
|
+
get pageUrl() {
|
|
6251
|
+
return this.event?.payload?.url || null;
|
|
6252
|
+
}
|
|
6253
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RequestDemoClickedWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6254
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: RequestDemoClickedWidgetComponent, isStandalone: true, selector: "rtsee-request-demo-clicked-widget", usesInheritance: true, ngImport: i0, template: "<div class=\"rtsee-event-widget request-demo-clicked-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge demo-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">campaign</span>\n <span class=\"widget-badge-label\">Demo Requested</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media\">\n <div class=\"widget-thumbnail-placeholder demo-placeholder\">\n <span class=\"material-icons-outlined\">event_available</span>\n </div>\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"title\">{{ title }}</span>\n <span class=\"widget-subtitle\">Opened demo request modal</span>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
6255
|
+
}
|
|
6256
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RequestDemoClickedWidgetComponent, decorators: [{
|
|
6257
|
+
type: Component,
|
|
6258
|
+
args: [{ selector: 'rtsee-request-demo-clicked-widget', standalone: true, imports: [CommonModule], template: "<div class=\"rtsee-event-widget request-demo-clicked-widget\">\n <div class=\"widget-header\">\n <div class=\"widget-badge demo-badge\">\n <span class=\"material-icons-outlined widget-badge-icon\">campaign</span>\n <span class=\"widget-badge-label\">Demo Requested</span>\n </div>\n <div\n class=\"widget-timer\"\n [class.live]=\"isLive\"\n [title]=\"isLive ? 'Currently active' : 'Time spent before next event'\"\n >\n <span class=\"material-icons-outlined widget-timer-icon\">timer</span>\n <span class=\"widget-timer-text\">{{ durationText }}</span>\n </div>\n </div>\n\n <div class=\"widget-body\">\n <div class=\"widget-media\">\n <div class=\"widget-thumbnail-placeholder demo-placeholder\">\n <span class=\"material-icons-outlined\">event_available</span>\n </div>\n </div>\n\n <div class=\"widget-info\">\n <span class=\"widget-title\" [title]=\"title\">{{ title }}</span>\n <span class=\"widget-subtitle\">Opened demo request modal</span>\n </div>\n </div>\n</div>\n" }]
|
|
6259
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6260
|
+
|
|
5090
6261
|
class EventsWidgetsService {
|
|
5091
6262
|
constructor() {
|
|
5092
6263
|
this.widgetsMap = [
|
|
@@ -5102,10 +6273,53 @@ class EventsWidgetsService {
|
|
|
5102
6273
|
name: 'slide-number-changed',
|
|
5103
6274
|
component: SlideNumberChangedWidgetComponent,
|
|
5104
6275
|
},
|
|
6276
|
+
{
|
|
6277
|
+
name: 'profile-opened',
|
|
6278
|
+
component: ProfileOpenedWidgetComponent,
|
|
6279
|
+
},
|
|
6280
|
+
{
|
|
6281
|
+
name: 'chat-opened',
|
|
6282
|
+
component: ChatOpenedWidgetComponent,
|
|
6283
|
+
},
|
|
6284
|
+
{
|
|
6285
|
+
name: 'chat-created',
|
|
6286
|
+
component: ChatCreatedWidgetComponent,
|
|
6287
|
+
},
|
|
6288
|
+
{
|
|
6289
|
+
name: 'chat-member-invite-clicked',
|
|
6290
|
+
component: ChatMemberInviteClickedWidgetComponent,
|
|
6291
|
+
},
|
|
6292
|
+
{
|
|
6293
|
+
name: 'chat-agent-created',
|
|
6294
|
+
component: ChatAgentCreatedWidgetComponent,
|
|
6295
|
+
},
|
|
6296
|
+
{
|
|
6297
|
+
name: 'chat-message-sent',
|
|
6298
|
+
component: ChatMessageSentWidgetComponent,
|
|
6299
|
+
},
|
|
6300
|
+
{
|
|
6301
|
+
name: 'application-created',
|
|
6302
|
+
component: ApplicationEventWidgetComponent,
|
|
6303
|
+
},
|
|
6304
|
+
{
|
|
6305
|
+
name: 'application-updated',
|
|
6306
|
+
component: ApplicationEventWidgetComponent,
|
|
6307
|
+
},
|
|
6308
|
+
{
|
|
6309
|
+
name: 'application-deleted',
|
|
6310
|
+
component: ApplicationEventWidgetComponent,
|
|
6311
|
+
},
|
|
6312
|
+
{
|
|
6313
|
+
name: 'request-demo-clicked',
|
|
6314
|
+
component: RequestDemoClickedWidgetComponent,
|
|
6315
|
+
},
|
|
5105
6316
|
];
|
|
5106
6317
|
}
|
|
5107
6318
|
getWidgetComponentByName(name) {
|
|
5108
6319
|
/* eslint-disable */
|
|
6320
|
+
if (!name) {
|
|
6321
|
+
return null;
|
|
6322
|
+
}
|
|
5109
6323
|
const mapping = this.widgetsMap.find((e) => e.name === name);
|
|
5110
6324
|
if (!mapping) {
|
|
5111
6325
|
return null;
|
|
@@ -5131,9 +6345,24 @@ class EventThumbnailComponent {
|
|
|
5131
6345
|
this.cd = cd;
|
|
5132
6346
|
this.timeInAgoFormat = '';
|
|
5133
6347
|
}
|
|
6348
|
+
get widgetName() {
|
|
6349
|
+
return this.event?.widget || this.event?.name;
|
|
6350
|
+
}
|
|
6351
|
+
get hasWidget() {
|
|
6352
|
+
return !!this.widgetsService.getWidgetComponentByName(this.widgetName);
|
|
6353
|
+
}
|
|
6354
|
+
get hasDetails() {
|
|
6355
|
+
const payload = this.event?.payload;
|
|
6356
|
+
if (!payload) {
|
|
6357
|
+
return false;
|
|
6358
|
+
}
|
|
6359
|
+
const hasDataEntries = typeof payload.data === 'object' &&
|
|
6360
|
+
payload.data !== null &&
|
|
6361
|
+
Object.keys(payload.data).length > 0;
|
|
6362
|
+
return !!(hasDataEntries || payload.url || payload.text);
|
|
6363
|
+
}
|
|
5134
6364
|
ngOnInit() {
|
|
5135
|
-
|
|
5136
|
-
if (eventData) {
|
|
6365
|
+
if (this.hasDetails) {
|
|
5137
6366
|
this.generateTooltip();
|
|
5138
6367
|
}
|
|
5139
6368
|
this.timeInAgoFormat = this.timeFormatService.toAgo(this.event.createdAt);
|
|
@@ -5142,27 +6371,30 @@ class EventThumbnailComponent {
|
|
|
5142
6371
|
}, 20000);
|
|
5143
6372
|
}
|
|
5144
6373
|
generateTooltip() {
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
const eventData = this.event.payload?.data || this.event.data;
|
|
5148
|
-
if (typeof eventData !== 'object' || !eventData) {
|
|
6374
|
+
const payload = this.event?.payload;
|
|
6375
|
+
if (!payload) {
|
|
5149
6376
|
return;
|
|
5150
6377
|
}
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
tooltip += key + ' -> ' + eventData[key];
|
|
6378
|
+
const entries = new Map();
|
|
6379
|
+
const payloadData = payload.data;
|
|
6380
|
+
if (typeof payloadData === 'object' && payloadData !== null) {
|
|
6381
|
+
Object.entries(payloadData).forEach(([key, value]) => {
|
|
6382
|
+
if (value !== undefined && value !== null) {
|
|
6383
|
+
entries.set(key, value);
|
|
5158
6384
|
}
|
|
5159
|
-
}
|
|
5160
|
-
this.tooltip = tooltip;
|
|
6385
|
+
});
|
|
5161
6386
|
}
|
|
5162
|
-
|
|
5163
|
-
|
|
6387
|
+
if (payload.url && !entries.has('url')) {
|
|
6388
|
+
entries.set('url', payload.url);
|
|
5164
6389
|
}
|
|
5165
|
-
|
|
6390
|
+
if (payload.text && !entries.has('text')) {
|
|
6391
|
+
entries.set('text', payload.text);
|
|
6392
|
+
}
|
|
6393
|
+
const lines = [];
|
|
6394
|
+
entries.forEach((value, key) => {
|
|
6395
|
+
lines.push(`${key} -> ${String(value)}`);
|
|
6396
|
+
});
|
|
6397
|
+
this.tooltip = lines.join('\n');
|
|
5166
6398
|
}
|
|
5167
6399
|
ngOnChanges(changes) {
|
|
5168
6400
|
if (this.componentRef) {
|
|
@@ -5177,12 +6409,8 @@ class EventThumbnailComponent {
|
|
|
5177
6409
|
}
|
|
5178
6410
|
ngAfterViewInit() {
|
|
5179
6411
|
this.cd.detectChanges();
|
|
5180
|
-
|
|
5181
|
-
if (this.
|
|
5182
|
-
const widget = this.widgetsService.getWidgetComponentByName(this.event.widget);
|
|
5183
|
-
if (!widget) {
|
|
5184
|
-
return;
|
|
5185
|
-
}
|
|
6412
|
+
const widget = this.widgetsService.getWidgetComponentByName(this.widgetName);
|
|
6413
|
+
if (widget && this.widgetHost) {
|
|
5186
6414
|
const viewContainerRef = this.widgetHost.viewContainerRef;
|
|
5187
6415
|
viewContainerRef.clear();
|
|
5188
6416
|
const componentToShow = this.componentFactoryResolver.resolveComponentFactory(widget);
|
|
@@ -5191,14 +6419,13 @@ class EventThumbnailComponent {
|
|
|
5191
6419
|
this.componentRef.instance.session = this.session;
|
|
5192
6420
|
this.componentRef.changeDetectorRef.detectChanges();
|
|
5193
6421
|
}
|
|
5194
|
-
/* eslint-enable */
|
|
5195
6422
|
}
|
|
5196
6423
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: EventThumbnailComponent, deps: [{ token: EventsWidgetsService }, { token: i0.ComponentFactoryResolver }, { token: TimeFormatHelperService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5197
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: EventThumbnailComponent, isStandalone: true, selector: "rtsee-event-thumbnail", inputs: { event: "event", session: "session" }, viewQueries: [{ propertyName: "widgetHost", first: true, predicate: WidgetDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rtsee-events-dashboard-event-thumbnail\">\n @if (
|
|
6424
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: EventThumbnailComponent, isStandalone: true, selector: "rtsee-event-thumbnail", inputs: { event: "event", session: "session" }, viewQueries: [{ propertyName: "widgetHost", first: true, predicate: WidgetDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rtsee-events-dashboard-event-thumbnail\">\n @if (hasWidget) {\n <ng-template widgetHost></ng-template>\n } @else {\n <div\n class=\"rtsee-events-dashboard-default-event-thumbnail\"\n [ngClass]=\"{\n 'rtsee-events-dashboard-default-event-thumbnail-with-data': hasDetails,\n }\"\n >\n <div class=\"rtsee-events-dashboard-default-event-thumbnail-name\">\n {{ event.name }}\n </div>\n <div class=\"rtsee-events-dashboard-default-event-thumbnail-info\">\n @if (hasDetails && tooltip) {\n <div\n class=\"rtsee-events-dashboard-default-event-thumbnail-details\"\n [title]=\"tooltip\"\n >\n <span\n class=\"rtsee-events-dashboard-default-event-thumbnail-details-icon material-icons-outlined\"\n >info</span\n >\n </div>\n }\n <div class=\"rtsee-events-dashboard-default-event-thumbnail-time\">\n <span>{{ timeInAgoFormat }}</span>\n </div>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: WidgetDirective, selector: "[widgetHost]" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
5198
6425
|
}
|
|
5199
6426
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: EventThumbnailComponent, decorators: [{
|
|
5200
6427
|
type: Component,
|
|
5201
|
-
args: [{ selector: 'rtsee-event-thumbnail', imports: [WidgetDirective, NgClass], standalone: true, template: "<div class=\"rtsee-events-dashboard-event-thumbnail\">\n @if (
|
|
6428
|
+
args: [{ selector: 'rtsee-event-thumbnail', imports: [WidgetDirective, NgClass], standalone: true, template: "<div class=\"rtsee-events-dashboard-event-thumbnail\">\n @if (hasWidget) {\n <ng-template widgetHost></ng-template>\n } @else {\n <div\n class=\"rtsee-events-dashboard-default-event-thumbnail\"\n [ngClass]=\"{\n 'rtsee-events-dashboard-default-event-thumbnail-with-data': hasDetails,\n }\"\n >\n <div class=\"rtsee-events-dashboard-default-event-thumbnail-name\">\n {{ event.name }}\n </div>\n <div class=\"rtsee-events-dashboard-default-event-thumbnail-info\">\n @if (hasDetails && tooltip) {\n <div\n class=\"rtsee-events-dashboard-default-event-thumbnail-details\"\n [title]=\"tooltip\"\n >\n <span\n class=\"rtsee-events-dashboard-default-event-thumbnail-details-icon material-icons-outlined\"\n >info</span\n >\n </div>\n }\n <div class=\"rtsee-events-dashboard-default-event-thumbnail-time\">\n <span>{{ timeInAgoFormat }}</span>\n </div>\n </div>\n </div>\n }\n</div>\n" }]
|
|
5202
6429
|
}], ctorParameters: () => [{ type: EventsWidgetsService }, { type: i0.ComponentFactoryResolver }, { type: TimeFormatHelperService }, { type: i0.ChangeDetectorRef }], propDecorators: { event: [{
|
|
5203
6430
|
type: Input
|
|
5204
6431
|
}], session: [{
|
|
@@ -5337,13 +6564,13 @@ class JoinCallComponent {
|
|
|
5337
6564
|
this.recentlyCopied = false;
|
|
5338
6565
|
}, 2000);
|
|
5339
6566
|
}
|
|
5340
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: JoinCallComponent, deps: [{ token: i1$
|
|
6567
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: JoinCallComponent, deps: [{ token: i1$4.MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5341
6568
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: JoinCallComponent, isStandalone: true, selector: "rtsee-join-call", inputs: { presentation: "presentation", room: "room" }, providers: [MessageService], ngImport: i0, template: "<div class=\"rtsee-join-call\">\n <div class=\"rtsee-join-call-button\">\n <p-button [label]=\"presentation.labels[RTSeeTextLabelKeys.START_A_CALL_BUTTON]\"\n (click)=\"presentation.emitJoinRoomCallEvent()\"\n ></p-button>\n </div>\n <div class=\"rtsee-share-call-link\">\n <div class=\"rtsee-share-call-explain-section\">\n <div class=\"rtsee-share-call-explain-section-icon\">\n <span class=\"pi pi-link rtsee-link-icon\"></span>\n </div>\n <div class=\"rtsee-share-call-explain-section-text\">\n <span>Anyone can join your storytelling session using this link.</span>\n </div>\n </div>\n <div class=\"rtsee-share-call-link-section\">\n <p-toast position=\"bottom-center\" />\n <p-button [icon]=\"recentlyCopied ? 'pi pi-check' : 'pi pi-copy'\"\n severity=\"secondary\"\n class=\"rtsee-share-call-link-copy-btn\"\n [cdkCopyToClipboard]=\"window.location.origin + '?room_id=' + room.id\"\n (cdkCopyToClipboardCopied)=\"copyClicked()\"\n ></p-button>\n <p-message severity=\"info\"\n class=\"rtsee-share-call-link-text\"\n >{{ window.location.origin + '?room_id=' + room.id }}</p-message>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "component", type: Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] }); }
|
|
5342
6569
|
}
|
|
5343
6570
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: JoinCallComponent, decorators: [{
|
|
5344
6571
|
type: Component,
|
|
5345
6572
|
args: [{ selector: 'rtsee-join-call', imports: [Button, CdkCopyToClipboard, Message, Toast], providers: [MessageService], template: "<div class=\"rtsee-join-call\">\n <div class=\"rtsee-join-call-button\">\n <p-button [label]=\"presentation.labels[RTSeeTextLabelKeys.START_A_CALL_BUTTON]\"\n (click)=\"presentation.emitJoinRoomCallEvent()\"\n ></p-button>\n </div>\n <div class=\"rtsee-share-call-link\">\n <div class=\"rtsee-share-call-explain-section\">\n <div class=\"rtsee-share-call-explain-section-icon\">\n <span class=\"pi pi-link rtsee-link-icon\"></span>\n </div>\n <div class=\"rtsee-share-call-explain-section-text\">\n <span>Anyone can join your storytelling session using this link.</span>\n </div>\n </div>\n <div class=\"rtsee-share-call-link-section\">\n <p-toast position=\"bottom-center\" />\n <p-button [icon]=\"recentlyCopied ? 'pi pi-check' : 'pi pi-copy'\"\n severity=\"secondary\"\n class=\"rtsee-share-call-link-copy-btn\"\n [cdkCopyToClipboard]=\"window.location.origin + '?room_id=' + room.id\"\n (cdkCopyToClipboardCopied)=\"copyClicked()\"\n ></p-button>\n <p-message severity=\"info\"\n class=\"rtsee-share-call-link-text\"\n >{{ window.location.origin + '?room_id=' + room.id }}</p-message>\n </div>\n </div>\n</div>\n" }]
|
|
5346
|
-
}], ctorParameters: () => [{ type: i1$
|
|
6573
|
+
}], ctorParameters: () => [{ type: i1$4.MessageService }], propDecorators: { presentation: [{
|
|
5347
6574
|
type: Input
|
|
5348
6575
|
}], room: [{
|
|
5349
6576
|
type: Input
|
|
@@ -5982,7 +7209,7 @@ class IllustratorComponent {
|
|
|
5982
7209
|
return item.id || `agent-${index}`;
|
|
5983
7210
|
}
|
|
5984
7211
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: IllustratorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5985
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: IllustratorComponent, isStandalone: true, selector: "rtsee-illustrator", inputs: { illustrator: "illustrator" }, ngImport: i0, template: "<div class=\"rtsee-illustrator-container\" [ngClass]=\"{ 'rtsee-illustrator--expanded': illustrator.expanded }\">\n <!-- Collapsed Bottom Bar -->\n @if (!illustrator.expanded) {\n <div class=\"rtsee-illustrator-collapsed-bar\" (click)=\"toggleExpand()\">\n <div class=\"rtsee-illustrator-collapsed-info\">\n <div class=\"rtsee-illustrator-badge-icon\">\n <i class=\"pi pi-palette\"></i>\n </div>\n <div class=\"rtsee-illustrator-collapsed-title\">\n <span class=\"rtsee-illustrator-brand-text\">NanoBanana Illustrator</span>\n @if (illustrator.activeAgent) {\n <span class=\"rtsee-illustrator-agent-pill\">\n <i class=\"pi pi-bolt\"></i>\n {{ illustrator.activeAgent.name }}\n </span>\n } @else {\n <span class=\"rtsee-illustrator-agent-pill rtsee-illustrator-agent-pill--waiting\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n Waiting for Chat Agent...\n </span>\n }\n </div>\n </div>\n\n <div class=\"rtsee-illustrator-collapsed-meta\">\n @if (illustrator.reviewingGeneratedImage && illustrator.currentGeneratedImageUrl) {\n <span class=\"rtsee-illustrator-collapsed-review-pill\">\n <img [src]=\"illustrator.currentGeneratedImageUrl\" alt=\"Draft\" class=\"rtsee-illustrator-collapsed-thumb\" />\n <span>\u2728 Reviewing Draft</span>\n </span>\n }\n @if (illustrator.contextImages.length > 0) {\n <span class=\"rtsee-illustrator-context-count\">\n <i class=\"pi pi-images\"></i>\n {{ illustrator.activeContextImages.length }} / {{ illustrator.contextImages.length }} context refs\n </span>\n }\n @if (illustrator.prompt) {\n <span class=\"rtsee-illustrator-prompt-preview\">\n \"{{ illustrator.prompt.length > 50 ? (illustrator.prompt | slice:0:50) + '\u2026' : illustrator.prompt }}\"\n </span>\n }\n <button type=\"button\" class=\"rtsee-illustrator-expand-btn\" aria-label=\"Expand Illustrator\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Expanded Drawer -->\n @if (illustrator.expanded) {\n <div class=\"rtsee-illustrator-expanded-panel\">\n <!-- Header -->\n <header class=\"rtsee-illustrator-header\">\n <div class=\"rtsee-illustrator-title-group\">\n <div class=\"rtsee-illustrator-icon-circle\">\n <i class=\"pi pi-palette\"></i>\n </div>\n <div>\n <h3 class=\"rtsee-illustrator-heading\">NanoBanana Illustrator</h3>\n <p class=\"rtsee-illustrator-subheading\">Generate enchanted fairy tale visuals with rich contextual styling</p>\n </div>\n </div>\n\n <div class=\"rtsee-illustrator-header-controls\">\n <!-- Agent Picker -->\n <div class=\"rtsee-illustrator-agent-select-wrapper\">\n <label class=\"rtsee-illustrator-agent-label\" for=\"rtsee-illustrator-agent-select\">\n <i class=\"pi pi-sparkles\"></i> Agent:\n </label>\n @if (illustrator.agents.length > 0) {\n <select\n id=\"rtsee-illustrator-agent-select\"\n class=\"rtsee-illustrator-select\"\n [value]=\"illustrator.activeAgentId || ''\"\n (change)=\"onSelectAgent($event)\"\n >\n @for (agent of illustrator.agents; track trackByAgentId($index, agent)) {\n <option [value]=\"agent.id\">\n {{ agent.name }} {{ agent.model ? '(' + agent.model + ')' : '' }}\n </option>\n }\n </select>\n } @else {\n <button\n type=\"button\"\n class=\"rtsee-illustrator-btn-mini\"\n (click)=\"refreshAgents()\"\n title=\"Query active agents from RTSeeChat\"\n >\n <i class=\"pi pi-refresh\"></i>\n <span>Connect RTSeeChat</span>\n </button>\n }\n </div>\n\n <!-- Config Toggle Button -->\n <button\n type=\"button\"\n class=\"rtsee-illustrator-header-btn\"\n [ngClass]=\"{ 'rtsee-illustrator-header-btn--active': illustrator.configExpanded }\"\n (click)=\"toggleConfig()\"\n title=\"Toggle NanoBanana Configuration\"\n >\n <i class=\"pi pi-sliders-h\"></i>\n <span>Config</span>\n <i class=\"pi\" [ngClass]=\"illustrator.configExpanded ? 'pi-chevron-up' : 'pi-chevron-down'\"></i>\n </button>\n\n <!-- Collapse Drawer Button -->\n <button\n type=\"button\"\n class=\"rtsee-illustrator-header-btn rtsee-illustrator-header-btn--close\"\n (click)=\"toggleExpand()\"\n aria-label=\"Collapse Illustrator\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </header>\n\n <!-- Collapsible Config Section -->\n @if (illustrator.configExpanded) {\n <div class=\"rtsee-illustrator-config-panel\">\n <div class=\"rtsee-illustrator-config-grid\">\n <!-- Aspect Ratio -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-aspect-ratio\">\n <i class=\"pi pi-stop\"></i> Aspect Ratio (Default 1:1)\n </label>\n <select\n id=\"cfg-aspect-ratio\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.aspectRatio\"\n >\n @for (ratio of aspectRatios; track ratio) {\n <option [value]=\"ratio\">{{ ratio }}{{ ratio === '1:1' ? ' (Square - Fairy Tale Default)' : '' }}</option>\n }\n </select>\n </div>\n\n <!-- Style Preset -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-style\">\n <i class=\"pi pi-paint-brush\"></i> Illustration Style\n </label>\n <select\n id=\"cfg-style\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.style\"\n >\n @for (s of styles; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n </div>\n\n <!-- Mood Preset -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-mood\">\n <i class=\"pi pi-heart\"></i> Mood & Atmosphere\n </label>\n <select\n id=\"cfg-mood\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.mood\"\n >\n @for (m of moods; track m) {\n <option [value]=\"m\">{{ m }}</option>\n }\n </select>\n </div>\n\n <!-- Lighting Preset -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-lighting\">\n <i class=\"pi pi-sun\"></i> Lighting\n </label>\n <select\n id=\"cfg-lighting\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.lighting\"\n >\n @for (l of lightings; track l) {\n <option [value]=\"l\">{{ l }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Negative Prompt -->\n <div class=\"rtsee-illustrator-config-item rtsee-illustrator-config-item--full\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-negative-prompt\">\n <i class=\"pi pi-ban\"></i> Negative Prompt (What to exclude)\n </label>\n <input\n id=\"cfg-negative-prompt\"\n type=\"text\"\n class=\"rtsee-illustrator-input\"\n [(ngModel)]=\"illustrator.config.negativePrompt\"\n placeholder=\"e.g. modern items, cars, text, watermark, blurry...\"\n />\n </div>\n </div>\n }\n\n <!-- Context Images Section -->\n @if (illustrator.contextImages.length > 0) {\n <div class=\"rtsee-illustrator-context-section\">\n <div class=\"rtsee-illustrator-section-header\">\n <span class=\"rtsee-illustrator-section-title\">\n <i class=\"pi pi-images\"></i> Story Context References ({{ illustrator.activeContextImages.length }} of {{ illustrator.contextImages.length }} active)\n </span>\n <button\n type=\"button\"\n class=\"rtsee-illustrator-btn-text\"\n (click)=\"illustrator.clearContext()\"\n title=\"Clear all context references\"\n >\n <i class=\"pi pi-trash\"></i> Clear All\n </button>\n </div>\n\n <div class=\"rtsee-illustrator-context-cards\">\n @for (img of illustrator.contextImages; track trackByImageId($index, img)) {\n <div class=\"rtsee-illustrator-context-card\" [ngClass]=\"{ 'rtsee-illustrator-context-card--inactive': !img.active }\">\n <!-- Thumbnail & Active Checkbox -->\n <div class=\"rtsee-illustrator-card-thumb-col\">\n <div class=\"rtsee-illustrator-card-thumb-wrapper\">\n @if (img.imageUrl) {\n <img [src]=\"img.imageUrl\" [alt]=\"img.title\" class=\"rtsee-illustrator-card-img\" />\n } @else {\n <div class=\"rtsee-illustrator-card-no-img\">\n <i class=\"pi pi-image\"></i>\n </div>\n }\n </div>\n <label class=\"rtsee-illustrator-checkbox-label\">\n <input\n type=\"checkbox\"\n [checked]=\"img.active !== false\"\n (change)=\"toggleActive(img)\"\n />\n <span>Active</span>\n </label>\n </div>\n\n <!-- Editable Fields -->\n <div class=\"rtsee-illustrator-card-fields\">\n <div class=\"rtsee-illustrator-card-header\">\n <span class=\"rtsee-illustrator-source-badge\">{{ img.sourceType || 'reference' }}</span>\n <input\n type=\"text\"\n class=\"rtsee-illustrator-card-title-input\"\n [(ngModel)]=\"img.title\"\n placeholder=\"Reference title...\"\n />\n <button\n type=\"button\"\n class=\"rtsee-illustrator-card-remove-btn\"\n (click)=\"removeImage(img.id)\"\n aria-label=\"Remove image from context\"\n title=\"Remove from context\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n\n <div class=\"rtsee-illustrator-card-inputs-grid\">\n <div class=\"rtsee-illustrator-input-group\">\n <label class=\"rtsee-illustrator-input-sublabel\">Visual Description (Style / Appearance):</label>\n <textarea\n class=\"rtsee-illustrator-card-textarea\"\n rows=\"2\"\n [(ngModel)]=\"img.visualDescription\"\n placeholder=\"Key visual features, colors, clothing, texture, lighting...\"\n ></textarea>\n </div>\n <div class=\"rtsee-illustrator-input-group\">\n <label class=\"rtsee-illustrator-input-sublabel\">Context / Role Description:</label>\n <textarea\n class=\"rtsee-illustrator-card-textarea\"\n rows=\"2\"\n [(ngModel)]=\"img.description\"\n placeholder=\"Context or lore in this fairy tale scene...\"\n ></textarea>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Generation Error Banner -->\n @if (illustrator.generationError) {\n <div class=\"rtsee-illustrator-error-banner\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span class=\"rtsee-illustrator-error-text\">{{ illustrator.generationError }}</span>\n <button type=\"button\" class=\"rtsee-illustrator-error-close\" (click)=\"illustrator.generationError = null\" aria-label=\"Dismiss error\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n }\n\n <!-- Reviewing Generated Image Mode -->\n @if (illustrator.reviewingGeneratedImage && illustrator.currentGeneratedImageUrl) {\n <div class=\"rtsee-illustrator-review-panel\">\n <div class=\"rtsee-illustrator-review-header\">\n <div class=\"rtsee-illustrator-review-title\">\n <span class=\"rtsee-illustrator-review-badge\">\n <i class=\"pi pi-sparkles\"></i> Reviewing Generated Image\n </span>\n <span class=\"rtsee-illustrator-review-sub\">Review the result, request iterative modifications, or discard.</span>\n </div>\n <div class=\"rtsee-illustrator-review-quick-actions\">\n <p-button\n label=\"Accept & Keep\"\n icon=\"pi pi-check\"\n severity=\"success\"\n (click)=\"acceptGeneratedImage()\"\n />\n <p-button\n label=\"Discard\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n (click)=\"discardGeneratedImage()\"\n />\n </div>\n </div>\n\n <!-- Image Preview -->\n <div class=\"rtsee-illustrator-preview-box\">\n <img [src]=\"illustrator.currentGeneratedImageUrl\" alt=\"Generated fairy tale illustration\" class=\"rtsee-illustrator-preview-img\" />\n <a [href]=\"illustrator.currentGeneratedImageUrl\" target=\"_blank\" rel=\"noopener\" class=\"rtsee-illustrator-preview-zoom-btn\" title=\"Open full image in new tab\">\n <i class=\"pi pi-external-link\"></i> Full View\n </a>\n </div>\n\n <!-- Iteration Modification Controls -->\n <div class=\"rtsee-illustrator-iteration-box\">\n <div class=\"rtsee-illustrator-iteration-info\">\n <span class=\"rtsee-illustrator-iteration-tag\">\n <i class=\"pi pi-refresh\"></i> Request Modifications & Iterate\n </span>\n <span class=\"rtsee-illustrator-iteration-context-hint\">\n <i class=\"pi pi-info-circle\"></i>\n All active context references ({{ illustrator.activeContextImages.length }}) are sent to NanoBanana alongside this base picture.\n </span>\n </div>\n\n <textarea\n class=\"rtsee-illustrator-prompt-textarea rtsee-illustrator-prompt-textarea--iteration\"\n rows=\"3\"\n [(ngModel)]=\"illustrator.iterationPrompt\"\n placeholder=\"Describe modifications to apply to this picture (e.g. 'Make the wizard's cloak sapphire blue with silver runes, add glowing fireflies, soften the background trees')...\"\n (keydown.meta.enter)=\"submitIteration()\"\n (keydown.control.enter)=\"submitIteration()\"\n ></textarea>\n\n <div class=\"rtsee-illustrator-prompt-footer\">\n <span class=\"rtsee-illustrator-tip\">\n <i class=\"pi pi-info-circle\"></i>\n Press <strong>\u2318+Enter</strong> to iterate on this picture.\n </span>\n\n <div class=\"rtsee-illustrator-actions\">\n <p-button\n label=\"Discard\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n (click)=\"discardGeneratedImage()\"\n />\n <p-button\n label=\"Iterate & Regenerate\"\n icon=\"pi pi-refresh\"\n [loading]=\"illustrator.submitting\"\n [disabled]=\"!illustrator.canSubmit\"\n (click)=\"submitIteration()\"\n />\n </div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Prompt Input & Submit Action (Standard Mode) -->\n <div class=\"rtsee-illustrator-prompt-section\">\n <div class=\"rtsee-illustrator-prompt-box\">\n <textarea\n class=\"rtsee-illustrator-prompt-textarea\"\n rows=\"3\"\n [(ngModel)]=\"illustrator.prompt\"\n placeholder=\"Describe the fairy tale illustration to generate (e.g. 'A cozy cottage tucked deep inside the emerald moss woods, magical amber lanterns glowing warmly from the windows, soft fireflies in the air')...\"\n (keydown.meta.enter)=\"submitPrompt()\"\n (keydown.control.enter)=\"submitPrompt()\"\n ></textarea>\n\n <div class=\"rtsee-illustrator-prompt-footer\">\n <span class=\"rtsee-illustrator-tip\">\n <i class=\"pi pi-info-circle\"></i>\n Press <strong>\u2318+Enter</strong> to submit. Context characters, artifacts, locations & slides are sent to NanoBanana.\n </span>\n\n <div class=\"rtsee-illustrator-actions\">\n <p-button\n label=\"Generate Illustration\"\n icon=\"pi pi-sparkles\"\n [loading]=\"illustrator.submitting\"\n [disabled]=\"!illustrator.canSubmit\"\n (click)=\"submitPrompt()\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: i2$1.SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7212
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: IllustratorComponent, isStandalone: true, selector: "rtsee-illustrator", inputs: { illustrator: "illustrator" }, ngImport: i0, template: "<div class=\"rtsee-illustrator-container\" [ngClass]=\"{ 'rtsee-illustrator--expanded': illustrator.expanded }\">\n <!-- Collapsed Bottom Bar -->\n @if (!illustrator.expanded) {\n <div class=\"rtsee-illustrator-collapsed-bar\" (click)=\"toggleExpand()\">\n <div class=\"rtsee-illustrator-collapsed-info\">\n <div class=\"rtsee-illustrator-badge-icon\">\n <i class=\"pi pi-palette\"></i>\n </div>\n <div class=\"rtsee-illustrator-collapsed-title\">\n <span class=\"rtsee-illustrator-brand-text\">NanoBanana Illustrator</span>\n @if (illustrator.activeAgent) {\n <span class=\"rtsee-illustrator-agent-pill\">\n <i class=\"pi pi-bolt\"></i>\n {{ illustrator.activeAgent.name }}\n </span>\n } @else {\n <span class=\"rtsee-illustrator-agent-pill rtsee-illustrator-agent-pill--waiting\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n Waiting for Chat Agent...\n </span>\n }\n </div>\n </div>\n\n <div class=\"rtsee-illustrator-collapsed-meta\">\n @if (illustrator.reviewingGeneratedImage && illustrator.currentGeneratedImageUrl) {\n <span class=\"rtsee-illustrator-collapsed-review-pill\">\n <img [src]=\"illustrator.currentGeneratedImageUrl\" alt=\"Draft\" class=\"rtsee-illustrator-collapsed-thumb\" />\n <span>\u2728 Reviewing Draft</span>\n </span>\n }\n @if (illustrator.contextImages.length > 0) {\n <span class=\"rtsee-illustrator-context-count\">\n <i class=\"pi pi-images\"></i>\n {{ illustrator.activeContextImages.length }} / {{ illustrator.contextImages.length }} context refs\n </span>\n }\n @if (illustrator.prompt) {\n <span class=\"rtsee-illustrator-prompt-preview\">\n \"{{ illustrator.prompt.length > 50 ? (illustrator.prompt | slice:0:50) + '\u2026' : illustrator.prompt }}\"\n </span>\n }\n <button type=\"button\" class=\"rtsee-illustrator-expand-btn\" aria-label=\"Expand Illustrator\">\n <i class=\"pi pi-chevron-up\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Expanded Drawer -->\n @if (illustrator.expanded) {\n <div class=\"rtsee-illustrator-expanded-panel\">\n <!-- Header -->\n <header class=\"rtsee-illustrator-header\">\n <div class=\"rtsee-illustrator-title-group\">\n <div class=\"rtsee-illustrator-icon-circle\">\n <i class=\"pi pi-palette\"></i>\n </div>\n <div>\n <h3 class=\"rtsee-illustrator-heading\">NanoBanana Illustrator</h3>\n <p class=\"rtsee-illustrator-subheading\">Generate enchanted fairy tale visuals with rich contextual styling</p>\n </div>\n </div>\n\n <div class=\"rtsee-illustrator-header-controls\">\n <!-- Agent Picker -->\n <div class=\"rtsee-illustrator-agent-select-wrapper\">\n <label class=\"rtsee-illustrator-agent-label\" for=\"rtsee-illustrator-agent-select\">\n <i class=\"pi pi-sparkles\"></i> Agent:\n </label>\n @if (illustrator.agents.length > 0) {\n <select\n id=\"rtsee-illustrator-agent-select\"\n class=\"rtsee-illustrator-select\"\n [value]=\"illustrator.activeAgentId || ''\"\n (change)=\"onSelectAgent($event)\"\n >\n @for (agent of illustrator.agents; track trackByAgentId($index, agent)) {\n <option [value]=\"agent.id\">\n {{ agent.name }} {{ agent.model ? '(' + agent.model + ')' : '' }}\n </option>\n }\n </select>\n } @else {\n <button\n type=\"button\"\n class=\"rtsee-illustrator-btn-mini\"\n (click)=\"refreshAgents()\"\n title=\"Query active agents from RTSeeChat\"\n >\n <i class=\"pi pi-refresh\"></i>\n <span>Connect RTSeeChat</span>\n </button>\n }\n </div>\n\n <!-- Config Toggle Button -->\n <button\n type=\"button\"\n class=\"rtsee-illustrator-header-btn\"\n [ngClass]=\"{ 'rtsee-illustrator-header-btn--active': illustrator.configExpanded }\"\n (click)=\"toggleConfig()\"\n title=\"Toggle NanoBanana Configuration\"\n >\n <i class=\"pi pi-sliders-h\"></i>\n <span>Config</span>\n <i class=\"pi\" [ngClass]=\"illustrator.configExpanded ? 'pi-chevron-up' : 'pi-chevron-down'\"></i>\n </button>\n\n <!-- Collapse Drawer Button -->\n <button\n type=\"button\"\n class=\"rtsee-illustrator-header-btn rtsee-illustrator-header-btn--close\"\n (click)=\"toggleExpand()\"\n aria-label=\"Collapse Illustrator\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </header>\n\n <!-- Collapsible Config Section -->\n @if (illustrator.configExpanded) {\n <div class=\"rtsee-illustrator-config-panel\">\n <div class=\"rtsee-illustrator-config-grid\">\n <!-- Aspect Ratio -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-aspect-ratio\">\n <i class=\"pi pi-stop\"></i> Aspect Ratio (Default 1:1)\n </label>\n <select\n id=\"cfg-aspect-ratio\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.aspectRatio\"\n >\n @for (ratio of aspectRatios; track ratio) {\n <option [value]=\"ratio\">{{ ratio }}{{ ratio === '1:1' ? ' (Square - Fairy Tale Default)' : '' }}</option>\n }\n </select>\n </div>\n\n <!-- Style Preset -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-style\">\n <i class=\"pi pi-paint-brush\"></i> Illustration Style\n </label>\n <select\n id=\"cfg-style\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.style\"\n >\n @for (s of styles; track s) {\n <option [value]=\"s\">{{ s }}</option>\n }\n </select>\n </div>\n\n <!-- Mood Preset -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-mood\">\n <i class=\"pi pi-heart\"></i> Mood & Atmosphere\n </label>\n <select\n id=\"cfg-mood\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.mood\"\n >\n @for (m of moods; track m) {\n <option [value]=\"m\">{{ m }}</option>\n }\n </select>\n </div>\n\n <!-- Lighting Preset -->\n <div class=\"rtsee-illustrator-config-item\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-lighting\">\n <i class=\"pi pi-sun\"></i> Lighting\n </label>\n <select\n id=\"cfg-lighting\"\n class=\"rtsee-illustrator-select\"\n [(ngModel)]=\"illustrator.config.lighting\"\n >\n @for (l of lightings; track l) {\n <option [value]=\"l\">{{ l }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Negative Prompt -->\n <div class=\"rtsee-illustrator-config-item rtsee-illustrator-config-item--full\">\n <label class=\"rtsee-illustrator-field-label\" for=\"cfg-negative-prompt\">\n <i class=\"pi pi-ban\"></i> Negative Prompt (What to exclude)\n </label>\n <input\n id=\"cfg-negative-prompt\"\n type=\"text\"\n class=\"rtsee-illustrator-input\"\n [(ngModel)]=\"illustrator.config.negativePrompt\"\n placeholder=\"e.g. modern items, cars, text, watermark, blurry...\"\n />\n </div>\n </div>\n }\n\n <!-- Context Images Section -->\n @if (illustrator.contextImages.length > 0) {\n <div class=\"rtsee-illustrator-context-section\">\n <div class=\"rtsee-illustrator-section-header\">\n <span class=\"rtsee-illustrator-section-title\">\n <i class=\"pi pi-images\"></i> Story Context References ({{ illustrator.activeContextImages.length }} of {{ illustrator.contextImages.length }} active)\n </span>\n <button\n type=\"button\"\n class=\"rtsee-illustrator-btn-text\"\n (click)=\"illustrator.clearContext()\"\n title=\"Clear all context references\"\n >\n <i class=\"pi pi-trash\"></i> Clear All\n </button>\n </div>\n\n <div class=\"rtsee-illustrator-context-cards\">\n @for (img of illustrator.contextImages; track trackByImageId($index, img)) {\n <div class=\"rtsee-illustrator-context-card\" [ngClass]=\"{ 'rtsee-illustrator-context-card--inactive': !img.active }\">\n <!-- Thumbnail & Active Checkbox -->\n <div class=\"rtsee-illustrator-card-thumb-col\">\n <div class=\"rtsee-illustrator-card-thumb-wrapper\">\n @if (img.imageUrl) {\n <img [src]=\"img.imageUrl\" [alt]=\"img.title\" class=\"rtsee-illustrator-card-img\" />\n } @else {\n <div class=\"rtsee-illustrator-card-no-img\">\n <i class=\"pi pi-image\"></i>\n </div>\n }\n </div>\n <label class=\"rtsee-illustrator-checkbox-label\">\n <input\n type=\"checkbox\"\n [checked]=\"img.active !== false\"\n (change)=\"toggleActive(img)\"\n />\n <span>Active</span>\n </label>\n </div>\n\n <!-- Editable Fields -->\n <div class=\"rtsee-illustrator-card-fields\">\n <div class=\"rtsee-illustrator-card-header\">\n <span class=\"rtsee-illustrator-source-badge\">{{ img.sourceType || 'reference' }}</span>\n <input\n type=\"text\"\n class=\"rtsee-illustrator-card-title-input\"\n [(ngModel)]=\"img.title\"\n placeholder=\"Reference title...\"\n />\n <button\n type=\"button\"\n class=\"rtsee-illustrator-card-remove-btn\"\n (click)=\"removeImage(img.id)\"\n aria-label=\"Remove image from context\"\n title=\"Remove from context\"\n >\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n\n <div class=\"rtsee-illustrator-card-inputs-grid\">\n <div class=\"rtsee-illustrator-input-group\">\n <label class=\"rtsee-illustrator-input-sublabel\">Visual Description (Style / Appearance):</label>\n <textarea\n class=\"rtsee-illustrator-card-textarea\"\n rows=\"2\"\n [(ngModel)]=\"img.visualDescription\"\n placeholder=\"Key visual features, colors, clothing, texture, lighting...\"\n ></textarea>\n </div>\n <div class=\"rtsee-illustrator-input-group\">\n <label class=\"rtsee-illustrator-input-sublabel\">Context / Role Description:</label>\n <textarea\n class=\"rtsee-illustrator-card-textarea\"\n rows=\"2\"\n [(ngModel)]=\"img.description\"\n placeholder=\"Context or lore in this fairy tale scene...\"\n ></textarea>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Generation Error Banner -->\n @if (illustrator.generationError) {\n <div class=\"rtsee-illustrator-error-banner\">\n <i class=\"pi pi-exclamation-triangle\"></i>\n <span class=\"rtsee-illustrator-error-text\">{{ illustrator.generationError }}</span>\n <button type=\"button\" class=\"rtsee-illustrator-error-close\" (click)=\"illustrator.generationError = null\" aria-label=\"Dismiss error\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n }\n\n <!-- Reviewing Generated Image Mode -->\n @if (illustrator.reviewingGeneratedImage && illustrator.currentGeneratedImageUrl) {\n <div class=\"rtsee-illustrator-review-panel\">\n <div class=\"rtsee-illustrator-review-header\">\n <div class=\"rtsee-illustrator-review-title\">\n <span class=\"rtsee-illustrator-review-badge\">\n <i class=\"pi pi-sparkles\"></i> Reviewing Generated Image\n </span>\n <span class=\"rtsee-illustrator-review-sub\">Review the result, request iterative modifications, or discard.</span>\n </div>\n <div class=\"rtsee-illustrator-review-quick-actions\">\n <p-button\n label=\"Accept & Keep\"\n icon=\"pi pi-check\"\n severity=\"success\"\n (click)=\"acceptGeneratedImage()\"\n />\n <p-button\n label=\"Discard\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n (click)=\"discardGeneratedImage()\"\n />\n </div>\n </div>\n\n <!-- Image Preview -->\n <div class=\"rtsee-illustrator-preview-box\">\n <img [src]=\"illustrator.currentGeneratedImageUrl\" alt=\"Generated fairy tale illustration\" class=\"rtsee-illustrator-preview-img\" />\n <a [href]=\"illustrator.currentGeneratedImageUrl\" target=\"_blank\" rel=\"noopener\" class=\"rtsee-illustrator-preview-zoom-btn\" title=\"Open full image in new tab\">\n <i class=\"pi pi-external-link\"></i> Full View\n </a>\n </div>\n\n <!-- Iteration Modification Controls -->\n <div class=\"rtsee-illustrator-iteration-box\">\n <div class=\"rtsee-illustrator-iteration-info\">\n <span class=\"rtsee-illustrator-iteration-tag\">\n <i class=\"pi pi-refresh\"></i> Request Modifications & Iterate\n </span>\n <span class=\"rtsee-illustrator-iteration-context-hint\">\n <i class=\"pi pi-info-circle\"></i>\n All active context references ({{ illustrator.activeContextImages.length }}) are sent to NanoBanana alongside this base picture.\n </span>\n </div>\n\n <textarea\n class=\"rtsee-illustrator-prompt-textarea rtsee-illustrator-prompt-textarea--iteration\"\n rows=\"3\"\n [(ngModel)]=\"illustrator.iterationPrompt\"\n placeholder=\"Describe modifications to apply to this picture (e.g. 'Make the wizard's cloak sapphire blue with silver runes, add glowing fireflies, soften the background trees')...\"\n (keydown.meta.enter)=\"submitIteration()\"\n (keydown.control.enter)=\"submitIteration()\"\n ></textarea>\n\n <div class=\"rtsee-illustrator-prompt-footer\">\n <span class=\"rtsee-illustrator-tip\">\n <i class=\"pi pi-info-circle\"></i>\n Press <strong>\u2318+Enter</strong> to iterate on this picture.\n </span>\n\n <div class=\"rtsee-illustrator-actions\">\n <p-button\n label=\"Discard\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n (click)=\"discardGeneratedImage()\"\n />\n <p-button\n label=\"Iterate & Regenerate\"\n icon=\"pi pi-refresh\"\n [loading]=\"illustrator.submitting\"\n [disabled]=\"!illustrator.canSubmit\"\n (click)=\"submitIteration()\"\n />\n </div>\n </div>\n </div>\n </div>\n } @else {\n <!-- Prompt Input & Submit Action (Standard Mode) -->\n <div class=\"rtsee-illustrator-prompt-section\">\n <div class=\"rtsee-illustrator-prompt-box\">\n <textarea\n class=\"rtsee-illustrator-prompt-textarea\"\n rows=\"3\"\n [(ngModel)]=\"illustrator.prompt\"\n placeholder=\"Describe the fairy tale illustration to generate (e.g. 'A cozy cottage tucked deep inside the emerald moss woods, magical amber lanterns glowing warmly from the windows, soft fireflies in the air')...\"\n (keydown.meta.enter)=\"submitPrompt()\"\n (keydown.control.enter)=\"submitPrompt()\"\n ></textarea>\n\n <div class=\"rtsee-illustrator-prompt-footer\">\n <span class=\"rtsee-illustrator-tip\">\n <i class=\"pi pi-info-circle\"></i>\n Press <strong>\u2318+Enter</strong> to submit. Context characters, artifacts, locations & slides are sent to NanoBanana.\n </span>\n\n <div class=\"rtsee-illustrator-actions\">\n <p-button\n label=\"Generate Illustration\"\n icon=\"pi pi-sparkles\"\n [loading]=\"illustrator.submitting\"\n [disabled]=\"!illustrator.canSubmit\"\n (click)=\"submitPrompt()\"\n />\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: i1$3.SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
5986
7213
|
}
|
|
5987
7214
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: IllustratorComponent, decorators: [{
|
|
5988
7215
|
type: Component,
|
|
@@ -6562,7 +7789,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
6562
7789
|
|
|
6563
7790
|
class RtseeEntityCommentsComponent {
|
|
6564
7791
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeEntityCommentsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6565
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RtseeEntityCommentsComponent, isStandalone: true, selector: "rtsee-entity-comments", inputs: { messenger: "messenger", chat: "chat", entity: "entity" }, ngImport: i0, template: "<div class=\"rtsee-entity-comments\" data-ugc=\"true\" rel=\"ugc\" aria-label=\"User comments\">\n @if (messenger && chat) {\n <rtsee-chat [messenger]=\"messenger\"\n [chatData]=\"chat\"\n [entity]=\"entity\"\n ></rtsee-chat>\n }\n</div>\n", dependencies: [{ kind: "component", type: ChatComponent, selector: "rtsee-chat", inputs: ["chat", "chatData", "entity", "messenger"] }] }); }
|
|
7792
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RtseeEntityCommentsComponent, isStandalone: true, selector: "rtsee-entity-comments", inputs: { messenger: "messenger", chat: "chat", entity: "entity" }, ngImport: i0, template: "<div class=\"rtsee-entity-comments\" data-ugc=\"true\" rel=\"ugc\" aria-label=\"User comments\">\n @if (messenger && chat) {\n <rtsee-chat [messenger]=\"messenger\"\n [chatData]=\"chat\"\n [entity]=\"entity\"\n ></rtsee-chat>\n }\n</div>\n", dependencies: [{ kind: "component", type: ChatComponent, selector: "rtsee-chat", inputs: ["chat", "chatData", "entity", "messenger", "isFramed"] }] }); }
|
|
6566
7793
|
}
|
|
6567
7794
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeEntityCommentsComponent, decorators: [{
|
|
6568
7795
|
type: Component,
|
|
@@ -7017,7 +8244,7 @@ class StoryDetailsComponent {
|
|
|
7017
8244
|
return stars;
|
|
7018
8245
|
}
|
|
7019
8246
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7020
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryDetailsComponent, isStandalone: true, selector: "rtsee-story-details", inputs: { story: "story", presentation: "presentation", messenger: "messenger" }, ngImport: i0, template: "<div\n class=\"rtsee-story-details\"\n itemscope\n itemtype=\"https://schema.org/ShortStory\"\n>\n @if (story.imageUrl) {\n <meta itemprop=\"image\" [attr.content]=\"story.imageUrl\" />\n }\n @if (story.languageKey) {\n <meta itemprop=\"inLanguage\" [attr.content]=\"story.languageKey === 'ua' ? 'uk' : 'en'\" />\n }\n @if (story.totalSlides) {\n <meta itemprop=\"numberOfPages\" [attr.content]=\"story.totalSlides\" />\n }\n <section\n class=\"rtsee-story-details-cover\"\n [style.background-image]=\"'url(' + story.imageUrl + ')'\"\n >\n <button\n class=\"rtsee-story-details-btn-close\"\n [routerLink]=\"[presentation.homePage]\"\n (click)=\"presentation.closeStoryDetails()\"\n aria-label=\"Close\"\n >\n <span class=\"pi pi-times\"></span>\n </button>\n <div class=\"rtsee-story-details-cover-overlay\"></div>\n <div class=\"rtsee-story-details-cover-content\">\n <div class=\"rtsee-story-details-cover-badges\">\n @if (story.categories?.length && false) {\n @for (category of story.categories; track category.id) {\n <span class=\"rtsee-story-details-tag-pill\">\n {{ category.name }}\n </span>\n }\n }\n @if (story.tags?.length) {\n @for (tag of story.tags; track tag.id) {\n <span\n class=\"rtsee-story-details-tag-pill rtsee-story-details-tag-pill-label\"\n >\n @if (tag.symbol) {\n <span class=\"symbol\">{{ tag.symbol }}</span>\n }\n {{ tag.name }}\n </span>\n }\n }\n </div>\n\n <h1 class=\"rtsee-story-details-cover-title\" itemprop=\"name\">{{ story.name }}</h1>\n\n <div class=\"rtsee-story-details-cover-meta\">\n @if (story.rating !== null) {\n <div\n class=\"rtsee-story-details-cover-rating\"\n itemprop=\"aggregateRating\"\n itemscope\n itemtype=\"https://schema.org/AggregateRating\"\n >\n <meta itemprop=\"bestRating\" content=\"5\" />\n <meta itemprop=\"worstRating\" content=\"1\" />\n <span class=\"rtsee-story-details-stars\">\n @for (star of getStarArray(story.rating); track $index) {\n <span\n class=\"rtsee-story-details-star\"\n [class.rtsee-story-details-star-full]=\"star === 'full'\"\n [class.rtsee-story-details-star-half]=\"star === 'half'\"\n [class.rtsee-story-details-star-empty]=\"star === 'empty'\"\n >\n @if (star === \"full\") {\n \u2605\n } @else if (star === \"half\") {\n \u2605\n } @else {\n \u2606\n }\n </span>\n }\n </span>\n <span class=\"rtsee-story-details-rating-number\" itemprop=\"ratingValue\">{{\n story.rating\n }}</span>\n @if (story.ratesCount !== null) {\n <meta itemprop=\"ratingCount\" [attr.content]=\"story.ratesCount\" />\n <span class=\"rtsee-story-details-rating-count\">\n <span>(</span>\n <span>{{ presentation.labels[RTSeeTextLabelKeys.FEEDBACKS_LABEL] }}:</span>\n <span> </span>\n <span itemprop=\"reviewCount\">{{ story.ratesCount }}</span>\n <span>)</span>\n </span\n >\n }\n </div>\n }\n </div>\n </div>\n </section>\n\n <!-- CONTENT AREA -->\n <div class=\"rtsee-story-details-content-wrapper\">\n <!-- Reading panel: what the user is about to read + the main CTA -->\n <section class=\"rtsee-story-details-reading-panel\" aria-label=\"{{ story.name }}\">\n @if (story.totalSlides) {\n <rtsee-story-slides-preview\n [story]=\"story\"\n [slidesLabel]=\"presentation.labels[RTSeeTextLabelKeys.STORY_PAGES_LABEL]\"\n [minuteLabel]=\"presentation.labels[RTSeeTextLabelKeys.MINUTE_LABEL]\"\n ></rtsee-story-slides-preview>\n }\n <p-button\n (click)=\"presentation.setActiveStory(story)\"\n [severity]=\"'primary'\"\n [label]=\"story.preselectedSlideNumber ? presentation.labels[RTSeeTextLabelKeys.CONTINUE_READING_BUTTON] : presentation.labels[RTSeeTextLabelKeys.START_READING_BUTTON]\"\n icon=\"pi pi-book\"\n iconPos=\"left\"\n class=\"rtsee-story-details-start-reading rts-action-button\"\n >\n </p-button>\n </section>\n <div class=\"rtsee-story-details-content-grid\">\n <!-- Description Card -->\n <article class=\"rtsee-story-details-glass-card\">\n <div class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\" />\n <path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\" />\n </svg>\n <h2>{{presentation.labels[RTSeeTextLabelKeys.STORY_ABOUT_LABEL]}}</h2>\n </div>\n <p class=\"rtsee-story-details-glass-card-text\" itemprop=\"description\">\n {{ story.description }}\n </p>\n </article>\n\n @if (story.history) {\n <article class=\"rtsee-story-details-glass-card\">\n <div class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 14 14\" />\n </svg>\n <h2>{{presentation.labels[RTSeeTextLabelKeys.STORY_HISTORY_LABEL]}}</h2>\n </div>\n <p class=\"rtsee-story-details-glass-card-text\" itemprop=\"backstory\">\n {{ story.history }}\n </p>\n </article>\n }\n\n @if (story.moralMeaning) {\n <article class=\"rtsee-story-details-glass-card\">\n <div class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n <h2>{{presentation.labels[RTSeeTextLabelKeys.STORY_MORAL_LABEL]}}</h2>\n </div>\n <p class=\"rtsee-story-details-glass-card-text\" itemprop=\"teaches\">\n {{ story.moralMeaning }}\n </p>\n </article>\n }\n </div>\n\n <!-- Author -->\n @if (story.author) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-author-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\" />\n </svg>\n <h2 id=\"rtsee-story-details-author-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.STORY_AUTHOR_LABEL] }}\n </h2>\n </header>\n <div class=\"rtsee-story-details-elements-featured\">\n <rtsee-story-element-thumbnail\n [name]=\"story.author.name\"\n [description]=\"story.author.description\"\n [imageUrl]=\"story.author.imageUrl\"\n itemProp=\"author\"\n schemaType=\"Person\"\n [horizontal]=\"true\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </div>\n </section>\n }\n\n <!-- Characters -->\n @if (story.characters.length) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-characters-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"9\" cy=\"7\" r=\"4\" />\n <path d=\"M23 21v-2a4 4 0 0 0-3-3.87\" />\n <path d=\"M16 3.13a4 4 0 0 1 0 7.75\" />\n </svg>\n <h2 id=\"rtsee-story-details-characters-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.CHARACTERS_LABEL] }}\n </h2>\n </header>\n <ul class=\"rtsee-story-details-elements-grid\" role=\"list\">\n @for (character of story.characters; track character.id) {\n <li class=\"rtsee-story-details-elements-item\">\n <rtsee-story-element-thumbnail\n [name]=\"character.name\"\n [description]=\"character.description\"\n [imageUrl]=\"character.imageUrl\"\n itemProp=\"character\"\n schemaType=\"Person\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </li>\n }\n </ul>\n </section>\n }\n\n <!-- Artifacts -->\n @if (story.artifacts.length) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-artifacts-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 3h12l4 6-10 13L2 9z\" />\n <path d=\"M11 3 8 9l4 13 4-13-3-6\" />\n <path d=\"M2 9h20\" />\n </svg>\n <h2 id=\"rtsee-story-details-artifacts-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.ARTIFACTS_LABEL] }}\n </h2>\n </header>\n <ul class=\"rtsee-story-details-elements-grid\" role=\"list\">\n @for (artifact of story.artifacts; track artifact.id) {\n <li class=\"rtsee-story-details-elements-item\">\n <rtsee-story-element-thumbnail\n [name]=\"artifact.name\"\n [description]=\"artifact.description\"\n [imageUrl]=\"artifact.imageUrl\"\n itemProp=\"mentions\"\n schemaType=\"Thing\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </li>\n }\n </ul>\n </section>\n }\n\n <!-- Places -->\n @if (story.locations.length) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-places-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n </svg>\n <h2 id=\"rtsee-story-details-places-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.LOCATIONS_LABEL] }}\n </h2>\n </header>\n <ul class=\"rtsee-story-details-elements-grid\" role=\"list\">\n @for (place of story.locations; track place.id) {\n <li class=\"rtsee-story-details-elements-item\">\n <rtsee-story-element-thumbnail\n [name]=\"place.name\"\n [description]=\"place.description\"\n [imageUrl]=\"place.imageUrl\"\n itemProp=\"contentLocation\"\n schemaType=\"Place\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </li>\n }\n </ul>\n </section>\n }\n\n @if (messenger) {\n <rtsee-entity-preview\n [entity]=\"story\"\n [messenger]=\"messenger\"\n ></rtsee-entity-preview>\n }\n\n @if (story.categories?.length && false) {\n <div class=\"rtsee-story-details-categories\">\n @for (category of story.categories; track category.id) {\n <p-tag [value]=\"category.name\"></p-tag>\n }\n </div>\n }\n\n @if (story.tags?.length && false) {\n <div class=\"rtsee-story-details-labels\">\n @for (tag of story.tags; track tag.id) {\n <p-chip class=\"rtsee-story-details-label\">\n @if (tag.symbol) {\n <span class=\"rtsee-story-details-label-left\">{{\n tag.symbol\n }}</span>\n }\n <span class=\"rtsee-story-details-label-right\">{{\n tag.name\n }}</span>\n </p-chip>\n }\n </div>\n }\n\n <div class=\"rtsee-story-details-description-history\"></div>\n @if (story.isPublished && false) {\n <div class=\"rtsee-story-details-feedback\">\n <p>feedback here</p>\n </div>\n } @else if (messenger && story.discussion && false) {\n <div class=\"rtsee-story-details-votes\">\n <p class=\"rtsee-story-details-comments-label\">Comments</p>\n <rtsee-chat\n [messenger]=\"messenger\"\n [chatData]=\"story.discussion\"\n ></rtsee-chat>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: Chip, selector: "p-chip", inputs: ["label", "icon", "image", "alt", "styleClass", "disabled", "removable", "removeIcon", "chipProps"], outputs: ["onRemove", "onImageError"] }, { kind: "component", type: Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ChatComponent, selector: "rtsee-chat", inputs: ["chat", "chatData", "entity", "messenger"] }, { kind: "component", type: RtseeEntityPreviewComponent, selector: "rtsee-entity-preview", inputs: ["entity", "messenger"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: StoryElementThumbnailComponent, selector: "rtsee-story-element-thumbnail", inputs: ["name", "description", "imageUrl", "itemProp", "schemaType", "horizontal", "showMoreLabel", "showLessLabel"] }, { kind: "component", type: StorySlidesPreviewComponent, selector: "rtsee-story-slides-preview", inputs: ["story", "slidesLabel", "minuteLabel", "count"] }] }); }
|
|
8247
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryDetailsComponent, isStandalone: true, selector: "rtsee-story-details", inputs: { story: "story", presentation: "presentation", messenger: "messenger" }, ngImport: i0, template: "<div\n class=\"rtsee-story-details\"\n itemscope\n itemtype=\"https://schema.org/ShortStory\"\n>\n @if (story.imageUrl) {\n <meta itemprop=\"image\" [attr.content]=\"story.imageUrl\" />\n }\n @if (story.languageKey) {\n <meta itemprop=\"inLanguage\" [attr.content]=\"story.languageKey === 'ua' ? 'uk' : 'en'\" />\n }\n @if (story.totalSlides) {\n <meta itemprop=\"numberOfPages\" [attr.content]=\"story.totalSlides\" />\n }\n <section\n class=\"rtsee-story-details-cover\"\n [style.background-image]=\"'url(' + story.imageUrl + ')'\"\n >\n <button\n class=\"rtsee-story-details-btn-close\"\n [routerLink]=\"[presentation.homePage]\"\n (click)=\"presentation.closeStoryDetails()\"\n aria-label=\"Close\"\n >\n <span class=\"pi pi-times\"></span>\n </button>\n <div class=\"rtsee-story-details-cover-overlay\"></div>\n <div class=\"rtsee-story-details-cover-content\">\n <div class=\"rtsee-story-details-cover-badges\">\n @if (story.categories?.length && false) {\n @for (category of story.categories; track category.id) {\n <span class=\"rtsee-story-details-tag-pill\">\n {{ category.name }}\n </span>\n }\n }\n @if (story.tags?.length) {\n @for (tag of story.tags; track tag.id) {\n <span\n class=\"rtsee-story-details-tag-pill rtsee-story-details-tag-pill-label\"\n >\n @if (tag.symbol) {\n <span class=\"symbol\">{{ tag.symbol }}</span>\n }\n {{ tag.name }}\n </span>\n }\n }\n </div>\n\n <h1 class=\"rtsee-story-details-cover-title\" itemprop=\"name\">{{ story.name }}</h1>\n\n <div class=\"rtsee-story-details-cover-meta\">\n @if (story.rating !== null) {\n <div\n class=\"rtsee-story-details-cover-rating\"\n itemprop=\"aggregateRating\"\n itemscope\n itemtype=\"https://schema.org/AggregateRating\"\n >\n <meta itemprop=\"bestRating\" content=\"5\" />\n <meta itemprop=\"worstRating\" content=\"1\" />\n <span class=\"rtsee-story-details-stars\">\n @for (star of getStarArray(story.rating); track $index) {\n <span\n class=\"rtsee-story-details-star\"\n [class.rtsee-story-details-star-full]=\"star === 'full'\"\n [class.rtsee-story-details-star-half]=\"star === 'half'\"\n [class.rtsee-story-details-star-empty]=\"star === 'empty'\"\n >\n @if (star === \"full\") {\n \u2605\n } @else if (star === \"half\") {\n \u2605\n } @else {\n \u2606\n }\n </span>\n }\n </span>\n <span class=\"rtsee-story-details-rating-number\" itemprop=\"ratingValue\">{{\n story.rating\n }}</span>\n @if (story.ratesCount !== null) {\n <meta itemprop=\"ratingCount\" [attr.content]=\"story.ratesCount\" />\n <span class=\"rtsee-story-details-rating-count\">\n <span>(</span>\n <span>{{ presentation.labels[RTSeeTextLabelKeys.FEEDBACKS_LABEL] }}:</span>\n <span> </span>\n <span itemprop=\"reviewCount\">{{ story.ratesCount }}</span>\n <span>)</span>\n </span\n >\n }\n </div>\n }\n </div>\n </div>\n </section>\n\n <!-- CONTENT AREA -->\n <div class=\"rtsee-story-details-content-wrapper\">\n <!-- Reading panel: what the user is about to read + the main CTA -->\n <section class=\"rtsee-story-details-reading-panel\" aria-label=\"{{ story.name }}\">\n @if (story.totalSlides) {\n <rtsee-story-slides-preview\n [story]=\"story\"\n [slidesLabel]=\"presentation.labels[RTSeeTextLabelKeys.STORY_PAGES_LABEL]\"\n [minuteLabel]=\"presentation.labels[RTSeeTextLabelKeys.MINUTE_LABEL]\"\n ></rtsee-story-slides-preview>\n }\n <p-button\n (click)=\"presentation.setActiveStory(story)\"\n [severity]=\"'primary'\"\n [label]=\"story.preselectedSlideNumber ? presentation.labels[RTSeeTextLabelKeys.CONTINUE_READING_BUTTON] : presentation.labels[RTSeeTextLabelKeys.START_READING_BUTTON]\"\n icon=\"pi pi-book\"\n iconPos=\"left\"\n class=\"rtsee-story-details-start-reading rts-action-button\"\n >\n </p-button>\n </section>\n <div class=\"rtsee-story-details-content-grid\">\n <!-- Description Card -->\n <article class=\"rtsee-story-details-glass-card\">\n <div class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\" />\n <path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\" />\n </svg>\n <h2>{{presentation.labels[RTSeeTextLabelKeys.STORY_ABOUT_LABEL]}}</h2>\n </div>\n <p class=\"rtsee-story-details-glass-card-text\" itemprop=\"description\">\n {{ story.description }}\n </p>\n </article>\n\n @if (story.history) {\n <article class=\"rtsee-story-details-glass-card\">\n <div class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 14 14\" />\n </svg>\n <h2>{{presentation.labels[RTSeeTextLabelKeys.STORY_HISTORY_LABEL]}}</h2>\n </div>\n <p class=\"rtsee-story-details-glass-card-text\" itemprop=\"backstory\">\n {{ story.history }}\n </p>\n </article>\n }\n\n @if (story.moralMeaning) {\n <article class=\"rtsee-story-details-glass-card\">\n <div class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n <h2>{{presentation.labels[RTSeeTextLabelKeys.STORY_MORAL_LABEL]}}</h2>\n </div>\n <p class=\"rtsee-story-details-glass-card-text\" itemprop=\"teaches\">\n {{ story.moralMeaning }}\n </p>\n </article>\n }\n </div>\n\n <!-- Author -->\n @if (story.author) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-author-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 20h9\" />\n <path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\" />\n </svg>\n <h2 id=\"rtsee-story-details-author-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.STORY_AUTHOR_LABEL] }}\n </h2>\n </header>\n <div class=\"rtsee-story-details-elements-featured\">\n <rtsee-story-element-thumbnail\n [name]=\"story.author.name\"\n [description]=\"story.author.description\"\n [imageUrl]=\"story.author.imageUrl\"\n itemProp=\"author\"\n schemaType=\"Person\"\n [horizontal]=\"true\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </div>\n </section>\n }\n\n <!-- Characters -->\n @if (story.characters.length) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-characters-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"9\" cy=\"7\" r=\"4\" />\n <path d=\"M23 21v-2a4 4 0 0 0-3-3.87\" />\n <path d=\"M16 3.13a4 4 0 0 1 0 7.75\" />\n </svg>\n <h2 id=\"rtsee-story-details-characters-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.CHARACTERS_LABEL] }}\n </h2>\n </header>\n <ul class=\"rtsee-story-details-elements-grid\" role=\"list\">\n @for (character of story.characters; track character.id) {\n <li class=\"rtsee-story-details-elements-item\">\n <rtsee-story-element-thumbnail\n [name]=\"character.name\"\n [description]=\"character.description\"\n [imageUrl]=\"character.imageUrl\"\n itemProp=\"character\"\n schemaType=\"Person\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </li>\n }\n </ul>\n </section>\n }\n\n <!-- Artifacts -->\n @if (story.artifacts.length) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-artifacts-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 3h12l4 6-10 13L2 9z\" />\n <path d=\"M11 3 8 9l4 13 4-13-3-6\" />\n <path d=\"M2 9h20\" />\n </svg>\n <h2 id=\"rtsee-story-details-artifacts-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.ARTIFACTS_LABEL] }}\n </h2>\n </header>\n <ul class=\"rtsee-story-details-elements-grid\" role=\"list\">\n @for (artifact of story.artifacts; track artifact.id) {\n <li class=\"rtsee-story-details-elements-item\">\n <rtsee-story-element-thumbnail\n [name]=\"artifact.name\"\n [description]=\"artifact.description\"\n [imageUrl]=\"artifact.imageUrl\"\n itemProp=\"mentions\"\n schemaType=\"Thing\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </li>\n }\n </ul>\n </section>\n }\n\n <!-- Places -->\n @if (story.locations.length) {\n <section\n class=\"rtsee-story-details-elements\"\n aria-labelledby=\"rtsee-story-details-places-heading\"\n >\n <header class=\"rtsee-story-details-glass-card-header\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\" />\n <circle cx=\"12\" cy=\"10\" r=\"3\" />\n </svg>\n <h2 id=\"rtsee-story-details-places-heading\">\n {{ presentation.labels[RTSeeTextLabelKeys.LOCATIONS_LABEL] }}\n </h2>\n </header>\n <ul class=\"rtsee-story-details-elements-grid\" role=\"list\">\n @for (place of story.locations; track place.id) {\n <li class=\"rtsee-story-details-elements-item\">\n <rtsee-story-element-thumbnail\n [name]=\"place.name\"\n [description]=\"place.description\"\n [imageUrl]=\"place.imageUrl\"\n itemProp=\"contentLocation\"\n schemaType=\"Place\"\n [showMoreLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_MORE_LABEL]\"\n [showLessLabel]=\"presentation.labels[RTSeeTextLabelKeys.SHOW_LESS_LABEL]\"\n ></rtsee-story-element-thumbnail>\n </li>\n }\n </ul>\n </section>\n }\n\n @if (messenger) {\n <rtsee-entity-preview\n [entity]=\"story\"\n [messenger]=\"messenger\"\n ></rtsee-entity-preview>\n }\n\n @if (story.categories?.length && false) {\n <div class=\"rtsee-story-details-categories\">\n @for (category of story.categories; track category.id) {\n <p-tag [value]=\"category.name\"></p-tag>\n }\n </div>\n }\n\n @if (story.tags?.length && false) {\n <div class=\"rtsee-story-details-labels\">\n @for (tag of story.tags; track tag.id) {\n <p-chip class=\"rtsee-story-details-label\">\n @if (tag.symbol) {\n <span class=\"rtsee-story-details-label-left\">{{\n tag.symbol\n }}</span>\n }\n <span class=\"rtsee-story-details-label-right\">{{\n tag.name\n }}</span>\n </p-chip>\n }\n </div>\n }\n\n <div class=\"rtsee-story-details-description-history\"></div>\n @if (story.isPublished && false) {\n <div class=\"rtsee-story-details-feedback\">\n <p>feedback here</p>\n </div>\n } @else if (messenger && story.discussion && false) {\n <div class=\"rtsee-story-details-votes\">\n <p class=\"rtsee-story-details-comments-label\">Comments</p>\n <rtsee-chat\n [messenger]=\"messenger\"\n [chatData]=\"story.discussion\"\n ></rtsee-chat>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: Chip, selector: "p-chip", inputs: ["label", "icon", "image", "alt", "styleClass", "disabled", "removable", "removeIcon", "chipProps"], outputs: ["onRemove", "onImageError"] }, { kind: "component", type: Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ChatComponent, selector: "rtsee-chat", inputs: ["chat", "chatData", "entity", "messenger", "isFramed"] }, { kind: "component", type: RtseeEntityPreviewComponent, selector: "rtsee-entity-preview", inputs: ["entity", "messenger"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: StoryElementThumbnailComponent, selector: "rtsee-story-element-thumbnail", inputs: ["name", "description", "imageUrl", "itemProp", "schemaType", "horizontal", "showMoreLabel", "showLessLabel"] }, { kind: "component", type: StorySlidesPreviewComponent, selector: "rtsee-story-slides-preview", inputs: ["story", "slidesLabel", "minuteLabel", "count"] }] }); }
|
|
7021
8248
|
}
|
|
7022
8249
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryDetailsComponent, decorators: [{
|
|
7023
8250
|
type: Component,
|
|
@@ -7163,7 +8390,7 @@ class RTSeeContainerComponent {
|
|
|
7163
8390
|
this.isSidenavFullScreen = rtseeRoute.fullScreen || false;
|
|
7164
8391
|
}
|
|
7165
8392
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeContainerComponent, deps: [{ token: RTSeeAuthService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7166
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RTSeeContainerComponent, isStandalone: true, selector: "rtsee-container", inputs: { rtsee: "rtsee", navigationConfig: "navigationConfig", auth: "auth" }, ngImport: i0, template: "<div class=\"rtsee-shell\"\n [ngClass]=\"{\n 'rtsee-shell-conference-mode': rtsee.conference && rtsee.conference.isInActiveCall,\n 'rtsee-shell-messenger-active': rtsee.messenger && rtsee.activeTab === 'messenger',\n 'rtsee-shell-dashboard-active': rtsee.eventsDashboard && rtsee.activeTab === 'events-dashboard',\n 'rtsee-shell-presentation-active': rtsee.presentation && rtsee.activeTab === 'presentation',\n 'rtsee-shell-side-nav-expanded': isSidenavExpanded,\n 'rtsee-shell-side-nav-is-content': isSidenavContent,\n 'rtsee-shell-side-nav-full-screen': isSidenavFullScreen,\n 'rtsee-lang-eng': rtsee.messenger && rtsee.messenger.currentLanguage === 'eng',\n 'rtsee-lang-ua': rtsee.messenger && rtsee.messenger.currentLanguage === 'ua'\n }\"\n>\n <div class=\"rtsee-nav-block\">\n <rtsee-nav [config]=\"navigationConfig\" [rtsee]=\"rtsee\"></rtsee-nav>\n </div>\n\n <div class=\"rtsee-shell-panel\">\n <div class=\"rtsee-shell-panel-inner\">\n @if (rtsee.conference && rtsee.conference.isInActiveCall) {\n <div class=\"rtsee-conference-container\">\n <rtsee-conference [rtSee]=\"rtsee.conference\"\n ></rtsee-conference>\n </div>\n }\n\n @if (rtsee.messenger) {\n <div class=\"rtsee-messenger-container\">\n <rtsee-messenger [messenger]=\"rtsee.messenger\"\n ></rtsee-messenger>\n </div>\n }\n\n @if (rtsee.eventsDashboard && rtsee.eventsDashboard.isReady) {\n <div class=\"rtsee-events-dashboard-container\">\n <rtsee-events-dashboard [eventsDashboard]=\"rtsee.eventsDashboard\"\n ></rtsee-events-dashboard>\n </div>\n }\n\n @if (rtsee.presentation && rtsee.presentation.isActive) {\n <div class=\"rtsee-presentation-container\">\n <rtsee-presentation [presentation]=\"rtsee.presentation\"\n [messenger]=\"rtsee.messenger\"\n ></rtsee-presentation>\n </div>\n }\n </div>\n </div>\n\n <div class=\"rtsee-content\">\n <ng-content></ng-content>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RTSeeConferenceComponent, selector: "rtsee-conference", inputs: ["rtSee"] }, { kind: "component", type: MessengerComponent, selector: "rtsee-messenger", inputs: ["messenger"] }, { kind: "component", type: RtseeEventsDashboardComponent, selector: "rtsee-events-dashboard", inputs: ["eventsDashboard"] }, { kind: "component", type: PresentationComponent, selector: "rtsee-presentation", inputs: ["presentation", "messenger"] }, { kind: "component", type: RtseeNavComponent, selector: "rtsee-nav", inputs: ["config", "rtsee"] }] }); }
|
|
8393
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RTSeeContainerComponent, isStandalone: true, selector: "rtsee-container", inputs: { rtsee: "rtsee", navigationConfig: "navigationConfig", auth: "auth" }, ngImport: i0, template: "<div class=\"rtsee-shell\"\n [ngClass]=\"{\n 'rtsee-shell-conference-mode': rtsee.conference && rtsee.conference.isInActiveCall,\n 'rtsee-shell-messenger-active': rtsee.messenger && rtsee.activeTab === 'messenger',\n 'rtsee-shell-dashboard-active': rtsee.eventsDashboard && rtsee.activeTab === 'events-dashboard',\n 'rtsee-shell-presentation-active': rtsee.presentation && rtsee.activeTab === 'presentation',\n 'rtsee-shell-side-nav-expanded': isSidenavExpanded,\n 'rtsee-shell-side-nav-is-content': isSidenavContent,\n 'rtsee-shell-side-nav-full-screen': isSidenavFullScreen,\n 'rtsee-lang-eng': rtsee.messenger && rtsee.messenger.currentLanguage === 'eng',\n 'rtsee-lang-ua': rtsee.messenger && rtsee.messenger.currentLanguage === 'ua'\n }\"\n>\n <div class=\"rtsee-nav-block\">\n <rtsee-nav [config]=\"navigationConfig\" [rtsee]=\"rtsee\"></rtsee-nav>\n </div>\n\n <div class=\"rtsee-shell-panel\">\n <div class=\"rtsee-shell-panel-inner\">\n @if (rtsee.conference && rtsee.conference.isInActiveCall) {\n <div class=\"rtsee-conference-container\">\n <rtsee-conference [rtSee]=\"rtsee.conference\"\n ></rtsee-conference>\n </div>\n }\n\n @if (rtsee.messenger) {\n <div class=\"rtsee-messenger-container\">\n <rtsee-messenger [messenger]=\"rtsee.messenger\"\n ></rtsee-messenger>\n </div>\n }\n\n @if (rtsee.eventsDashboard && rtsee.eventsDashboard.isReady) {\n <div class=\"rtsee-events-dashboard-container\">\n <rtsee-events-dashboard [eventsDashboard]=\"rtsee.eventsDashboard\"\n ></rtsee-events-dashboard>\n </div>\n }\n\n @if (rtsee.presentation && rtsee.presentation.isActive) {\n <div class=\"rtsee-presentation-container\">\n <rtsee-presentation [presentation]=\"rtsee.presentation\"\n [messenger]=\"rtsee.messenger\"\n ></rtsee-presentation>\n </div>\n }\n </div>\n </div>\n\n <div class=\"rtsee-content\">\n <ng-content></ng-content>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RTSeeConferenceComponent, selector: "rtsee-conference", inputs: ["rtSee"] }, { kind: "component", type: MessengerComponent, selector: "rtsee-messenger", inputs: ["messenger", "isFramed"] }, { kind: "component", type: RtseeEventsDashboardComponent, selector: "rtsee-events-dashboard", inputs: ["eventsDashboard"] }, { kind: "component", type: PresentationComponent, selector: "rtsee-presentation", inputs: ["presentation", "messenger"] }, { kind: "component", type: RtseeNavComponent, selector: "rtsee-nav", inputs: ["config", "rtsee"] }] }); }
|
|
7167
8394
|
}
|
|
7168
8395
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeContainerComponent, decorators: [{
|
|
7169
8396
|
type: Component,
|
|
@@ -8091,7 +9318,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
8091
9318
|
|
|
8092
9319
|
class PrivacyPolicyComponent {
|
|
8093
9320
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PrivacyPolicyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8094
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: PrivacyPolicyComponent, isStandalone: true, selector: "rtsee-privacy-policy", ngImport: i0, template: "<div class=\"privacy-policy-container\">\n <div class=\"policy-card rts-glass-card\">\n <div class=\"header-section\">\n <div class=\"header-content\">\n <h1>Terms of Use & Privacy Policy</h1>\n </div>\n </div>\n\n <div class=\"content-section\">\n <p-message severity=\"info\" [closable]=\"false\" class=\"info-banner\">\n <ng-template pTemplate>\n <div class=\"p-message-content\">\n <p class=\"last-updated\"><strong>Last Updated:</strong> December 2024</p>\n <p>By using our services, you agree to the terms and conditions outlined in this document. Please read this Privacy Policy and Terms of Use carefully before using our platform.</p>\n </div>\n </ng-template>\n </p-message>\n\n <h2>1. Acceptance of Terms</h2>\n <p>By accessing and using this service, you accept and agree to be bound by the terms and provision of this agreement. If you do not agree to abide by the above, please do not use this service.</p>\n\n <h2>2. Privacy Policy</h2>\n\n <h3>2.1 Information We Collect</h3>\n <p>We collect information you provide directly to us, such as when you create an account, use our services, or contact us for support. This may include:</p>\n <ul>\n <li><strong>Personal Information:</strong> Name, email address, phone number, and other contact details</li>\n <li><strong>Account Information:</strong> Username, password, and profile information</li>\n <li><strong>Usage Data:</strong> Information about how you use our services, including pages visited, time spent, and features used</li>\n <li><strong>Device Information:</strong> IP address, browser type, operating system, and device identifiers</li>\n <li><strong>Cookies and Tracking:</strong> We use cookies and similar technologies to enhance your experience</li>\n </ul>\n\n <h3>2.2 How We Use Your Information</h3>\n <p>We use the information we collect to:</p>\n <ul>\n <li>Provide, maintain, and improve our services</li>\n <li>Process transactions and send related information</li>\n <li>Send technical notices, updates, security alerts, and support messages</li>\n <li>Respond to your comments, questions, and requests</li>\n <li>Monitor and analyze trends, usage, and activities</li>\n <li>Personalize and improve your experience</li>\n <li>Detect, investigate, and prevent fraudulent transactions and other illegal activities</li>\n </ul>\n\n <h3>2.3 Information Sharing and Disclosure</h3>\n <p>We do not sell, trade, or otherwise transfer your personal information to third parties without your consent, except in the following circumstances:</p>\n <ul>\n <li><strong>Service Providers:</strong> We may share information with trusted third-party service providers who assist us in operating our platform</li>\n <li><strong>Legal Requirements:</strong> We may disclose information when required by law or to protect our rights and safety</li>\n <li><strong>Business Transfers:</strong> In connection with any merger, sale of assets, or acquisition of all or a portion of our business</li>\n <li><strong>Consent:</strong> We may share information with your explicit consent</li>\n </ul>\n\n <h3>2.4 Data Security</h3>\n <p>We implement appropriate technical and organizational security measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction. However, no method of transmission over the internet or electronic storage is 100% secure.</p>\n\n <h3>2.5 Data Retention</h3>\n <p>We retain your personal information for as long as necessary to provide our services and fulfill the purposes outlined in this privacy policy, unless a longer retention period is required or permitted by law.</p>\n\n <h3>2.6 Your Rights</h3>\n <p>Depending on your location, you may have certain rights regarding your personal information, including:</p>\n <ul>\n <li>The right to access and receive a copy of your personal information</li>\n <li>The right to rectify or update your personal information</li>\n <li>The right to erase your personal information</li>\n <li>The right to restrict or object to the processing of your personal information</li>\n <li>The right to data portability</li>\n <li>The right to withdraw consent at any time</li>\n </ul>\n\n <h2>3. Terms of Service</h2>\n\n <h3>3.1 User Accounts</h3>\n <p>To access certain features of our service, you may be required to create an account. You are responsible for:</p>\n <ul>\n <li>Maintaining the confidentiality of your account credentials</li>\n <li>All activities that occur under your account</li>\n <li>Notifying us immediately of any unauthorized use of your account</li>\n <li>Providing accurate and up-to-date information</li>\n </ul>\n\n <h3>3.2 Acceptable Use</h3>\n <p>You agree not to use our service for any unlawful purpose or any purpose prohibited under this clause. You may not use our service in any manner that could damage, disable, overburden, or impair our servers or networks.</p>\n\n <h3>3.3 Prohibited Activities</h3>\n <p>The following activities are prohibited:</p>\n <ul>\n <li>Violating any applicable laws or regulations</li>\n <li>Transmitting or procuring the sending of any unsolicited or unauthorized advertising</li>\n <li>Attempting to gain unauthorized access to any portion of our service</li>\n <li>Interfering with or disrupting the service or servers connected to the service</li>\n <li>Using any automated system to access the service for any purpose</li>\n <li>Impersonating any person or entity or misrepresenting your affiliation with a person or entity</li>\n </ul>\n\n <h3>3.4 Intellectual Property</h3>\n <p>The service and its original content, features, and functionality are and will remain the exclusive property of our company and its licensors. The service is protected by copyright, trademark, and other laws.</p>\n\n <h3>3.5 Termination</h3>\n <p>We may terminate or suspend your account and bar access to the service immediately, without prior notice or liability, under our sole discretion, for any reason whatsoever, including without limitation if you breach the Terms.</p>\n\n <h3>3.6 Disclaimer</h3>\n <p>The information on this service is provided on an \"as is\" basis. To the fullest extent permitted by law, this company excludes all representations, warranties, conditions and terms relating to our service and the use of this service.</p>\n\n <h3>3.7 Limitation of Liability</h3>\n <p>In no event shall our company, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable for any indirect, incidental, special, consequential, or punitive damages, including without limitation, loss of profits, data, use, goodwill, or other intangible losses, resulting from your use of the service.</p>\n\n <h2>4. Cookies and Tracking Technologies</h2>\n <p>We use cookies and similar tracking technologies to track activity on our service and hold certain information. Cookies are files with a small amount of data which may include an anonymous unique identifier. You can instruct your browser to refuse all cookies or to indicate when a cookie is being sent.</p>\n\n <h2>5. Third-Party Services</h2>\n <p>Our service may contain links to third-party websites or services that are not owned or controlled by us. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party websites or services.</p>\n\n <h2>6. Children's Privacy</h2>\n <p>Our service does not address anyone under the age of 13. We do not knowingly collect personally identifiable information from children under 13. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us.</p>\n\n <h2>7. International Data Transfers</h2>\n <p>Your information may be transferred to and processed in countries other than your own. We ensure that such transfers comply with applicable data protection laws and implement appropriate safeguards to protect your personal information.</p>\n\n <h2>8. Changes to This Policy</h2>\n <p>We reserve the right to update or change our Privacy Policy and Terms of Use at any time. We will notify you of any changes by posting the new Privacy Policy and Terms of Use on this page and updating the \"Last Updated\" date.</p>\n\n <div class=\"contact-section\">\n <h2>9. Contact Information</h2>\n <p>If you have any questions about this Privacy Policy and Terms of Use, please contact us:</p>\n <ul>\n <li><strong>Email:</strong> [Your Email Address]</li>\n <li><strong>Address:</strong> [Your Company Address]</li>\n <li><strong>Phone:</strong> [Your Contact Number]</li>\n </ul>\n </div>\n\n <div class=\"footer-section\">\n <p>This document was last updated on December 2024</p>\n </div>\n </div>\n </div>\n</div>\n\n", dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i2$2.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
|
|
9321
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: PrivacyPolicyComponent, isStandalone: true, selector: "rtsee-privacy-policy", ngImport: i0, template: "<div class=\"privacy-policy-container\">\n <div class=\"policy-card rts-glass-card\">\n <div class=\"header-section\">\n <div class=\"header-content\">\n <h1>Terms of Use & Privacy Policy</h1>\n </div>\n </div>\n\n <div class=\"content-section\">\n <p-message severity=\"info\" [closable]=\"false\" class=\"info-banner\">\n <ng-template pTemplate>\n <div class=\"p-message-content\">\n <p class=\"last-updated\"><strong>Last Updated:</strong> December 2024</p>\n <p>By using our services, you agree to the terms and conditions outlined in this document. Please read this Privacy Policy and Terms of Use carefully before using our platform.</p>\n </div>\n </ng-template>\n </p-message>\n\n <h2>1. Acceptance of Terms</h2>\n <p>By accessing and using this service, you accept and agree to be bound by the terms and provision of this agreement. If you do not agree to abide by the above, please do not use this service.</p>\n\n <h2>2. Privacy Policy</h2>\n\n <h3>2.1 Information We Collect</h3>\n <p>We collect information you provide directly to us, such as when you create an account, use our services, or contact us for support. This may include:</p>\n <ul>\n <li><strong>Personal Information:</strong> Name, email address, phone number, and other contact details</li>\n <li><strong>Account Information:</strong> Username, password, and profile information</li>\n <li><strong>Usage Data:</strong> Information about how you use our services, including pages visited, time spent, and features used</li>\n <li><strong>Device Information:</strong> IP address, browser type, operating system, and device identifiers</li>\n <li><strong>Cookies and Tracking:</strong> We use cookies and similar technologies to enhance your experience</li>\n </ul>\n\n <h3>2.2 How We Use Your Information</h3>\n <p>We use the information we collect to:</p>\n <ul>\n <li>Provide, maintain, and improve our services</li>\n <li>Process transactions and send related information</li>\n <li>Send technical notices, updates, security alerts, and support messages</li>\n <li>Respond to your comments, questions, and requests</li>\n <li>Monitor and analyze trends, usage, and activities</li>\n <li>Personalize and improve your experience</li>\n <li>Detect, investigate, and prevent fraudulent transactions and other illegal activities</li>\n </ul>\n\n <h3>2.3 Information Sharing and Disclosure</h3>\n <p>We do not sell, trade, or otherwise transfer your personal information to third parties without your consent, except in the following circumstances:</p>\n <ul>\n <li><strong>Service Providers:</strong> We may share information with trusted third-party service providers who assist us in operating our platform</li>\n <li><strong>Legal Requirements:</strong> We may disclose information when required by law or to protect our rights and safety</li>\n <li><strong>Business Transfers:</strong> In connection with any merger, sale of assets, or acquisition of all or a portion of our business</li>\n <li><strong>Consent:</strong> We may share information with your explicit consent</li>\n </ul>\n\n <h3>2.4 Data Security</h3>\n <p>We implement appropriate technical and organizational security measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction. However, no method of transmission over the internet or electronic storage is 100% secure.</p>\n\n <h3>2.5 Data Retention</h3>\n <p>We retain your personal information for as long as necessary to provide our services and fulfill the purposes outlined in this privacy policy, unless a longer retention period is required or permitted by law.</p>\n\n <h3>2.6 Your Rights</h3>\n <p>Depending on your location, you may have certain rights regarding your personal information, including:</p>\n <ul>\n <li>The right to access and receive a copy of your personal information</li>\n <li>The right to rectify or update your personal information</li>\n <li>The right to erase your personal information</li>\n <li>The right to restrict or object to the processing of your personal information</li>\n <li>The right to data portability</li>\n <li>The right to withdraw consent at any time</li>\n </ul>\n\n <h2>3. Terms of Service</h2>\n\n <h3>3.1 User Accounts</h3>\n <p>To access certain features of our service, you may be required to create an account. You are responsible for:</p>\n <ul>\n <li>Maintaining the confidentiality of your account credentials</li>\n <li>All activities that occur under your account</li>\n <li>Notifying us immediately of any unauthorized use of your account</li>\n <li>Providing accurate and up-to-date information</li>\n </ul>\n\n <h3>3.2 Acceptable Use</h3>\n <p>You agree not to use our service for any unlawful purpose or any purpose prohibited under this clause. You may not use our service in any manner that could damage, disable, overburden, or impair our servers or networks.</p>\n\n <h3>3.3 Prohibited Activities</h3>\n <p>The following activities are prohibited:</p>\n <ul>\n <li>Violating any applicable laws or regulations</li>\n <li>Transmitting or procuring the sending of any unsolicited or unauthorized advertising</li>\n <li>Attempting to gain unauthorized access to any portion of our service</li>\n <li>Interfering with or disrupting the service or servers connected to the service</li>\n <li>Using any automated system to access the service for any purpose</li>\n <li>Impersonating any person or entity or misrepresenting your affiliation with a person or entity</li>\n </ul>\n\n <h3>3.4 Intellectual Property</h3>\n <p>The service and its original content, features, and functionality are and will remain the exclusive property of our company and its licensors. The service is protected by copyright, trademark, and other laws.</p>\n\n <h3>3.5 Termination</h3>\n <p>We may terminate or suspend your account and bar access to the service immediately, without prior notice or liability, under our sole discretion, for any reason whatsoever, including without limitation if you breach the Terms.</p>\n\n <h3>3.6 Disclaimer</h3>\n <p>The information on this service is provided on an \"as is\" basis. To the fullest extent permitted by law, this company excludes all representations, warranties, conditions and terms relating to our service and the use of this service.</p>\n\n <h3>3.7 Limitation of Liability</h3>\n <p>In no event shall our company, nor its directors, employees, partners, agents, suppliers, or affiliates, be liable for any indirect, incidental, special, consequential, or punitive damages, including without limitation, loss of profits, data, use, goodwill, or other intangible losses, resulting from your use of the service.</p>\n\n <h2>4. Cookies and Tracking Technologies</h2>\n <p>We use cookies and similar tracking technologies to track activity on our service and hold certain information. Cookies are files with a small amount of data which may include an anonymous unique identifier. You can instruct your browser to refuse all cookies or to indicate when a cookie is being sent.</p>\n\n <h2>5. Third-Party Services</h2>\n <p>Our service may contain links to third-party websites or services that are not owned or controlled by us. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party websites or services.</p>\n\n <h2>6. Children's Privacy</h2>\n <p>Our service does not address anyone under the age of 13. We do not knowingly collect personally identifiable information from children under 13. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us.</p>\n\n <h2>7. International Data Transfers</h2>\n <p>Your information may be transferred to and processed in countries other than your own. We ensure that such transfers comply with applicable data protection laws and implement appropriate safeguards to protect your personal information.</p>\n\n <h2>8. Changes to This Policy</h2>\n <p>We reserve the right to update or change our Privacy Policy and Terms of Use at any time. We will notify you of any changes by posting the new Privacy Policy and Terms of Use on this page and updating the \"Last Updated\" date.</p>\n\n <div class=\"contact-section\">\n <h2>9. Contact Information</h2>\n <p>If you have any questions about this Privacy Policy and Terms of Use, please contact us:</p>\n <ul>\n <li><strong>Email:</strong> [Your Email Address]</li>\n <li><strong>Address:</strong> [Your Company Address]</li>\n <li><strong>Phone:</strong> [Your Contact Number]</li>\n </ul>\n </div>\n\n <div class=\"footer-section\">\n <p>This document was last updated on December 2024</p>\n </div>\n </div>\n </div>\n</div>\n\n", dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i1$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i2$1.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
|
|
8095
9322
|
}
|
|
8096
9323
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PrivacyPolicyComponent, decorators: [{
|
|
8097
9324
|
type: Component,
|
|
@@ -8439,5 +9666,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
8439
9666
|
* Generated bundle index. Do not edit.
|
|
8440
9667
|
*/
|
|
8441
9668
|
|
|
8442
|
-
export { BaseEventWidgetComponent, EntitiesConfigurationsListComponent, EntitiesListComponent, EventsWidgetsService, FormComponent, GtagService, IllustratorComponent, InteractiveStoryEditorComponent, ManageEntityComponent, ManageEntityConfigurationComponent, MessengerComponent, NgxService, PaymentProductSnippetComponent, PresentationComponent, ProfileComponent, RTSeeAuthComponent, RTSeeConferenceComponent, RTSeeContainerComponent, RTSeeControlsComponent, RTSeeModule, RTSeeTaskComponent, RtseeEntityCommentsComponent, RtseeEntityPreviewComponent, RtseeEntityTagsComponent, RtseeEventsDashboardComponent, RtseePeerComponent, RtseeSettingsComponent, RtseeTagGroupManageComponent, RtseeTagGroupsManageComponent, RtseeTagManageComponent, RtseeTagsAccordionMenuComponent, SlideNumberChangedWidgetComponent, StoryDetailsOpenedWidgetComponent, StoryElementsSectionComponent, StoryReadingStartedWidgetComponent, TranslationsPanelComponent };
|
|
9669
|
+
export { ApplicationEventWidgetComponent, BaseEventWidgetComponent, ChatAgentCreatedWidgetComponent, ChatCreatedWidgetComponent, ChatMemberInviteClickedWidgetComponent, ChatMessageSentWidgetComponent, ChatOpenedWidgetComponent, DefaultTaskActionPromptComponent, DefaultTaskActionThumbnailComponent, EntitiesConfigurationsListComponent, EntitiesListComponent, EventsWidgetsService, FormComponent, GtagService, IllustratorComponent, InteractiveStoryEditorComponent, ManageEntityComponent, ManageEntityConfigurationComponent, MessengerComponent, NgxService, PaymentProductSnippetComponent, PresentationComponent, ProfileComponent, ProfileOpenedWidgetComponent, RTSeeAuthComponent, RTSeeConferenceComponent, RTSeeContainerComponent, RTSeeControlsComponent, RTSeeModule, RTSeeTaskActionComponent, RTSeeTaskComponent, RequestDemoClickedWidgetComponent, RtseeEntityCommentsComponent, RtseeEntityPreviewComponent, RtseeEntityTagsComponent, RtseeEventsDashboardComponent, RtseePeerComponent, RtseeSettingsComponent, RtseeTagGroupManageComponent, RtseeTagGroupsManageComponent, RtseeTagManageComponent, RtseeTagsAccordionMenuComponent, SlideNumberChangedWidgetComponent, SlideTaskActionThumbnailComponent, StoryDetailsOpenedWidgetComponent, StoryElementsSectionComponent, StoryReadingStartedWidgetComponent, StoryTaskActionThumbnailComponent, TaskActionPromptComponent, TaskActionThumbnailComponent, TaskActionWidgetsService, TranslationsPanelComponent };
|
|
8443
9670
|
//# sourceMappingURL=rtsee-ngx.mjs.map
|