@rtsee/ngx 0.0.120 → 0.0.122
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 +1424 -167
- package/dist/ngx/fesm2022/rtsee-ngx.mjs.map +1 -1
- package/dist/ngx/index.d.ts +288 -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 +43 -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 +84 -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
|
}
|
|
@@ -1598,6 +1603,80 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
1598
1603
|
type: Output
|
|
1599
1604
|
}] } });
|
|
1600
1605
|
|
|
1606
|
+
class InviteLinkComponent {
|
|
1607
|
+
constructor() {
|
|
1608
|
+
this.inviteUrl = '';
|
|
1609
|
+
this.disclaimer = '';
|
|
1610
|
+
this.copied = false;
|
|
1611
|
+
this.loading = false;
|
|
1612
|
+
this.RTSeeTextLabelKeys = RTSeeTextLabelKeys;
|
|
1613
|
+
}
|
|
1614
|
+
async ngOnInit() {
|
|
1615
|
+
if (!this.inviteUrl && this.messenger) {
|
|
1616
|
+
await this.loadInviteLink();
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
async loadInviteLink() {
|
|
1620
|
+
if (!this.messenger)
|
|
1621
|
+
return;
|
|
1622
|
+
this.loading = true;
|
|
1623
|
+
try {
|
|
1624
|
+
const result = await this.messenger.remoteActions.getChatInvitationLink.send({
|
|
1625
|
+
chatId: this.chatId,
|
|
1626
|
+
});
|
|
1627
|
+
if (result?.invitationLink) {
|
|
1628
|
+
this.inviteUrl = result.invitationLink;
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
catch (e) {
|
|
1632
|
+
console.log('Failed to fetch chat invitation link', e);
|
|
1633
|
+
}
|
|
1634
|
+
finally {
|
|
1635
|
+
this.loading = false;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
async copyToClipboard() {
|
|
1639
|
+
const targetChat = this.chatId
|
|
1640
|
+
? this.messenger?.getChatById?.(this.chatId) || this.messenger?.openedChat
|
|
1641
|
+
: this.messenger?.openedChat;
|
|
1642
|
+
this.messenger?.trackChatMemberInviteClicked?.(targetChat, this.inviteUrl);
|
|
1643
|
+
try {
|
|
1644
|
+
await navigator.clipboard.writeText(this.inviteUrl);
|
|
1645
|
+
this.copied = true;
|
|
1646
|
+
setTimeout(() => {
|
|
1647
|
+
this.copied = false;
|
|
1648
|
+
}, 2000);
|
|
1649
|
+
}
|
|
1650
|
+
catch {
|
|
1651
|
+
// Fallback for older browsers
|
|
1652
|
+
const textArea = document.createElement('textarea');
|
|
1653
|
+
textArea.value = this.inviteUrl;
|
|
1654
|
+
document.body.appendChild(textArea);
|
|
1655
|
+
textArea.select();
|
|
1656
|
+
document.execCommand('copy');
|
|
1657
|
+
document.body.removeChild(textArea);
|
|
1658
|
+
this.copied = true;
|
|
1659
|
+
setTimeout(() => {
|
|
1660
|
+
this.copied = false;
|
|
1661
|
+
}, 2000);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InviteLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1665
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InviteLinkComponent, isStandalone: true, selector: "rtsee-invite-link", inputs: { inviteUrl: "inviteUrl", chatId: "chatId", messenger: "messenger", disclaimer: "disclaimer" }, ngImport: i0, template: "<div class=\"rts-invite-link\">\n <div class=\"rts-invite-link-info\">\n <span class=\"rts-invite-link-icon material-icons-outlined\">link</span>\n <div class=\"rts-invite-link-info-text\">\n <h4>{{ messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_LINK_TITLE] || 'Invite Link' }}</h4>\n <p>{{ disclaimer || (chatId ? messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_LINK_DISCLAIMER] : messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_DISCLAIMER]) || 'Anyone who opens this link can join the chat.' }}</p>\n </div>\n </div>\n\n @if (loading) {\n <div class=\"rts-invite-link-loading\">\n <span class=\"material-icons-outlined rts-spin-icon\">autorenew</span>\n <span>{{ messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_LINK_GENERATING] || 'Generating invite link...' }}</span>\n </div>\n } @else {\n <div class=\"rts-invite-link-url-container\">\n <p-inputgroup>\n <input pInputText\n [value]=\"inviteUrl\"\n readonly\n class=\"rts-invite-link-url-input\"\n />\n <p-button [icon]=\"copied ? 'pi pi-check' : 'pi pi-copy'\"\n [severity]=\"copied ? 'success' : 'primary'\"\n (click)=\"copyToClipboard()\"\n [label]=\"copied ? (messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_COPIED_BUTTON] || 'Copied!') : (messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_COPY_BUTTON] || 'Copy')\"\n />\n </p-inputgroup>\n </div>\n }\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: InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }] }); }
|
|
1666
|
+
}
|
|
1667
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InviteLinkComponent, decorators: [{
|
|
1668
|
+
type: Component,
|
|
1669
|
+
args: [{ selector: 'rtsee-invite-link', standalone: true, imports: [Button, InputText, InputGroup], template: "<div class=\"rts-invite-link\">\n <div class=\"rts-invite-link-info\">\n <span class=\"rts-invite-link-icon material-icons-outlined\">link</span>\n <div class=\"rts-invite-link-info-text\">\n <h4>{{ messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_LINK_TITLE] || 'Invite Link' }}</h4>\n <p>{{ disclaimer || (chatId ? messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_LINK_DISCLAIMER] : messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_DISCLAIMER]) || 'Anyone who opens this link can join the chat.' }}</p>\n </div>\n </div>\n\n @if (loading) {\n <div class=\"rts-invite-link-loading\">\n <span class=\"material-icons-outlined rts-spin-icon\">autorenew</span>\n <span>{{ messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_INVITE_LINK_GENERATING] || 'Generating invite link...' }}</span>\n </div>\n } @else {\n <div class=\"rts-invite-link-url-container\">\n <p-inputgroup>\n <input pInputText\n [value]=\"inviteUrl\"\n readonly\n class=\"rts-invite-link-url-input\"\n />\n <p-button [icon]=\"copied ? 'pi pi-check' : 'pi pi-copy'\"\n [severity]=\"copied ? 'success' : 'primary'\"\n (click)=\"copyToClipboard()\"\n [label]=\"copied ? (messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_COPIED_BUTTON] || 'Copied!') : (messenger?.labels?.[RTSeeTextLabelKeys.MESSENGER_COPY_BUTTON] || 'Copy')\"\n />\n </p-inputgroup>\n </div>\n }\n</div>\n" }]
|
|
1670
|
+
}], propDecorators: { inviteUrl: [{
|
|
1671
|
+
type: Input
|
|
1672
|
+
}], chatId: [{
|
|
1673
|
+
type: Input
|
|
1674
|
+
}], messenger: [{
|
|
1675
|
+
type: Input
|
|
1676
|
+
}], disclaimer: [{
|
|
1677
|
+
type: Input
|
|
1678
|
+
}] } });
|
|
1679
|
+
|
|
1601
1680
|
class DefaultImagesService {
|
|
1602
1681
|
constructor() {
|
|
1603
1682
|
this.PROFILE = 'https://werf-assets.s3.amazonaws.com/default-profile-logo.png';
|
|
@@ -1641,6 +1720,13 @@ class MessengerHeaderComponent {
|
|
|
1641
1720
|
this.isDropdownOpen = false;
|
|
1642
1721
|
this.messenger.openManageChatInfo();
|
|
1643
1722
|
}
|
|
1723
|
+
openInviteUserDialog() {
|
|
1724
|
+
this.isDropdownOpen = false;
|
|
1725
|
+
this.messenger.openInviteUser();
|
|
1726
|
+
}
|
|
1727
|
+
closeInviteUserDialog() {
|
|
1728
|
+
this.messenger.closeInviteUser();
|
|
1729
|
+
}
|
|
1644
1730
|
closeManageChatDialog() {
|
|
1645
1731
|
this.messenger.closeManageChatInfo();
|
|
1646
1732
|
}
|
|
@@ -1721,11 +1807,11 @@ class MessengerHeaderComponent {
|
|
|
1721
1807
|
this.defaultImagesService.PROFILE;
|
|
1722
1808
|
}
|
|
1723
1809
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessengerHeaderComponent, deps: [{ token: DefaultImagesService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1724
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessengerHeaderComponent, isStandalone: true, selector: "rtsee-messenger-header", inputs: { messenger: "messenger" }, ngImport: i0, template: "<div class=\"rts-messenger-header\"\n [ngClass]=\"{\n 'rts-messenger-header-chat-opened': messenger.openedChat && !messenger.manageChatInfo,\n 'rts-chat-header-unread': messenger.openedChat && !messenger.unreadMessagesCount,\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo,\n 'rts-messenger-header-create-chat-mode': messenger.manageChatInfo,\n 'rts-messenger-header-my-profile-mode': messenger.ownProfileOpened,\n 'rts-messenger-header-chat-info-mode': (messenger.openedProfile || messenger.openedChatDetails) && !messenger.ownProfileOpened && !messenger.manageChatInfo,\n 'rts-messenger-header-chat-image-expanded': imageExpandedToSquare,\n 'rts-messenger-header-image-square': imageExpandedToSquare\n }\"\n>\n <span class=\"rts-messenger-header-collapse-button\"\n (click)=\"messenger.manageChatInfo ? closeManageChatDialog() : collapseInfo()\"\n >\n <span class=\"pi pi-arrow-left\"></span>\n </span>\n <div class=\"rts-messenger-header-left\">\n @if (!messenger.openedChat && messenger.myPeer) {\n <div class=\"rts-messenger-header-avatar\"\n (click)=\"onMyAvatarClick()\"\n (dblclick)=\"onMyAvatarDblClick()\"\n >\n <div [style.background-image]=\"'url(' + myProfileImageUrl + ')'\"\n class=\"rts-messenger-header-avatar-image\">\n </div>\n </div>\n } @else if (messenger.openedChat) {\n <button class=\"rts-messenger-close-chat\"\n (click)=\"messenger.closeChat()\"\n >\n <span class=\"material-icons-outlined\">arrow_back</span>\n @if (messenger.unreadMessagesCount) {\n <span class=\"unread-count\">{{messenger.unreadMessagesCount}}</span>\n }\n </button>\n }\n </div>\n <div class=\"rts-messenger-header-right\">\n @if (messenger.openedChat) {\n <div class=\"rts-messenger-chat-image-container rts-messenger-header-avatar\"\n (click)=\"onChatImageClick()\"\n (dblclick)=\"onChatImageDblClick()\"\n >\n <div class=\"rts-messenger-chat-image rts-messenger-header-avatar-image\"\n [style.background-image]=\"'url(' + chatImageUrl + ')'\"\n ></div>\n </div>\n } @else {\n <div class=\"rts-messenger-header-actions\">\n <button class=\"rts-messenger-header-add-button\"\n (click)=\"toggleDropdown()\"\n >\n <span class=\"material-icons-outlined\">add</span>\n </button>\n\n @if (isDropdownOpen) {\n <div class=\"rts-messenger-header-dropdown-backdrop\"\n (click)=\"closeDropdown()\"\n ></div>\n <div class=\"rts-messenger-header-dropdown\">\n <button class=\"rts-messenger-header-dropdown-item\"\n (click)=\"openNewChatDialog()\"\n >\n <span class=\"material-icons-outlined rts-messenger-header-dropdown-icon\">chat_bubble_outline</span>\n <span>
|
|
1810
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessengerHeaderComponent, isStandalone: true, selector: "rtsee-messenger-header", inputs: { messenger: "messenger" }, ngImport: i0, template: "<div class=\"rts-messenger-header\"\n [ngClass]=\"{\n 'rts-messenger-header-chat-opened': messenger.openedChat && !messenger.manageChatInfo && !messenger.inviteUserOpened,\n 'rts-chat-header-unread': messenger.openedChat && !messenger.unreadMessagesCount,\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo || messenger.inviteUserOpened,\n 'rts-messenger-header-create-chat-mode': messenger.manageChatInfo || messenger.inviteUserOpened,\n 'rts-messenger-header-my-profile-mode': messenger.ownProfileOpened,\n 'rts-messenger-header-chat-info-mode': (messenger.openedProfile || messenger.openedChatDetails) && !messenger.ownProfileOpened && !messenger.manageChatInfo && !messenger.inviteUserOpened,\n 'rts-messenger-header-chat-image-expanded': imageExpandedToSquare,\n 'rts-messenger-header-image-square': imageExpandedToSquare\n }\"\n>\n <span class=\"rts-messenger-header-collapse-button\"\n (click)=\"messenger.manageChatInfo ? closeManageChatDialog() : (messenger.inviteUserOpened ? closeInviteUserDialog() : collapseInfo())\"\n >\n <span class=\"pi pi-arrow-left\"></span>\n </span>\n <div class=\"rts-messenger-header-left\">\n @if (!messenger.openedChat && messenger.myPeer) {\n <div class=\"rts-messenger-header-avatar\"\n (click)=\"onMyAvatarClick()\"\n (dblclick)=\"onMyAvatarDblClick()\"\n >\n <div [style.background-image]=\"'url(' + myProfileImageUrl + ')'\"\n class=\"rts-messenger-header-avatar-image\">\n </div>\n </div>\n } @else if (messenger.openedChat) {\n <button class=\"rts-messenger-close-chat\"\n (click)=\"messenger.closeChat()\"\n >\n <span class=\"material-icons-outlined\">arrow_back</span>\n @if (messenger.unreadMessagesCount) {\n <span class=\"unread-count\">{{messenger.unreadMessagesCount}}</span>\n }\n </button>\n }\n </div>\n <div class=\"rts-messenger-header-right\">\n @if (messenger.openedChat) {\n <div class=\"rts-messenger-chat-image-container rts-messenger-header-avatar\"\n (click)=\"onChatImageClick()\"\n (dblclick)=\"onChatImageDblClick()\"\n >\n <div class=\"rts-messenger-chat-image rts-messenger-header-avatar-image\"\n [style.background-image]=\"'url(' + chatImageUrl + ')'\"\n ></div>\n </div>\n } @else {\n <div class=\"rts-messenger-header-actions\">\n <button class=\"rts-messenger-header-add-button\"\n (click)=\"toggleDropdown()\"\n >\n <span class=\"material-icons-outlined\">add</span>\n </button>\n\n @if (isDropdownOpen) {\n <div class=\"rts-messenger-header-dropdown-backdrop\"\n (click)=\"closeDropdown()\"\n ></div>\n <div class=\"rts-messenger-header-dropdown\">\n <button class=\"rts-messenger-header-dropdown-item\"\n (click)=\"openInviteUserDialog()\"\n >\n <span class=\"material-icons-outlined rts-messenger-header-dropdown-icon\">person_add</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_BUTTON] }}</span>\n </button>\n <button class=\"rts-messenger-header-dropdown-item\"\n (click)=\"openNewChatDialog()\"\n >\n <span class=\"material-icons-outlined rts-messenger-header-dropdown-icon\">chat_bubble_outline</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_NEW_CHAT_BUTTON] }}</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"rts-messenger-header-center\">\n @if (messenger.manageChatInfo) {\n <div class=\"rts-messenger-header-create-chat-container\">\n <rtsee-manage-chat-info [messenger]=\"messenger\"\n [chat]=\"messenger.manageChatInfo.chat || undefined\"\n (chatSaved)=\"onChatSaved($event)\"\n (cancelled)=\"closeManageChatDialog()\"\n ></rtsee-manage-chat-info>\n </div>\n } @else if (messenger.inviteUserOpened) {\n <div class=\"rts-messenger-header-create-chat-container rts-messenger-header-invite-user-container\">\n <div class=\"rts-create-chat\">\n <h3 class=\"rts-create-chat-title\">{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_BUTTON] }}</h3>\n <rtsee-invite-link [messenger]=\"messenger\"\n [disclaimer]=\"messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_DISCLAIMER]\"\n ></rtsee-invite-link>\n </div>\n </div>\n } @else if (messenger.openedChat) {\n <div [ngClass]=\"{'rts-messenger-header-opened-chat-info-expanded': messenger.openedProfile || messenger.openedChatDetails}\"\n class=\"rts-messenger-header-opened-chat-info\">\n <div class=\"rts-messenger-profile-header-placeholder\">\n <p class=\"rts-messenger-header-chat-title\"\n >{{ headerTitle }}</p>\n </div>\n\n <div class=\"rts-messenger-profile-data-container\">\n @if (messenger.openedChatDetails && isGroupOrChannelChat && messenger.chatInfo) {\n <rtsee-chat-info [messenger]=\"messenger\"\n [chatInfo]=\"messenger.chatInfo\"\n (editChatInfo)=\"messenger.openManageChatInfo(messenger.openedChat)\"\n (chatDeleted)=\"messenger.closeChatInfo()\"\n ></rtsee-chat-info>\n } @else if (messenger.openedChatDetails || messenger.openedProfile) {\n <rtsee-profile [messenger]=\"messenger\"\n ></rtsee-profile>\n }\n </div>\n </div>\n } @else {\n @if (messenger.ownProfileOpened) {\n <div class=\"rts-messenger-header-opened-chat-info rts-messenger-header-opened-chat-info-expanded\">\n <div class=\"rts-messenger-profile-header-placeholder\">\n <p class=\"rts-messenger-header-chat-title\">{{ headerTitle }}</p>\n </div>\n <div class=\"rts-messenger-profile-data-container\">\n <rtsee-profile [messenger]=\"messenger\"\n [peer]=\"messenger.myPeer\"\n ></rtsee-profile>\n </div>\n </div>\n } @else {\n <p class=\"rts-messenger-header-title\"\n >{{messenger.labels[RTSeeTextLabelKeys.MESSANGER_TITLE]}}</p>\n <rtsee-profile [messenger]=\"messenger\"\n [peer]=\"messenger.myPeer\"\n ></rtsee-profile>\n }\n }\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ProfileComponent, selector: "rtsee-profile", inputs: ["messenger", "peer"] }, { kind: "component", type: ChatInfoComponent, selector: "rtsee-chat-info", inputs: ["messenger", "chatInfo"], outputs: ["editChatInfo", "chatDeleted"] }, { kind: "component", type: ManageChatInfoComponent, selector: "rtsee-manage-chat-info", inputs: ["messenger", "chat"], outputs: ["chatSaved", "cancelled"] }, { kind: "component", type: InviteLinkComponent, selector: "rtsee-invite-link", inputs: ["inviteUrl", "chatId", "messenger", "disclaimer"] }] }); }
|
|
1725
1811
|
}
|
|
1726
1812
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessengerHeaderComponent, decorators: [{
|
|
1727
1813
|
type: Component,
|
|
1728
|
-
args: [{ selector: 'rtsee-messenger-header', imports: [NgClass, ProfileComponent, ChatInfoComponent, ManageChatInfoComponent], standalone: true, template: "<div class=\"rts-messenger-header\"\n [ngClass]=\"{\n 'rts-messenger-header-chat-opened': messenger.openedChat && !messenger.manageChatInfo,\n 'rts-chat-header-unread': messenger.openedChat && !messenger.unreadMessagesCount,\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo,\n 'rts-messenger-header-create-chat-mode': messenger.manageChatInfo,\n 'rts-messenger-header-my-profile-mode': messenger.ownProfileOpened,\n 'rts-messenger-header-chat-info-mode': (messenger.openedProfile || messenger.openedChatDetails) && !messenger.ownProfileOpened && !messenger.manageChatInfo,\n 'rts-messenger-header-chat-image-expanded': imageExpandedToSquare,\n 'rts-messenger-header-image-square': imageExpandedToSquare\n }\"\n>\n <span class=\"rts-messenger-header-collapse-button\"\n (click)=\"messenger.manageChatInfo ? closeManageChatDialog() : collapseInfo()\"\n >\n <span class=\"pi pi-arrow-left\"></span>\n </span>\n <div class=\"rts-messenger-header-left\">\n @if (!messenger.openedChat && messenger.myPeer) {\n <div class=\"rts-messenger-header-avatar\"\n (click)=\"onMyAvatarClick()\"\n (dblclick)=\"onMyAvatarDblClick()\"\n >\n <div [style.background-image]=\"'url(' + myProfileImageUrl + ')'\"\n class=\"rts-messenger-header-avatar-image\">\n </div>\n </div>\n } @else if (messenger.openedChat) {\n <button class=\"rts-messenger-close-chat\"\n (click)=\"messenger.closeChat()\"\n >\n <span class=\"material-icons-outlined\">arrow_back</span>\n @if (messenger.unreadMessagesCount) {\n <span class=\"unread-count\">{{messenger.unreadMessagesCount}}</span>\n }\n </button>\n }\n </div>\n <div class=\"rts-messenger-header-right\">\n @if (messenger.openedChat) {\n <div class=\"rts-messenger-chat-image-container rts-messenger-header-avatar\"\n (click)=\"onChatImageClick()\"\n (dblclick)=\"onChatImageDblClick()\"\n >\n <div class=\"rts-messenger-chat-image rts-messenger-header-avatar-image\"\n [style.background-image]=\"'url(' + chatImageUrl + ')'\"\n ></div>\n </div>\n } @else {\n <div class=\"rts-messenger-header-actions\">\n <button class=\"rts-messenger-header-add-button\"\n (click)=\"toggleDropdown()\"\n >\n <span class=\"material-icons-outlined\">add</span>\n </button>\n\n @if (isDropdownOpen) {\n <div class=\"rts-messenger-header-dropdown-backdrop\"\n (click)=\"closeDropdown()\"\n ></div>\n <div class=\"rts-messenger-header-dropdown\">\n <button class=\"rts-messenger-header-dropdown-item\"\n (click)=\"openNewChatDialog()\"\n >\n <span class=\"material-icons-outlined rts-messenger-header-dropdown-icon\">chat_bubble_outline</span>\n <span>
|
|
1814
|
+
args: [{ selector: 'rtsee-messenger-header', imports: [NgClass, ProfileComponent, ChatInfoComponent, ManageChatInfoComponent, InviteLinkComponent], standalone: true, template: "<div class=\"rts-messenger-header\"\n [ngClass]=\"{\n 'rts-messenger-header-chat-opened': messenger.openedChat && !messenger.manageChatInfo && !messenger.inviteUserOpened,\n 'rts-chat-header-unread': messenger.openedChat && !messenger.unreadMessagesCount,\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo || messenger.inviteUserOpened,\n 'rts-messenger-header-create-chat-mode': messenger.manageChatInfo || messenger.inviteUserOpened,\n 'rts-messenger-header-my-profile-mode': messenger.ownProfileOpened,\n 'rts-messenger-header-chat-info-mode': (messenger.openedProfile || messenger.openedChatDetails) && !messenger.ownProfileOpened && !messenger.manageChatInfo && !messenger.inviteUserOpened,\n 'rts-messenger-header-chat-image-expanded': imageExpandedToSquare,\n 'rts-messenger-header-image-square': imageExpandedToSquare\n }\"\n>\n <span class=\"rts-messenger-header-collapse-button\"\n (click)=\"messenger.manageChatInfo ? closeManageChatDialog() : (messenger.inviteUserOpened ? closeInviteUserDialog() : collapseInfo())\"\n >\n <span class=\"pi pi-arrow-left\"></span>\n </span>\n <div class=\"rts-messenger-header-left\">\n @if (!messenger.openedChat && messenger.myPeer) {\n <div class=\"rts-messenger-header-avatar\"\n (click)=\"onMyAvatarClick()\"\n (dblclick)=\"onMyAvatarDblClick()\"\n >\n <div [style.background-image]=\"'url(' + myProfileImageUrl + ')'\"\n class=\"rts-messenger-header-avatar-image\">\n </div>\n </div>\n } @else if (messenger.openedChat) {\n <button class=\"rts-messenger-close-chat\"\n (click)=\"messenger.closeChat()\"\n >\n <span class=\"material-icons-outlined\">arrow_back</span>\n @if (messenger.unreadMessagesCount) {\n <span class=\"unread-count\">{{messenger.unreadMessagesCount}}</span>\n }\n </button>\n }\n </div>\n <div class=\"rts-messenger-header-right\">\n @if (messenger.openedChat) {\n <div class=\"rts-messenger-chat-image-container rts-messenger-header-avatar\"\n (click)=\"onChatImageClick()\"\n (dblclick)=\"onChatImageDblClick()\"\n >\n <div class=\"rts-messenger-chat-image rts-messenger-header-avatar-image\"\n [style.background-image]=\"'url(' + chatImageUrl + ')'\"\n ></div>\n </div>\n } @else {\n <div class=\"rts-messenger-header-actions\">\n <button class=\"rts-messenger-header-add-button\"\n (click)=\"toggleDropdown()\"\n >\n <span class=\"material-icons-outlined\">add</span>\n </button>\n\n @if (isDropdownOpen) {\n <div class=\"rts-messenger-header-dropdown-backdrop\"\n (click)=\"closeDropdown()\"\n ></div>\n <div class=\"rts-messenger-header-dropdown\">\n <button class=\"rts-messenger-header-dropdown-item\"\n (click)=\"openInviteUserDialog()\"\n >\n <span class=\"material-icons-outlined rts-messenger-header-dropdown-icon\">person_add</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_BUTTON] }}</span>\n </button>\n <button class=\"rts-messenger-header-dropdown-item\"\n (click)=\"openNewChatDialog()\"\n >\n <span class=\"material-icons-outlined rts-messenger-header-dropdown-icon\">chat_bubble_outline</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_NEW_CHAT_BUTTON] }}</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n <div class=\"rts-messenger-header-center\">\n @if (messenger.manageChatInfo) {\n <div class=\"rts-messenger-header-create-chat-container\">\n <rtsee-manage-chat-info [messenger]=\"messenger\"\n [chat]=\"messenger.manageChatInfo.chat || undefined\"\n (chatSaved)=\"onChatSaved($event)\"\n (cancelled)=\"closeManageChatDialog()\"\n ></rtsee-manage-chat-info>\n </div>\n } @else if (messenger.inviteUserOpened) {\n <div class=\"rts-messenger-header-create-chat-container rts-messenger-header-invite-user-container\">\n <div class=\"rts-create-chat\">\n <h3 class=\"rts-create-chat-title\">{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_BUTTON] }}</h3>\n <rtsee-invite-link [messenger]=\"messenger\"\n [disclaimer]=\"messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_DISCLAIMER]\"\n ></rtsee-invite-link>\n </div>\n </div>\n } @else if (messenger.openedChat) {\n <div [ngClass]=\"{'rts-messenger-header-opened-chat-info-expanded': messenger.openedProfile || messenger.openedChatDetails}\"\n class=\"rts-messenger-header-opened-chat-info\">\n <div class=\"rts-messenger-profile-header-placeholder\">\n <p class=\"rts-messenger-header-chat-title\"\n >{{ headerTitle }}</p>\n </div>\n\n <div class=\"rts-messenger-profile-data-container\">\n @if (messenger.openedChatDetails && isGroupOrChannelChat && messenger.chatInfo) {\n <rtsee-chat-info [messenger]=\"messenger\"\n [chatInfo]=\"messenger.chatInfo\"\n (editChatInfo)=\"messenger.openManageChatInfo(messenger.openedChat)\"\n (chatDeleted)=\"messenger.closeChatInfo()\"\n ></rtsee-chat-info>\n } @else if (messenger.openedChatDetails || messenger.openedProfile) {\n <rtsee-profile [messenger]=\"messenger\"\n ></rtsee-profile>\n }\n </div>\n </div>\n } @else {\n @if (messenger.ownProfileOpened) {\n <div class=\"rts-messenger-header-opened-chat-info rts-messenger-header-opened-chat-info-expanded\">\n <div class=\"rts-messenger-profile-header-placeholder\">\n <p class=\"rts-messenger-header-chat-title\">{{ headerTitle }}</p>\n </div>\n <div class=\"rts-messenger-profile-data-container\">\n <rtsee-profile [messenger]=\"messenger\"\n [peer]=\"messenger.myPeer\"\n ></rtsee-profile>\n </div>\n </div>\n } @else {\n <p class=\"rts-messenger-header-title\"\n >{{messenger.labels[RTSeeTextLabelKeys.MESSANGER_TITLE]}}</p>\n <rtsee-profile [messenger]=\"messenger\"\n [peer]=\"messenger.myPeer\"\n ></rtsee-profile>\n }\n }\n </div>\n</div>\n" }]
|
|
1729
1815
|
}], ctorParameters: () => [{ type: DefaultImagesService }], propDecorators: { messenger: [{
|
|
1730
1816
|
type: Input
|
|
1731
1817
|
}] } });
|
|
@@ -1885,15 +1971,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
1885
1971
|
}] } });
|
|
1886
1972
|
|
|
1887
1973
|
class ChatsListComponent {
|
|
1974
|
+
constructor() {
|
|
1975
|
+
this.RTSeeTextLabelKeys = RTSeeTextLabelKeys;
|
|
1976
|
+
}
|
|
1888
1977
|
ngOnInit() {
|
|
1889
1978
|
// console.log(this.chats);
|
|
1890
1979
|
}
|
|
1980
|
+
onInviteUserClick() {
|
|
1981
|
+
this.messenger.openInviteUser();
|
|
1982
|
+
}
|
|
1983
|
+
onCreateGroupClick() {
|
|
1984
|
+
this.messenger.openManageChatInfo();
|
|
1985
|
+
}
|
|
1891
1986
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1892
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1987
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChatsListComponent, isStandalone: true, selector: "rtsee-chats-list", inputs: { messenger: "messenger", chats: "chats" }, ngImport: i0, template: "<div class=\"rts-chats-list\">\n @if (chats && chats.length) {\n <div class=\"rts-chat-thumbnail-container\" *ngFor=\"let chat of chats; let last = last;\">\n <rtsee-chat-thumbnail [chat]=\"chat.thumbnail\" [messenger]=\"messenger\"></rtsee-chat-thumbnail>\n </div>\n } @else if (!messenger.loadingChatsInProgress) {\n <div class=\"rts-chats-list-empty\">\n <span class=\"material-icons-outlined rts-chats-list-empty-icon\">forum</span>\n <p class=\"rts-chats-list-empty-disclaimer\">\n {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_NO_CHATS_DISCLAIMER] }}\n </p>\n <div class=\"rts-chats-list-empty-actions\">\n <button type=\"button\"\n class=\"rts-btn rts-btn-primary rts-chats-list-empty-btn\"\n (click)=\"onInviteUserClick()\"\n >\n <span class=\"material-icons-outlined\">person_add</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_BUTTON] }}</span>\n </button>\n <button type=\"button\"\n class=\"rts-btn rts-btn-secondary rts-chats-list-empty-btn\"\n (click)=\"onCreateGroupClick()\"\n >\n <span class=\"material-icons-outlined\">group_add</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_CREATE_GROUP_BUTTON] }}</span>\n </button>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ChatThumbnailComponent, selector: "rtsee-chat-thumbnail", inputs: ["chat", "messenger"] }] }); }
|
|
1893
1988
|
}
|
|
1894
1989
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatsListComponent, decorators: [{
|
|
1895
1990
|
type: Component,
|
|
1896
|
-
args: [{ selector: 'rtsee-chats-list', imports: [NgForOf, ChatThumbnailComponent], standalone: true, template: "<div class=\"rts-chats-list\">\n <div class=\"rts-chat-thumbnail-container\" *ngFor=\"let chat of chats; let last = last;\">\n
|
|
1991
|
+
args: [{ selector: 'rtsee-chats-list', imports: [NgForOf, ChatThumbnailComponent], standalone: true, template: "<div class=\"rts-chats-list\">\n @if (chats && chats.length) {\n <div class=\"rts-chat-thumbnail-container\" *ngFor=\"let chat of chats; let last = last;\">\n <rtsee-chat-thumbnail [chat]=\"chat.thumbnail\" [messenger]=\"messenger\"></rtsee-chat-thumbnail>\n </div>\n } @else if (!messenger.loadingChatsInProgress) {\n <div class=\"rts-chats-list-empty\">\n <span class=\"material-icons-outlined rts-chats-list-empty-icon\">forum</span>\n <p class=\"rts-chats-list-empty-disclaimer\">\n {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_NO_CHATS_DISCLAIMER] }}\n </p>\n <div class=\"rts-chats-list-empty-actions\">\n <button type=\"button\"\n class=\"rts-btn rts-btn-primary rts-chats-list-empty-btn\"\n (click)=\"onInviteUserClick()\"\n >\n <span class=\"material-icons-outlined\">person_add</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_USER_BUTTON] }}</span>\n </button>\n <button type=\"button\"\n class=\"rts-btn rts-btn-secondary rts-chats-list-empty-btn\"\n (click)=\"onCreateGroupClick()\"\n >\n <span class=\"material-icons-outlined\">group_add</span>\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_CREATE_GROUP_BUTTON] }}</span>\n </button>\n </div>\n </div>\n }\n</div>\n" }]
|
|
1897
1992
|
}], propDecorators: { messenger: [{
|
|
1898
1993
|
type: Input
|
|
1899
1994
|
}], chats: [{
|
|
@@ -1961,11 +2056,11 @@ class RatingComponent {
|
|
|
1961
2056
|
this.init();
|
|
1962
2057
|
}
|
|
1963
2058
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RatingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1964
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RatingComponent, isStandalone: true, selector: "rtsee-rating", inputs: { config: "config", rate: "rate" }, ngImport: i0, template: "<div\n class=\"rtsee-rating\"\n data-ugc=\"true\"\n rel=\"ugc\"\n itemprop=\"reviewRating\"\n itemscope\n itemtype=\"https://schema.org/Rating\"\n>\n <meta itemprop=\"bestRating\" content=\"5\" />\n
|
|
2059
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RatingComponent, isStandalone: true, selector: "rtsee-rating", inputs: { config: "config", rate: "rate" }, ngImport: i0, template: "<div\n class=\"rtsee-rating\"\n data-ugc=\"true\"\n rel=\"ugc\"\n [attr.itemprop]=\"!mutable ? 'reviewRating' : null\"\n [attr.itemscope]=\"!mutable ? '' : null\"\n [attr.itemtype]=\"!mutable ? 'https://schema.org/Rating' : null\"\n>\n @if (!mutable) {\n <meta itemprop=\"bestRating\" content=\"5\" />\n <meta itemprop=\"worstRating\" content=\"1\" />\n }\n @for (star of stars; track $index) {\n <span class=\"rtsee-rating-star\"\n [ngClass]=\"{\n 'rtsee-rating-star-full': star === 'full',\n 'rtsee-rating-star-half': star === 'half',\n 'rtsee-rating-star-empty': star === 'empty',\n 'rtsee-rating-star-clickable': mutable\n }\"\n (click)=\"onStarClicked($index)\"\n >\u2605</span>\n }\n @if (rateValue) {\n <span class=\"rtsee-rating-number\" [attr.itemprop]=\"!mutable ? 'ratingValue' : null\">{{ rateValue | number:'1.1-1' }}</span>\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: DecimalPipe, name: "number" }] }); }
|
|
1965
2060
|
}
|
|
1966
2061
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RatingComponent, decorators: [{
|
|
1967
2062
|
type: Component,
|
|
1968
|
-
args: [{ selector: 'rtsee-rating', imports: [NgClass, DecimalPipe], template: "<div\n class=\"rtsee-rating\"\n data-ugc=\"true\"\n rel=\"ugc\"\n itemprop=\"reviewRating\"\n itemscope\n itemtype=\"https://schema.org/Rating\"\n>\n <meta itemprop=\"bestRating\" content=\"5\" />\n
|
|
2063
|
+
args: [{ selector: 'rtsee-rating', imports: [NgClass, DecimalPipe], template: "<div\n class=\"rtsee-rating\"\n data-ugc=\"true\"\n rel=\"ugc\"\n [attr.itemprop]=\"!mutable ? 'reviewRating' : null\"\n [attr.itemscope]=\"!mutable ? '' : null\"\n [attr.itemtype]=\"!mutable ? 'https://schema.org/Rating' : null\"\n>\n @if (!mutable) {\n <meta itemprop=\"bestRating\" content=\"5\" />\n <meta itemprop=\"worstRating\" content=\"1\" />\n }\n @for (star of stars; track $index) {\n <span class=\"rtsee-rating-star\"\n [ngClass]=\"{\n 'rtsee-rating-star-full': star === 'full',\n 'rtsee-rating-star-half': star === 'half',\n 'rtsee-rating-star-empty': star === 'empty',\n 'rtsee-rating-star-clickable': mutable\n }\"\n (click)=\"onStarClicked($index)\"\n >\u2605</span>\n }\n @if (rateValue) {\n <span class=\"rtsee-rating-number\" [attr.itemprop]=\"!mutable ? 'ratingValue' : null\">{{ rateValue | number:'1.1-1' }}</span>\n }\n</div>\n" }]
|
|
1969
2064
|
}], propDecorators: { config: [{
|
|
1970
2065
|
type: Input
|
|
1971
2066
|
}], rate: [{
|
|
@@ -2444,6 +2539,808 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2444
2539
|
type: Input
|
|
2445
2540
|
}] } });
|
|
2446
2541
|
|
|
2542
|
+
/**
|
|
2543
|
+
* Full client-side representation of a single OzzyTaskAction.
|
|
2544
|
+
* Displays input, logs, output, and/or errors of the action.
|
|
2545
|
+
*/
|
|
2546
|
+
class RTSeeTaskActionComponent {
|
|
2547
|
+
constructor(cdr) {
|
|
2548
|
+
this.cdr = cdr;
|
|
2549
|
+
this.copied = null;
|
|
2550
|
+
this.subscribedAction = null;
|
|
2551
|
+
this.onChangedBound = () => this.onActionChanged();
|
|
2552
|
+
}
|
|
2553
|
+
ngOnInit() {
|
|
2554
|
+
this.subscribe();
|
|
2555
|
+
this.ensureLoaded();
|
|
2556
|
+
}
|
|
2557
|
+
ngOnChanges(changes) {
|
|
2558
|
+
if (changes['action'] && !changes['action'].firstChange) {
|
|
2559
|
+
this.subscribe();
|
|
2560
|
+
this.ensureLoaded();
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
ngOnDestroy() {
|
|
2564
|
+
this.unsubscribe();
|
|
2565
|
+
}
|
|
2566
|
+
get statusLabel() {
|
|
2567
|
+
switch (this.action?.status) {
|
|
2568
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2569
|
+
return 'Running';
|
|
2570
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2571
|
+
return 'Completed';
|
|
2572
|
+
case OzzyTaskStatus.FAIL:
|
|
2573
|
+
return 'Failed';
|
|
2574
|
+
default:
|
|
2575
|
+
return 'Ready';
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
get statusClass() {
|
|
2579
|
+
switch (this.action?.status) {
|
|
2580
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2581
|
+
return 'rts-task-action-status-running';
|
|
2582
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2583
|
+
return 'rts-task-action-status-success';
|
|
2584
|
+
case OzzyTaskStatus.FAIL:
|
|
2585
|
+
return 'rts-task-action-status-fail';
|
|
2586
|
+
default:
|
|
2587
|
+
return 'rts-task-action-status-ready';
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
get inputJson() {
|
|
2591
|
+
return this.toJson(this.action?.input);
|
|
2592
|
+
}
|
|
2593
|
+
get outputJson() {
|
|
2594
|
+
return this.toJson(this.action?.output);
|
|
2595
|
+
}
|
|
2596
|
+
get hasOutput() {
|
|
2597
|
+
return this.action?.output !== undefined && this.action?.output !== null;
|
|
2598
|
+
}
|
|
2599
|
+
get hasLogs() {
|
|
2600
|
+
return !!(this.action?.logs?.length || this.action?.liveText);
|
|
2601
|
+
}
|
|
2602
|
+
async copy(kind) {
|
|
2603
|
+
try {
|
|
2604
|
+
await navigator.clipboard.writeText(kind === 'input' ? this.inputJson : this.outputJson);
|
|
2605
|
+
this.copied = kind;
|
|
2606
|
+
this.cdr.detectChanges();
|
|
2607
|
+
setTimeout(() => {
|
|
2608
|
+
this.copied = null;
|
|
2609
|
+
this.cdr.detectChanges();
|
|
2610
|
+
}, 1500);
|
|
2611
|
+
}
|
|
2612
|
+
catch (e) {
|
|
2613
|
+
console.log('Failed to copy', e);
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
trackLog(index, log) {
|
|
2617
|
+
return `${index}-${log.level}`;
|
|
2618
|
+
}
|
|
2619
|
+
ensureLoaded() {
|
|
2620
|
+
if (this.action && !this.action.loaded && !this.action.isRunning) {
|
|
2621
|
+
void this.action.load();
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
toJson(value) {
|
|
2625
|
+
if (value === undefined || value === null) {
|
|
2626
|
+
return '';
|
|
2627
|
+
}
|
|
2628
|
+
try {
|
|
2629
|
+
return JSON.stringify(value, null, 2);
|
|
2630
|
+
}
|
|
2631
|
+
catch {
|
|
2632
|
+
return String(value);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
subscribe() {
|
|
2636
|
+
if (this.subscribedAction === this.action) {
|
|
2637
|
+
return;
|
|
2638
|
+
}
|
|
2639
|
+
this.unsubscribe();
|
|
2640
|
+
if (this.action) {
|
|
2641
|
+
this.subscribedAction = this.action;
|
|
2642
|
+
this.action.on(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
unsubscribe() {
|
|
2646
|
+
this.subscribedAction?.off(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
2647
|
+
this.subscribedAction = null;
|
|
2648
|
+
}
|
|
2649
|
+
onActionChanged() {
|
|
2650
|
+
this.cdr.detectChanges();
|
|
2651
|
+
const el = this.logsContainer?.nativeElement;
|
|
2652
|
+
if (el) {
|
|
2653
|
+
el.scrollTop = el.scrollHeight;
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
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 }); }
|
|
2657
|
+
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" }] }); }
|
|
2658
|
+
}
|
|
2659
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeTaskActionComponent, decorators: [{
|
|
2660
|
+
type: Component,
|
|
2661
|
+
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"] }]
|
|
2662
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { action: [{
|
|
2663
|
+
type: Input
|
|
2664
|
+
}], logsContainer: [{
|
|
2665
|
+
type: ViewChild,
|
|
2666
|
+
args: ['logsContainer']
|
|
2667
|
+
}] } });
|
|
2668
|
+
|
|
2669
|
+
class DefaultTaskActionThumbnailComponent {
|
|
2670
|
+
constructor() {
|
|
2671
|
+
this.expanded = false;
|
|
2672
|
+
}
|
|
2673
|
+
get statusClass() {
|
|
2674
|
+
switch (this.action?.status) {
|
|
2675
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2676
|
+
return 'rts-action-thumb-status-success';
|
|
2677
|
+
case OzzyTaskStatus.FAIL:
|
|
2678
|
+
return 'rts-action-thumb-status-fail';
|
|
2679
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2680
|
+
return 'rts-action-thumb-status-running';
|
|
2681
|
+
default:
|
|
2682
|
+
return 'rts-action-thumb-status-ready';
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
onToggle() {
|
|
2686
|
+
this.toggleExpand?.();
|
|
2687
|
+
}
|
|
2688
|
+
onButtonClick(event) {
|
|
2689
|
+
event.stopPropagation();
|
|
2690
|
+
this.toggleExpand?.();
|
|
2691
|
+
}
|
|
2692
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionThumbnailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2693
|
+
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: `
|
|
2694
|
+
<div class="rts-action-thumb-default" [ngClass]="statusClass" (click)="onToggle()">
|
|
2695
|
+
<div class="rts-action-thumb-left">
|
|
2696
|
+
<span class="rts-action-thumb-dot"></span>
|
|
2697
|
+
<span class="rts-action-thumb-name" [title]="action?.name || 'Action'">
|
|
2698
|
+
{{ action?.name || 'Action' }}
|
|
2699
|
+
</span>
|
|
2700
|
+
</div>
|
|
2701
|
+
<button type="button"
|
|
2702
|
+
class="rts-action-thumb-expand"
|
|
2703
|
+
(click)="onButtonClick($event)"
|
|
2704
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2705
|
+
>
|
|
2706
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2707
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2708
|
+
</button>
|
|
2709
|
+
</div>
|
|
2710
|
+
`, 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"] }] }); }
|
|
2711
|
+
}
|
|
2712
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionThumbnailComponent, decorators: [{
|
|
2713
|
+
type: Component,
|
|
2714
|
+
args: [{ selector: 'rtsee-default-task-action-thumbnail', standalone: true, imports: [NgClass], template: `
|
|
2715
|
+
<div class="rts-action-thumb-default" [ngClass]="statusClass" (click)="onToggle()">
|
|
2716
|
+
<div class="rts-action-thumb-left">
|
|
2717
|
+
<span class="rts-action-thumb-dot"></span>
|
|
2718
|
+
<span class="rts-action-thumb-name" [title]="action?.name || 'Action'">
|
|
2719
|
+
{{ action?.name || 'Action' }}
|
|
2720
|
+
</span>
|
|
2721
|
+
</div>
|
|
2722
|
+
<button type="button"
|
|
2723
|
+
class="rts-action-thumb-expand"
|
|
2724
|
+
(click)="onButtonClick($event)"
|
|
2725
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2726
|
+
>
|
|
2727
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2728
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2729
|
+
</button>
|
|
2730
|
+
</div>
|
|
2731
|
+
`, 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"] }]
|
|
2732
|
+
}], propDecorators: { action: [{
|
|
2733
|
+
type: Input
|
|
2734
|
+
}], task: [{
|
|
2735
|
+
type: Input
|
|
2736
|
+
}], expanded: [{
|
|
2737
|
+
type: Input
|
|
2738
|
+
}], toggleExpand: [{
|
|
2739
|
+
type: Input
|
|
2740
|
+
}] } });
|
|
2741
|
+
|
|
2742
|
+
/**
|
|
2743
|
+
* Custom task-action thumbnail widget for Story creation / update actions.
|
|
2744
|
+
* Displays story-name, recommendedAge, friendlyUrl, and 2-line truncated
|
|
2745
|
+
* description, moralMeaning, and history with full text tooltip on hover.
|
|
2746
|
+
*/
|
|
2747
|
+
class StoryTaskActionThumbnailComponent {
|
|
2748
|
+
constructor() {
|
|
2749
|
+
this.expanded = false;
|
|
2750
|
+
}
|
|
2751
|
+
get storyData() {
|
|
2752
|
+
return {
|
|
2753
|
+
...(this.action?.input || {}),
|
|
2754
|
+
...(this.action?.output || {}),
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2757
|
+
get storyName() {
|
|
2758
|
+
return this.storyData.name || this.action?.name || 'Story';
|
|
2759
|
+
}
|
|
2760
|
+
get recommendedAge() {
|
|
2761
|
+
return this.storyData.recommendedAge || '';
|
|
2762
|
+
}
|
|
2763
|
+
get friendlyUrl() {
|
|
2764
|
+
return this.storyData.friendlyUrl || '';
|
|
2765
|
+
}
|
|
2766
|
+
get description() {
|
|
2767
|
+
return this.storyData.description || '';
|
|
2768
|
+
}
|
|
2769
|
+
get moralMeaning() {
|
|
2770
|
+
return this.storyData.moralMeaning || '';
|
|
2771
|
+
}
|
|
2772
|
+
get history() {
|
|
2773
|
+
return this.storyData.history || '';
|
|
2774
|
+
}
|
|
2775
|
+
get statusClass() {
|
|
2776
|
+
switch (this.action?.status) {
|
|
2777
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2778
|
+
return 'rts-story-thumb-status-success';
|
|
2779
|
+
case OzzyTaskStatus.FAIL:
|
|
2780
|
+
return 'rts-story-thumb-status-fail';
|
|
2781
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2782
|
+
return 'rts-story-thumb-status-running';
|
|
2783
|
+
default:
|
|
2784
|
+
return 'rts-story-thumb-status-ready';
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
onToggle() {
|
|
2788
|
+
this.toggleExpand?.();
|
|
2789
|
+
}
|
|
2790
|
+
onButtonClick(event) {
|
|
2791
|
+
event.stopPropagation();
|
|
2792
|
+
this.toggleExpand?.();
|
|
2793
|
+
}
|
|
2794
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryTaskActionThumbnailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2795
|
+
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: `
|
|
2796
|
+
<div class="rts-story-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2797
|
+
<div class="rts-story-thumb-header">
|
|
2798
|
+
<div class="rts-story-thumb-title-wrap">
|
|
2799
|
+
<span class="rts-story-thumb-dot"></span>
|
|
2800
|
+
<span class="rts-story-thumb-badge">Story</span>
|
|
2801
|
+
<span class="rts-story-thumb-name" [title]="storyName">{{ storyName }}</span>
|
|
2802
|
+
@if (recommendedAge) {
|
|
2803
|
+
<span class="rts-story-thumb-age" [title]="'Recommended age: ' + recommendedAge">
|
|
2804
|
+
{{ recommendedAge }}
|
|
2805
|
+
</span>
|
|
2806
|
+
}
|
|
2807
|
+
@if (friendlyUrl) {
|
|
2808
|
+
<span class="rts-story-thumb-url" [title]="friendlyUrl">/{{ friendlyUrl }}</span>
|
|
2809
|
+
}
|
|
2810
|
+
</div>
|
|
2811
|
+
<button type="button"
|
|
2812
|
+
class="rts-story-thumb-expand"
|
|
2813
|
+
(click)="onButtonClick($event)"
|
|
2814
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2815
|
+
>
|
|
2816
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2817
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2818
|
+
</button>
|
|
2819
|
+
</div>
|
|
2820
|
+
|
|
2821
|
+
@if (description || moralMeaning || history) {
|
|
2822
|
+
<div class="rts-story-thumb-fields">
|
|
2823
|
+
@if (description) {
|
|
2824
|
+
<div class="rts-story-thumb-field">
|
|
2825
|
+
<span class="rts-story-thumb-field-label">Description</span>
|
|
2826
|
+
<p class="rts-story-thumb-truncated" [title]="description">{{ description }}</p>
|
|
2827
|
+
</div>
|
|
2828
|
+
}
|
|
2829
|
+
@if (moralMeaning) {
|
|
2830
|
+
<div class="rts-story-thumb-field">
|
|
2831
|
+
<span class="rts-story-thumb-field-label">Moral Meaning</span>
|
|
2832
|
+
<p class="rts-story-thumb-truncated" [title]="moralMeaning">{{ moralMeaning }}</p>
|
|
2833
|
+
</div>
|
|
2834
|
+
}
|
|
2835
|
+
@if (history) {
|
|
2836
|
+
<div class="rts-story-thumb-field">
|
|
2837
|
+
<span class="rts-story-thumb-field-label">History</span>
|
|
2838
|
+
<p class="rts-story-thumb-truncated" [title]="history">{{ history }}</p>
|
|
2839
|
+
</div>
|
|
2840
|
+
}
|
|
2841
|
+
</div>
|
|
2842
|
+
}
|
|
2843
|
+
</div>
|
|
2844
|
+
`, 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"] }] }); }
|
|
2845
|
+
}
|
|
2846
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryTaskActionThumbnailComponent, decorators: [{
|
|
2847
|
+
type: Component,
|
|
2848
|
+
args: [{ selector: 'rtsee-story-task-action-thumbnail', standalone: true, imports: [NgClass], template: `
|
|
2849
|
+
<div class="rts-story-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2850
|
+
<div class="rts-story-thumb-header">
|
|
2851
|
+
<div class="rts-story-thumb-title-wrap">
|
|
2852
|
+
<span class="rts-story-thumb-dot"></span>
|
|
2853
|
+
<span class="rts-story-thumb-badge">Story</span>
|
|
2854
|
+
<span class="rts-story-thumb-name" [title]="storyName">{{ storyName }}</span>
|
|
2855
|
+
@if (recommendedAge) {
|
|
2856
|
+
<span class="rts-story-thumb-age" [title]="'Recommended age: ' + recommendedAge">
|
|
2857
|
+
{{ recommendedAge }}
|
|
2858
|
+
</span>
|
|
2859
|
+
}
|
|
2860
|
+
@if (friendlyUrl) {
|
|
2861
|
+
<span class="rts-story-thumb-url" [title]="friendlyUrl">/{{ friendlyUrl }}</span>
|
|
2862
|
+
}
|
|
2863
|
+
</div>
|
|
2864
|
+
<button type="button"
|
|
2865
|
+
class="rts-story-thumb-expand"
|
|
2866
|
+
(click)="onButtonClick($event)"
|
|
2867
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2868
|
+
>
|
|
2869
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2870
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2871
|
+
</button>
|
|
2872
|
+
</div>
|
|
2873
|
+
|
|
2874
|
+
@if (description || moralMeaning || history) {
|
|
2875
|
+
<div class="rts-story-thumb-fields">
|
|
2876
|
+
@if (description) {
|
|
2877
|
+
<div class="rts-story-thumb-field">
|
|
2878
|
+
<span class="rts-story-thumb-field-label">Description</span>
|
|
2879
|
+
<p class="rts-story-thumb-truncated" [title]="description">{{ description }}</p>
|
|
2880
|
+
</div>
|
|
2881
|
+
}
|
|
2882
|
+
@if (moralMeaning) {
|
|
2883
|
+
<div class="rts-story-thumb-field">
|
|
2884
|
+
<span class="rts-story-thumb-field-label">Moral Meaning</span>
|
|
2885
|
+
<p class="rts-story-thumb-truncated" [title]="moralMeaning">{{ moralMeaning }}</p>
|
|
2886
|
+
</div>
|
|
2887
|
+
}
|
|
2888
|
+
@if (history) {
|
|
2889
|
+
<div class="rts-story-thumb-field">
|
|
2890
|
+
<span class="rts-story-thumb-field-label">History</span>
|
|
2891
|
+
<p class="rts-story-thumb-truncated" [title]="history">{{ history }}</p>
|
|
2892
|
+
</div>
|
|
2893
|
+
}
|
|
2894
|
+
</div>
|
|
2895
|
+
}
|
|
2896
|
+
</div>
|
|
2897
|
+
`, 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"] }]
|
|
2898
|
+
}], propDecorators: { action: [{
|
|
2899
|
+
type: Input
|
|
2900
|
+
}], task: [{
|
|
2901
|
+
type: Input
|
|
2902
|
+
}], expanded: [{
|
|
2903
|
+
type: Input
|
|
2904
|
+
}], toggleExpand: [{
|
|
2905
|
+
type: Input
|
|
2906
|
+
}] } });
|
|
2907
|
+
|
|
2908
|
+
/**
|
|
2909
|
+
* Custom task-action thumbnail widget for Slide creation / update actions.
|
|
2910
|
+
* Displays slide number and 2 first truncated lines of slide text with full text tooltip on hover.
|
|
2911
|
+
*/
|
|
2912
|
+
class SlideTaskActionThumbnailComponent {
|
|
2913
|
+
constructor() {
|
|
2914
|
+
this.expanded = false;
|
|
2915
|
+
}
|
|
2916
|
+
get slideData() {
|
|
2917
|
+
return {
|
|
2918
|
+
...(this.action?.input || {}),
|
|
2919
|
+
...(this.action?.output || {}),
|
|
2920
|
+
};
|
|
2921
|
+
}
|
|
2922
|
+
get slideNumber() {
|
|
2923
|
+
return this.slideData.slideNumber ?? '-';
|
|
2924
|
+
}
|
|
2925
|
+
get slideText() {
|
|
2926
|
+
return this.slideData.text || '';
|
|
2927
|
+
}
|
|
2928
|
+
get statusClass() {
|
|
2929
|
+
switch (this.action?.status) {
|
|
2930
|
+
case OzzyTaskStatus.SUCCESS:
|
|
2931
|
+
return 'rts-slide-thumb-status-success';
|
|
2932
|
+
case OzzyTaskStatus.FAIL:
|
|
2933
|
+
return 'rts-slide-thumb-status-fail';
|
|
2934
|
+
case OzzyTaskStatus.IN_PROGRESS:
|
|
2935
|
+
return 'rts-slide-thumb-status-running';
|
|
2936
|
+
default:
|
|
2937
|
+
return 'rts-slide-thumb-status-ready';
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
onToggle() {
|
|
2941
|
+
this.toggleExpand?.();
|
|
2942
|
+
}
|
|
2943
|
+
onButtonClick(event) {
|
|
2944
|
+
event.stopPropagation();
|
|
2945
|
+
this.toggleExpand?.();
|
|
2946
|
+
}
|
|
2947
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SlideTaskActionThumbnailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2948
|
+
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: `
|
|
2949
|
+
<div class="rts-slide-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2950
|
+
<div class="rts-slide-thumb-header">
|
|
2951
|
+
<div class="rts-slide-thumb-title-wrap">
|
|
2952
|
+
<span class="rts-slide-thumb-dot"></span>
|
|
2953
|
+
<span class="rts-slide-thumb-number">Slide #{{ slideNumber }}</span>
|
|
2954
|
+
<span class="rts-slide-thumb-action-name">{{ action?.name }}</span>
|
|
2955
|
+
</div>
|
|
2956
|
+
<button type="button"
|
|
2957
|
+
class="rts-slide-thumb-expand"
|
|
2958
|
+
(click)="onButtonClick($event)"
|
|
2959
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2960
|
+
>
|
|
2961
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2962
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2963
|
+
</button>
|
|
2964
|
+
</div>
|
|
2965
|
+
|
|
2966
|
+
@if (slideText) {
|
|
2967
|
+
<p class="rts-slide-thumb-text" [title]="slideText">{{ slideText }}</p>
|
|
2968
|
+
}
|
|
2969
|
+
</div>
|
|
2970
|
+
`, 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"] }] }); }
|
|
2971
|
+
}
|
|
2972
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SlideTaskActionThumbnailComponent, decorators: [{
|
|
2973
|
+
type: Component,
|
|
2974
|
+
args: [{ selector: 'rtsee-slide-task-action-thumbnail', standalone: true, imports: [NgClass], template: `
|
|
2975
|
+
<div class="rts-slide-thumb" [ngClass]="statusClass" (click)="onToggle()">
|
|
2976
|
+
<div class="rts-slide-thumb-header">
|
|
2977
|
+
<div class="rts-slide-thumb-title-wrap">
|
|
2978
|
+
<span class="rts-slide-thumb-dot"></span>
|
|
2979
|
+
<span class="rts-slide-thumb-number">Slide #{{ slideNumber }}</span>
|
|
2980
|
+
<span class="rts-slide-thumb-action-name">{{ action?.name }}</span>
|
|
2981
|
+
</div>
|
|
2982
|
+
<button type="button"
|
|
2983
|
+
class="rts-slide-thumb-expand"
|
|
2984
|
+
(click)="onButtonClick($event)"
|
|
2985
|
+
[title]="expanded ? 'Collapse action details' : 'Expand action details'"
|
|
2986
|
+
>
|
|
2987
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
2988
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
2989
|
+
</button>
|
|
2990
|
+
</div>
|
|
2991
|
+
|
|
2992
|
+
@if (slideText) {
|
|
2993
|
+
<p class="rts-slide-thumb-text" [title]="slideText">{{ slideText }}</p>
|
|
2994
|
+
}
|
|
2995
|
+
</div>
|
|
2996
|
+
`, 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"] }]
|
|
2997
|
+
}], propDecorators: { action: [{
|
|
2998
|
+
type: Input
|
|
2999
|
+
}], task: [{
|
|
3000
|
+
type: Input
|
|
3001
|
+
}], expanded: [{
|
|
3002
|
+
type: Input
|
|
3003
|
+
}], toggleExpand: [{
|
|
3004
|
+
type: Input
|
|
3005
|
+
}] } });
|
|
3006
|
+
|
|
3007
|
+
class DefaultTaskActionPromptComponent {
|
|
3008
|
+
constructor() {
|
|
3009
|
+
this.expanded = false;
|
|
3010
|
+
this.responseValue = '';
|
|
3011
|
+
this.submitting = false;
|
|
3012
|
+
}
|
|
3013
|
+
get promptDataJson() {
|
|
3014
|
+
if (this.prompt?.data === undefined || this.prompt?.data === null) {
|
|
3015
|
+
return '';
|
|
3016
|
+
}
|
|
3017
|
+
try {
|
|
3018
|
+
return JSON.stringify(this.prompt.data, null, 2);
|
|
3019
|
+
}
|
|
3020
|
+
catch {
|
|
3021
|
+
return String(this.prompt.data);
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
onToggle() {
|
|
3025
|
+
this.toggleExpand?.();
|
|
3026
|
+
}
|
|
3027
|
+
onButtonClick(event) {
|
|
3028
|
+
event.stopPropagation();
|
|
3029
|
+
this.toggleExpand?.();
|
|
3030
|
+
}
|
|
3031
|
+
async submit() {
|
|
3032
|
+
if (!this.task || !this.prompt || this.submitting) {
|
|
3033
|
+
return;
|
|
3034
|
+
}
|
|
3035
|
+
this.submitting = true;
|
|
3036
|
+
try {
|
|
3037
|
+
await this.task.respondToPrompt(this.prompt.id, this.responseValue);
|
|
3038
|
+
}
|
|
3039
|
+
finally {
|
|
3040
|
+
this.submitting = false;
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionPromptComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3044
|
+
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: `
|
|
3045
|
+
<div class="rts-prompt-default">
|
|
3046
|
+
<div class="rts-prompt-header" (click)="onToggle()">
|
|
3047
|
+
<div class="rts-prompt-left">
|
|
3048
|
+
<span class="rts-prompt-badge">Prompt</span>
|
|
3049
|
+
<span class="rts-prompt-name" [title]="prompt?.name || 'Prompt'">
|
|
3050
|
+
{{ prompt?.name || 'Prompt' }}
|
|
3051
|
+
</span>
|
|
3052
|
+
</div>
|
|
3053
|
+
<button type="button"
|
|
3054
|
+
class="rts-prompt-expand"
|
|
3055
|
+
(click)="onButtonClick($event)"
|
|
3056
|
+
>
|
|
3057
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
3058
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
3059
|
+
</button>
|
|
3060
|
+
</div>
|
|
3061
|
+
|
|
3062
|
+
@if (expanded && prompt) {
|
|
3063
|
+
<div class="rts-prompt-body">
|
|
3064
|
+
@if (promptDataJson) {
|
|
3065
|
+
<pre class="rts-prompt-code"><code>{{ promptDataJson }}</code></pre>
|
|
3066
|
+
}
|
|
3067
|
+
@if (!prompt.resolved) {
|
|
3068
|
+
<div class="rts-prompt-Controls">
|
|
3069
|
+
<input type="text"
|
|
3070
|
+
class="rts-prompt-input"
|
|
3071
|
+
[(ngModel)]="responseValue"
|
|
3072
|
+
placeholder="Provide response…"
|
|
3073
|
+
/>
|
|
3074
|
+
<button type="button"
|
|
3075
|
+
class="rts-prompt-submit"
|
|
3076
|
+
[disabled]="submitting"
|
|
3077
|
+
(click)="submit()"
|
|
3078
|
+
>
|
|
3079
|
+
Send
|
|
3080
|
+
</button>
|
|
3081
|
+
</div>
|
|
3082
|
+
} @else {
|
|
3083
|
+
<div class="rts-prompt-resolved">Prompt answered.</div>
|
|
3084
|
+
}
|
|
3085
|
+
</div>
|
|
3086
|
+
}
|
|
3087
|
+
</div>
|
|
3088
|
+
`, 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"] }] }); }
|
|
3089
|
+
}
|
|
3090
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DefaultTaskActionPromptComponent, decorators: [{
|
|
3091
|
+
type: Component,
|
|
3092
|
+
args: [{ selector: 'rtsee-default-task-action-prompt', standalone: true, imports: [NgClass, FormsModule], template: `
|
|
3093
|
+
<div class="rts-prompt-default">
|
|
3094
|
+
<div class="rts-prompt-header" (click)="onToggle()">
|
|
3095
|
+
<div class="rts-prompt-left">
|
|
3096
|
+
<span class="rts-prompt-badge">Prompt</span>
|
|
3097
|
+
<span class="rts-prompt-name" [title]="prompt?.name || 'Prompt'">
|
|
3098
|
+
{{ prompt?.name || 'Prompt' }}
|
|
3099
|
+
</span>
|
|
3100
|
+
</div>
|
|
3101
|
+
<button type="button"
|
|
3102
|
+
class="rts-prompt-expand"
|
|
3103
|
+
(click)="onButtonClick($event)"
|
|
3104
|
+
>
|
|
3105
|
+
{{ expanded ? 'Hide' : 'Expand' }}
|
|
3106
|
+
<span class="pi" [ngClass]="expanded ? 'pi-chevron-up' : 'pi-chevron-down'"></span>
|
|
3107
|
+
</button>
|
|
3108
|
+
</div>
|
|
3109
|
+
|
|
3110
|
+
@if (expanded && prompt) {
|
|
3111
|
+
<div class="rts-prompt-body">
|
|
3112
|
+
@if (promptDataJson) {
|
|
3113
|
+
<pre class="rts-prompt-code"><code>{{ promptDataJson }}</code></pre>
|
|
3114
|
+
}
|
|
3115
|
+
@if (!prompt.resolved) {
|
|
3116
|
+
<div class="rts-prompt-Controls">
|
|
3117
|
+
<input type="text"
|
|
3118
|
+
class="rts-prompt-input"
|
|
3119
|
+
[(ngModel)]="responseValue"
|
|
3120
|
+
placeholder="Provide response…"
|
|
3121
|
+
/>
|
|
3122
|
+
<button type="button"
|
|
3123
|
+
class="rts-prompt-submit"
|
|
3124
|
+
[disabled]="submitting"
|
|
3125
|
+
(click)="submit()"
|
|
3126
|
+
>
|
|
3127
|
+
Send
|
|
3128
|
+
</button>
|
|
3129
|
+
</div>
|
|
3130
|
+
} @else {
|
|
3131
|
+
<div class="rts-prompt-resolved">Prompt answered.</div>
|
|
3132
|
+
}
|
|
3133
|
+
</div>
|
|
3134
|
+
}
|
|
3135
|
+
</div>
|
|
3136
|
+
`, 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"] }]
|
|
3137
|
+
}], propDecorators: { prompt: [{
|
|
3138
|
+
type: Input
|
|
3139
|
+
}], task: [{
|
|
3140
|
+
type: Input
|
|
3141
|
+
}], expanded: [{
|
|
3142
|
+
type: Input
|
|
3143
|
+
}], toggleExpand: [{
|
|
3144
|
+
type: Input
|
|
3145
|
+
}] } });
|
|
3146
|
+
|
|
3147
|
+
/**
|
|
3148
|
+
* Registry of custom client-side widgets for task-action-thumbnails and task-action-prompts.
|
|
3149
|
+
* Falls back to DefaultTaskActionThumbnailComponent / DefaultTaskActionPromptComponent.
|
|
3150
|
+
*/
|
|
3151
|
+
class TaskActionWidgetsService {
|
|
3152
|
+
constructor() {
|
|
3153
|
+
this.thumbnailsMap = [
|
|
3154
|
+
{ name: CREATE_STORY_ACTION_NAME, component: StoryTaskActionThumbnailComponent },
|
|
3155
|
+
{ name: EDIT_STORY_ACTION_NAME, component: StoryTaskActionThumbnailComponent },
|
|
3156
|
+
{ name: CREATE_SLIDE_ACTION_NAME, component: SlideTaskActionThumbnailComponent },
|
|
3157
|
+
{ name: EDIT_SLIDE_ACTION_NAME, component: SlideTaskActionThumbnailComponent },
|
|
3158
|
+
];
|
|
3159
|
+
this.promptsMap = [];
|
|
3160
|
+
}
|
|
3161
|
+
registerThumbnail(widget) {
|
|
3162
|
+
this.thumbnailsMap = [
|
|
3163
|
+
...this.thumbnailsMap.filter((e) => e.name !== widget.name),
|
|
3164
|
+
widget,
|
|
3165
|
+
];
|
|
3166
|
+
}
|
|
3167
|
+
registerPrompt(widget) {
|
|
3168
|
+
this.promptsMap = [
|
|
3169
|
+
...this.promptsMap.filter((e) => e.name !== widget.name),
|
|
3170
|
+
widget,
|
|
3171
|
+
];
|
|
3172
|
+
}
|
|
3173
|
+
getThumbnailComponentByName(name) {
|
|
3174
|
+
if (!name) {
|
|
3175
|
+
return DefaultTaskActionThumbnailComponent;
|
|
3176
|
+
}
|
|
3177
|
+
return (this.thumbnailsMap.find((e) => e.name === name)?.component ||
|
|
3178
|
+
DefaultTaskActionThumbnailComponent);
|
|
3179
|
+
}
|
|
3180
|
+
getPromptComponentByName(name) {
|
|
3181
|
+
if (!name) {
|
|
3182
|
+
return DefaultTaskActionPromptComponent;
|
|
3183
|
+
}
|
|
3184
|
+
return (this.promptsMap.find((e) => e.name === name)?.component ||
|
|
3185
|
+
DefaultTaskActionPromptComponent);
|
|
3186
|
+
}
|
|
3187
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionWidgetsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3188
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionWidgetsService, providedIn: 'root' }); }
|
|
3189
|
+
}
|
|
3190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionWidgetsService, decorators: [{
|
|
3191
|
+
type: Injectable,
|
|
3192
|
+
args: [{
|
|
3193
|
+
providedIn: 'root',
|
|
3194
|
+
}]
|
|
3195
|
+
}] });
|
|
3196
|
+
|
|
3197
|
+
/**
|
|
3198
|
+
* Minified thumbnail representation of an OzzyClientTaskAction.
|
|
3199
|
+
* Renders the registered custom thumbnail widget (or DefaultTaskActionThumbnailComponent)
|
|
3200
|
+
* and expands into the full RTSeeTaskActionComponent view on toggle.
|
|
3201
|
+
*/
|
|
3202
|
+
class TaskActionThumbnailComponent {
|
|
3203
|
+
constructor(cdr, actionWidgets) {
|
|
3204
|
+
this.cdr = cdr;
|
|
3205
|
+
this.actionWidgets = actionWidgets;
|
|
3206
|
+
this.expanded = false;
|
|
3207
|
+
this.subscribedAction = null;
|
|
3208
|
+
this.onChangedBound = () => this.cdr.detectChanges();
|
|
3209
|
+
this.toggleExpandBound = () => this.toggleExpand();
|
|
3210
|
+
}
|
|
3211
|
+
ngOnInit() {
|
|
3212
|
+
this.subscribe();
|
|
3213
|
+
}
|
|
3214
|
+
ngOnChanges(changes) {
|
|
3215
|
+
if (changes['action'] && !changes['action'].firstChange) {
|
|
3216
|
+
this.subscribe();
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
ngOnDestroy() {
|
|
3220
|
+
this.unsubscribe();
|
|
3221
|
+
}
|
|
3222
|
+
get thumbnailComponent() {
|
|
3223
|
+
return this.actionWidgets.getThumbnailComponentByName(this.action?.name);
|
|
3224
|
+
}
|
|
3225
|
+
get thumbnailInputs() {
|
|
3226
|
+
return {
|
|
3227
|
+
action: this.action,
|
|
3228
|
+
task: this.task,
|
|
3229
|
+
expanded: this.expanded,
|
|
3230
|
+
toggleExpand: this.toggleExpandBound,
|
|
3231
|
+
};
|
|
3232
|
+
}
|
|
3233
|
+
toggleExpand() {
|
|
3234
|
+
this.expanded = !this.expanded;
|
|
3235
|
+
if (this.expanded && this.action && !this.action.loaded && !this.action.isRunning) {
|
|
3236
|
+
void this.action.load();
|
|
3237
|
+
}
|
|
3238
|
+
this.cdr.detectChanges();
|
|
3239
|
+
}
|
|
3240
|
+
subscribe() {
|
|
3241
|
+
if (this.subscribedAction === this.action) {
|
|
3242
|
+
return;
|
|
3243
|
+
}
|
|
3244
|
+
this.unsubscribe();
|
|
3245
|
+
if (this.action) {
|
|
3246
|
+
this.subscribedAction = this.action;
|
|
3247
|
+
this.action.on(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
unsubscribe() {
|
|
3251
|
+
this.subscribedAction?.off(OzzyClientTaskActionEvents.CHANGED, this.onChangedBound);
|
|
3252
|
+
this.subscribedAction = null;
|
|
3253
|
+
}
|
|
3254
|
+
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 }); }
|
|
3255
|
+
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: `
|
|
3256
|
+
<div class="rts-action-thumbnail-host">
|
|
3257
|
+
@if (action) {
|
|
3258
|
+
<ng-container
|
|
3259
|
+
*ngComponentOutlet="thumbnailComponent; inputs: thumbnailInputs"
|
|
3260
|
+
></ng-container>
|
|
3261
|
+
|
|
3262
|
+
@if (expanded) {
|
|
3263
|
+
<div class="rts-action-thumbnail-expanded">
|
|
3264
|
+
<rtsee-task-action [action]="action"></rtsee-task-action>
|
|
3265
|
+
</div>
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
</div>
|
|
3269
|
+
`, 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"] }] }); }
|
|
3270
|
+
}
|
|
3271
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionThumbnailComponent, decorators: [{
|
|
3272
|
+
type: Component,
|
|
3273
|
+
args: [{ selector: 'rtsee-task-action-thumbnail, task-action-thumbnail', standalone: true, imports: [NgComponentOutlet, RTSeeTaskActionComponent], template: `
|
|
3274
|
+
<div class="rts-action-thumbnail-host">
|
|
3275
|
+
@if (action) {
|
|
3276
|
+
<ng-container
|
|
3277
|
+
*ngComponentOutlet="thumbnailComponent; inputs: thumbnailInputs"
|
|
3278
|
+
></ng-container>
|
|
3279
|
+
|
|
3280
|
+
@if (expanded) {
|
|
3281
|
+
<div class="rts-action-thumbnail-expanded">
|
|
3282
|
+
<rtsee-task-action [action]="action"></rtsee-task-action>
|
|
3283
|
+
</div>
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
</div>
|
|
3287
|
+
`, 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"] }]
|
|
3288
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: TaskActionWidgetsService }], propDecorators: { action: [{
|
|
3289
|
+
type: Input
|
|
3290
|
+
}], task: [{
|
|
3291
|
+
type: Input
|
|
3292
|
+
}] } });
|
|
3293
|
+
|
|
3294
|
+
/**
|
|
3295
|
+
* Host component for a task action prompt.
|
|
3296
|
+
* Renders the registered custom prompt widget (or DefaultTaskActionPromptComponent).
|
|
3297
|
+
*/
|
|
3298
|
+
class TaskActionPromptComponent {
|
|
3299
|
+
constructor(cdr, actionWidgets) {
|
|
3300
|
+
this.cdr = cdr;
|
|
3301
|
+
this.actionWidgets = actionWidgets;
|
|
3302
|
+
this.expanded = false;
|
|
3303
|
+
this.toggleExpandBound = () => this.toggleExpand();
|
|
3304
|
+
}
|
|
3305
|
+
get promptComponent() {
|
|
3306
|
+
return this.actionWidgets.getPromptComponentByName(this.prompt?.name);
|
|
3307
|
+
}
|
|
3308
|
+
get promptInputs() {
|
|
3309
|
+
return {
|
|
3310
|
+
prompt: this.prompt,
|
|
3311
|
+
task: this.task,
|
|
3312
|
+
expanded: this.expanded,
|
|
3313
|
+
toggleExpand: this.toggleExpandBound,
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
toggleExpand() {
|
|
3317
|
+
this.expanded = !this.expanded;
|
|
3318
|
+
this.cdr.detectChanges();
|
|
3319
|
+
}
|
|
3320
|
+
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 }); }
|
|
3321
|
+
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: `
|
|
3322
|
+
@if (prompt) {
|
|
3323
|
+
<ng-container
|
|
3324
|
+
*ngComponentOutlet="promptComponent; inputs: promptInputs"
|
|
3325
|
+
></ng-container>
|
|
3326
|
+
}
|
|
3327
|
+
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }] }); }
|
|
3328
|
+
}
|
|
3329
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TaskActionPromptComponent, decorators: [{
|
|
3330
|
+
type: Component,
|
|
3331
|
+
args: [{ selector: 'rtsee-task-action-prompt, task-action-prompt', standalone: true, imports: [NgComponentOutlet], template: `
|
|
3332
|
+
@if (prompt) {
|
|
3333
|
+
<ng-container
|
|
3334
|
+
*ngComponentOutlet="promptComponent; inputs: promptInputs"
|
|
3335
|
+
></ng-container>
|
|
3336
|
+
}
|
|
3337
|
+
`, styles: [":host{display:block}\n"] }]
|
|
3338
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: TaskActionWidgetsService }], propDecorators: { prompt: [{
|
|
3339
|
+
type: Input
|
|
3340
|
+
}], task: [{
|
|
3341
|
+
type: Input
|
|
3342
|
+
}] } });
|
|
3343
|
+
|
|
2447
3344
|
/**
|
|
2448
3345
|
* Default client-side representation of a server-side OzzyTask.
|
|
2449
3346
|
* Can be used directly (`[task]`) or as a message widget (`message.data.taskId`).
|
|
@@ -2462,10 +3359,12 @@ class RTSeeTaskComponent {
|
|
|
2462
3359
|
this.task = this.messenger.ozzy.getTask(this.message.data.taskId);
|
|
2463
3360
|
}
|
|
2464
3361
|
this.subscribe();
|
|
3362
|
+
this.ensureActions();
|
|
2465
3363
|
}
|
|
2466
3364
|
ngOnChanges(changes) {
|
|
2467
3365
|
if (changes['task'] && !changes['task'].firstChange) {
|
|
2468
3366
|
this.subscribe();
|
|
3367
|
+
this.ensureActions();
|
|
2469
3368
|
}
|
|
2470
3369
|
}
|
|
2471
3370
|
ngOnDestroy() {
|
|
@@ -2504,12 +3403,27 @@ class RTSeeTaskComponent {
|
|
|
2504
3403
|
get hasOutput() {
|
|
2505
3404
|
return this.task?.output !== undefined && this.task?.output !== null;
|
|
2506
3405
|
}
|
|
2507
|
-
get
|
|
2508
|
-
return !!(this.task?.
|
|
3406
|
+
get hasActions() {
|
|
3407
|
+
return !!(this.task?.actions?.length || this.task?.actionsLoading);
|
|
3408
|
+
}
|
|
3409
|
+
get hasPrompts() {
|
|
3410
|
+
return !!(this.task?.prompts?.length);
|
|
2509
3411
|
}
|
|
2510
3412
|
execute() {
|
|
2511
3413
|
void this.task?.execute();
|
|
2512
3414
|
}
|
|
3415
|
+
loadMoreActions() {
|
|
3416
|
+
void this.task?.loadMoreActions();
|
|
3417
|
+
}
|
|
3418
|
+
onActionsScroll(event) {
|
|
3419
|
+
const el = event.target;
|
|
3420
|
+
if (!el || !this.task?.hasMoreActions || this.task.actionsLoading) {
|
|
3421
|
+
return;
|
|
3422
|
+
}
|
|
3423
|
+
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 40) {
|
|
3424
|
+
void this.task.loadMoreActions();
|
|
3425
|
+
}
|
|
3426
|
+
}
|
|
2513
3427
|
async copy(kind) {
|
|
2514
3428
|
try {
|
|
2515
3429
|
await navigator.clipboard.writeText(kind === 'input' ? this.inputJson : this.outputJson);
|
|
@@ -2524,8 +3438,19 @@ class RTSeeTaskComponent {
|
|
|
2524
3438
|
console.log('Failed to copy', e);
|
|
2525
3439
|
}
|
|
2526
3440
|
}
|
|
2527
|
-
|
|
2528
|
-
return
|
|
3441
|
+
trackAction(_index, action) {
|
|
3442
|
+
return action.id;
|
|
3443
|
+
}
|
|
3444
|
+
trackPrompt(_index, prompt) {
|
|
3445
|
+
return prompt.id;
|
|
3446
|
+
}
|
|
3447
|
+
ensureActions() {
|
|
3448
|
+
if (!this.task) {
|
|
3449
|
+
return;
|
|
3450
|
+
}
|
|
3451
|
+
if (this.task.status !== OzzyTaskStatus.CREATED) {
|
|
3452
|
+
this.task.ensureActionsLoaded();
|
|
3453
|
+
}
|
|
2529
3454
|
}
|
|
2530
3455
|
toJson(value) {
|
|
2531
3456
|
if (value === undefined || value === null) {
|
|
@@ -2553,18 +3478,21 @@ class RTSeeTaskComponent {
|
|
|
2553
3478
|
this.subscribedTask = null;
|
|
2554
3479
|
}
|
|
2555
3480
|
onTaskChanged() {
|
|
3481
|
+
this.ensureActions();
|
|
2556
3482
|
this.cdr.detectChanges();
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
el
|
|
3483
|
+
if (this.task?.isRunning) {
|
|
3484
|
+
const el = this.actionsContainer?.nativeElement;
|
|
3485
|
+
if (el) {
|
|
3486
|
+
el.scrollTop = el.scrollHeight;
|
|
3487
|
+
}
|
|
2560
3488
|
}
|
|
2561
3489
|
}
|
|
2562
3490
|
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" }] }); }
|
|
3491
|
+
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
3492
|
}
|
|
2565
3493
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeTaskComponent, decorators: [{
|
|
2566
3494
|
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"] }]
|
|
3495
|
+
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
3496
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { task: [{
|
|
2569
3497
|
type: Input
|
|
2570
3498
|
}], message: [{
|
|
@@ -2575,9 +3503,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2575
3503
|
type: Input
|
|
2576
3504
|
}], allowExecute: [{
|
|
2577
3505
|
type: Input
|
|
2578
|
-
}],
|
|
3506
|
+
}], actionsContainer: [{
|
|
2579
3507
|
type: ViewChild,
|
|
2580
|
-
args: ['
|
|
3508
|
+
args: ['actionsContainer']
|
|
2581
3509
|
}] } });
|
|
2582
3510
|
|
|
2583
3511
|
/**
|
|
@@ -3581,17 +4509,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
3581
4509
|
}] } });
|
|
3582
4510
|
|
|
3583
4511
|
class MessagesListComponent {
|
|
3584
|
-
constructor(timeFormatService, scroller, document) {
|
|
4512
|
+
constructor(timeFormatService, scroller, hostRef, document) {
|
|
3585
4513
|
this.timeFormatService = timeFormatService;
|
|
3586
4514
|
this.scroller = scroller;
|
|
4515
|
+
this.hostRef = hostRef;
|
|
3587
4516
|
this.document = document;
|
|
3588
4517
|
this.messagesGroups = [];
|
|
3589
4518
|
this.firstGroupedMessage = null;
|
|
3590
4519
|
this.lastGroupedMessage = null;
|
|
3591
4520
|
this.shouldStickToBottom = true;
|
|
4521
|
+
this.isWindowScroll = false;
|
|
3592
4522
|
this.resizeObserver = null;
|
|
3593
4523
|
this.onMediaCapture = null;
|
|
3594
4524
|
this.initialScrollInterval = null;
|
|
4525
|
+
this.lastContainerScrollTop = 0;
|
|
4526
|
+
this.lastWindowScrollTop = 0;
|
|
4527
|
+
this.isFramed = false;
|
|
3595
4528
|
this.RTSeeChatTypes = RTSeeChatTypes;
|
|
3596
4529
|
this.bindScrollFunction = () => {
|
|
3597
4530
|
this.shouldStickToBottom = true;
|
|
@@ -3604,29 +4537,66 @@ class MessagesListComponent {
|
|
|
3604
4537
|
}
|
|
3605
4538
|
};
|
|
3606
4539
|
}
|
|
4540
|
+
get isStandalone() {
|
|
4541
|
+
return Boolean(this.chat?.isStandalone);
|
|
4542
|
+
}
|
|
3607
4543
|
onWindowScroll(event) {
|
|
3608
|
-
this.
|
|
4544
|
+
this.updateScrollMode();
|
|
4545
|
+
if (!this.isWindowScroll) {
|
|
4546
|
+
return;
|
|
4547
|
+
}
|
|
3609
4548
|
const verticalOffset = window.pageYOffset ||
|
|
3610
4549
|
this.document.documentElement.scrollTop ||
|
|
3611
4550
|
this.document.body.scrollTop ||
|
|
3612
4551
|
0;
|
|
3613
|
-
|
|
4552
|
+
const scrollingUp = verticalOffset < this.lastWindowScrollTop;
|
|
4553
|
+
const scrollingDown = verticalOffset > this.lastWindowScrollTop;
|
|
4554
|
+
this.lastWindowScrollTop = verticalOffset;
|
|
4555
|
+
if (this.isStandalone) {
|
|
4556
|
+
const el = this.contentBlock?.nativeElement || this.scrollContainer?.nativeElement;
|
|
4557
|
+
if (!el || el.getClientRects().length === 0) {
|
|
4558
|
+
return;
|
|
4559
|
+
}
|
|
4560
|
+
const rect = el.getBoundingClientRect();
|
|
4561
|
+
const viewportHeight = window.innerHeight || this.document.documentElement.clientHeight || 0;
|
|
4562
|
+
if (scrollingDown && rect.bottom - viewportHeight < 300) {
|
|
4563
|
+
this.onScroll();
|
|
4564
|
+
}
|
|
4565
|
+
else if (scrollingUp && rect.top > -300 && rect.top <= 300) {
|
|
4566
|
+
this.onScrolledToTop();
|
|
4567
|
+
}
|
|
4568
|
+
return;
|
|
4569
|
+
}
|
|
4570
|
+
if (!this.isShellMobileChatActive()) {
|
|
3614
4571
|
return;
|
|
3615
4572
|
}
|
|
3616
|
-
|
|
4573
|
+
this.checkScrollPosition();
|
|
4574
|
+
if (scrollingUp && verticalOffset < 300) {
|
|
3617
4575
|
this.onScrolledToTop();
|
|
3618
4576
|
}
|
|
4577
|
+
else if (scrollingDown) {
|
|
4578
|
+
const scrollHeight = Math.max(this.document.documentElement.scrollHeight, this.document.body.scrollHeight);
|
|
4579
|
+
const clientHeight = window.innerHeight;
|
|
4580
|
+
if (scrollHeight - (verticalOffset + clientHeight) < 300) {
|
|
4581
|
+
this.onScroll();
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
3619
4584
|
}
|
|
3620
4585
|
onWindowResize() {
|
|
4586
|
+
this.updateScrollMode();
|
|
3621
4587
|
if (this.shouldStickToBottom) {
|
|
3622
4588
|
this.scrollToBottom();
|
|
3623
4589
|
}
|
|
3624
4590
|
}
|
|
3625
4591
|
ngOnInit() {
|
|
4592
|
+
this.updateScrollMode();
|
|
3626
4593
|
this.bindChatEvents(this.chat);
|
|
3627
4594
|
this.groupMessages();
|
|
3628
4595
|
}
|
|
3629
4596
|
ngOnChanges(changes) {
|
|
4597
|
+
if (changes['chat'] || changes['isFramed']) {
|
|
4598
|
+
this.updateScrollMode();
|
|
4599
|
+
}
|
|
3630
4600
|
if (changes['chat'] && !changes['chat'].firstChange) {
|
|
3631
4601
|
const prevChat = changes['chat'].previousValue;
|
|
3632
4602
|
this.unbindChatEvents(prevChat);
|
|
@@ -3636,7 +4606,8 @@ class MessagesListComponent {
|
|
|
3636
4606
|
}
|
|
3637
4607
|
}
|
|
3638
4608
|
ngAfterViewInit() {
|
|
3639
|
-
|
|
4609
|
+
this.updateScrollMode();
|
|
4610
|
+
if (this.isStandalone) {
|
|
3640
4611
|
return;
|
|
3641
4612
|
}
|
|
3642
4613
|
this.enforceInitialScroll();
|
|
@@ -3681,8 +4652,25 @@ class MessagesListComponent {
|
|
|
3681
4652
|
}
|
|
3682
4653
|
}
|
|
3683
4654
|
onContainerScroll(event) {
|
|
4655
|
+
this.updateScrollMode();
|
|
4656
|
+
if (this.isWindowScroll) {
|
|
4657
|
+
return;
|
|
4658
|
+
}
|
|
3684
4659
|
this.checkScrollPosition();
|
|
3685
|
-
this.
|
|
4660
|
+
const el = this.scrollContainer?.nativeElement;
|
|
4661
|
+
if (!el) {
|
|
4662
|
+
return;
|
|
4663
|
+
}
|
|
4664
|
+
const scrollTop = el.scrollTop;
|
|
4665
|
+
const scrollingUp = scrollTop < this.lastContainerScrollTop;
|
|
4666
|
+
const scrollingDown = scrollTop > this.lastContainerScrollTop;
|
|
4667
|
+
this.lastContainerScrollTop = scrollTop;
|
|
4668
|
+
if (scrollingUp && scrollTop < 300) {
|
|
4669
|
+
this.onScrolledToTop();
|
|
4670
|
+
}
|
|
4671
|
+
else if (scrollingDown && el.scrollHeight - (scrollTop + el.clientHeight) < 300) {
|
|
4672
|
+
this.onScroll();
|
|
4673
|
+
}
|
|
3686
4674
|
}
|
|
3687
4675
|
onScrolledToTop() {
|
|
3688
4676
|
if (this.chat.messagesLoadInProgress || this.chat.firstMessageLoaded) {
|
|
@@ -3691,36 +4679,26 @@ class MessagesListComponent {
|
|
|
3691
4679
|
this.chat.loadRemoteMessages('back');
|
|
3692
4680
|
}
|
|
3693
4681
|
onScroll() {
|
|
3694
|
-
if (this.chat.messagesLoadInProgress) {
|
|
4682
|
+
if (this.chat.messagesLoadInProgress || this.chat.lastMessageLoaded) {
|
|
3695
4683
|
return;
|
|
3696
4684
|
}
|
|
3697
4685
|
this.chat.loadRemoteMessages('front');
|
|
3698
4686
|
}
|
|
3699
4687
|
scrollToBottom(immediate = false) {
|
|
3700
|
-
if (this.
|
|
4688
|
+
if (this.isStandalone) {
|
|
3701
4689
|
return;
|
|
3702
4690
|
}
|
|
4691
|
+
this.updateScrollMode();
|
|
3703
4692
|
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);
|
|
4693
|
+
if (this.isShellMobileChatActive()) {
|
|
4694
|
+
const target = Math.max(this.document.documentElement.scrollHeight, this.document.body.scrollHeight);
|
|
3718
4695
|
window.scrollTo({ top: target, behavior: 'instant' });
|
|
3719
4696
|
this.scroller.scrollToPosition([0, target]);
|
|
3720
4697
|
}
|
|
3721
|
-
if (this.scrollContainer?.nativeElement) {
|
|
4698
|
+
else if (!this.isWindowScroll && this.scrollContainer?.nativeElement) {
|
|
3722
4699
|
const el = this.scrollContainer.nativeElement;
|
|
3723
4700
|
el.scrollTop = el.scrollHeight;
|
|
4701
|
+
this.lastContainerScrollTop = el.scrollTop;
|
|
3724
4702
|
}
|
|
3725
4703
|
};
|
|
3726
4704
|
performScroll();
|
|
@@ -3743,11 +4721,11 @@ class MessagesListComponent {
|
|
|
3743
4721
|
}
|
|
3744
4722
|
isAtBottom() {
|
|
3745
4723
|
const threshold = 150; // px threshold from bottom
|
|
3746
|
-
if (
|
|
3747
|
-
const scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
|
4724
|
+
if (this.isShellMobileChatActive()) {
|
|
4725
|
+
const scrollHeight = Math.max(this.document.documentElement.scrollHeight, this.document.body.scrollHeight);
|
|
3748
4726
|
const scrollTop = window.pageYOffset ||
|
|
3749
|
-
document.documentElement.scrollTop ||
|
|
3750
|
-
document.body.scrollTop ||
|
|
4727
|
+
this.document.documentElement.scrollTop ||
|
|
4728
|
+
this.document.body.scrollTop ||
|
|
3751
4729
|
0;
|
|
3752
4730
|
const clientHeight = window.innerHeight;
|
|
3753
4731
|
return scrollHeight - (scrollTop + clientHeight) <= threshold;
|
|
@@ -3759,6 +4737,36 @@ class MessagesListComponent {
|
|
|
3759
4737
|
return el.scrollHeight - (el.scrollTop + el.clientHeight) <= threshold;
|
|
3760
4738
|
}
|
|
3761
4739
|
}
|
|
4740
|
+
isMobileViewport() {
|
|
4741
|
+
return (typeof window !== 'undefined' &&
|
|
4742
|
+
window.innerWidth < COMMON_CONSTANTS.mobileBreakpoint);
|
|
4743
|
+
}
|
|
4744
|
+
isShellMobileChatActive() {
|
|
4745
|
+
if (this.isStandalone || this.isFramed || !this.isMobileViewport()) {
|
|
4746
|
+
return false;
|
|
4747
|
+
}
|
|
4748
|
+
const el = this.scrollContainer?.nativeElement || this.hostRef?.nativeElement;
|
|
4749
|
+
if (!el) {
|
|
4750
|
+
return false;
|
|
4751
|
+
}
|
|
4752
|
+
const shell = typeof el.closest === 'function' ? el.closest('.rtsee-shell') : null;
|
|
4753
|
+
if (shell && !shell.classList.contains('rtsee-shell-messenger-active')) {
|
|
4754
|
+
return false;
|
|
4755
|
+
}
|
|
4756
|
+
return el.getClientRects().length > 0;
|
|
4757
|
+
}
|
|
4758
|
+
computeIsWindowScroll() {
|
|
4759
|
+
if (this.isStandalone) {
|
|
4760
|
+
return true;
|
|
4761
|
+
}
|
|
4762
|
+
if (this.isFramed) {
|
|
4763
|
+
return false;
|
|
4764
|
+
}
|
|
4765
|
+
return this.isMobileViewport();
|
|
4766
|
+
}
|
|
4767
|
+
updateScrollMode() {
|
|
4768
|
+
this.isWindowScroll = this.computeIsWindowScroll();
|
|
4769
|
+
}
|
|
3762
4770
|
enforceInitialScroll() {
|
|
3763
4771
|
this.shouldStickToBottom = true;
|
|
3764
4772
|
this.scrollToBottom();
|
|
@@ -3834,19 +4842,21 @@ class MessagesListComponent {
|
|
|
3834
4842
|
this.firstGroupedMessage = this.chat.messages[0];
|
|
3835
4843
|
this.lastGroupedMessage = this.chat.messages[this.chat.messages.length - 1];
|
|
3836
4844
|
}
|
|
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]=\"
|
|
4845
|
+
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 }); }
|
|
4846
|
+
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
4847
|
}
|
|
3840
4848
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessagesListComponent, decorators: [{
|
|
3841
4849
|
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:
|
|
4850
|
+
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" }]
|
|
4851
|
+
}], ctorParameters: () => [{ type: TimeFormatHelperService }, { type: i1$3.ViewportScroller }, { type: i0.ElementRef }, { type: Document, decorators: [{
|
|
3844
4852
|
type: Inject,
|
|
3845
4853
|
args: [DOCUMENT]
|
|
3846
4854
|
}] }], propDecorators: { chat: [{
|
|
3847
4855
|
type: Input
|
|
3848
4856
|
}], messenger: [{
|
|
3849
4857
|
type: Input
|
|
4858
|
+
}], isFramed: [{
|
|
4859
|
+
type: Input
|
|
3850
4860
|
}], scrollContainer: [{
|
|
3851
4861
|
type: ViewChild,
|
|
3852
4862
|
args: ['scrollBlock']
|
|
@@ -4288,75 +5298,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4288
5298
|
args: ['messageTextarea']
|
|
4289
5299
|
}] } });
|
|
4290
5300
|
|
|
4291
|
-
class InviteLinkComponent {
|
|
4292
|
-
constructor() {
|
|
4293
|
-
this.inviteUrl = '';
|
|
4294
|
-
this.disclaimer = 'Anyone who opens this link can join the chat.';
|
|
4295
|
-
this.copied = false;
|
|
4296
|
-
this.loading = false;
|
|
4297
|
-
}
|
|
4298
|
-
async ngOnInit() {
|
|
4299
|
-
if (!this.inviteUrl && this.chatId && this.messenger) {
|
|
4300
|
-
await this.loadInviteLink();
|
|
4301
|
-
}
|
|
4302
|
-
}
|
|
4303
|
-
async loadInviteLink() {
|
|
4304
|
-
if (!this.chatId || !this.messenger)
|
|
4305
|
-
return;
|
|
4306
|
-
this.loading = true;
|
|
4307
|
-
try {
|
|
4308
|
-
const result = await this.messenger.remoteActions.getChatInvitationLink.send({
|
|
4309
|
-
chatId: this.chatId,
|
|
4310
|
-
});
|
|
4311
|
-
if (result?.invitationLink) {
|
|
4312
|
-
this.inviteUrl = result.invitationLink;
|
|
4313
|
-
}
|
|
4314
|
-
}
|
|
4315
|
-
catch (e) {
|
|
4316
|
-
console.log('Failed to fetch chat invitation link', e);
|
|
4317
|
-
}
|
|
4318
|
-
finally {
|
|
4319
|
-
this.loading = false;
|
|
4320
|
-
}
|
|
4321
|
-
}
|
|
4322
|
-
async copyToClipboard() {
|
|
4323
|
-
try {
|
|
4324
|
-
await navigator.clipboard.writeText(this.inviteUrl);
|
|
4325
|
-
this.copied = true;
|
|
4326
|
-
setTimeout(() => {
|
|
4327
|
-
this.copied = false;
|
|
4328
|
-
}, 2000);
|
|
4329
|
-
}
|
|
4330
|
-
catch {
|
|
4331
|
-
// Fallback for older browsers
|
|
4332
|
-
const textArea = document.createElement('textarea');
|
|
4333
|
-
textArea.value = this.inviteUrl;
|
|
4334
|
-
document.body.appendChild(textArea);
|
|
4335
|
-
textArea.select();
|
|
4336
|
-
document.execCommand('copy');
|
|
4337
|
-
document.body.removeChild(textArea);
|
|
4338
|
-
this.copied = true;
|
|
4339
|
-
setTimeout(() => {
|
|
4340
|
-
this.copied = false;
|
|
4341
|
-
}, 2000);
|
|
4342
|
-
}
|
|
4343
|
-
}
|
|
4344
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InviteLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4345
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InviteLinkComponent, isStandalone: true, selector: "rtsee-invite-link", inputs: { inviteUrl: "inviteUrl", chatId: "chatId", messenger: "messenger", disclaimer: "disclaimer" }, ngImport: i0, template: "<div class=\"rts-invite-link\">\n <div class=\"rts-invite-link-info\">\n <span class=\"rts-invite-link-icon material-icons-outlined\">link</span>\n <div class=\"rts-invite-link-info-text\">\n <h4>Invite Link</h4>\n <p>{{ disclaimer }}</p>\n </div>\n </div>\n\n @if (loading) {\n <div class=\"rts-invite-link-loading\">\n <span class=\"material-icons-outlined rts-spin-icon\">autorenew</span>\n <span>Generating invite link...</span>\n </div>\n } @else {\n <div class=\"rts-invite-link-url-container\">\n <p-inputgroup>\n <input pInputText\n [value]=\"inviteUrl\"\n readonly\n class=\"rts-invite-link-url-input\"\n />\n <p-button [icon]=\"copied ? 'pi pi-check' : 'pi pi-copy'\"\n [severity]=\"copied ? 'success' : 'primary'\"\n (click)=\"copyToClipboard()\"\n [label]=\"copied ? 'Copied!' : 'Copy'\"\n />\n </p-inputgroup>\n </div>\n }\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: InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "component", type: InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }] }); }
|
|
4346
|
-
}
|
|
4347
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InviteLinkComponent, decorators: [{
|
|
4348
|
-
type: Component,
|
|
4349
|
-
args: [{ selector: 'rtsee-invite-link', standalone: true, imports: [Button, InputText, InputGroup], template: "<div class=\"rts-invite-link\">\n <div class=\"rts-invite-link-info\">\n <span class=\"rts-invite-link-icon material-icons-outlined\">link</span>\n <div class=\"rts-invite-link-info-text\">\n <h4>Invite Link</h4>\n <p>{{ disclaimer }}</p>\n </div>\n </div>\n\n @if (loading) {\n <div class=\"rts-invite-link-loading\">\n <span class=\"material-icons-outlined rts-spin-icon\">autorenew</span>\n <span>Generating invite link...</span>\n </div>\n } @else {\n <div class=\"rts-invite-link-url-container\">\n <p-inputgroup>\n <input pInputText\n [value]=\"inviteUrl\"\n readonly\n class=\"rts-invite-link-url-input\"\n />\n <p-button [icon]=\"copied ? 'pi pi-check' : 'pi pi-copy'\"\n [severity]=\"copied ? 'success' : 'primary'\"\n (click)=\"copyToClipboard()\"\n [label]=\"copied ? 'Copied!' : 'Copy'\"\n />\n </p-inputgroup>\n </div>\n }\n</div>\n" }]
|
|
4350
|
-
}], propDecorators: { inviteUrl: [{
|
|
4351
|
-
type: Input
|
|
4352
|
-
}], chatId: [{
|
|
4353
|
-
type: Input
|
|
4354
|
-
}], messenger: [{
|
|
4355
|
-
type: Input
|
|
4356
|
-
}], disclaimer: [{
|
|
4357
|
-
type: Input
|
|
4358
|
-
}] } });
|
|
4359
|
-
|
|
4360
5301
|
class ViewportObserverDirective {
|
|
4361
5302
|
constructor(element) {
|
|
4362
5303
|
this.element = element;
|
|
@@ -4398,6 +5339,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4398
5339
|
|
|
4399
5340
|
class ChatComponent {
|
|
4400
5341
|
constructor() {
|
|
5342
|
+
this.isFramed = false;
|
|
4401
5343
|
this.showInvite = false;
|
|
4402
5344
|
}
|
|
4403
5345
|
get isSoleAdmin() {
|
|
@@ -4443,7 +5385,7 @@ class ChatComponent {
|
|
|
4443
5385
|
}
|
|
4444
5386
|
}
|
|
4445
5387
|
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"] }] }); }
|
|
5388
|
+
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
5389
|
}
|
|
4448
5390
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatComponent, decorators: [{
|
|
4449
5391
|
type: Component,
|
|
@@ -4453,7 +5395,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4453
5395
|
InviteLinkComponent,
|
|
4454
5396
|
ViewportObserverDirective,
|
|
4455
5397
|
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" }]
|
|
5398
|
+
], 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
5399
|
}], propDecorators: { chat: [{
|
|
4458
5400
|
type: Input
|
|
4459
5401
|
}], chatData: [{
|
|
@@ -4462,6 +5404,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4462
5404
|
type: Input
|
|
4463
5405
|
}], messenger: [{
|
|
4464
5406
|
type: Input
|
|
5407
|
+
}], isFramed: [{
|
|
5408
|
+
type: Input
|
|
4465
5409
|
}] } });
|
|
4466
5410
|
|
|
4467
5411
|
class ManageProfileComponent {
|
|
@@ -4833,11 +5777,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4833
5777
|
}] } });
|
|
4834
5778
|
|
|
4835
5779
|
class MessengerComponent {
|
|
5780
|
+
constructor() {
|
|
5781
|
+
this.isFramed = false;
|
|
5782
|
+
this.RTSeeTextLabelKeys = RTSeeTextLabelKeys;
|
|
5783
|
+
}
|
|
4836
5784
|
onScroll() {
|
|
4837
5785
|
void this.messenger.loadChats();
|
|
4838
5786
|
}
|
|
4839
5787
|
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.
|
|
5788
|
+
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 || messenger.inviteUserOpened,\n 'rts-messenger-folded': messenger.folded,\n 'rts-messenger-overlay-window': messenger.isOverlayPageOpened,\n 'rts-messenger-framed': isFramed\n}\">\n @if (messenger.pendingInviteToken) {\n <div class=\"rts-invite-popup-modal\">\n <div class=\"rts-invite-popup-content\">\n <span class=\"material-icons-outlined rts-invite-popup-icon\">mail_outline</span>\n <div class=\"rts-invite-popup-text\">\n @if (messenger.pendingInviteInfo?.inviter?.name) {\n <strong>{{ messenger.pendingInviteInfo?.inviter?.name }}</strong>\n <span> {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_TEXT] }}</span>\n @if (messenger.pendingInviteInfo?.chat?.name) {\n <span class=\"rts-invite-popup-chat-name\"> ({{ messenger.pendingInviteInfo?.chat?.name }})</span>\n }\n } @else {\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_GENERIC_TEXT] }}</span>\n }\n </div>\n </div>\n <div class=\"rts-invite-popup-actions\">\n <button type=\"button\"\n class=\"rts-btn rts-btn-secondary rts-invite-popup-btn\"\n [disabled]=\"messenger.inviteJoinInProgress\"\n (click)=\"messenger.ignoreChatInvitation()\"\n >\n {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_IGNORE_BUTTON] }}\n </button>\n <button type=\"button\"\n class=\"rts-btn rts-btn-primary rts-invite-popup-btn\"\n [disabled]=\"messenger.inviteJoinInProgress\"\n (click)=\"messenger.acceptChatInvitation()\"\n >\n {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_JOIN_BUTTON] }}\n </button>\n </div>\n </div>\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
5789
|
}
|
|
4842
5790
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessengerComponent, decorators: [{
|
|
4843
5791
|
type: Component,
|
|
@@ -4855,9 +5803,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4855
5803
|
PaymentPageComponent,
|
|
4856
5804
|
PaymentValidationPageComponent,
|
|
4857
5805
|
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.
|
|
5806
|
+
], standalone: true, template: "<div class=\"rts-messenger rts-theme-dark\" [ngClass]=\"{\n 'rts-messenger-header-expanded': messenger.openedProfile || messenger.openedChatDetails || messenger.manageChatInfo || messenger.inviteUserOpened,\n 'rts-messenger-folded': messenger.folded,\n 'rts-messenger-overlay-window': messenger.isOverlayPageOpened,\n 'rts-messenger-framed': isFramed\n}\">\n @if (messenger.pendingInviteToken) {\n <div class=\"rts-invite-popup-modal\">\n <div class=\"rts-invite-popup-content\">\n <span class=\"material-icons-outlined rts-invite-popup-icon\">mail_outline</span>\n <div class=\"rts-invite-popup-text\">\n @if (messenger.pendingInviteInfo?.inviter?.name) {\n <strong>{{ messenger.pendingInviteInfo?.inviter?.name }}</strong>\n <span> {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_TEXT] }}</span>\n @if (messenger.pendingInviteInfo?.chat?.name) {\n <span class=\"rts-invite-popup-chat-name\"> ({{ messenger.pendingInviteInfo?.chat?.name }})</span>\n }\n } @else {\n <span>{{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_GENERIC_TEXT] }}</span>\n }\n </div>\n </div>\n <div class=\"rts-invite-popup-actions\">\n <button type=\"button\"\n class=\"rts-btn rts-btn-secondary rts-invite-popup-btn\"\n [disabled]=\"messenger.inviteJoinInProgress\"\n (click)=\"messenger.ignoreChatInvitation()\"\n >\n {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_IGNORE_BUTTON] }}\n </button>\n <button type=\"button\"\n class=\"rts-btn rts-btn-primary rts-invite-popup-btn\"\n [disabled]=\"messenger.inviteJoinInProgress\"\n (click)=\"messenger.acceptChatInvitation()\"\n >\n {{ messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_JOIN_BUTTON] }}\n </button>\n </div>\n </div>\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
5807
|
}], propDecorators: { messenger: [{
|
|
4860
5808
|
type: Input
|
|
5809
|
+
}], isFramed: [{
|
|
5810
|
+
type: Input
|
|
4861
5811
|
}] } });
|
|
4862
5812
|
|
|
4863
5813
|
class BaseEventWidgetComponent {
|
|
@@ -5087,6 +6037,245 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
5087
6037
|
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
6038
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
5089
6039
|
|
|
6040
|
+
class ProfileOpenedWidgetComponent extends BaseEventWidgetComponent {
|
|
6041
|
+
constructor(cd) {
|
|
6042
|
+
super(cd);
|
|
6043
|
+
}
|
|
6044
|
+
get userName() {
|
|
6045
|
+
const raw = this.event?.payload?.text ||
|
|
6046
|
+
this.event?.payload?.data?.name ||
|
|
6047
|
+
'User Profile';
|
|
6048
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6049
|
+
}
|
|
6050
|
+
get imageUrl() {
|
|
6051
|
+
return (this.event?.payload?.url ||
|
|
6052
|
+
this.event?.payload?.imageUrl ||
|
|
6053
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6054
|
+
null);
|
|
6055
|
+
}
|
|
6056
|
+
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 }); }
|
|
6057
|
+
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 }] }); }
|
|
6058
|
+
}
|
|
6059
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ProfileOpenedWidgetComponent, decorators: [{
|
|
6060
|
+
type: Component,
|
|
6061
|
+
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" }]
|
|
6062
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6063
|
+
|
|
6064
|
+
class ChatOpenedWidgetComponent extends BaseEventWidgetComponent {
|
|
6065
|
+
constructor(cd) {
|
|
6066
|
+
super(cd);
|
|
6067
|
+
}
|
|
6068
|
+
get chatName() {
|
|
6069
|
+
const raw = this.event?.payload?.text ||
|
|
6070
|
+
this.event?.payload?.data?.chatName ||
|
|
6071
|
+
'Chat';
|
|
6072
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6073
|
+
}
|
|
6074
|
+
get imageUrl() {
|
|
6075
|
+
return (this.event?.payload?.imageUrl ||
|
|
6076
|
+
this.event?.payload?.url ||
|
|
6077
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6078
|
+
null);
|
|
6079
|
+
}
|
|
6080
|
+
get chatTypeLabel() {
|
|
6081
|
+
const type = this.event?.payload?.data?.chatType;
|
|
6082
|
+
if (type === 'channel')
|
|
6083
|
+
return 'Channel conversation';
|
|
6084
|
+
if (type === 'group')
|
|
6085
|
+
return 'Group conversation';
|
|
6086
|
+
return 'Active conversation';
|
|
6087
|
+
}
|
|
6088
|
+
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 }); }
|
|
6089
|
+
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 }] }); }
|
|
6090
|
+
}
|
|
6091
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatOpenedWidgetComponent, decorators: [{
|
|
6092
|
+
type: Component,
|
|
6093
|
+
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" }]
|
|
6094
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6095
|
+
|
|
6096
|
+
class ChatCreatedWidgetComponent extends BaseEventWidgetComponent {
|
|
6097
|
+
constructor(cd) {
|
|
6098
|
+
super(cd);
|
|
6099
|
+
}
|
|
6100
|
+
get chatName() {
|
|
6101
|
+
const raw = this.event?.payload?.text ||
|
|
6102
|
+
this.event?.payload?.data?.chatName ||
|
|
6103
|
+
'New Chat';
|
|
6104
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6105
|
+
}
|
|
6106
|
+
get imageUrl() {
|
|
6107
|
+
return (this.event?.payload?.imageUrl ||
|
|
6108
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6109
|
+
null);
|
|
6110
|
+
}
|
|
6111
|
+
get chatTypeLabel() {
|
|
6112
|
+
const type = this.event?.payload?.data?.chatType || this.event?.payload?.url;
|
|
6113
|
+
if (type === 'channel')
|
|
6114
|
+
return 'Created channel';
|
|
6115
|
+
if (type === 'group')
|
|
6116
|
+
return 'Created group chat';
|
|
6117
|
+
return 'Created new chat';
|
|
6118
|
+
}
|
|
6119
|
+
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 }); }
|
|
6120
|
+
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 }] }); }
|
|
6121
|
+
}
|
|
6122
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatCreatedWidgetComponent, decorators: [{
|
|
6123
|
+
type: Component,
|
|
6124
|
+
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" }]
|
|
6125
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6126
|
+
|
|
6127
|
+
class ChatMemberInviteClickedWidgetComponent extends BaseEventWidgetComponent {
|
|
6128
|
+
constructor(cd) {
|
|
6129
|
+
super(cd);
|
|
6130
|
+
}
|
|
6131
|
+
get chatName() {
|
|
6132
|
+
const raw = this.event?.payload?.text ||
|
|
6133
|
+
this.event?.payload?.data?.chatName ||
|
|
6134
|
+
'Chat';
|
|
6135
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6136
|
+
}
|
|
6137
|
+
get imageUrl() {
|
|
6138
|
+
return (this.event?.payload?.imageUrl ||
|
|
6139
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6140
|
+
null);
|
|
6141
|
+
}
|
|
6142
|
+
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 }); }
|
|
6143
|
+
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 }] }); }
|
|
6144
|
+
}
|
|
6145
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatMemberInviteClickedWidgetComponent, decorators: [{
|
|
6146
|
+
type: Component,
|
|
6147
|
+
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" }]
|
|
6148
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6149
|
+
|
|
6150
|
+
class ChatAgentCreatedWidgetComponent extends BaseEventWidgetComponent {
|
|
6151
|
+
constructor(cd) {
|
|
6152
|
+
super(cd);
|
|
6153
|
+
}
|
|
6154
|
+
get agentName() {
|
|
6155
|
+
const raw = this.event?.payload?.text ||
|
|
6156
|
+
this.event?.payload?.data?.agentName ||
|
|
6157
|
+
'AI Agent';
|
|
6158
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6159
|
+
}
|
|
6160
|
+
get chatName() {
|
|
6161
|
+
const raw = this.event?.payload?.data?.chatName ||
|
|
6162
|
+
this.event?.payload?.url ||
|
|
6163
|
+
'';
|
|
6164
|
+
const cleaned = String(raw).replace(/\*/g, ' ').trim();
|
|
6165
|
+
return cleaned ? `Added to ${cleaned}` : 'AI Agent added to chat';
|
|
6166
|
+
}
|
|
6167
|
+
get imageUrl() {
|
|
6168
|
+
return (this.event?.payload?.imageUrl ||
|
|
6169
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6170
|
+
null);
|
|
6171
|
+
}
|
|
6172
|
+
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 }); }
|
|
6173
|
+
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 }] }); }
|
|
6174
|
+
}
|
|
6175
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatAgentCreatedWidgetComponent, decorators: [{
|
|
6176
|
+
type: Component,
|
|
6177
|
+
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" }]
|
|
6178
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6179
|
+
|
|
6180
|
+
class ChatMessageSentWidgetComponent extends BaseEventWidgetComponent {
|
|
6181
|
+
constructor(cd) {
|
|
6182
|
+
super(cd);
|
|
6183
|
+
}
|
|
6184
|
+
get chatName() {
|
|
6185
|
+
const raw = this.event?.payload?.text ||
|
|
6186
|
+
this.event?.payload?.data?.chatName ||
|
|
6187
|
+
'Chat';
|
|
6188
|
+
return String(raw).replace(/\*/g, ' ').trim();
|
|
6189
|
+
}
|
|
6190
|
+
get imageUrl() {
|
|
6191
|
+
return (this.event?.payload?.imageUrl ||
|
|
6192
|
+
this.event?.payload?.data?.imageUrl ||
|
|
6193
|
+
null);
|
|
6194
|
+
}
|
|
6195
|
+
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 }); }
|
|
6196
|
+
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 }] }); }
|
|
6197
|
+
}
|
|
6198
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChatMessageSentWidgetComponent, decorators: [{
|
|
6199
|
+
type: Component,
|
|
6200
|
+
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" }]
|
|
6201
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6202
|
+
|
|
6203
|
+
class ApplicationEventWidgetComponent extends BaseEventWidgetComponent {
|
|
6204
|
+
constructor(cd) {
|
|
6205
|
+
super(cd);
|
|
6206
|
+
}
|
|
6207
|
+
get eventAction() {
|
|
6208
|
+
const key = this.event?.widget || this.event?.name || '';
|
|
6209
|
+
if (key.includes('deleted'))
|
|
6210
|
+
return 'deleted';
|
|
6211
|
+
if (key.includes('updated'))
|
|
6212
|
+
return 'updated';
|
|
6213
|
+
return 'created';
|
|
6214
|
+
}
|
|
6215
|
+
get badgeLabel() {
|
|
6216
|
+
if (this.eventAction === 'deleted')
|
|
6217
|
+
return 'App Deleted';
|
|
6218
|
+
if (this.eventAction === 'updated')
|
|
6219
|
+
return 'App Updated';
|
|
6220
|
+
return 'App Created';
|
|
6221
|
+
}
|
|
6222
|
+
get badgeIcon() {
|
|
6223
|
+
if (this.eventAction === 'deleted')
|
|
6224
|
+
return 'delete_outline';
|
|
6225
|
+
if (this.eventAction === 'updated')
|
|
6226
|
+
return 'edit';
|
|
6227
|
+
return 'add_box';
|
|
6228
|
+
}
|
|
6229
|
+
get badgeClass() {
|
|
6230
|
+
if (this.eventAction === 'deleted')
|
|
6231
|
+
return 'app-deleted-badge';
|
|
6232
|
+
if (this.eventAction === 'updated')
|
|
6233
|
+
return 'app-updated-badge';
|
|
6234
|
+
return 'app-created-badge';
|
|
6235
|
+
}
|
|
6236
|
+
get placeholderClass() {
|
|
6237
|
+
if (this.eventAction === 'deleted')
|
|
6238
|
+
return 'app-deleted-placeholder';
|
|
6239
|
+
if (this.eventAction === 'updated')
|
|
6240
|
+
return 'app-updated-placeholder';
|
|
6241
|
+
return 'app-created-placeholder';
|
|
6242
|
+
}
|
|
6243
|
+
get appName() {
|
|
6244
|
+
return (this.event?.payload?.text ||
|
|
6245
|
+
this.event?.payload?.data?.name ||
|
|
6246
|
+
'Application');
|
|
6247
|
+
}
|
|
6248
|
+
get appUrl() {
|
|
6249
|
+
return (this.event?.payload?.url ||
|
|
6250
|
+
this.event?.payload?.data?.url ||
|
|
6251
|
+
null);
|
|
6252
|
+
}
|
|
6253
|
+
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 }); }
|
|
6254
|
+
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"] }] }); }
|
|
6255
|
+
}
|
|
6256
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ApplicationEventWidgetComponent, decorators: [{
|
|
6257
|
+
type: Component,
|
|
6258
|
+
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" }]
|
|
6259
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6260
|
+
|
|
6261
|
+
class RequestDemoClickedWidgetComponent extends BaseEventWidgetComponent {
|
|
6262
|
+
constructor(cd) {
|
|
6263
|
+
super(cd);
|
|
6264
|
+
}
|
|
6265
|
+
get title() {
|
|
6266
|
+
return this.event?.payload?.text || 'Request A Demo';
|
|
6267
|
+
}
|
|
6268
|
+
get pageUrl() {
|
|
6269
|
+
return this.event?.payload?.url || null;
|
|
6270
|
+
}
|
|
6271
|
+
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 }); }
|
|
6272
|
+
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 }] }); }
|
|
6273
|
+
}
|
|
6274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RequestDemoClickedWidgetComponent, decorators: [{
|
|
6275
|
+
type: Component,
|
|
6276
|
+
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" }]
|
|
6277
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
|
6278
|
+
|
|
5090
6279
|
class EventsWidgetsService {
|
|
5091
6280
|
constructor() {
|
|
5092
6281
|
this.widgetsMap = [
|
|
@@ -5102,10 +6291,53 @@ class EventsWidgetsService {
|
|
|
5102
6291
|
name: 'slide-number-changed',
|
|
5103
6292
|
component: SlideNumberChangedWidgetComponent,
|
|
5104
6293
|
},
|
|
6294
|
+
{
|
|
6295
|
+
name: 'profile-opened',
|
|
6296
|
+
component: ProfileOpenedWidgetComponent,
|
|
6297
|
+
},
|
|
6298
|
+
{
|
|
6299
|
+
name: 'chat-opened',
|
|
6300
|
+
component: ChatOpenedWidgetComponent,
|
|
6301
|
+
},
|
|
6302
|
+
{
|
|
6303
|
+
name: 'chat-created',
|
|
6304
|
+
component: ChatCreatedWidgetComponent,
|
|
6305
|
+
},
|
|
6306
|
+
{
|
|
6307
|
+
name: 'chat-member-invite-clicked',
|
|
6308
|
+
component: ChatMemberInviteClickedWidgetComponent,
|
|
6309
|
+
},
|
|
6310
|
+
{
|
|
6311
|
+
name: 'chat-agent-created',
|
|
6312
|
+
component: ChatAgentCreatedWidgetComponent,
|
|
6313
|
+
},
|
|
6314
|
+
{
|
|
6315
|
+
name: 'chat-message-sent',
|
|
6316
|
+
component: ChatMessageSentWidgetComponent,
|
|
6317
|
+
},
|
|
6318
|
+
{
|
|
6319
|
+
name: 'application-created',
|
|
6320
|
+
component: ApplicationEventWidgetComponent,
|
|
6321
|
+
},
|
|
6322
|
+
{
|
|
6323
|
+
name: 'application-updated',
|
|
6324
|
+
component: ApplicationEventWidgetComponent,
|
|
6325
|
+
},
|
|
6326
|
+
{
|
|
6327
|
+
name: 'application-deleted',
|
|
6328
|
+
component: ApplicationEventWidgetComponent,
|
|
6329
|
+
},
|
|
6330
|
+
{
|
|
6331
|
+
name: 'request-demo-clicked',
|
|
6332
|
+
component: RequestDemoClickedWidgetComponent,
|
|
6333
|
+
},
|
|
5105
6334
|
];
|
|
5106
6335
|
}
|
|
5107
6336
|
getWidgetComponentByName(name) {
|
|
5108
6337
|
/* eslint-disable */
|
|
6338
|
+
if (!name) {
|
|
6339
|
+
return null;
|
|
6340
|
+
}
|
|
5109
6341
|
const mapping = this.widgetsMap.find((e) => e.name === name);
|
|
5110
6342
|
if (!mapping) {
|
|
5111
6343
|
return null;
|
|
@@ -5131,9 +6363,24 @@ class EventThumbnailComponent {
|
|
|
5131
6363
|
this.cd = cd;
|
|
5132
6364
|
this.timeInAgoFormat = '';
|
|
5133
6365
|
}
|
|
6366
|
+
get widgetName() {
|
|
6367
|
+
return this.event?.widget || this.event?.name;
|
|
6368
|
+
}
|
|
6369
|
+
get hasWidget() {
|
|
6370
|
+
return !!this.widgetsService.getWidgetComponentByName(this.widgetName);
|
|
6371
|
+
}
|
|
6372
|
+
get hasDetails() {
|
|
6373
|
+
const payload = this.event?.payload;
|
|
6374
|
+
if (!payload) {
|
|
6375
|
+
return false;
|
|
6376
|
+
}
|
|
6377
|
+
const hasDataEntries = typeof payload.data === 'object' &&
|
|
6378
|
+
payload.data !== null &&
|
|
6379
|
+
Object.keys(payload.data).length > 0;
|
|
6380
|
+
return !!(hasDataEntries || payload.url || payload.text);
|
|
6381
|
+
}
|
|
5134
6382
|
ngOnInit() {
|
|
5135
|
-
|
|
5136
|
-
if (eventData) {
|
|
6383
|
+
if (this.hasDetails) {
|
|
5137
6384
|
this.generateTooltip();
|
|
5138
6385
|
}
|
|
5139
6386
|
this.timeInAgoFormat = this.timeFormatService.toAgo(this.event.createdAt);
|
|
@@ -5142,27 +6389,30 @@ class EventThumbnailComponent {
|
|
|
5142
6389
|
}, 20000);
|
|
5143
6390
|
}
|
|
5144
6391
|
generateTooltip() {
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
const eventData = this.event.payload?.data || this.event.data;
|
|
5148
|
-
if (typeof eventData !== 'object' || !eventData) {
|
|
6392
|
+
const payload = this.event?.payload;
|
|
6393
|
+
if (!payload) {
|
|
5149
6394
|
return;
|
|
5150
6395
|
}
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
tooltip += key + ' -> ' + eventData[key];
|
|
6396
|
+
const entries = new Map();
|
|
6397
|
+
const payloadData = payload.data;
|
|
6398
|
+
if (typeof payloadData === 'object' && payloadData !== null) {
|
|
6399
|
+
Object.entries(payloadData).forEach(([key, value]) => {
|
|
6400
|
+
if (value !== undefined && value !== null) {
|
|
6401
|
+
entries.set(key, value);
|
|
5158
6402
|
}
|
|
5159
|
-
}
|
|
5160
|
-
this.tooltip = tooltip;
|
|
6403
|
+
});
|
|
5161
6404
|
}
|
|
5162
|
-
|
|
5163
|
-
|
|
6405
|
+
if (payload.url && !entries.has('url')) {
|
|
6406
|
+
entries.set('url', payload.url);
|
|
5164
6407
|
}
|
|
5165
|
-
|
|
6408
|
+
if (payload.text && !entries.has('text')) {
|
|
6409
|
+
entries.set('text', payload.text);
|
|
6410
|
+
}
|
|
6411
|
+
const lines = [];
|
|
6412
|
+
entries.forEach((value, key) => {
|
|
6413
|
+
lines.push(`${key} -> ${String(value)}`);
|
|
6414
|
+
});
|
|
6415
|
+
this.tooltip = lines.join('\n');
|
|
5166
6416
|
}
|
|
5167
6417
|
ngOnChanges(changes) {
|
|
5168
6418
|
if (this.componentRef) {
|
|
@@ -5177,12 +6427,8 @@ class EventThumbnailComponent {
|
|
|
5177
6427
|
}
|
|
5178
6428
|
ngAfterViewInit() {
|
|
5179
6429
|
this.cd.detectChanges();
|
|
5180
|
-
|
|
5181
|
-
if (this.
|
|
5182
|
-
const widget = this.widgetsService.getWidgetComponentByName(this.event.widget);
|
|
5183
|
-
if (!widget) {
|
|
5184
|
-
return;
|
|
5185
|
-
}
|
|
6430
|
+
const widget = this.widgetsService.getWidgetComponentByName(this.widgetName);
|
|
6431
|
+
if (widget && this.widgetHost) {
|
|
5186
6432
|
const viewContainerRef = this.widgetHost.viewContainerRef;
|
|
5187
6433
|
viewContainerRef.clear();
|
|
5188
6434
|
const componentToShow = this.componentFactoryResolver.resolveComponentFactory(widget);
|
|
@@ -5191,14 +6437,13 @@ class EventThumbnailComponent {
|
|
|
5191
6437
|
this.componentRef.instance.session = this.session;
|
|
5192
6438
|
this.componentRef.changeDetectorRef.detectChanges();
|
|
5193
6439
|
}
|
|
5194
|
-
/* eslint-enable */
|
|
5195
6440
|
}
|
|
5196
6441
|
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 (
|
|
6442
|
+
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
6443
|
}
|
|
5199
6444
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: EventThumbnailComponent, decorators: [{
|
|
5200
6445
|
type: Component,
|
|
5201
|
-
args: [{ selector: 'rtsee-event-thumbnail', imports: [WidgetDirective, NgClass], standalone: true, template: "<div class=\"rtsee-events-dashboard-event-thumbnail\">\n @if (
|
|
6446
|
+
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
6447
|
}], ctorParameters: () => [{ type: EventsWidgetsService }, { type: i0.ComponentFactoryResolver }, { type: TimeFormatHelperService }, { type: i0.ChangeDetectorRef }], propDecorators: { event: [{
|
|
5203
6448
|
type: Input
|
|
5204
6449
|
}], session: [{
|
|
@@ -5337,13 +6582,13 @@ class JoinCallComponent {
|
|
|
5337
6582
|
this.recentlyCopied = false;
|
|
5338
6583
|
}, 2000);
|
|
5339
6584
|
}
|
|
5340
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: JoinCallComponent, deps: [{ token: i1$
|
|
6585
|
+
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
6586
|
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
6587
|
}
|
|
5343
6588
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: JoinCallComponent, decorators: [{
|
|
5344
6589
|
type: Component,
|
|
5345
6590
|
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$
|
|
6591
|
+
}], ctorParameters: () => [{ type: i1$4.MessageService }], propDecorators: { presentation: [{
|
|
5347
6592
|
type: Input
|
|
5348
6593
|
}], room: [{
|
|
5349
6594
|
type: Input
|
|
@@ -5982,7 +7227,7 @@ class IllustratorComponent {
|
|
|
5982
7227
|
return item.id || `agent-${index}`;
|
|
5983
7228
|
}
|
|
5984
7229
|
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 }); }
|
|
7230
|
+
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
7231
|
}
|
|
5987
7232
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: IllustratorComponent, decorators: [{
|
|
5988
7233
|
type: Component,
|
|
@@ -6562,7 +7807,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
6562
7807
|
|
|
6563
7808
|
class RtseeEntityCommentsComponent {
|
|
6564
7809
|
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"] }] }); }
|
|
7810
|
+
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
7811
|
}
|
|
6567
7812
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeEntityCommentsComponent, decorators: [{
|
|
6568
7813
|
type: Component,
|
|
@@ -6622,12 +7867,14 @@ class RateInputComponent {
|
|
|
6622
7867
|
}
|
|
6623
7868
|
}
|
|
6624
7869
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RateInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6625
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RateInputComponent, isStandalone: true, selector: "rtsee-rate-input", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"rtsee-rate-input\">\n <div class=\"rtsee-rate-input-header\">\n <h3 class=\"rtsee-rate-input-name\">{{ config.name }}</h3>\n @if (config.description) {\n <p class=\"rtsee-rate-input-description\">{{ config.description }}</p>\n }\n </div>\n <div class=\"rtsee-rate-form-container\">\n <form [formGroup]=\"sendRateForm\" class=\"rtsee-rate-form\">\n <textarea\n [invalid]=\"false\"\n [autoResize]=\"true\"\n formControlName=\"comment\"\n pTextarea\n placeholder=\"Your comment here...\"\n class=\"rtsee-rate-comment-field\"\n rows=\"1\"\n cols=\"30\"\n ></textarea>\n </form>\n </div>\n <div class=\"rtsee-rate-select-container\">\n <rtsee-rating [config]=\"config\"></rtsee-rating>\n @if (!config.rate?.value && showMissingRateError) {\n <p-message severity=\"error\">Please add your rate!</p-message>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "component", type: RatingComponent, selector: "rtsee-rating", inputs: ["config", "rate"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
|
|
7870
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RateInputComponent, isStandalone: true, selector: "rtsee-rate-input", inputs: { showMissingRateError: "showMissingRateError", config: "config" }, ngImport: i0, template: "<div class=\"rtsee-rate-input\">\n <div class=\"rtsee-rate-input-header\">\n <h3 class=\"rtsee-rate-input-name\">{{ config.name }}</h3>\n @if (config.description) {\n <p class=\"rtsee-rate-input-description\">{{ config.description }}</p>\n }\n </div>\n <div class=\"rtsee-rate-form-container\">\n <form [formGroup]=\"sendRateForm\" class=\"rtsee-rate-form\">\n <textarea\n [invalid]=\"false\"\n [autoResize]=\"true\"\n formControlName=\"comment\"\n pTextarea\n placeholder=\"Your comment here...\"\n class=\"rtsee-rate-comment-field\"\n rows=\"1\"\n cols=\"30\"\n ></textarea>\n </form>\n </div>\n <div class=\"rtsee-rate-select-container\">\n <rtsee-rating [config]=\"config\"></rtsee-rating>\n @if (!config.rate?.value && showMissingRateError) {\n <p-message severity=\"error\">Please add your rate!</p-message>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "component", type: RatingComponent, selector: "rtsee-rating", inputs: ["config", "rate"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
|
|
6626
7871
|
}
|
|
6627
7872
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RateInputComponent, decorators: [{
|
|
6628
7873
|
type: Component,
|
|
6629
7874
|
args: [{ selector: 'rtsee-rate-input', imports: [ReactiveFormsModule, Textarea, RatingComponent, Message], standalone: true, template: "<div class=\"rtsee-rate-input\">\n <div class=\"rtsee-rate-input-header\">\n <h3 class=\"rtsee-rate-input-name\">{{ config.name }}</h3>\n @if (config.description) {\n <p class=\"rtsee-rate-input-description\">{{ config.description }}</p>\n }\n </div>\n <div class=\"rtsee-rate-form-container\">\n <form [formGroup]=\"sendRateForm\" class=\"rtsee-rate-form\">\n <textarea\n [invalid]=\"false\"\n [autoResize]=\"true\"\n formControlName=\"comment\"\n pTextarea\n placeholder=\"Your comment here...\"\n class=\"rtsee-rate-comment-field\"\n rows=\"1\"\n cols=\"30\"\n ></textarea>\n </form>\n </div>\n <div class=\"rtsee-rate-select-container\">\n <rtsee-rating [config]=\"config\"></rtsee-rating>\n @if (!config.rate?.value && showMissingRateError) {\n <p-message severity=\"error\">Please add your rate!</p-message>\n }\n </div>\n</div>\n" }]
|
|
6630
|
-
}], propDecorators: {
|
|
7875
|
+
}], propDecorators: { showMissingRateError: [{
|
|
7876
|
+
type: Input
|
|
7877
|
+
}], config: [{
|
|
6631
7878
|
type: Input
|
|
6632
7879
|
}] } });
|
|
6633
7880
|
|
|
@@ -6673,6 +7920,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
6673
7920
|
class RaterComponent {
|
|
6674
7921
|
constructor() {
|
|
6675
7922
|
this.isEditing = false;
|
|
7923
|
+
this.showMissingRateError = false;
|
|
6676
7924
|
this.RTSeeTextLabelKeys = RTSeeTextLabelKeys;
|
|
6677
7925
|
}
|
|
6678
7926
|
ngOnInit() {
|
|
@@ -6688,6 +7936,13 @@ class RaterComponent {
|
|
|
6688
7936
|
const rates = this.rater.configsWithRates
|
|
6689
7937
|
.map((config) => config.rate)
|
|
6690
7938
|
.filter((r) => !!r);
|
|
7939
|
+
const hasInvalidRate = rates.length === 0 ||
|
|
7940
|
+
rates.some((r) => typeof r.value !== 'number' || !Number.isFinite(r.value) || r.value <= 0);
|
|
7941
|
+
if (hasInvalidRate) {
|
|
7942
|
+
this.showMissingRateError = true;
|
|
7943
|
+
return;
|
|
7944
|
+
}
|
|
7945
|
+
this.showMissingRateError = false;
|
|
6691
7946
|
if (this.rater.userRateGroup) {
|
|
6692
7947
|
await this.rater.editRateGroup({
|
|
6693
7948
|
...this.rater.userRateGroup,
|
|
@@ -6712,6 +7967,7 @@ class RaterComponent {
|
|
|
6712
7967
|
}
|
|
6713
7968
|
}
|
|
6714
7969
|
startEdit() {
|
|
7970
|
+
this.showMissingRateError = false;
|
|
6715
7971
|
this.isEditing = true;
|
|
6716
7972
|
}
|
|
6717
7973
|
async getRatingConfigurations() {
|
|
@@ -6724,11 +7980,11 @@ class RaterComponent {
|
|
|
6724
7980
|
return rates;
|
|
6725
7981
|
}
|
|
6726
7982
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RaterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6727
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RaterComponent, isStandalone: true, selector: "rtsee-rater", inputs: { entity: "entity", rater: "rater" }, ngImport: i0, template: "<div class=\"rtsee-rater\" [ngClass]=\"{'rtsee-rater-view-mode': rater.userRateGroup && !isEditing}\">\n @if (rater.userRateGroup && !isEditing) {\n <rtsee-rate-item\n [group]=\"rater.userRateGroup\"\n [rater]=\"rater\"\n [showActions]=\"true\"\n (edit)=\"startEdit()\"\n (delete)=\"deleteRate()\"\n ></rtsee-rate-item>\n } @else {\n <div class=\"rtsee-rater-user-header\">\n @if (rater.peer?.imageUrl) {\n <img\n class=\"rtsee-rater-avatar\"\n [src]=\"rater.peer?.imageUrl\"\n alt=\"User avatar\"\n />\n } @else {\n <div class=\"rtsee-rater-avatar-fallback\">\n {{ (rater.peer?.name || \"?\").substring(0, 1) }}\n </div>\n }\n <div class=\"rtsee-rater-user-info\">\n <span class=\"rtsee-rater-user-name\">{{\n rater.peer?.name || \"Anonymous\"\n }}</span>\n <span class=\"rtsee-rater-user-status\">Rating publicly</span>\n </div>\n </div>\n <hr class=\"rtsee-rater-divider\" />\n @for (config of rater.configsWithRates; track config.id) {\n <rtsee-rate-input
|
|
7983
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RaterComponent, isStandalone: true, selector: "rtsee-rater", inputs: { entity: "entity", rater: "rater" }, ngImport: i0, template: "<div class=\"rtsee-rater\" [ngClass]=\"{'rtsee-rater-view-mode': rater.userRateGroup && !isEditing}\">\n @if (rater.userRateGroup && !isEditing) {\n <rtsee-rate-item\n [group]=\"rater.userRateGroup\"\n [rater]=\"rater\"\n [showActions]=\"true\"\n (edit)=\"startEdit()\"\n (delete)=\"deleteRate()\"\n ></rtsee-rate-item>\n } @else {\n <div class=\"rtsee-rater-user-header\">\n @if (rater.peer?.imageUrl) {\n <img\n class=\"rtsee-rater-avatar\"\n [src]=\"rater.peer?.imageUrl\"\n alt=\"User avatar\"\n />\n } @else {\n <div class=\"rtsee-rater-avatar-fallback\">\n {{ (rater.peer?.name || \"?\").substring(0, 1) }}\n </div>\n }\n <div class=\"rtsee-rater-user-info\">\n <span class=\"rtsee-rater-user-name\">{{\n rater.peer?.name || \"Anonymous\"\n }}</span>\n <span class=\"rtsee-rater-user-status\">Rating publicly</span>\n </div>\n </div>\n <hr class=\"rtsee-rater-divider\" />\n @for (config of rater.configsWithRates; track config.id) {\n <rtsee-rate-input\n [config]=\"config\"\n [showMissingRateError]=\"showMissingRateError\"\n ></rtsee-rate-input>\n }\n <div class=\"rtsee-rater-actions\">\n @if (rater.userRateGroup) {\n <p-button\n (click)=\"sendRate()\"\n [severity]=\"'success'\"\n [label]=\"rater.messenger.labels[RTSeeTextLabelKeys.RATER_UPDATE]\"\n type=\"submit\"\n class=\"rtsee-rater-btn-update rts-action-button\"\n >\n <span class=\"pi pi-check\"></span>\n </p-button>\n <p-button\n (click)=\"deleteRate()\"\n [severity]=\"'danger'\"\n [label]=\"rater.messenger.labels[RTSeeTextLabelKeys.RATER_DELETE]\"\n class=\"rtsee-rater-btn-delete rts-action-button\"\n >\n <span class=\"pi pi-trash\"></span>\n </p-button>\n } @else {\n <p-button\n (click)=\"sendRate()\"\n [severity]=\"'primary'\"\n [label]=\"rater.messenger.labels[RTSeeTextLabelKeys.RATER_SEND]\"\n type=\"submit\"\n class=\"rtsee-rater-btn-send rts-action-button\"\n >\n <span class=\"pi pi-send\"></span>\n </p-button>\n }\n </div>\n }\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: "component", type: RateInputComponent, selector: "rtsee-rate-input", inputs: ["showMissingRateError", "config"] }, { kind: "component", type: RateItemComponent, selector: "rtsee-rate-item", inputs: ["group", "rater", "showActions"], outputs: ["edit", "delete"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
6728
7984
|
}
|
|
6729
7985
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RaterComponent, decorators: [{
|
|
6730
7986
|
type: Component,
|
|
6731
|
-
args: [{ selector: 'rtsee-rater', imports: [Button, RateInputComponent, RateItemComponent, NgClass], template: "<div class=\"rtsee-rater\" [ngClass]=\"{'rtsee-rater-view-mode': rater.userRateGroup && !isEditing}\">\n @if (rater.userRateGroup && !isEditing) {\n <rtsee-rate-item\n [group]=\"rater.userRateGroup\"\n [rater]=\"rater\"\n [showActions]=\"true\"\n (edit)=\"startEdit()\"\n (delete)=\"deleteRate()\"\n ></rtsee-rate-item>\n } @else {\n <div class=\"rtsee-rater-user-header\">\n @if (rater.peer?.imageUrl) {\n <img\n class=\"rtsee-rater-avatar\"\n [src]=\"rater.peer?.imageUrl\"\n alt=\"User avatar\"\n />\n } @else {\n <div class=\"rtsee-rater-avatar-fallback\">\n {{ (rater.peer?.name || \"?\").substring(0, 1) }}\n </div>\n }\n <div class=\"rtsee-rater-user-info\">\n <span class=\"rtsee-rater-user-name\">{{\n rater.peer?.name || \"Anonymous\"\n }}</span>\n <span class=\"rtsee-rater-user-status\">Rating publicly</span>\n </div>\n </div>\n <hr class=\"rtsee-rater-divider\" />\n @for (config of rater.configsWithRates; track config.id) {\n <rtsee-rate-input
|
|
7987
|
+
args: [{ selector: 'rtsee-rater', imports: [Button, RateInputComponent, RateItemComponent, NgClass], template: "<div class=\"rtsee-rater\" [ngClass]=\"{'rtsee-rater-view-mode': rater.userRateGroup && !isEditing}\">\n @if (rater.userRateGroup && !isEditing) {\n <rtsee-rate-item\n [group]=\"rater.userRateGroup\"\n [rater]=\"rater\"\n [showActions]=\"true\"\n (edit)=\"startEdit()\"\n (delete)=\"deleteRate()\"\n ></rtsee-rate-item>\n } @else {\n <div class=\"rtsee-rater-user-header\">\n @if (rater.peer?.imageUrl) {\n <img\n class=\"rtsee-rater-avatar\"\n [src]=\"rater.peer?.imageUrl\"\n alt=\"User avatar\"\n />\n } @else {\n <div class=\"rtsee-rater-avatar-fallback\">\n {{ (rater.peer?.name || \"?\").substring(0, 1) }}\n </div>\n }\n <div class=\"rtsee-rater-user-info\">\n <span class=\"rtsee-rater-user-name\">{{\n rater.peer?.name || \"Anonymous\"\n }}</span>\n <span class=\"rtsee-rater-user-status\">Rating publicly</span>\n </div>\n </div>\n <hr class=\"rtsee-rater-divider\" />\n @for (config of rater.configsWithRates; track config.id) {\n <rtsee-rate-input\n [config]=\"config\"\n [showMissingRateError]=\"showMissingRateError\"\n ></rtsee-rate-input>\n }\n <div class=\"rtsee-rater-actions\">\n @if (rater.userRateGroup) {\n <p-button\n (click)=\"sendRate()\"\n [severity]=\"'success'\"\n [label]=\"rater.messenger.labels[RTSeeTextLabelKeys.RATER_UPDATE]\"\n type=\"submit\"\n class=\"rtsee-rater-btn-update rts-action-button\"\n >\n <span class=\"pi pi-check\"></span>\n </p-button>\n <p-button\n (click)=\"deleteRate()\"\n [severity]=\"'danger'\"\n [label]=\"rater.messenger.labels[RTSeeTextLabelKeys.RATER_DELETE]\"\n class=\"rtsee-rater-btn-delete rts-action-button\"\n >\n <span class=\"pi pi-trash\"></span>\n </p-button>\n } @else {\n <p-button\n (click)=\"sendRate()\"\n [severity]=\"'primary'\"\n [label]=\"rater.messenger.labels[RTSeeTextLabelKeys.RATER_SEND]\"\n type=\"submit\"\n class=\"rtsee-rater-btn-send rts-action-button\"\n >\n <span class=\"pi pi-send\"></span>\n </p-button>\n }\n </div>\n }\n</div>\n" }]
|
|
6732
7988
|
}], propDecorators: { entity: [{
|
|
6733
7989
|
type: Input
|
|
6734
7990
|
}], rater: [{
|
|
@@ -7017,11 +8273,11 @@ class StoryDetailsComponent {
|
|
|
7017
8273
|
return stars;
|
|
7018
8274
|
}
|
|
7019
8275
|
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"] }] }); }
|
|
8276
|
+
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/Book\"\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 && story.rating > 0) {\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 <meta itemprop=\"ratingCount\" [attr.content]=\"story.ratesCount || 1\" />\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 || 1 }}</span>\n <span>)</span>\n </span\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
8277
|
}
|
|
7022
8278
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryDetailsComponent, decorators: [{
|
|
7023
8279
|
type: Component,
|
|
7024
|
-
args: [{ selector: 'rtsee-story-details', imports: [Chip, Tag, Button, ChatComponent, RtseeEntityPreviewComponent, RouterLink, StoryElementThumbnailComponent, StorySlidesPreviewComponent], 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" }]
|
|
8280
|
+
args: [{ selector: 'rtsee-story-details', imports: [Chip, Tag, Button, ChatComponent, RtseeEntityPreviewComponent, RouterLink, StoryElementThumbnailComponent, StorySlidesPreviewComponent], template: "<div\n class=\"rtsee-story-details\"\n itemscope\n itemtype=\"https://schema.org/Book\"\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 && story.rating > 0) {\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 <meta itemprop=\"ratingCount\" [attr.content]=\"story.ratesCount || 1\" />\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 || 1 }}</span>\n <span>)</span>\n </span\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" }]
|
|
7025
8281
|
}], propDecorators: { story: [{
|
|
7026
8282
|
type: Input
|
|
7027
8283
|
}], presentation: [{
|
|
@@ -7127,6 +8383,7 @@ class RTSeeContainerComponent {
|
|
|
7127
8383
|
this.isSidenavExpanded = true;
|
|
7128
8384
|
this.isSidenavContent = false;
|
|
7129
8385
|
this.isSidenavFullScreen = false;
|
|
8386
|
+
this.RTSeeTextLabelKeys = RTSeeTextLabelKeys;
|
|
7130
8387
|
}
|
|
7131
8388
|
ngOnInit() {
|
|
7132
8389
|
this.authService.init(this.auth);
|
|
@@ -7163,7 +8420,7 @@ class RTSeeContainerComponent {
|
|
|
7163
8420
|
this.isSidenavFullScreen = rtseeRoute.fullScreen || false;
|
|
7164
8421
|
}
|
|
7165
8422
|
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"] }] }); }
|
|
8423
|
+
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 && rtsee.messenger.pendingInviteToken && rtsee.activeTab !== 'messenger') {\n <div class=\"rtsee-mobile-invite-popup-wrapper rts-theme-dark\">\n <div class=\"rts-invite-popup-modal\">\n <div class=\"rts-invite-popup-content\">\n <span class=\"material-icons-outlined rts-invite-popup-icon\">mail_outline</span>\n <div class=\"rts-invite-popup-text\">\n @if (rtsee.messenger.pendingInviteInfo?.inviter?.name) {\n <strong>{{ rtsee.messenger.pendingInviteInfo?.inviter?.name }}</strong>\n <span> {{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_TEXT] }}</span>\n @if (rtsee.messenger.pendingInviteInfo?.chat?.name) {\n <span class=\"rts-invite-popup-chat-name\"> ({{ rtsee.messenger.pendingInviteInfo?.chat?.name }})</span>\n }\n } @else {\n <span>{{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_GENERIC_TEXT] }}</span>\n }\n </div>\n </div>\n <div class=\"rts-invite-popup-actions\">\n <button type=\"button\"\n class=\"rts-btn rts-btn-secondary rts-invite-popup-btn\"\n [disabled]=\"rtsee.messenger.inviteJoinInProgress\"\n (click)=\"rtsee.messenger.ignoreChatInvitation()\"\n >\n {{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_IGNORE_BUTTON] }}\n </button>\n <button type=\"button\"\n class=\"rts-btn rts-btn-primary rts-invite-popup-btn\"\n [disabled]=\"rtsee.messenger.inviteJoinInProgress\"\n (click)=\"rtsee.messenger.acceptChatInvitation()\"\n >\n {{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_JOIN_BUTTON] }}\n </button>\n </div>\n </div>\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
8424
|
}
|
|
7168
8425
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RTSeeContainerComponent, decorators: [{
|
|
7169
8426
|
type: Component,
|
|
@@ -7174,7 +8431,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
7174
8431
|
RtseeEventsDashboardComponent,
|
|
7175
8432
|
PresentationComponent,
|
|
7176
8433
|
RtseeNavComponent,
|
|
7177
|
-
], standalone: true, 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" }]
|
|
8434
|
+
], standalone: true, 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 && rtsee.messenger.pendingInviteToken && rtsee.activeTab !== 'messenger') {\n <div class=\"rtsee-mobile-invite-popup-wrapper rts-theme-dark\">\n <div class=\"rts-invite-popup-modal\">\n <div class=\"rts-invite-popup-content\">\n <span class=\"material-icons-outlined rts-invite-popup-icon\">mail_outline</span>\n <div class=\"rts-invite-popup-text\">\n @if (rtsee.messenger.pendingInviteInfo?.inviter?.name) {\n <strong>{{ rtsee.messenger.pendingInviteInfo?.inviter?.name }}</strong>\n <span> {{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_TEXT] }}</span>\n @if (rtsee.messenger.pendingInviteInfo?.chat?.name) {\n <span class=\"rts-invite-popup-chat-name\"> ({{ rtsee.messenger.pendingInviteInfo?.chat?.name }})</span>\n }\n } @else {\n <span>{{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_POPUP_GENERIC_TEXT] }}</span>\n }\n </div>\n </div>\n <div class=\"rts-invite-popup-actions\">\n <button type=\"button\"\n class=\"rts-btn rts-btn-secondary rts-invite-popup-btn\"\n [disabled]=\"rtsee.messenger.inviteJoinInProgress\"\n (click)=\"rtsee.messenger.ignoreChatInvitation()\"\n >\n {{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_IGNORE_BUTTON] }}\n </button>\n <button type=\"button\"\n class=\"rts-btn rts-btn-primary rts-invite-popup-btn\"\n [disabled]=\"rtsee.messenger.inviteJoinInProgress\"\n (click)=\"rtsee.messenger.acceptChatInvitation()\"\n >\n {{ rtsee.messenger.labels[RTSeeTextLabelKeys.MESSENGER_INVITE_JOIN_BUTTON] }}\n </button>\n </div>\n </div>\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" }]
|
|
7178
8435
|
}], ctorParameters: () => [{ type: RTSeeAuthService }, { type: i2.Router }], propDecorators: { rtsee: [{
|
|
7179
8436
|
type: Input
|
|
7180
8437
|
}], navigationConfig: [{
|
|
@@ -8091,7 +9348,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
8091
9348
|
|
|
8092
9349
|
class PrivacyPolicyComponent {
|
|
8093
9350
|
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"] }] }); }
|
|
9351
|
+
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
9352
|
}
|
|
8096
9353
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PrivacyPolicyComponent, decorators: [{
|
|
8097
9354
|
type: Component,
|
|
@@ -8439,5 +9696,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
8439
9696
|
* Generated bundle index. Do not edit.
|
|
8440
9697
|
*/
|
|
8441
9698
|
|
|
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 };
|
|
9699
|
+
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
9700
|
//# sourceMappingURL=rtsee-ngx.mjs.map
|