@rtsee/ngx 0.0.117 → 0.0.119
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.
|
@@ -54,7 +54,7 @@ import { Tag } from 'primeng/tag';
|
|
|
54
54
|
import { SelectButton } from 'primeng/selectbutton';
|
|
55
55
|
import { RTSeeRoutesList } from '@rtsee/factory';
|
|
56
56
|
import { Avatar } from 'primeng/avatar';
|
|
57
|
-
import { Image } from 'primeng/image';
|
|
57
|
+
import { Image as Image$1 } from 'primeng/image';
|
|
58
58
|
import { PanelMenu } from 'primeng/panelmenu';
|
|
59
59
|
import { Menu } from 'primeng/menu';
|
|
60
60
|
import { Password } from 'primeng/password';
|
|
@@ -1961,11 +1961,11 @@ class RatingComponent {
|
|
|
1961
1961
|
this.init();
|
|
1962
1962
|
}
|
|
1963
1963
|
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
|
|
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 <meta itemprop=\"worstRating\" content=\"1\" />\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\" itemprop=\"ratingValue\">{{ 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
1965
|
}
|
|
1966
1966
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RatingComponent, decorators: [{
|
|
1967
1967
|
type: Component,
|
|
1968
|
-
args: [{ selector: 'rtsee-rating', imports: [NgClass, DecimalPipe], template: "<div
|
|
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 <meta itemprop=\"worstRating\" content=\"1\" />\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\" itemprop=\"ratingValue\">{{ rateValue | number:'1.1-1' }}</span>\n }\n</div>\n" }]
|
|
1969
1969
|
}], propDecorators: { config: [{
|
|
1970
1970
|
type: Input
|
|
1971
1971
|
}], rate: [{
|
|
@@ -2122,7 +2122,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2122
2122
|
}] } });
|
|
2123
2123
|
|
|
2124
2124
|
class MediaWidgetComponent {
|
|
2125
|
-
constructor() {
|
|
2125
|
+
constructor(cdr) {
|
|
2126
|
+
this.cdr = cdr;
|
|
2126
2127
|
this.showCost = true;
|
|
2127
2128
|
this.visibleImages = [];
|
|
2128
2129
|
this.hiddenCount = 0;
|
|
@@ -2130,6 +2131,7 @@ class MediaWidgetComponent {
|
|
|
2130
2131
|
this.downloadingUrl = null;
|
|
2131
2132
|
this.loadedImageUrls = new Set();
|
|
2132
2133
|
this.erroredImageUrls = new Set();
|
|
2134
|
+
this.preloadingImageUrls = new Set();
|
|
2133
2135
|
this.MAX_GRID = 4;
|
|
2134
2136
|
}
|
|
2135
2137
|
ngOnInit() {
|
|
@@ -2142,26 +2144,102 @@ class MediaWidgetComponent {
|
|
|
2142
2144
|
this.updateVisibleImages();
|
|
2143
2145
|
}
|
|
2144
2146
|
}
|
|
2145
|
-
|
|
2147
|
+
get isAiGenerated() {
|
|
2148
|
+
return Boolean(this.message?.from?.isAgent ||
|
|
2149
|
+
this.message?.cost ||
|
|
2150
|
+
this.message?.data?.flowId ||
|
|
2151
|
+
this.message?.data?.requestId ||
|
|
2152
|
+
this.message?.data?.awaitingGeneration);
|
|
2153
|
+
}
|
|
2154
|
+
get isAwaitingGeneration() {
|
|
2155
|
+
return !this.hasImages && !this.hasVideo;
|
|
2156
|
+
}
|
|
2157
|
+
get awaitingPlaceholderText() {
|
|
2158
|
+
return this.message?.data?.placeholderText || 'Generating image...';
|
|
2159
|
+
}
|
|
2160
|
+
/** Downsized version for rendering/export, the original otherwise */
|
|
2146
2161
|
previewUrl(img) {
|
|
2147
2162
|
return img.smallVersionUrl || img.url;
|
|
2148
2163
|
}
|
|
2164
|
+
/**
|
|
2165
|
+
* URL bound to the <img> element:
|
|
2166
|
+
* - While the full-size image is already loaded and `smallVersionUrl` is being preloaded,
|
|
2167
|
+
* keep displaying the loaded full-size `img.url` so there is no blank flicker,
|
|
2168
|
+
* then swap to `img.smallVersionUrl` as soon as it finishes preloading.
|
|
2169
|
+
*/
|
|
2170
|
+
displayUrl(img) {
|
|
2171
|
+
if (img.smallVersionUrl) {
|
|
2172
|
+
if (this.loadedImageUrls.has(img.smallVersionUrl)) {
|
|
2173
|
+
return img.smallVersionUrl;
|
|
2174
|
+
}
|
|
2175
|
+
if (this.loadedImageUrls.has(img.url)) {
|
|
2176
|
+
this.preloadSmallVersion(img.smallVersionUrl);
|
|
2177
|
+
return img.url;
|
|
2178
|
+
}
|
|
2179
|
+
return img.smallVersionUrl;
|
|
2180
|
+
}
|
|
2181
|
+
return img.url;
|
|
2182
|
+
}
|
|
2183
|
+
/**
|
|
2184
|
+
* True while the full-size image is being compressed/uploaded by ImageCropper/Uploader
|
|
2185
|
+
* or while the resulting `smallVersionUrl` is preloading to replace the full-size image.
|
|
2186
|
+
*/
|
|
2187
|
+
isProcessingImage(img) {
|
|
2188
|
+
const optimizingMessage = Boolean(this.message?.data?.isOptimizingImages ||
|
|
2189
|
+
this.messenger?.isOptimizingMessageImages?.(this.message?.id));
|
|
2190
|
+
if (optimizingMessage && !img.smallVersionUrl) {
|
|
2191
|
+
return true;
|
|
2192
|
+
}
|
|
2193
|
+
if (img.smallVersionUrl &&
|
|
2194
|
+
this.loadedImageUrls.has(img.url) &&
|
|
2195
|
+
!this.loadedImageUrls.has(img.smallVersionUrl) &&
|
|
2196
|
+
!this.erroredImageUrls.has(img.smallVersionUrl)) {
|
|
2197
|
+
return true;
|
|
2198
|
+
}
|
|
2199
|
+
return false;
|
|
2200
|
+
}
|
|
2149
2201
|
isImageLoaded(img) {
|
|
2150
|
-
const url = this.
|
|
2202
|
+
const url = this.displayUrl(img);
|
|
2151
2203
|
return this.loadedImageUrls.has(url);
|
|
2152
2204
|
}
|
|
2153
2205
|
isImageError(img) {
|
|
2154
|
-
const url = this.
|
|
2206
|
+
const url = this.displayUrl(img);
|
|
2155
2207
|
return this.erroredImageUrls.has(url);
|
|
2156
2208
|
}
|
|
2157
2209
|
onImageLoad(img) {
|
|
2158
|
-
const url = this.
|
|
2210
|
+
const url = this.displayUrl(img);
|
|
2159
2211
|
this.loadedImageUrls.add(url);
|
|
2212
|
+
if (img.smallVersionUrl && url === img.url && !this.loadedImageUrls.has(img.smallVersionUrl)) {
|
|
2213
|
+
this.preloadSmallVersion(img.smallVersionUrl);
|
|
2214
|
+
}
|
|
2160
2215
|
}
|
|
2161
2216
|
onImageError(img) {
|
|
2162
|
-
const url = this.
|
|
2217
|
+
const url = this.displayUrl(img);
|
|
2163
2218
|
this.erroredImageUrls.add(url);
|
|
2164
2219
|
}
|
|
2220
|
+
preloadSmallVersion(smallUrl) {
|
|
2221
|
+
if (typeof window === 'undefined' ||
|
|
2222
|
+
!smallUrl ||
|
|
2223
|
+
this.loadedImageUrls.has(smallUrl) ||
|
|
2224
|
+
this.preloadingImageUrls.has(smallUrl)) {
|
|
2225
|
+
return;
|
|
2226
|
+
}
|
|
2227
|
+
this.preloadingImageUrls.add(smallUrl);
|
|
2228
|
+
const preloader = new Image();
|
|
2229
|
+
preloader.onload = () => {
|
|
2230
|
+
this.preloadingImageUrls.delete(smallUrl);
|
|
2231
|
+
this.loadedImageUrls.add(smallUrl);
|
|
2232
|
+
this.cdr.markForCheck();
|
|
2233
|
+
this.cdr.detectChanges();
|
|
2234
|
+
};
|
|
2235
|
+
preloader.onerror = () => {
|
|
2236
|
+
this.preloadingImageUrls.delete(smallUrl);
|
|
2237
|
+
this.erroredImageUrls.add(smallUrl);
|
|
2238
|
+
this.cdr.markForCheck();
|
|
2239
|
+
this.cdr.detectChanges();
|
|
2240
|
+
};
|
|
2241
|
+
preloader.src = smallUrl;
|
|
2242
|
+
}
|
|
2165
2243
|
async downloadOriginal(event, img) {
|
|
2166
2244
|
event.stopPropagation();
|
|
2167
2245
|
event.preventDefault();
|
|
@@ -2215,11 +2293,12 @@ class MediaWidgetComponent {
|
|
|
2215
2293
|
sendToIllustrator(event, img) {
|
|
2216
2294
|
event.stopPropagation();
|
|
2217
2295
|
event.preventDefault();
|
|
2218
|
-
|
|
2219
|
-
|
|
2296
|
+
const targetUrl = this.previewUrl(img);
|
|
2297
|
+
if (typeof window !== 'undefined' && targetUrl) {
|
|
2298
|
+
// Use the web-optimized URL (smallVersionUrl when available) for Illustrator & Story Editor
|
|
2220
2299
|
window.dispatchEvent(new CustomEvent(RTSeeIllustratorEvents.SET_IMAGE_FOR_REVIEW, {
|
|
2221
2300
|
detail: {
|
|
2222
|
-
imageUrl:
|
|
2301
|
+
imageUrl: targetUrl,
|
|
2223
2302
|
prompt: img.name || (typeof this.message.text === 'string' ? this.message.text : '') || '',
|
|
2224
2303
|
source: 'messenger',
|
|
2225
2304
|
},
|
|
@@ -2229,11 +2308,12 @@ class MediaWidgetComponent {
|
|
|
2229
2308
|
addToContext(event, img) {
|
|
2230
2309
|
event.stopPropagation();
|
|
2231
2310
|
event.preventDefault();
|
|
2232
|
-
|
|
2311
|
+
const targetUrl = this.previewUrl(img);
|
|
2312
|
+
if (typeof window !== 'undefined' && targetUrl) {
|
|
2233
2313
|
window.dispatchEvent(new CustomEvent(RTSeeIllustratorEvents.ADD_IMAGE_TO_CONTEXT, {
|
|
2234
2314
|
detail: {
|
|
2235
2315
|
id: 'chat-img-' + Math.random().toString(36).substring(2, 9),
|
|
2236
|
-
imageUrl:
|
|
2316
|
+
imageUrl: targetUrl,
|
|
2237
2317
|
title: img.name || 'Chat image',
|
|
2238
2318
|
description: (typeof this.message.text === 'string' ? this.message.text : '') || '',
|
|
2239
2319
|
visualDescription: '',
|
|
@@ -2244,7 +2324,11 @@ class MediaWidgetComponent {
|
|
|
2244
2324
|
}
|
|
2245
2325
|
}
|
|
2246
2326
|
updateVisibleImages() {
|
|
2247
|
-
const
|
|
2327
|
+
const rawImages = this.message?.images || [];
|
|
2328
|
+
// AI-generated messages only show a single image; user messages can show multiple images
|
|
2329
|
+
const all = this.isAiGenerated && rawImages.length > 1
|
|
2330
|
+
? [rawImages[rawImages.length - 1]]
|
|
2331
|
+
: rawImages;
|
|
2248
2332
|
if (this.showAll || all.length <= this.MAX_GRID) {
|
|
2249
2333
|
this.visibleImages = all;
|
|
2250
2334
|
this.hiddenCount = 0;
|
|
@@ -2253,27 +2337,33 @@ class MediaWidgetComponent {
|
|
|
2253
2337
|
this.visibleImages = all.slice(0, this.MAX_GRID);
|
|
2254
2338
|
this.hiddenCount = all.length - this.MAX_GRID;
|
|
2255
2339
|
}
|
|
2340
|
+
for (const img of this.visibleImages) {
|
|
2341
|
+
if (img.smallVersionUrl && this.loadedImageUrls.has(img.url) && !this.loadedImageUrls.has(img.smallVersionUrl)) {
|
|
2342
|
+
this.preloadSmallVersion(img.smallVersionUrl);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2256
2345
|
}
|
|
2257
2346
|
notifyRequestedGeneration() {
|
|
2258
2347
|
const reqId = this.message?.data?.requestId;
|
|
2259
|
-
|
|
2348
|
+
const optimizedUrl = this.visibleImages[0]?.smallVersionUrl;
|
|
2349
|
+
if (reqId && optimizedUrl && typeof window !== 'undefined') {
|
|
2260
2350
|
window.dispatchEvent(new CustomEvent(RTSeeIllustratorEvents.REQUESTED_GENERATION_SUCCEED, {
|
|
2261
2351
|
detail: {
|
|
2262
2352
|
requestId: reqId,
|
|
2263
|
-
imageUrl:
|
|
2353
|
+
imageUrl: optimizedUrl,
|
|
2264
2354
|
messageId: this.message.id,
|
|
2265
2355
|
chatId: this.chat?.id,
|
|
2266
2356
|
},
|
|
2267
2357
|
}));
|
|
2268
2358
|
}
|
|
2269
2359
|
}
|
|
2270
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MediaWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2271
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MediaWidgetComponent, isStandalone: true, selector: "rtsee-media-widget", inputs: { message: "message", messenger: "messenger", chat: "chat", showCost: "showCost" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-media-widget\">\n <!-- Video player -->\n @if (message.video) {\n <div class=\"rts-media-video\">\n <video\n controls\n playsinline\n preload=\"metadata\"\n [src]=\"message.video.url\"\n class=\"rts-video-player\"\n >\n Your browser does not support video playback.\n </video>\n </div>\n }\n\n <!-- Image grid -->\n @if (hasImages) {\n <div class=\"rts-media-images\" [ngClass]=\"gridClass\">\n @for (img of visibleImages; track img.id || img.url) {\n <div class=\"rts-media-image-wrapper\" [class.rts-image-loaded]=\"isImageLoaded(img)\">\n <!-- Media Placeholder (preview before image loads) -->\n @if (!isImageLoaded(img)) {\n <div class=\"rts-media-placeholder\" [class.rts-placeholder-error]=\"isImageError(img)\">\n <div class=\"rts-media-placeholder-shimmer\"></div>\n <div class=\"rts-media-placeholder-content\">\n @if (isImageError(img)) {\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">broken_image</span>\n <span class=\"rts-media-placeholder-text\">Failed to load</span>\n } @else {\n <div class=\"rts-media-placeholder-icon-wrap\">\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">image</span>\n </div>\n <span class=\"rts-media-placeholder-text\">{{ img.name || 'Loading media preview...' }}</span>\n }\n </div>\n </div>\n }\n\n <img\n [src]=\"previewUrl(img)\"\n [alt]=\"img.name\"\n class=\"rts-media-image\"\n [class.rts-media-image-loaded]=\"isImageLoaded(img)\"\n (load)=\"onImageLoad(img)\"\n (error)=\"onImageError(img)\"\n loading=\"lazy\"\n />\n\n @if (isImageLoaded(img)) {\n <button\n type=\"button\"\n class=\"rts-media-btn-download\"\n [class.rts-downloading]=\"downloadingUrl === img.url\"\n title=\"Download original image\"\n aria-label=\"Download original image\"\n (click)=\"downloadOriginal($event, img)\"\n >\n <i class=\"pi\" [ngClass]=\"downloadingUrl === img.url ? 'pi-spin pi-spinner' : 'pi-download'\"></i>\n </button>\n <div class=\"rts-media-image-actions\">\n <button\n type=\"button\"\n class=\"rts-media-btn-paint\"\n title=\"Send image to Illustrator (Review & Iterate)\"\n (click)=\"sendToIllustrator($event, img)\"\n >\n <i class=\"pi pi-palette\"></i>\n <span>+ paint</span>\n </button>\n <button\n type=\"button\"\n class=\"rts-media-btn-context\"\n title=\"Add image to Illustrator context references\"\n (click)=\"addToContext($event, img)\"\n >\n <i class=\"pi pi-plus\"></i>\n <span>+ context</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Show more / less toggle -->\n @if (hiddenCount > 0 || showAll) {\n <button class=\"rts-media-toggle\" (click)=\"toggleShowAll()\">\n {{ showAll ? 'Show less' : 'Show ' + hiddenCount + ' more' }}\n </button>\n }\n\n <!-- Cost display (optional, disabled when nested inside agentic widget) -->\n @if (showCost && message.cost) {\n <div class=\"rts-media-cost\">\n <rtsee-cost-display [cost]=\"message.cost\"></rtsee-cost-display>\n </div>\n }\n</div>\n", styles: [".rts-media-widget{max-width:100%}.rts-media-video{border-radius:8px;overflow:hidden;margin-bottom:6px;aspect-ratio:16/9;background:#000}.rts-video-player{width:100%;height:100%;max-height:360px;border-radius:8px;background:#000;display:block}.rts-media-images{display:grid;gap:4px;border-radius:8px;overflow:hidden;margin-bottom:4px}.rts-media-grid-1{grid-template-columns:1fr}.rts-media-grid-1 .rts-media-image-wrapper{min-height:220px;aspect-ratio:16/10}.rts-media-grid-1 .rts-media-image-wrapper.rts-image-loaded{min-height:0;aspect-ratio:auto}.rts-media-grid-2{grid-template-columns:1fr 1fr}.rts-media-grid-2 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-grid-4 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e);display:flex;align-items:center;justify-content:center}.rts-media-placeholder{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#1a1a2af5,#12121cfa);border:1px solid rgba(255,255,255,.06);border-radius:6px;z-index:2;overflow:hidden;pointer-events:none}.rts-media-placeholder .rts-media-placeholder-shimmer{position:absolute;top:0;left:-150%;width:150%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.03) 30%,rgba(168,85,247,.12) 50%,rgba(255,255,255,.03) 70%,transparent 100%);animation:rts-media-shimmer 2.2s infinite ease-in-out}.rts-media-placeholder .rts-media-placeholder-content{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:12px;text-align:center;max-width:90%}.rts-media-placeholder .rts-media-placeholder-icon-wrap{width:42px;height:42px;border-radius:50%;background:#6c5ce726;border:1px solid rgba(168,85,247,.35);display:flex;align-items:center;justify-content:center;animation:rts-media-pulse 2s infinite ease-in-out;box-shadow:0 4px 16px #6c5ce733}.rts-media-placeholder .rts-media-placeholder-icon{font-size:22px;color:var(--rts-accent-light, #c084fc)}.rts-media-placeholder .rts-media-placeholder-text{font-size:11px;font-weight:500;color:var(--rts-text-muted, #94a3b8);max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon-wrap{background:#ef444426;border-color:#ef444459;animation:none;box-shadow:none}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon{color:#ef4444}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-text{color:#f87171}@keyframes rts-media-shimmer{0%{transform:translate(0)}to{transform:translate(200%)}}@keyframes rts-media-pulse{0%,to{transform:scale(1);opacity:.85}50%{transform:scale(1.08);opacity:1;box-shadow:0 0 16px #a855f766}}.rts-media-image-actions{position:absolute;top:8px;right:8px;z-index:5;display:inline-flex;align-items:center;gap:6px}.rts-media-btn-paint{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#e9d5ff;border:1px solid rgba(168,85,247,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-paint i{font-size:11px;color:#c084fc}.rts-media-btn-paint span{line-height:1}.rts-media-btn-paint:hover{background:#9333eae6;color:#fff;border-color:#a855f7;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #a855f773}.rts-media-btn-paint:hover i{color:#fff}.rts-media-btn-paint:active{transform:translateY(0) scale(.98)}.rts-media-btn-context{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#bae6fd;border:1px solid rgba(56,189,248,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-context i{font-size:11px;color:#38bdf8}.rts-media-btn-context span{line-height:1}.rts-media-btn-context:hover{background:#0ea5e9e6;color:#fff;border-color:#38bdf8;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #38bdf873}.rts-media-btn-context:hover i{color:#fff}.rts-media-btn-context:active{transform:translateY(0) scale(.98)}.rts-media-btn-download{position:absolute;left:8px;bottom:8px;z-index:5;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;padding:0;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#d1fae5;border:1px solid rgba(52,211,153,.45);border-radius:50%;cursor:pointer;opacity:.85;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-download i{font-size:12px;color:#34d399}.rts-media-btn-download:hover{opacity:1;background:#10b981e6;border-color:#34d399;transform:translateY(-1px) scale(1.08);box-shadow:0 4px 12px #34d39973}.rts-media-btn-download:hover i{color:#fff}.rts-media-btn-download:active{transform:translateY(0) scale(.96)}.rts-media-btn-download.rts-downloading{cursor:progress;opacity:1}.rts-media-image{width:100%;height:100%;max-height:280px;object-fit:cover;display:block;opacity:0;transition:opacity .25s ease-out,transform .2s ease;cursor:pointer}.rts-media-image.rts-media-image-loaded{opacity:1}.rts-media-image:hover{transform:scale(1.02)}.rts-media-grid-1 .rts-media-image{height:auto;max-height:400px;object-fit:contain}.rts-media-toggle{display:block;width:100%;padding:6px 0;border:none;background:none;color:var(--rts-agent-accent, #8b5cf6);font-size:12px;font-weight:500;cursor:pointer;text-align:center;transition:opacity .15s ease}.rts-media-toggle:hover{opacity:.8}.rts-media-cost{display:flex;justify-content:flex-end;padding-top:4px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CostDisplayComponent, selector: "rtsee-cost-display", inputs: ["cost"] }] }); }
|
|
2360
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MediaWidgetComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2361
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MediaWidgetComponent, isStandalone: true, selector: "rtsee-media-widget", inputs: { message: "message", messenger: "messenger", chat: "chat", showCost: "showCost" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-media-widget\">\n <!-- Video player -->\n @if (message.video) {\n <div class=\"rts-media-video\">\n <video\n controls\n playsinline\n preload=\"metadata\"\n [src]=\"message.video.url\"\n class=\"rts-video-player\"\n >\n Your browser does not support video playback.\n </video>\n </div>\n }\n\n <!-- Awaiting AI image generation preloader -->\n @if (isAwaitingGeneration) {\n <div class=\"rts-media-images rts-media-grid-1\">\n <div class=\"rts-media-image-wrapper\">\n <div class=\"rts-media-placeholder\">\n <div class=\"rts-media-placeholder-shimmer\"></div>\n <div class=\"rts-media-placeholder-content\">\n <div class=\"rts-media-placeholder-icon-wrap\">\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">image</span>\n </div>\n <span class=\"rts-media-placeholder-text\">{{ awaitingPlaceholderText }}</span>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Image grid -->\n @if (hasImages) {\n <div class=\"rts-media-images\" [ngClass]=\"gridClass\">\n @for (img of visibleImages; track img.id || $index) {\n <div class=\"rts-media-image-wrapper\" [class.rts-image-loaded]=\"isImageLoaded(img)\">\n <!-- Media Placeholder (preview before image loads) -->\n @if (!isImageLoaded(img)) {\n <div class=\"rts-media-placeholder\" [class.rts-placeholder-error]=\"isImageError(img)\">\n <div class=\"rts-media-placeholder-shimmer\"></div>\n <div class=\"rts-media-placeholder-content\">\n @if (isImageError(img)) {\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">broken_image</span>\n <span class=\"rts-media-placeholder-text\">Failed to load</span>\n } @else {\n <div class=\"rts-media-placeholder-icon-wrap\">\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">image</span>\n </div>\n <span class=\"rts-media-placeholder-text\">{{ img.name || 'Loading media preview...' }}</span>\n }\n </div>\n </div>\n }\n\n <img\n [src]=\"displayUrl(img)\"\n [alt]=\"img.name\"\n class=\"rts-media-image\"\n [class.rts-media-image-loaded]=\"isImageLoaded(img)\"\n [class.rts-media-image-processing]=\"isImageLoaded(img) && isProcessingImage(img)\"\n (load)=\"onImageLoad(img)\"\n (error)=\"onImageError(img)\"\n loading=\"lazy\"\n />\n\n @if (isImageLoaded(img) && isProcessingImage(img)) {\n <div class=\"rts-media-processing-overlay\">\n <div class=\"rts-media-processing-badge\">\n <span class=\"rts-media-processing-spinner\"></span>\n <span class=\"rts-media-processing-text\">processing...</span>\n </div>\n </div>\n }\n\n @if (isImageLoaded(img) && !isProcessingImage(img)) {\n <button\n type=\"button\"\n class=\"rts-media-btn-download\"\n [class.rts-downloading]=\"downloadingUrl === img.url\"\n title=\"Download original image\"\n aria-label=\"Download original image\"\n (click)=\"downloadOriginal($event, img)\"\n >\n <i class=\"pi\" [ngClass]=\"downloadingUrl === img.url ? 'pi-spin pi-spinner' : 'pi-download'\"></i>\n </button>\n <div class=\"rts-media-image-actions\">\n <button\n type=\"button\"\n class=\"rts-media-btn-paint\"\n title=\"Send image to Illustrator (Review & Iterate)\"\n (click)=\"sendToIllustrator($event, img)\"\n >\n <i class=\"pi pi-palette\"></i>\n <span>+ paint</span>\n </button>\n <button\n type=\"button\"\n class=\"rts-media-btn-context\"\n title=\"Add image to Illustrator context references\"\n (click)=\"addToContext($event, img)\"\n >\n <i class=\"pi pi-plus\"></i>\n <span>+ context</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Show more / less toggle -->\n @if (hiddenCount > 0 || showAll) {\n <button class=\"rts-media-toggle\" (click)=\"toggleShowAll()\">\n {{ showAll ? 'Show less' : 'Show ' + hiddenCount + ' more' }}\n </button>\n }\n\n <!-- Cost display (optional, disabled when nested inside agentic widget) -->\n @if (showCost && message.cost) {\n <div class=\"rts-media-cost\">\n <rtsee-cost-display [cost]=\"message.cost\"></rtsee-cost-display>\n </div>\n }\n</div>\n", styles: [".rts-media-widget{max-width:100%}.rts-media-video{border-radius:8px;overflow:hidden;margin-bottom:6px;aspect-ratio:16/9;background:#000}.rts-video-player{width:100%;height:100%;max-height:360px;border-radius:8px;background:#000;display:block}.rts-media-images{display:grid;gap:4px;border-radius:8px;overflow:hidden;margin-bottom:4px}.rts-media-grid-1{grid-template-columns:1fr}.rts-media-grid-1 .rts-media-image-wrapper{min-height:220px;aspect-ratio:16/10}.rts-media-grid-1 .rts-media-image-wrapper.rts-image-loaded{min-height:0;aspect-ratio:auto}.rts-media-grid-2{grid-template-columns:1fr 1fr}.rts-media-grid-2 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-grid-4 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e);display:flex;align-items:center;justify-content:center}.rts-media-placeholder{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#1a1a2af5,#12121cfa);border:1px solid rgba(255,255,255,.06);border-radius:6px;z-index:2;overflow:hidden;pointer-events:none}.rts-media-placeholder .rts-media-placeholder-shimmer{position:absolute;top:0;left:-150%;width:150%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.03) 30%,rgba(168,85,247,.12) 50%,rgba(255,255,255,.03) 70%,transparent 100%);animation:rts-media-shimmer 2.2s infinite ease-in-out}.rts-media-placeholder .rts-media-placeholder-content{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:12px;text-align:center;max-width:90%}.rts-media-placeholder .rts-media-placeholder-icon-wrap{width:42px;height:42px;border-radius:50%;background:#6c5ce726;border:1px solid rgba(168,85,247,.35);display:flex;align-items:center;justify-content:center;animation:rts-media-pulse 2s infinite ease-in-out;box-shadow:0 4px 16px #6c5ce733}.rts-media-placeholder .rts-media-placeholder-icon{font-size:22px;color:var(--rts-accent-light, #c084fc)}.rts-media-placeholder .rts-media-placeholder-text{font-size:11px;font-weight:500;color:var(--rts-text-muted, #94a3b8);max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon-wrap{background:#ef444426;border-color:#ef444459;animation:none;box-shadow:none}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon{color:#ef4444}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-text{color:#f87171}@keyframes rts-media-shimmer{0%{transform:translate(0)}to{transform:translate(200%)}}@keyframes rts-media-pulse{0%,to{transform:scale(1);opacity:.85}50%{transform:scale(1.08);opacity:1;box-shadow:0 0 16px #a855f766}}.rts-media-image-actions{position:absolute;top:8px;right:8px;z-index:5;display:inline-flex;align-items:center;gap:6px}.rts-media-btn-paint{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#e9d5ff;border:1px solid rgba(168,85,247,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-paint i{font-size:11px;color:#c084fc}.rts-media-btn-paint span{line-height:1}.rts-media-btn-paint:hover{background:#9333eae6;color:#fff;border-color:#a855f7;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #a855f773}.rts-media-btn-paint:hover i{color:#fff}.rts-media-btn-paint:active{transform:translateY(0) scale(.98)}.rts-media-btn-context{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#bae6fd;border:1px solid rgba(56,189,248,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-context i{font-size:11px;color:#38bdf8}.rts-media-btn-context span{line-height:1}.rts-media-btn-context:hover{background:#0ea5e9e6;color:#fff;border-color:#38bdf8;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #38bdf873}.rts-media-btn-context:hover i{color:#fff}.rts-media-btn-context:active{transform:translateY(0) scale(.98)}.rts-media-btn-download{position:absolute;left:8px;bottom:8px;z-index:5;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;padding:0;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#d1fae5;border:1px solid rgba(52,211,153,.45);border-radius:50%;cursor:pointer;opacity:.85;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-download i{font-size:12px;color:#34d399}.rts-media-btn-download:hover{opacity:1;background:#10b981e6;border-color:#34d399;transform:translateY(-1px) scale(1.08);box-shadow:0 4px 12px #34d39973}.rts-media-btn-download:hover i{color:#fff}.rts-media-btn-download:active{transform:translateY(0) scale(.96)}.rts-media-btn-download.rts-downloading{cursor:progress;opacity:1}.rts-media-image{width:100%;height:100%;max-height:280px;object-fit:cover;display:block;opacity:0;transition:opacity .25s ease-out,transform .2s ease;cursor:pointer}.rts-media-image.rts-media-image-loaded{opacity:1}.rts-media-image.rts-media-image-processing{filter:brightness(.75)}.rts-media-image:hover{transform:scale(1.02)}.rts-media-processing-overlay{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;background:#0f0f1959;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);pointer-events:none}.rts-media-processing-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:999px;background:#12121ce0;border:1px solid rgba(168,85,247,.45);box-shadow:0 4px 16px #00000073}.rts-media-processing-spinner{width:14px;height:14px;border-radius:50%;border:2px solid rgba(192,132,252,.28);border-top-color:#c084fc;animation:rts-media-spin .8s linear infinite}.rts-media-processing-text{font-size:12px;font-weight:600;color:#f3e8ff;letter-spacing:.02em}@keyframes rts-media-spin{to{transform:rotate(360deg)}}.rts-media-grid-1 .rts-media-image{height:auto;max-height:400px;object-fit:contain}.rts-media-toggle{display:block;width:100%;padding:6px 0;border:none;background:none;color:var(--rts-agent-accent, #8b5cf6);font-size:12px;font-weight:500;cursor:pointer;text-align:center;transition:opacity .15s ease}.rts-media-toggle:hover{opacity:.8}.rts-media-cost{display:flex;justify-content:flex-end;padding-top:4px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CostDisplayComponent, selector: "rtsee-cost-display", inputs: ["cost"] }] }); }
|
|
2272
2362
|
}
|
|
2273
2363
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MediaWidgetComponent, decorators: [{
|
|
2274
2364
|
type: Component,
|
|
2275
|
-
args: [{ selector: 'rtsee-media-widget', standalone: true, imports: [NgClass, CostDisplayComponent], template: "<div class=\"rts-media-widget\">\n <!-- Video player -->\n @if (message.video) {\n <div class=\"rts-media-video\">\n <video\n controls\n playsinline\n preload=\"metadata\"\n [src]=\"message.video.url\"\n class=\"rts-video-player\"\n >\n Your browser does not support video playback.\n </video>\n </div>\n }\n\n <!-- Image grid -->\n @if (hasImages) {\n <div class=\"rts-media-images\" [ngClass]=\"gridClass\">\n @for (img of visibleImages; track img.id || img.url) {\n <div class=\"rts-media-image-wrapper\" [class.rts-image-loaded]=\"isImageLoaded(img)\">\n <!-- Media Placeholder (preview before image loads) -->\n @if (!isImageLoaded(img)) {\n <div class=\"rts-media-placeholder\" [class.rts-placeholder-error]=\"isImageError(img)\">\n <div class=\"rts-media-placeholder-shimmer\"></div>\n <div class=\"rts-media-placeholder-content\">\n @if (isImageError(img)) {\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">broken_image</span>\n <span class=\"rts-media-placeholder-text\">Failed to load</span>\n } @else {\n <div class=\"rts-media-placeholder-icon-wrap\">\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">image</span>\n </div>\n <span class=\"rts-media-placeholder-text\">{{ img.name || 'Loading media preview...' }}</span>\n }\n </div>\n </div>\n }\n\n <img\n [src]=\"previewUrl(img)\"\n [alt]=\"img.name\"\n class=\"rts-media-image\"\n [class.rts-media-image-loaded]=\"isImageLoaded(img)\"\n (load)=\"onImageLoad(img)\"\n (error)=\"onImageError(img)\"\n loading=\"lazy\"\n />\n\n @if (isImageLoaded(img)) {\n <button\n type=\"button\"\n class=\"rts-media-btn-download\"\n [class.rts-downloading]=\"downloadingUrl === img.url\"\n title=\"Download original image\"\n aria-label=\"Download original image\"\n (click)=\"downloadOriginal($event, img)\"\n >\n <i class=\"pi\" [ngClass]=\"downloadingUrl === img.url ? 'pi-spin pi-spinner' : 'pi-download'\"></i>\n </button>\n <div class=\"rts-media-image-actions\">\n <button\n type=\"button\"\n class=\"rts-media-btn-paint\"\n title=\"Send image to Illustrator (Review & Iterate)\"\n (click)=\"sendToIllustrator($event, img)\"\n >\n <i class=\"pi pi-palette\"></i>\n <span>+ paint</span>\n </button>\n <button\n type=\"button\"\n class=\"rts-media-btn-context\"\n title=\"Add image to Illustrator context references\"\n (click)=\"addToContext($event, img)\"\n >\n <i class=\"pi pi-plus\"></i>\n <span>+ context</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Show more / less toggle -->\n @if (hiddenCount > 0 || showAll) {\n <button class=\"rts-media-toggle\" (click)=\"toggleShowAll()\">\n {{ showAll ? 'Show less' : 'Show ' + hiddenCount + ' more' }}\n </button>\n }\n\n <!-- Cost display (optional, disabled when nested inside agentic widget) -->\n @if (showCost && message.cost) {\n <div class=\"rts-media-cost\">\n <rtsee-cost-display [cost]=\"message.cost\"></rtsee-cost-display>\n </div>\n }\n</div>\n", styles: [".rts-media-widget{max-width:100%}.rts-media-video{border-radius:8px;overflow:hidden;margin-bottom:6px;aspect-ratio:16/9;background:#000}.rts-video-player{width:100%;height:100%;max-height:360px;border-radius:8px;background:#000;display:block}.rts-media-images{display:grid;gap:4px;border-radius:8px;overflow:hidden;margin-bottom:4px}.rts-media-grid-1{grid-template-columns:1fr}.rts-media-grid-1 .rts-media-image-wrapper{min-height:220px;aspect-ratio:16/10}.rts-media-grid-1 .rts-media-image-wrapper.rts-image-loaded{min-height:0;aspect-ratio:auto}.rts-media-grid-2{grid-template-columns:1fr 1fr}.rts-media-grid-2 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-grid-4 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e);display:flex;align-items:center;justify-content:center}.rts-media-placeholder{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#1a1a2af5,#12121cfa);border:1px solid rgba(255,255,255,.06);border-radius:6px;z-index:2;overflow:hidden;pointer-events:none}.rts-media-placeholder .rts-media-placeholder-shimmer{position:absolute;top:0;left:-150%;width:150%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.03) 30%,rgba(168,85,247,.12) 50%,rgba(255,255,255,.03) 70%,transparent 100%);animation:rts-media-shimmer 2.2s infinite ease-in-out}.rts-media-placeholder .rts-media-placeholder-content{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:12px;text-align:center;max-width:90%}.rts-media-placeholder .rts-media-placeholder-icon-wrap{width:42px;height:42px;border-radius:50%;background:#6c5ce726;border:1px solid rgba(168,85,247,.35);display:flex;align-items:center;justify-content:center;animation:rts-media-pulse 2s infinite ease-in-out;box-shadow:0 4px 16px #6c5ce733}.rts-media-placeholder .rts-media-placeholder-icon{font-size:22px;color:var(--rts-accent-light, #c084fc)}.rts-media-placeholder .rts-media-placeholder-text{font-size:11px;font-weight:500;color:var(--rts-text-muted, #94a3b8);max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon-wrap{background:#ef444426;border-color:#ef444459;animation:none;box-shadow:none}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon{color:#ef4444}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-text{color:#f87171}@keyframes rts-media-shimmer{0%{transform:translate(0)}to{transform:translate(200%)}}@keyframes rts-media-pulse{0%,to{transform:scale(1);opacity:.85}50%{transform:scale(1.08);opacity:1;box-shadow:0 0 16px #a855f766}}.rts-media-image-actions{position:absolute;top:8px;right:8px;z-index:5;display:inline-flex;align-items:center;gap:6px}.rts-media-btn-paint{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#e9d5ff;border:1px solid rgba(168,85,247,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-paint i{font-size:11px;color:#c084fc}.rts-media-btn-paint span{line-height:1}.rts-media-btn-paint:hover{background:#9333eae6;color:#fff;border-color:#a855f7;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #a855f773}.rts-media-btn-paint:hover i{color:#fff}.rts-media-btn-paint:active{transform:translateY(0) scale(.98)}.rts-media-btn-context{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#bae6fd;border:1px solid rgba(56,189,248,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-context i{font-size:11px;color:#38bdf8}.rts-media-btn-context span{line-height:1}.rts-media-btn-context:hover{background:#0ea5e9e6;color:#fff;border-color:#38bdf8;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #38bdf873}.rts-media-btn-context:hover i{color:#fff}.rts-media-btn-context:active{transform:translateY(0) scale(.98)}.rts-media-btn-download{position:absolute;left:8px;bottom:8px;z-index:5;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;padding:0;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#d1fae5;border:1px solid rgba(52,211,153,.45);border-radius:50%;cursor:pointer;opacity:.85;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-download i{font-size:12px;color:#34d399}.rts-media-btn-download:hover{opacity:1;background:#10b981e6;border-color:#34d399;transform:translateY(-1px) scale(1.08);box-shadow:0 4px 12px #34d39973}.rts-media-btn-download:hover i{color:#fff}.rts-media-btn-download:active{transform:translateY(0) scale(.96)}.rts-media-btn-download.rts-downloading{cursor:progress;opacity:1}.rts-media-image{width:100%;height:100%;max-height:280px;object-fit:cover;display:block;opacity:0;transition:opacity .25s ease-out,transform .2s ease;cursor:pointer}.rts-media-image.rts-media-image-loaded{opacity:1}.rts-media-image:hover{transform:scale(1.02)}.rts-media-grid-1 .rts-media-image{height:auto;max-height:400px;object-fit:contain}.rts-media-toggle{display:block;width:100%;padding:6px 0;border:none;background:none;color:var(--rts-agent-accent, #8b5cf6);font-size:12px;font-weight:500;cursor:pointer;text-align:center;transition:opacity .15s ease}.rts-media-toggle:hover{opacity:.8}.rts-media-cost{display:flex;justify-content:flex-end;padding-top:4px}\n"] }]
|
|
2276
|
-
}], propDecorators: { message: [{
|
|
2365
|
+
args: [{ selector: 'rtsee-media-widget', standalone: true, imports: [NgClass, CostDisplayComponent], template: "<div class=\"rts-media-widget\">\n <!-- Video player -->\n @if (message.video) {\n <div class=\"rts-media-video\">\n <video\n controls\n playsinline\n preload=\"metadata\"\n [src]=\"message.video.url\"\n class=\"rts-video-player\"\n >\n Your browser does not support video playback.\n </video>\n </div>\n }\n\n <!-- Awaiting AI image generation preloader -->\n @if (isAwaitingGeneration) {\n <div class=\"rts-media-images rts-media-grid-1\">\n <div class=\"rts-media-image-wrapper\">\n <div class=\"rts-media-placeholder\">\n <div class=\"rts-media-placeholder-shimmer\"></div>\n <div class=\"rts-media-placeholder-content\">\n <div class=\"rts-media-placeholder-icon-wrap\">\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">image</span>\n </div>\n <span class=\"rts-media-placeholder-text\">{{ awaitingPlaceholderText }}</span>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Image grid -->\n @if (hasImages) {\n <div class=\"rts-media-images\" [ngClass]=\"gridClass\">\n @for (img of visibleImages; track img.id || $index) {\n <div class=\"rts-media-image-wrapper\" [class.rts-image-loaded]=\"isImageLoaded(img)\">\n <!-- Media Placeholder (preview before image loads) -->\n @if (!isImageLoaded(img)) {\n <div class=\"rts-media-placeholder\" [class.rts-placeholder-error]=\"isImageError(img)\">\n <div class=\"rts-media-placeholder-shimmer\"></div>\n <div class=\"rts-media-placeholder-content\">\n @if (isImageError(img)) {\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">broken_image</span>\n <span class=\"rts-media-placeholder-text\">Failed to load</span>\n } @else {\n <div class=\"rts-media-placeholder-icon-wrap\">\n <span class=\"material-icons-outlined rts-media-placeholder-icon\">image</span>\n </div>\n <span class=\"rts-media-placeholder-text\">{{ img.name || 'Loading media preview...' }}</span>\n }\n </div>\n </div>\n }\n\n <img\n [src]=\"displayUrl(img)\"\n [alt]=\"img.name\"\n class=\"rts-media-image\"\n [class.rts-media-image-loaded]=\"isImageLoaded(img)\"\n [class.rts-media-image-processing]=\"isImageLoaded(img) && isProcessingImage(img)\"\n (load)=\"onImageLoad(img)\"\n (error)=\"onImageError(img)\"\n loading=\"lazy\"\n />\n\n @if (isImageLoaded(img) && isProcessingImage(img)) {\n <div class=\"rts-media-processing-overlay\">\n <div class=\"rts-media-processing-badge\">\n <span class=\"rts-media-processing-spinner\"></span>\n <span class=\"rts-media-processing-text\">processing...</span>\n </div>\n </div>\n }\n\n @if (isImageLoaded(img) && !isProcessingImage(img)) {\n <button\n type=\"button\"\n class=\"rts-media-btn-download\"\n [class.rts-downloading]=\"downloadingUrl === img.url\"\n title=\"Download original image\"\n aria-label=\"Download original image\"\n (click)=\"downloadOriginal($event, img)\"\n >\n <i class=\"pi\" [ngClass]=\"downloadingUrl === img.url ? 'pi-spin pi-spinner' : 'pi-download'\"></i>\n </button>\n <div class=\"rts-media-image-actions\">\n <button\n type=\"button\"\n class=\"rts-media-btn-paint\"\n title=\"Send image to Illustrator (Review & Iterate)\"\n (click)=\"sendToIllustrator($event, img)\"\n >\n <i class=\"pi pi-palette\"></i>\n <span>+ paint</span>\n </button>\n <button\n type=\"button\"\n class=\"rts-media-btn-context\"\n title=\"Add image to Illustrator context references\"\n (click)=\"addToContext($event, img)\"\n >\n <i class=\"pi pi-plus\"></i>\n <span>+ context</span>\n </button>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Show more / less toggle -->\n @if (hiddenCount > 0 || showAll) {\n <button class=\"rts-media-toggle\" (click)=\"toggleShowAll()\">\n {{ showAll ? 'Show less' : 'Show ' + hiddenCount + ' more' }}\n </button>\n }\n\n <!-- Cost display (optional, disabled when nested inside agentic widget) -->\n @if (showCost && message.cost) {\n <div class=\"rts-media-cost\">\n <rtsee-cost-display [cost]=\"message.cost\"></rtsee-cost-display>\n </div>\n }\n</div>\n", styles: [".rts-media-widget{max-width:100%}.rts-media-video{border-radius:8px;overflow:hidden;margin-bottom:6px;aspect-ratio:16/9;background:#000}.rts-video-player{width:100%;height:100%;max-height:360px;border-radius:8px;background:#000;display:block}.rts-media-images{display:grid;gap:4px;border-radius:8px;overflow:hidden;margin-bottom:4px}.rts-media-grid-1{grid-template-columns:1fr}.rts-media-grid-1 .rts-media-image-wrapper{min-height:220px;aspect-ratio:16/10}.rts-media-grid-1 .rts-media-image-wrapper.rts-image-loaded{min-height:0;aspect-ratio:auto}.rts-media-grid-2{grid-template-columns:1fr 1fr}.rts-media-grid-2 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-grid-4 .rts-media-image-wrapper{aspect-ratio:1/1;min-height:120px}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e);display:flex;align-items:center;justify-content:center}.rts-media-placeholder{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,#1a1a2af5,#12121cfa);border:1px solid rgba(255,255,255,.06);border-radius:6px;z-index:2;overflow:hidden;pointer-events:none}.rts-media-placeholder .rts-media-placeholder-shimmer{position:absolute;top:0;left:-150%;width:150%;height:100%;background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.03) 30%,rgba(168,85,247,.12) 50%,rgba(255,255,255,.03) 70%,transparent 100%);animation:rts-media-shimmer 2.2s infinite ease-in-out}.rts-media-placeholder .rts-media-placeholder-content{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:12px;text-align:center;max-width:90%}.rts-media-placeholder .rts-media-placeholder-icon-wrap{width:42px;height:42px;border-radius:50%;background:#6c5ce726;border:1px solid rgba(168,85,247,.35);display:flex;align-items:center;justify-content:center;animation:rts-media-pulse 2s infinite ease-in-out;box-shadow:0 4px 16px #6c5ce733}.rts-media-placeholder .rts-media-placeholder-icon{font-size:22px;color:var(--rts-accent-light, #c084fc)}.rts-media-placeholder .rts-media-placeholder-text{font-size:11px;font-weight:500;color:var(--rts-text-muted, #94a3b8);max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon-wrap{background:#ef444426;border-color:#ef444459;animation:none;box-shadow:none}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-icon{color:#ef4444}.rts-media-placeholder.rts-placeholder-error .rts-media-placeholder-text{color:#f87171}@keyframes rts-media-shimmer{0%{transform:translate(0)}to{transform:translate(200%)}}@keyframes rts-media-pulse{0%,to{transform:scale(1);opacity:.85}50%{transform:scale(1.08);opacity:1;box-shadow:0 0 16px #a855f766}}.rts-media-image-actions{position:absolute;top:8px;right:8px;z-index:5;display:inline-flex;align-items:center;gap:6px}.rts-media-btn-paint{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#e9d5ff;border:1px solid rgba(168,85,247,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-paint i{font-size:11px;color:#c084fc}.rts-media-btn-paint span{line-height:1}.rts-media-btn-paint:hover{background:#9333eae6;color:#fff;border-color:#a855f7;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #a855f773}.rts-media-btn-paint:hover i{color:#fff}.rts-media-btn-paint:active{transform:translateY(0) scale(.98)}.rts-media-btn-context{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#bae6fd;border:1px solid rgba(56,189,248,.45);border-radius:6px;font-size:11px;font-weight:600;cursor:pointer;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-context i{font-size:11px;color:#38bdf8}.rts-media-btn-context span{line-height:1}.rts-media-btn-context:hover{background:#0ea5e9e6;color:#fff;border-color:#38bdf8;transform:translateY(-1px) scale(1.04);box-shadow:0 4px 12px #38bdf873}.rts-media-btn-context:hover i{color:#fff}.rts-media-btn-context:active{transform:translateY(0) scale(.98)}.rts-media-btn-download{position:absolute;left:8px;bottom:8px;z-index:5;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;padding:0;background:#12121cd9;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#d1fae5;border:1px solid rgba(52,211,153,.45);border-radius:50%;cursor:pointer;opacity:.85;transition:all .2s cubic-bezier(.34,1.56,.64,1);box-shadow:0 2px 8px #00000080}.rts-media-btn-download i{font-size:12px;color:#34d399}.rts-media-btn-download:hover{opacity:1;background:#10b981e6;border-color:#34d399;transform:translateY(-1px) scale(1.08);box-shadow:0 4px 12px #34d39973}.rts-media-btn-download:hover i{color:#fff}.rts-media-btn-download:active{transform:translateY(0) scale(.96)}.rts-media-btn-download.rts-downloading{cursor:progress;opacity:1}.rts-media-image{width:100%;height:100%;max-height:280px;object-fit:cover;display:block;opacity:0;transition:opacity .25s ease-out,transform .2s ease;cursor:pointer}.rts-media-image.rts-media-image-loaded{opacity:1}.rts-media-image.rts-media-image-processing{filter:brightness(.75)}.rts-media-image:hover{transform:scale(1.02)}.rts-media-processing-overlay{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;background:#0f0f1959;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);pointer-events:none}.rts-media-processing-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:999px;background:#12121ce0;border:1px solid rgba(168,85,247,.45);box-shadow:0 4px 16px #00000073}.rts-media-processing-spinner{width:14px;height:14px;border-radius:50%;border:2px solid rgba(192,132,252,.28);border-top-color:#c084fc;animation:rts-media-spin .8s linear infinite}.rts-media-processing-text{font-size:12px;font-weight:600;color:#f3e8ff;letter-spacing:.02em}@keyframes rts-media-spin{to{transform:rotate(360deg)}}.rts-media-grid-1 .rts-media-image{height:auto;max-height:400px;object-fit:contain}.rts-media-toggle{display:block;width:100%;padding:6px 0;border:none;background:none;color:var(--rts-agent-accent, #8b5cf6);font-size:12px;font-weight:500;cursor:pointer;text-align:center;transition:opacity .15s ease}.rts-media-toggle:hover{opacity:.8}.rts-media-cost{display:flex;justify-content:flex-end;padding-top:4px}\n"] }]
|
|
2366
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { message: [{
|
|
2277
2367
|
type: Input
|
|
2278
2368
|
}], messenger: [{
|
|
2279
2369
|
type: Input
|
|
@@ -2639,6 +2729,9 @@ class StorytellerStoryLinkStepComponent {
|
|
|
2639
2729
|
return this.story.storyId ? `/story/${this.story.storyId}` : '';
|
|
2640
2730
|
}
|
|
2641
2731
|
get kicker() {
|
|
2732
|
+
if (this.story.repairedGrammar !== undefined || this.story.updatedSlidesCount !== undefined) {
|
|
2733
|
+
return 'Story repaired';
|
|
2734
|
+
}
|
|
2642
2735
|
const language = this.story.language ? getStoryTranslatorLanguage(this.story.language) : undefined;
|
|
2643
2736
|
return language ? `Translated to ${language.nativeName}` : 'Your story is ready';
|
|
2644
2737
|
}
|
|
@@ -2658,7 +2751,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
2658
2751
|
type: Input
|
|
2659
2752
|
}] } });
|
|
2660
2753
|
|
|
2661
|
-
const SEARCH_DEBOUNCE_MS = 250;
|
|
2754
|
+
const SEARCH_DEBOUNCE_MS$1 = 250;
|
|
2662
2755
|
/**
|
|
2663
2756
|
* Story Translator step 1: pick a story (autocomplete by name) and the target language.
|
|
2664
2757
|
*/
|
|
@@ -2672,10 +2765,13 @@ class StoryTranslatorFormStepComponent {
|
|
|
2672
2765
|
storyQuery: new FormControl(''),
|
|
2673
2766
|
storyId: new FormControl('', Validators.required),
|
|
2674
2767
|
language: new FormControl('', Validators.required),
|
|
2768
|
+
fromScratch: new FormControl(false),
|
|
2675
2769
|
agentId: new FormControl('', Validators.required),
|
|
2676
2770
|
/* eslint-enable */
|
|
2677
2771
|
});
|
|
2678
2772
|
this.selectedStory = null;
|
|
2773
|
+
this.hasExistingTranslation = false;
|
|
2774
|
+
this.checkingTranslations = false;
|
|
2679
2775
|
this.suggestions = [];
|
|
2680
2776
|
this.suggestionsOpened = false;
|
|
2681
2777
|
this.highlightedIndex = 0;
|
|
@@ -2683,6 +2779,7 @@ class StoryTranslatorFormStepComponent {
|
|
|
2683
2779
|
this.searchError = null;
|
|
2684
2780
|
this.searchTimer = null;
|
|
2685
2781
|
this.searchRequestId = 0;
|
|
2782
|
+
this.translationCheckRequestId = 0;
|
|
2686
2783
|
this.onChangedBound = () => this.onWorkflowChanged();
|
|
2687
2784
|
}
|
|
2688
2785
|
get agents() {
|
|
@@ -2722,10 +2819,11 @@ class StoryTranslatorFormStepComponent {
|
|
|
2722
2819
|
// typing invalidates the previous selection
|
|
2723
2820
|
if (this.selectedStory) {
|
|
2724
2821
|
this.selectedStory = null;
|
|
2725
|
-
this.
|
|
2822
|
+
this.hasExistingTranslation = false;
|
|
2823
|
+
this.form.patchValue({ storyId: '', fromScratch: false }, { emitEvent: false });
|
|
2726
2824
|
}
|
|
2727
2825
|
this.suggestionsOpened = true;
|
|
2728
|
-
this.scheduleSearch(SEARCH_DEBOUNCE_MS);
|
|
2826
|
+
this.scheduleSearch(SEARCH_DEBOUNCE_MS$1);
|
|
2729
2827
|
}
|
|
2730
2828
|
onStoryKeydown(event) {
|
|
2731
2829
|
if (!this.suggestionsOpened || !this.suggestions.length) {
|
|
@@ -2759,20 +2857,29 @@ class StoryTranslatorFormStepComponent {
|
|
|
2759
2857
|
return;
|
|
2760
2858
|
}
|
|
2761
2859
|
this.selectedStory = story;
|
|
2762
|
-
this.form.patchValue({ storyId: story.id, storyQuery: story.name }, { emitEvent: false });
|
|
2860
|
+
this.form.patchValue({ storyId: story.id, storyQuery: story.name, fromScratch: false }, { emitEvent: false });
|
|
2763
2861
|
this.form.get('storyId')?.markAsTouched();
|
|
2764
2862
|
this.suggestionsOpened = false;
|
|
2863
|
+
void this.checkExistingTranslation();
|
|
2765
2864
|
}
|
|
2766
2865
|
clearStory() {
|
|
2767
2866
|
if (this.readonly) {
|
|
2768
2867
|
return;
|
|
2769
2868
|
}
|
|
2770
2869
|
this.selectedStory = null;
|
|
2771
|
-
this.
|
|
2870
|
+
this.hasExistingTranslation = false;
|
|
2871
|
+
this.form.patchValue({ storyId: '', storyQuery: '', fromScratch: false }, { emitEvent: false });
|
|
2772
2872
|
this.suggestionsOpened = true;
|
|
2773
2873
|
this.scheduleSearch(0);
|
|
2774
2874
|
setTimeout(() => this.storyInput?.nativeElement.focus());
|
|
2775
2875
|
}
|
|
2876
|
+
onLanguageChange() {
|
|
2877
|
+
if (this.readonly) {
|
|
2878
|
+
return;
|
|
2879
|
+
}
|
|
2880
|
+
this.form.get('fromScratch')?.setValue(false, { emitEvent: false });
|
|
2881
|
+
void this.checkExistingTranslation();
|
|
2882
|
+
}
|
|
2776
2883
|
onDocumentMouseDown(event) {
|
|
2777
2884
|
if (this.suggestionsOpened && !this.host.nativeElement.contains(event.target)) {
|
|
2778
2885
|
this.suggestionsOpened = false;
|
|
@@ -2791,6 +2898,7 @@ class StoryTranslatorFormStepComponent {
|
|
|
2791
2898
|
storyName: this.selectedStory.name,
|
|
2792
2899
|
language: this.form.get('language')?.value,
|
|
2793
2900
|
agentId: this.form.get('agentId')?.value,
|
|
2901
|
+
fromScratch: this.hasExistingTranslation ? !!this.form.get('fromScratch')?.value : false,
|
|
2794
2902
|
});
|
|
2795
2903
|
}
|
|
2796
2904
|
cancel() {
|
|
@@ -2852,7 +2960,19 @@ class StoryTranslatorFormStepComponent {
|
|
|
2852
2960
|
const output = this.step?.output;
|
|
2853
2961
|
if (output?.storyId) {
|
|
2854
2962
|
this.selectedStory = { id: output.storyId, name: output.storyName || output.storyId };
|
|
2855
|
-
this.form.patchValue({
|
|
2963
|
+
this.form.patchValue({
|
|
2964
|
+
storyId: output.storyId,
|
|
2965
|
+
storyQuery: output.storyName || '',
|
|
2966
|
+
language: output.language,
|
|
2967
|
+
fromScratch: !!output.fromScratch,
|
|
2968
|
+
agentId: output.agentId,
|
|
2969
|
+
}, { emitEvent: false });
|
|
2970
|
+
if (output.fromScratch) {
|
|
2971
|
+
this.hasExistingTranslation = true;
|
|
2972
|
+
}
|
|
2973
|
+
else {
|
|
2974
|
+
void this.checkExistingTranslation(true);
|
|
2975
|
+
}
|
|
2856
2976
|
}
|
|
2857
2977
|
if (this.readonly) {
|
|
2858
2978
|
this.suggestionsOpened = false;
|
|
@@ -2862,12 +2982,324 @@ class StoryTranslatorFormStepComponent {
|
|
|
2862
2982
|
this.form.enable({ emitEvent: false });
|
|
2863
2983
|
}
|
|
2864
2984
|
}
|
|
2985
|
+
async checkExistingTranslation(preserveCheckboxValue = false) {
|
|
2986
|
+
const storyId = this.selectedStory?.id;
|
|
2987
|
+
const rawLang = this.form.get('language')?.value || '';
|
|
2988
|
+
const langInfo = getStoryTranslatorLanguage(rawLang);
|
|
2989
|
+
const languageKey = langInfo?.code || rawLang;
|
|
2990
|
+
if (!storyId || !languageKey) {
|
|
2991
|
+
this.hasExistingTranslation = false;
|
|
2992
|
+
this.checkingTranslations = false;
|
|
2993
|
+
if (!preserveCheckboxValue) {
|
|
2994
|
+
this.form.get('fromScratch')?.setValue(false, { emitEvent: false });
|
|
2995
|
+
}
|
|
2996
|
+
this.cdr.markForCheck();
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
const requestId = ++this.translationCheckRequestId;
|
|
3000
|
+
this.checkingTranslations = true;
|
|
3001
|
+
const aliases = this.selectedStory?.aliases || [];
|
|
3002
|
+
const hasAliasForLang = aliases.some((a) => {
|
|
3003
|
+
const norm = getStoryTranslatorLanguage(a.languageKey)?.code || a.languageKey;
|
|
3004
|
+
return norm === languageKey;
|
|
3005
|
+
});
|
|
3006
|
+
try {
|
|
3007
|
+
const translations = this.messenger?.ozzy
|
|
3008
|
+
? await this.messenger.ozzy.getStoryTranslations(storyId)
|
|
3009
|
+
: [];
|
|
3010
|
+
if (requestId !== this.translationCheckRequestId) {
|
|
3011
|
+
return;
|
|
3012
|
+
}
|
|
3013
|
+
const hasStoryTranslation = translations.some((t) => {
|
|
3014
|
+
const norm = getStoryTranslatorLanguage(t.languageKey)?.code || t.languageKey;
|
|
3015
|
+
return norm === languageKey;
|
|
3016
|
+
});
|
|
3017
|
+
this.hasExistingTranslation = hasAliasForLang || hasStoryTranslation;
|
|
3018
|
+
if (!this.hasExistingTranslation && !preserveCheckboxValue) {
|
|
3019
|
+
this.form.get('fromScratch')?.setValue(false, { emitEvent: false });
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
catch {
|
|
3023
|
+
if (requestId !== this.translationCheckRequestId) {
|
|
3024
|
+
return;
|
|
3025
|
+
}
|
|
3026
|
+
this.hasExistingTranslation = hasAliasForLang;
|
|
3027
|
+
}
|
|
3028
|
+
finally {
|
|
3029
|
+
if (requestId === this.translationCheckRequestId) {
|
|
3030
|
+
this.checkingTranslations = false;
|
|
3031
|
+
this.cdr.detectChanges();
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
2865
3035
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryTranslatorFormStepComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2866
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryTranslatorFormStepComponent, isStandalone: true, selector: "rtsee-story-translator-form-step", inputs: { step: "step", workflow: "workflow", chat: "chat", messenger: "messenger" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event)" } }, viewQueries: [{ propertyName: "storyInput", first: true, predicate: ["storyInput"], descendants: true }], ngImport: i0, template: "<form class=\"rts-storyteller-form\" [formGroup]=\"form\" (ngSubmit)=\"submit()\" autocomplete=\"off\">\n <div class=\"rts-storyteller-field\">\n <label class=\"rts-storyteller-label\" for=\"story-translator-story-{{ step.id }}\">Story</label>\n <div class=\"rts-st-autocomplete\">\n <span class=\"rts-st-autocomplete-icon pi\" [class.pi-search]=\"!searchInProgress\" [class.pi-spin]=\"searchInProgress\" [class.pi-spinner]=\"searchInProgress\"></span>\n <input #storyInput\n class=\"rts-storyteller-input rts-st-autocomplete-input\"\n [class.rts-storyteller-invalid]=\"isInvalid('storyId')\"\n [class.rts-st-autocomplete-selected]=\"!!selectedStory\"\n formControlName=\"storyQuery\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"suggestionsOpened\"\n placeholder=\"Search stories by name\u2026\"\n id=\"story-translator-story-{{ step.id }}\"\n (focus)=\"onStoryFocus()\"\n (input)=\"onStoryInput()\"\n (keydown)=\"onStoryKeydown($event)\"\n />\n @if (selectedStory && !readonly) {\n <button type=\"button\"\n class=\"rts-st-autocomplete-clear pi pi-times\"\n aria-label=\"Clear story\"\n id=\"story-translator-clear-{{ step.id }}\"\n (click)=\"clearStory()\"\n ></button>\n }\n\n @if (suggestionsOpened && !readonly) {\n <ul class=\"rts-st-autocomplete-panel\" role=\"listbox\">\n @if (searchError) {\n <li class=\"rts-st-autocomplete-empty rts-st-autocomplete-error\">{{ searchError }}</li>\n } @else if (!suggestions.length && !searchInProgress) {\n <li class=\"rts-st-autocomplete-empty\">No stories found</li>\n }\n @for (story of suggestions; track story.id; let i = $index) {\n <li class=\"rts-st-autocomplete-option\"\n role=\"option\"\n [class.rts-st-autocomplete-option-active]=\"i === highlightedIndex\"\n [attr.aria-selected]=\"story.id === selectedStory?.id\"\n (mouseenter)=\"highlightedIndex = i\"\n (mousedown)=\"$event.preventDefault(); selectStory(story)\"\n >\n @if (story.imageUrl) {\n <img class=\"rts-st-autocomplete-thumb\" [src]=\"story.imageUrl\" [alt]=\"story.name\" loading=\"lazy\" />\n } @else {\n <span class=\"rts-st-autocomplete-thumb rts-st-autocomplete-thumb-empty\">\uD83D\uDCD6</span>\n }\n <span class=\"rts-st-autocomplete-option-body\">\n <span class=\"rts-st-autocomplete-option-name\">{{ story.name }}</span>\n @if (story.totalSlides) {\n <span class=\"rts-st-autocomplete-option-meta\">{{ story.totalSlides }} slides</span>\n }\n </span>\n </li>\n }\n </ul>\n }\n </div>\n </div>\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Translate to</span>\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('language')\"\n formControlName=\"language\"\n id=\"story-translator-language-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select a language</option>\n @for (language of languages; track language.code) {\n <option [value]=\"language.code\">{{ language.nativeName }}</option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n </label>\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Agent</span>\n @if (agents.length) {\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('agentId')\"\n formControlName=\"agentId\"\n id=\"story-translator-agent-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select an agent</option>\n @for (agent of agents; track agent.id) {\n <option [value]=\"agent.id\">\n {{ agent.name }}{{ agent.agentConfiguration?.model?.model ? ' \u00B7 ' + agent.agentConfiguration?.model?.model : '' }}\n </option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n } @else {\n <div class=\"rts-storyteller-hint\">There are no agentic members in this chat. Add an agent to continue.</div>\n }\n </label>\n\n @if (workflow.submitError) {\n <div class=\"rts-storyteller-error\">{{ workflow.submitError }}</div>\n }\n\n @if (step.isActive) {\n <div class=\"rts-storyteller-actions rts-st-translator-actions\">\n @if (canCancel) {\n <button class=\"rts-st-cancel\"\n type=\"button\"\n id=\"story-translator-cancel-{{ step.id }}\"\n (click)=\"cancel()\"\n >Cancel</button>\n }\n <button class=\"rts-storyteller-submit\"\n type=\"submit\"\n [disabled]=\"workflow.submitInProgress || !agents.length\"\n id=\"story-translator-submit-{{ step.id }}\"\n >\n @if (workflow.submitInProgress) {\n <span class=\"rts-storyteller-spinner\"></span> Translating\u2026\n } @else {\n \uD83C\uDF10 Translate{{ selectedLanguage ? ' to ' + selectedLanguage.nativeName : '' }}\n }\n </button>\n </div>\n }\n</form>\n", styles: [":host{display:block;--rts-st-accent: #8b5cf6;--rts-st-accent-2: #6366f1}.rts-storyteller-form{display:flex;flex-direction:column;gap:12px}.rts-storyteller-field{display:flex;flex-direction:column;gap:5px}.rts-storyteller-label{display:flex;justify-content:space-between;align-items:baseline;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-counter{font-weight:500;letter-spacing:0;text-transform:none}.rts-storyteller-input{width:100%;box-sizing:border-box;padding:9px 12px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));color:var(--rts-text-primary);font:inherit;font-size:13px;outline:none;transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.rts-storyteller-input:focus{border-color:var(--rts-st-accent);box-shadow:0 0 0 3px #8b5cf62e}.rts-storyteller-input:disabled{opacity:.75;cursor:default}.rts-storyteller-input.rts-storyteller-invalid{border-color:#f43f5e;box-shadow:0 0 0 3px #f43f5e1f}.rts-storyteller-textarea{min-height:80px;resize:vertical;line-height:1.5}.rts-storyteller-textarea-lg{min-height:160px;max-height:480px}.rts-storyteller-select-wrap{position:relative}.rts-storyteller-select{appearance:none;padding-right:32px;cursor:pointer}.rts-storyteller-select-caret{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:10px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-hint{font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-error{padding:6px 10px;border-radius:6px;font-size:12px;color:#f43f5e;background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}.rts-storyteller-actions{display:flex;justify-content:flex-end}.rts-storyteller-submit{display:inline-flex;align-items:center;gap:6px;padding:8px 18px;border:none;border-radius:9px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent) 60%,#a78bfa);background-size:160% 160%;box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,background-position .4s ease}.rts-storyteller-submit:hover:not(:disabled){transform:translateY(-1px);background-position:100% 0;box-shadow:0 6px 18px -4px #6366f1bf}.rts-storyteller-submit:disabled{opacity:.6;cursor:default;box-shadow:none}.rts-storyteller-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-st-spin .8s linear infinite}.rts-story-link-card{display:flex;align-items:center;gap:12px;padding:14px;border-radius:12px;text-decoration:none;color:inherit;background:linear-gradient(135deg,#6366f11a,#8b5cf60f);border:1px solid rgba(139,92,246,.3);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;animation:rts-st-pop .4s cubic-bezier(.2,.9,.3,1.3)}.rts-story-link-card:hover{transform:translateY(-2px);border-color:var(--rts-st-accent);box-shadow:0 10px 28px -12px #8b5cf699}.rts-story-link-card:hover .rts-story-link-arrow{transform:translate(3px)}.rts-story-link-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:42px;height:42px;border-radius:12px;font-size:20px;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent))}.rts-story-link-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.rts-story-link-kicker{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-st-accent)}.rts-story-link-title{font-size:15px;font-weight:600;color:var(--rts-text-primary)}.rts-story-link-description{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.rts-story-link-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-link-arrow{color:var(--rts-st-accent);transition:transform .2s ease}@keyframes rts-st-spin{to{transform:rotate(360deg)}}@keyframes rts-st-pop{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}\n", ".rts-st-autocomplete{position:relative}.rts-st-autocomplete-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:12px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-input{padding-left:32px;padding-right:32px}.rts-st-autocomplete-input.rts-st-autocomplete-selected{font-weight:600}.rts-st-autocomplete-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;padding:0;border:none;border-radius:50%;font-size:10px;cursor:pointer;color:var(--rts-text-secondary, #8a8fa3);background:transparent;transition:background .15s ease,color .15s ease}.rts-st-autocomplete-clear:hover{color:var(--rts-text-primary);background:#8b5cf626}.rts-st-autocomplete-panel{position:absolute;z-index:20;left:0;right:0;top:calc(100% + 4px);max-height:240px;margin:0;padding:4px;overflow-y:auto;list-style:none;border-radius:10px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-secondary, var(--rts-bg-primary, #1d1f2b));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 14px 32px -12px #00000073;animation:rts-st-panel-in .14s ease-out}.rts-st-autocomplete-option{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:7px;cursor:pointer;transition:background .12s ease}.rts-st-autocomplete-option.rts-st-autocomplete-option-active{background:linear-gradient(135deg,#6366f129,#8b5cf61a)}.rts-st-autocomplete-option[aria-selected=true] .rts-st-autocomplete-option-name{color:var(--rts-st-accent)}.rts-st-autocomplete-thumb{flex-shrink:0;width:30px;height:30px;border-radius:7px;object-fit:cover}.rts-st-autocomplete-thumb-empty{display:flex;align-items:center;justify-content:center;font-size:15px;background:#8b5cf624}.rts-st-autocomplete-option-body{display:flex;flex-direction:column;min-width:0}.rts-st-autocomplete-option-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;color:var(--rts-text-primary)}.rts-st-autocomplete-option-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-empty{padding:8px;font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-error{font-style:normal;color:#f43f5e}.rts-st-translator-actions{gap:8px}.rts-st-cancel{padding:8px 16px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:transparent;color:var(--rts-text-secondary, #8a8fa3);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.rts-st-cancel:hover{color:var(--rts-text-primary);border-color:#f43f5e73;background:#f43f5e0f}@keyframes rts-st-panel-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.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"] }] }); }
|
|
3036
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryTranslatorFormStepComponent, isStandalone: true, selector: "rtsee-story-translator-form-step", inputs: { step: "step", workflow: "workflow", chat: "chat", messenger: "messenger" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event)" } }, viewQueries: [{ propertyName: "storyInput", first: true, predicate: ["storyInput"], descendants: true }], ngImport: i0, template: "<form class=\"rts-storyteller-form\" [formGroup]=\"form\" (ngSubmit)=\"submit()\" autocomplete=\"off\">\n <div class=\"rts-storyteller-field\">\n <label class=\"rts-storyteller-label\" for=\"story-translator-story-{{ step.id }}\">Story</label>\n <div class=\"rts-st-autocomplete\">\n <span class=\"rts-st-autocomplete-icon pi\" [class.pi-search]=\"!searchInProgress\" [class.pi-spin]=\"searchInProgress\" [class.pi-spinner]=\"searchInProgress\"></span>\n <input #storyInput\n class=\"rts-storyteller-input rts-st-autocomplete-input\"\n [class.rts-storyteller-invalid]=\"isInvalid('storyId')\"\n [class.rts-st-autocomplete-selected]=\"!!selectedStory\"\n formControlName=\"storyQuery\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"suggestionsOpened\"\n placeholder=\"Search stories by name\u2026\"\n id=\"story-translator-story-{{ step.id }}\"\n (focus)=\"onStoryFocus()\"\n (input)=\"onStoryInput()\"\n (keydown)=\"onStoryKeydown($event)\"\n />\n @if (selectedStory && !readonly) {\n <button type=\"button\"\n class=\"rts-st-autocomplete-clear pi pi-times\"\n aria-label=\"Clear story\"\n id=\"story-translator-clear-{{ step.id }}\"\n (click)=\"clearStory()\"\n ></button>\n }\n\n @if (suggestionsOpened && !readonly) {\n <ul class=\"rts-st-autocomplete-panel\" role=\"listbox\">\n @if (searchError) {\n <li class=\"rts-st-autocomplete-empty rts-st-autocomplete-error\">{{ searchError }}</li>\n } @else if (!suggestions.length && !searchInProgress) {\n <li class=\"rts-st-autocomplete-empty\">No stories found</li>\n }\n @for (story of suggestions; track story.id; let i = $index) {\n <li class=\"rts-st-autocomplete-option\"\n role=\"option\"\n [class.rts-st-autocomplete-option-active]=\"i === highlightedIndex\"\n [attr.aria-selected]=\"story.id === selectedStory?.id\"\n (mouseenter)=\"highlightedIndex = i\"\n (mousedown)=\"$event.preventDefault(); selectStory(story)\"\n >\n @if (story.imageUrl) {\n <img class=\"rts-st-autocomplete-thumb\" [src]=\"story.imageUrl\" [alt]=\"story.name\" loading=\"lazy\" />\n } @else {\n <span class=\"rts-st-autocomplete-thumb rts-st-autocomplete-thumb-empty\">\uD83D\uDCD6</span>\n }\n <span class=\"rts-st-autocomplete-option-body\">\n <span class=\"rts-st-autocomplete-option-name\">{{ story.name }}</span>\n @if (story.totalSlides) {\n <span class=\"rts-st-autocomplete-option-meta\">{{ story.totalSlides }} slides</span>\n }\n </span>\n </li>\n }\n </ul>\n }\n </div>\n </div>\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Translate to</span>\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('language')\"\n formControlName=\"language\"\n id=\"story-translator-language-{{ step.id }}\"\n (change)=\"onLanguageChange()\"\n >\n <option value=\"\" disabled>Select a language</option>\n @for (language of languages; track language.code) {\n <option [value]=\"language.code\">{{ language.nativeName }}</option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n </label>\n\n @if (hasExistingTranslation) {\n <label class=\"rts-st-checkbox-row\" for=\"story-translator-from-scratch-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"fromScratch\"\n id=\"story-translator-from-scratch-{{ step.id }}\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">From scratch</span>\n <span class=\"rts-st-checkbox-desc\">Overwrite existing {{ selectedLanguage?.nativeName || '' }} translations for all story elements</span>\n </span>\n </label>\n }\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Agent</span>\n @if (agents.length) {\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('agentId')\"\n formControlName=\"agentId\"\n id=\"story-translator-agent-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select an agent</option>\n @for (agent of agents; track agent.id) {\n <option [value]=\"agent.id\">\n {{ agent.name }}{{ agent.agentConfiguration?.model?.model ? ' \u00B7 ' + agent.agentConfiguration?.model?.model : '' }}\n </option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n } @else {\n <div class=\"rts-storyteller-hint\">There are no agentic members in this chat. Add an agent to continue.</div>\n }\n </label>\n\n @if (workflow.submitError) {\n <div class=\"rts-storyteller-error\">{{ workflow.submitError }}</div>\n }\n\n @if (step.isActive) {\n <div class=\"rts-storyteller-actions rts-st-translator-actions\">\n @if (canCancel) {\n <button class=\"rts-st-cancel\"\n type=\"button\"\n id=\"story-translator-cancel-{{ step.id }}\"\n (click)=\"cancel()\"\n >Cancel</button>\n }\n <button class=\"rts-storyteller-submit\"\n type=\"submit\"\n [disabled]=\"workflow.submitInProgress || !agents.length\"\n id=\"story-translator-submit-{{ step.id }}\"\n >\n @if (workflow.submitInProgress) {\n <span class=\"rts-storyteller-spinner\"></span> Translating\u2026\n } @else {\n \uD83C\uDF10 Translate{{ selectedLanguage ? ' to ' + selectedLanguage.nativeName : '' }}\n }\n </button>\n </div>\n }\n</form>\n", styles: [":host{display:block;--rts-st-accent: #8b5cf6;--rts-st-accent-2: #6366f1}.rts-storyteller-form{display:flex;flex-direction:column;gap:12px}.rts-storyteller-field{display:flex;flex-direction:column;gap:5px}.rts-storyteller-label{display:flex;justify-content:space-between;align-items:baseline;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-counter{font-weight:500;letter-spacing:0;text-transform:none}.rts-storyteller-input{width:100%;box-sizing:border-box;padding:9px 12px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));color:var(--rts-text-primary);font:inherit;font-size:13px;outline:none;transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.rts-storyteller-input:focus{border-color:var(--rts-st-accent);box-shadow:0 0 0 3px #8b5cf62e}.rts-storyteller-input:disabled{opacity:.75;cursor:default}.rts-storyteller-input.rts-storyteller-invalid{border-color:#f43f5e;box-shadow:0 0 0 3px #f43f5e1f}.rts-storyteller-textarea{min-height:80px;resize:vertical;line-height:1.5}.rts-storyteller-textarea-lg{min-height:160px;max-height:480px}.rts-storyteller-select-wrap{position:relative}.rts-storyteller-select{appearance:none;padding-right:32px;cursor:pointer}.rts-storyteller-select-caret{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:10px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-hint{font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-error{padding:6px 10px;border-radius:6px;font-size:12px;color:#f43f5e;background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}.rts-storyteller-actions{display:flex;justify-content:flex-end}.rts-storyteller-submit{display:inline-flex;align-items:center;gap:6px;padding:8px 18px;border:none;border-radius:9px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent) 60%,#a78bfa);background-size:160% 160%;box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,background-position .4s ease}.rts-storyteller-submit:hover:not(:disabled){transform:translateY(-1px);background-position:100% 0;box-shadow:0 6px 18px -4px #6366f1bf}.rts-storyteller-submit:disabled{opacity:.6;cursor:default;box-shadow:none}.rts-storyteller-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-st-spin .8s linear infinite}.rts-story-link-card{display:flex;align-items:center;gap:12px;padding:14px;border-radius:12px;text-decoration:none;color:inherit;background:linear-gradient(135deg,#6366f11a,#8b5cf60f);border:1px solid rgba(139,92,246,.3);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;animation:rts-st-pop .4s cubic-bezier(.2,.9,.3,1.3)}.rts-story-link-card:hover{transform:translateY(-2px);border-color:var(--rts-st-accent);box-shadow:0 10px 28px -12px #8b5cf699}.rts-story-link-card:hover .rts-story-link-arrow{transform:translate(3px)}.rts-story-link-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:42px;height:42px;border-radius:12px;font-size:20px;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent))}.rts-story-link-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.rts-story-link-kicker{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-st-accent)}.rts-story-link-title{font-size:15px;font-weight:600;color:var(--rts-text-primary)}.rts-story-link-description{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.rts-story-link-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-link-arrow{color:var(--rts-st-accent);transition:transform .2s ease}@keyframes rts-st-spin{to{transform:rotate(360deg)}}@keyframes rts-st-pop{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}\n", ".rts-st-autocomplete{position:relative}.rts-st-autocomplete-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:12px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-input{padding-left:32px;padding-right:32px}.rts-st-autocomplete-input.rts-st-autocomplete-selected{font-weight:600}.rts-st-autocomplete-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;padding:0;border:none;border-radius:50%;font-size:10px;cursor:pointer;color:var(--rts-text-secondary, #8a8fa3);background:transparent;transition:background .15s ease,color .15s ease}.rts-st-autocomplete-clear:hover{color:var(--rts-text-primary);background:#8b5cf626}.rts-st-autocomplete-panel{position:absolute;z-index:20;left:0;right:0;top:calc(100% + 4px);max-height:240px;margin:0;padding:4px;overflow-y:auto;list-style:none;border-radius:10px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-secondary, var(--rts-bg-primary, #1d1f2b));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 14px 32px -12px #00000073;animation:rts-st-panel-in .14s ease-out}.rts-st-autocomplete-option{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:7px;cursor:pointer;transition:background .12s ease}.rts-st-autocomplete-option.rts-st-autocomplete-option-active{background:linear-gradient(135deg,#6366f129,#8b5cf61a)}.rts-st-autocomplete-option[aria-selected=true] .rts-st-autocomplete-option-name{color:var(--rts-st-accent)}.rts-st-autocomplete-thumb{flex-shrink:0;width:30px;height:30px;border-radius:7px;object-fit:cover}.rts-st-autocomplete-thumb-empty{display:flex;align-items:center;justify-content:center;font-size:15px;background:#8b5cf624}.rts-st-autocomplete-option-body{display:flex;flex-direction:column;min-width:0}.rts-st-autocomplete-option-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;color:var(--rts-text-primary)}.rts-st-autocomplete-option-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-empty{padding:8px;font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-error{font-style:normal;color:#f43f5e}.rts-st-translator-actions{gap:8px}.rts-st-checkbox-row{display:flex;align-items:flex-start;gap:10px;padding:9px 11px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));cursor:pointer;-webkit-user-select:none;user-select:none;transition:border-color .15s ease,background .15s ease}.rts-st-checkbox-row:hover{border-color:#8b5cf673;background:#8b5cf60f}.rts-st-checkbox-input{margin-top:2px;width:15px;height:15px;flex-shrink:0;accent-color:var(--rts-st-accent, #8b5cf6);cursor:pointer}.rts-st-checkbox-body{display:flex;flex-direction:column;gap:2px;min-width:0}.rts-st-checkbox-title{font-size:13px;font-weight:600;color:var(--rts-text-primary)}.rts-st-checkbox-desc{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-cancel{padding:8px 16px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:transparent;color:var(--rts-text-secondary, #8a8fa3);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.rts-st-cancel:hover{color:var(--rts-text-primary);border-color:#f43f5e73;background:#f43f5e0f}@keyframes rts-st-panel-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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.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"] }] }); }
|
|
2867
3037
|
}
|
|
2868
3038
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryTranslatorFormStepComponent, decorators: [{
|
|
2869
3039
|
type: Component,
|
|
2870
|
-
args: [{ selector: 'rtsee-story-translator-form-step', standalone: true, imports: [ReactiveFormsModule], template: "<form class=\"rts-storyteller-form\" [formGroup]=\"form\" (ngSubmit)=\"submit()\" autocomplete=\"off\">\n <div class=\"rts-storyteller-field\">\n <label class=\"rts-storyteller-label\" for=\"story-translator-story-{{ step.id }}\">Story</label>\n <div class=\"rts-st-autocomplete\">\n <span class=\"rts-st-autocomplete-icon pi\" [class.pi-search]=\"!searchInProgress\" [class.pi-spin]=\"searchInProgress\" [class.pi-spinner]=\"searchInProgress\"></span>\n <input #storyInput\n class=\"rts-storyteller-input rts-st-autocomplete-input\"\n [class.rts-storyteller-invalid]=\"isInvalid('storyId')\"\n [class.rts-st-autocomplete-selected]=\"!!selectedStory\"\n formControlName=\"storyQuery\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"suggestionsOpened\"\n placeholder=\"Search stories by name\u2026\"\n id=\"story-translator-story-{{ step.id }}\"\n (focus)=\"onStoryFocus()\"\n (input)=\"onStoryInput()\"\n (keydown)=\"onStoryKeydown($event)\"\n />\n @if (selectedStory && !readonly) {\n <button type=\"button\"\n class=\"rts-st-autocomplete-clear pi pi-times\"\n aria-label=\"Clear story\"\n id=\"story-translator-clear-{{ step.id }}\"\n (click)=\"clearStory()\"\n ></button>\n }\n\n @if (suggestionsOpened && !readonly) {\n <ul class=\"rts-st-autocomplete-panel\" role=\"listbox\">\n @if (searchError) {\n <li class=\"rts-st-autocomplete-empty rts-st-autocomplete-error\">{{ searchError }}</li>\n } @else if (!suggestions.length && !searchInProgress) {\n <li class=\"rts-st-autocomplete-empty\">No stories found</li>\n }\n @for (story of suggestions; track story.id; let i = $index) {\n <li class=\"rts-st-autocomplete-option\"\n role=\"option\"\n [class.rts-st-autocomplete-option-active]=\"i === highlightedIndex\"\n [attr.aria-selected]=\"story.id === selectedStory?.id\"\n (mouseenter)=\"highlightedIndex = i\"\n (mousedown)=\"$event.preventDefault(); selectStory(story)\"\n >\n @if (story.imageUrl) {\n <img class=\"rts-st-autocomplete-thumb\" [src]=\"story.imageUrl\" [alt]=\"story.name\" loading=\"lazy\" />\n } @else {\n <span class=\"rts-st-autocomplete-thumb rts-st-autocomplete-thumb-empty\">\uD83D\uDCD6</span>\n }\n <span class=\"rts-st-autocomplete-option-body\">\n <span class=\"rts-st-autocomplete-option-name\">{{ story.name }}</span>\n @if (story.totalSlides) {\n <span class=\"rts-st-autocomplete-option-meta\">{{ story.totalSlides }} slides</span>\n }\n </span>\n </li>\n }\n </ul>\n }\n </div>\n </div>\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Translate to</span>\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('language')\"\n formControlName=\"language\"\n id=\"story-translator-language-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select a language</option>\n @for (language of languages; track language.code) {\n <option [value]=\"language.code\">{{ language.nativeName }}</option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n </label>\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Agent</span>\n @if (agents.length) {\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('agentId')\"\n formControlName=\"agentId\"\n id=\"story-translator-agent-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select an agent</option>\n @for (agent of agents; track agent.id) {\n <option [value]=\"agent.id\">\n {{ agent.name }}{{ agent.agentConfiguration?.model?.model ? ' \u00B7 ' + agent.agentConfiguration?.model?.model : '' }}\n </option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n } @else {\n <div class=\"rts-storyteller-hint\">There are no agentic members in this chat. Add an agent to continue.</div>\n }\n </label>\n\n @if (workflow.submitError) {\n <div class=\"rts-storyteller-error\">{{ workflow.submitError }}</div>\n }\n\n @if (step.isActive) {\n <div class=\"rts-storyteller-actions rts-st-translator-actions\">\n @if (canCancel) {\n <button class=\"rts-st-cancel\"\n type=\"button\"\n id=\"story-translator-cancel-{{ step.id }}\"\n (click)=\"cancel()\"\n >Cancel</button>\n }\n <button class=\"rts-storyteller-submit\"\n type=\"submit\"\n [disabled]=\"workflow.submitInProgress || !agents.length\"\n id=\"story-translator-submit-{{ step.id }}\"\n >\n @if (workflow.submitInProgress) {\n <span class=\"rts-storyteller-spinner\"></span> Translating\u2026\n } @else {\n \uD83C\uDF10 Translate{{ selectedLanguage ? ' to ' + selectedLanguage.nativeName : '' }}\n }\n </button>\n </div>\n }\n</form>\n", styles: [":host{display:block;--rts-st-accent: #8b5cf6;--rts-st-accent-2: #6366f1}.rts-storyteller-form{display:flex;flex-direction:column;gap:12px}.rts-storyteller-field{display:flex;flex-direction:column;gap:5px}.rts-storyteller-label{display:flex;justify-content:space-between;align-items:baseline;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-counter{font-weight:500;letter-spacing:0;text-transform:none}.rts-storyteller-input{width:100%;box-sizing:border-box;padding:9px 12px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));color:var(--rts-text-primary);font:inherit;font-size:13px;outline:none;transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.rts-storyteller-input:focus{border-color:var(--rts-st-accent);box-shadow:0 0 0 3px #8b5cf62e}.rts-storyteller-input:disabled{opacity:.75;cursor:default}.rts-storyteller-input.rts-storyteller-invalid{border-color:#f43f5e;box-shadow:0 0 0 3px #f43f5e1f}.rts-storyteller-textarea{min-height:80px;resize:vertical;line-height:1.5}.rts-storyteller-textarea-lg{min-height:160px;max-height:480px}.rts-storyteller-select-wrap{position:relative}.rts-storyteller-select{appearance:none;padding-right:32px;cursor:pointer}.rts-storyteller-select-caret{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:10px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-hint{font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-error{padding:6px 10px;border-radius:6px;font-size:12px;color:#f43f5e;background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}.rts-storyteller-actions{display:flex;justify-content:flex-end}.rts-storyteller-submit{display:inline-flex;align-items:center;gap:6px;padding:8px 18px;border:none;border-radius:9px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent) 60%,#a78bfa);background-size:160% 160%;box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,background-position .4s ease}.rts-storyteller-submit:hover:not(:disabled){transform:translateY(-1px);background-position:100% 0;box-shadow:0 6px 18px -4px #6366f1bf}.rts-storyteller-submit:disabled{opacity:.6;cursor:default;box-shadow:none}.rts-storyteller-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-st-spin .8s linear infinite}.rts-story-link-card{display:flex;align-items:center;gap:12px;padding:14px;border-radius:12px;text-decoration:none;color:inherit;background:linear-gradient(135deg,#6366f11a,#8b5cf60f);border:1px solid rgba(139,92,246,.3);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;animation:rts-st-pop .4s cubic-bezier(.2,.9,.3,1.3)}.rts-story-link-card:hover{transform:translateY(-2px);border-color:var(--rts-st-accent);box-shadow:0 10px 28px -12px #8b5cf699}.rts-story-link-card:hover .rts-story-link-arrow{transform:translate(3px)}.rts-story-link-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:42px;height:42px;border-radius:12px;font-size:20px;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent))}.rts-story-link-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.rts-story-link-kicker{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-st-accent)}.rts-story-link-title{font-size:15px;font-weight:600;color:var(--rts-text-primary)}.rts-story-link-description{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.rts-story-link-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-link-arrow{color:var(--rts-st-accent);transition:transform .2s ease}@keyframes rts-st-spin{to{transform:rotate(360deg)}}@keyframes rts-st-pop{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}\n", ".rts-st-autocomplete{position:relative}.rts-st-autocomplete-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:12px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-input{padding-left:32px;padding-right:32px}.rts-st-autocomplete-input.rts-st-autocomplete-selected{font-weight:600}.rts-st-autocomplete-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;padding:0;border:none;border-radius:50%;font-size:10px;cursor:pointer;color:var(--rts-text-secondary, #8a8fa3);background:transparent;transition:background .15s ease,color .15s ease}.rts-st-autocomplete-clear:hover{color:var(--rts-text-primary);background:#8b5cf626}.rts-st-autocomplete-panel{position:absolute;z-index:20;left:0;right:0;top:calc(100% + 4px);max-height:240px;margin:0;padding:4px;overflow-y:auto;list-style:none;border-radius:10px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-secondary, var(--rts-bg-primary, #1d1f2b));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 14px 32px -12px #00000073;animation:rts-st-panel-in .14s ease-out}.rts-st-autocomplete-option{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:7px;cursor:pointer;transition:background .12s ease}.rts-st-autocomplete-option.rts-st-autocomplete-option-active{background:linear-gradient(135deg,#6366f129,#8b5cf61a)}.rts-st-autocomplete-option[aria-selected=true] .rts-st-autocomplete-option-name{color:var(--rts-st-accent)}.rts-st-autocomplete-thumb{flex-shrink:0;width:30px;height:30px;border-radius:7px;object-fit:cover}.rts-st-autocomplete-thumb-empty{display:flex;align-items:center;justify-content:center;font-size:15px;background:#8b5cf624}.rts-st-autocomplete-option-body{display:flex;flex-direction:column;min-width:0}.rts-st-autocomplete-option-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;color:var(--rts-text-primary)}.rts-st-autocomplete-option-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-empty{padding:8px;font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-error{font-style:normal;color:#f43f5e}.rts-st-translator-actions{gap:8px}.rts-st-cancel{padding:8px 16px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:transparent;color:var(--rts-text-secondary, #8a8fa3);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.rts-st-cancel:hover{color:var(--rts-text-primary);border-color:#f43f5e73;background:#f43f5e0f}@keyframes rts-st-panel-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n"] }]
|
|
3040
|
+
args: [{ selector: 'rtsee-story-translator-form-step', standalone: true, imports: [ReactiveFormsModule], template: "<form class=\"rts-storyteller-form\" [formGroup]=\"form\" (ngSubmit)=\"submit()\" autocomplete=\"off\">\n <div class=\"rts-storyteller-field\">\n <label class=\"rts-storyteller-label\" for=\"story-translator-story-{{ step.id }}\">Story</label>\n <div class=\"rts-st-autocomplete\">\n <span class=\"rts-st-autocomplete-icon pi\" [class.pi-search]=\"!searchInProgress\" [class.pi-spin]=\"searchInProgress\" [class.pi-spinner]=\"searchInProgress\"></span>\n <input #storyInput\n class=\"rts-storyteller-input rts-st-autocomplete-input\"\n [class.rts-storyteller-invalid]=\"isInvalid('storyId')\"\n [class.rts-st-autocomplete-selected]=\"!!selectedStory\"\n formControlName=\"storyQuery\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"suggestionsOpened\"\n placeholder=\"Search stories by name\u2026\"\n id=\"story-translator-story-{{ step.id }}\"\n (focus)=\"onStoryFocus()\"\n (input)=\"onStoryInput()\"\n (keydown)=\"onStoryKeydown($event)\"\n />\n @if (selectedStory && !readonly) {\n <button type=\"button\"\n class=\"rts-st-autocomplete-clear pi pi-times\"\n aria-label=\"Clear story\"\n id=\"story-translator-clear-{{ step.id }}\"\n (click)=\"clearStory()\"\n ></button>\n }\n\n @if (suggestionsOpened && !readonly) {\n <ul class=\"rts-st-autocomplete-panel\" role=\"listbox\">\n @if (searchError) {\n <li class=\"rts-st-autocomplete-empty rts-st-autocomplete-error\">{{ searchError }}</li>\n } @else if (!suggestions.length && !searchInProgress) {\n <li class=\"rts-st-autocomplete-empty\">No stories found</li>\n }\n @for (story of suggestions; track story.id; let i = $index) {\n <li class=\"rts-st-autocomplete-option\"\n role=\"option\"\n [class.rts-st-autocomplete-option-active]=\"i === highlightedIndex\"\n [attr.aria-selected]=\"story.id === selectedStory?.id\"\n (mouseenter)=\"highlightedIndex = i\"\n (mousedown)=\"$event.preventDefault(); selectStory(story)\"\n >\n @if (story.imageUrl) {\n <img class=\"rts-st-autocomplete-thumb\" [src]=\"story.imageUrl\" [alt]=\"story.name\" loading=\"lazy\" />\n } @else {\n <span class=\"rts-st-autocomplete-thumb rts-st-autocomplete-thumb-empty\">\uD83D\uDCD6</span>\n }\n <span class=\"rts-st-autocomplete-option-body\">\n <span class=\"rts-st-autocomplete-option-name\">{{ story.name }}</span>\n @if (story.totalSlides) {\n <span class=\"rts-st-autocomplete-option-meta\">{{ story.totalSlides }} slides</span>\n }\n </span>\n </li>\n }\n </ul>\n }\n </div>\n </div>\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Translate to</span>\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('language')\"\n formControlName=\"language\"\n id=\"story-translator-language-{{ step.id }}\"\n (change)=\"onLanguageChange()\"\n >\n <option value=\"\" disabled>Select a language</option>\n @for (language of languages; track language.code) {\n <option [value]=\"language.code\">{{ language.nativeName }}</option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n </label>\n\n @if (hasExistingTranslation) {\n <label class=\"rts-st-checkbox-row\" for=\"story-translator-from-scratch-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"fromScratch\"\n id=\"story-translator-from-scratch-{{ step.id }}\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">From scratch</span>\n <span class=\"rts-st-checkbox-desc\">Overwrite existing {{ selectedLanguage?.nativeName || '' }} translations for all story elements</span>\n </span>\n </label>\n }\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Agent</span>\n @if (agents.length) {\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('agentId')\"\n formControlName=\"agentId\"\n id=\"story-translator-agent-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select an agent</option>\n @for (agent of agents; track agent.id) {\n <option [value]=\"agent.id\">\n {{ agent.name }}{{ agent.agentConfiguration?.model?.model ? ' \u00B7 ' + agent.agentConfiguration?.model?.model : '' }}\n </option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n } @else {\n <div class=\"rts-storyteller-hint\">There are no agentic members in this chat. Add an agent to continue.</div>\n }\n </label>\n\n @if (workflow.submitError) {\n <div class=\"rts-storyteller-error\">{{ workflow.submitError }}</div>\n }\n\n @if (step.isActive) {\n <div class=\"rts-storyteller-actions rts-st-translator-actions\">\n @if (canCancel) {\n <button class=\"rts-st-cancel\"\n type=\"button\"\n id=\"story-translator-cancel-{{ step.id }}\"\n (click)=\"cancel()\"\n >Cancel</button>\n }\n <button class=\"rts-storyteller-submit\"\n type=\"submit\"\n [disabled]=\"workflow.submitInProgress || !agents.length\"\n id=\"story-translator-submit-{{ step.id }}\"\n >\n @if (workflow.submitInProgress) {\n <span class=\"rts-storyteller-spinner\"></span> Translating\u2026\n } @else {\n \uD83C\uDF10 Translate{{ selectedLanguage ? ' to ' + selectedLanguage.nativeName : '' }}\n }\n </button>\n </div>\n }\n</form>\n", styles: [":host{display:block;--rts-st-accent: #8b5cf6;--rts-st-accent-2: #6366f1}.rts-storyteller-form{display:flex;flex-direction:column;gap:12px}.rts-storyteller-field{display:flex;flex-direction:column;gap:5px}.rts-storyteller-label{display:flex;justify-content:space-between;align-items:baseline;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-counter{font-weight:500;letter-spacing:0;text-transform:none}.rts-storyteller-input{width:100%;box-sizing:border-box;padding:9px 12px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));color:var(--rts-text-primary);font:inherit;font-size:13px;outline:none;transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.rts-storyteller-input:focus{border-color:var(--rts-st-accent);box-shadow:0 0 0 3px #8b5cf62e}.rts-storyteller-input:disabled{opacity:.75;cursor:default}.rts-storyteller-input.rts-storyteller-invalid{border-color:#f43f5e;box-shadow:0 0 0 3px #f43f5e1f}.rts-storyteller-textarea{min-height:80px;resize:vertical;line-height:1.5}.rts-storyteller-textarea-lg{min-height:160px;max-height:480px}.rts-storyteller-select-wrap{position:relative}.rts-storyteller-select{appearance:none;padding-right:32px;cursor:pointer}.rts-storyteller-select-caret{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:10px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-hint{font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-error{padding:6px 10px;border-radius:6px;font-size:12px;color:#f43f5e;background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}.rts-storyteller-actions{display:flex;justify-content:flex-end}.rts-storyteller-submit{display:inline-flex;align-items:center;gap:6px;padding:8px 18px;border:none;border-radius:9px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent) 60%,#a78bfa);background-size:160% 160%;box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,background-position .4s ease}.rts-storyteller-submit:hover:not(:disabled){transform:translateY(-1px);background-position:100% 0;box-shadow:0 6px 18px -4px #6366f1bf}.rts-storyteller-submit:disabled{opacity:.6;cursor:default;box-shadow:none}.rts-storyteller-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-st-spin .8s linear infinite}.rts-story-link-card{display:flex;align-items:center;gap:12px;padding:14px;border-radius:12px;text-decoration:none;color:inherit;background:linear-gradient(135deg,#6366f11a,#8b5cf60f);border:1px solid rgba(139,92,246,.3);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;animation:rts-st-pop .4s cubic-bezier(.2,.9,.3,1.3)}.rts-story-link-card:hover{transform:translateY(-2px);border-color:var(--rts-st-accent);box-shadow:0 10px 28px -12px #8b5cf699}.rts-story-link-card:hover .rts-story-link-arrow{transform:translate(3px)}.rts-story-link-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:42px;height:42px;border-radius:12px;font-size:20px;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent))}.rts-story-link-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.rts-story-link-kicker{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-st-accent)}.rts-story-link-title{font-size:15px;font-weight:600;color:var(--rts-text-primary)}.rts-story-link-description{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.rts-story-link-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-link-arrow{color:var(--rts-st-accent);transition:transform .2s ease}@keyframes rts-st-spin{to{transform:rotate(360deg)}}@keyframes rts-st-pop{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}\n", ".rts-st-autocomplete{position:relative}.rts-st-autocomplete-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:12px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-input{padding-left:32px;padding-right:32px}.rts-st-autocomplete-input.rts-st-autocomplete-selected{font-weight:600}.rts-st-autocomplete-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;padding:0;border:none;border-radius:50%;font-size:10px;cursor:pointer;color:var(--rts-text-secondary, #8a8fa3);background:transparent;transition:background .15s ease,color .15s ease}.rts-st-autocomplete-clear:hover{color:var(--rts-text-primary);background:#8b5cf626}.rts-st-autocomplete-panel{position:absolute;z-index:20;left:0;right:0;top:calc(100% + 4px);max-height:240px;margin:0;padding:4px;overflow-y:auto;list-style:none;border-radius:10px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-secondary, var(--rts-bg-primary, #1d1f2b));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 14px 32px -12px #00000073;animation:rts-st-panel-in .14s ease-out}.rts-st-autocomplete-option{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:7px;cursor:pointer;transition:background .12s ease}.rts-st-autocomplete-option.rts-st-autocomplete-option-active{background:linear-gradient(135deg,#6366f129,#8b5cf61a)}.rts-st-autocomplete-option[aria-selected=true] .rts-st-autocomplete-option-name{color:var(--rts-st-accent)}.rts-st-autocomplete-thumb{flex-shrink:0;width:30px;height:30px;border-radius:7px;object-fit:cover}.rts-st-autocomplete-thumb-empty{display:flex;align-items:center;justify-content:center;font-size:15px;background:#8b5cf624}.rts-st-autocomplete-option-body{display:flex;flex-direction:column;min-width:0}.rts-st-autocomplete-option-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;color:var(--rts-text-primary)}.rts-st-autocomplete-option-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-empty{padding:8px;font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-error{font-style:normal;color:#f43f5e}.rts-st-translator-actions{gap:8px}.rts-st-checkbox-row{display:flex;align-items:flex-start;gap:10px;padding:9px 11px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));cursor:pointer;-webkit-user-select:none;user-select:none;transition:border-color .15s ease,background .15s ease}.rts-st-checkbox-row:hover{border-color:#8b5cf673;background:#8b5cf60f}.rts-st-checkbox-input{margin-top:2px;width:15px;height:15px;flex-shrink:0;accent-color:var(--rts-st-accent, #8b5cf6);cursor:pointer}.rts-st-checkbox-body{display:flex;flex-direction:column;gap:2px;min-width:0}.rts-st-checkbox-title{font-size:13px;font-weight:600;color:var(--rts-text-primary)}.rts-st-checkbox-desc{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-cancel{padding:8px 16px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:transparent;color:var(--rts-text-secondary, #8a8fa3);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.rts-st-cancel:hover{color:var(--rts-text-primary);border-color:#f43f5e73;background:#f43f5e0f}@keyframes rts-st-panel-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n"] }]
|
|
3041
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { step: [{
|
|
3042
|
+
type: Input
|
|
3043
|
+
}], workflow: [{
|
|
3044
|
+
type: Input
|
|
3045
|
+
}], chat: [{
|
|
3046
|
+
type: Input
|
|
3047
|
+
}], messenger: [{
|
|
3048
|
+
type: Input
|
|
3049
|
+
}], storyInput: [{
|
|
3050
|
+
type: ViewChild,
|
|
3051
|
+
args: ['storyInput']
|
|
3052
|
+
}], onDocumentMouseDown: [{
|
|
3053
|
+
type: HostListener,
|
|
3054
|
+
args: ['document:mousedown', ['$event']]
|
|
3055
|
+
}] } });
|
|
3056
|
+
|
|
3057
|
+
const SEARCH_DEBOUNCE_MS = 250;
|
|
3058
|
+
/**
|
|
3059
|
+
* Story Repair step 1 (#RepairStory):
|
|
3060
|
+
* - Pick a story (autocomplete by name)
|
|
3061
|
+
* - Choose repair options via 4 checkboxes (Grammar & Flow, Characters, Artifacts, Locations), all checked by default
|
|
3062
|
+
* - Pick an agent
|
|
3063
|
+
*/
|
|
3064
|
+
class StoryRepairFormStepComponent {
|
|
3065
|
+
constructor(cdr, host) {
|
|
3066
|
+
this.cdr = cdr;
|
|
3067
|
+
this.host = host;
|
|
3068
|
+
this.form = new FormGroup({
|
|
3069
|
+
/* eslint-disable */
|
|
3070
|
+
storyQuery: new FormControl(''),
|
|
3071
|
+
storyId: new FormControl('', Validators.required),
|
|
3072
|
+
grammarAndFlow: new FormControl(true),
|
|
3073
|
+
characters: new FormControl(true),
|
|
3074
|
+
artifacts: new FormControl(true),
|
|
3075
|
+
locations: new FormControl(true),
|
|
3076
|
+
sanitizeImages: new FormControl(true),
|
|
3077
|
+
agentId: new FormControl('', Validators.required),
|
|
3078
|
+
/* eslint-enable */
|
|
3079
|
+
});
|
|
3080
|
+
this.selectedStory = null;
|
|
3081
|
+
this.suggestions = [];
|
|
3082
|
+
this.suggestionsOpened = false;
|
|
3083
|
+
this.highlightedIndex = 0;
|
|
3084
|
+
this.searchInProgress = false;
|
|
3085
|
+
this.searchError = null;
|
|
3086
|
+
this.optionsTouched = false;
|
|
3087
|
+
this.searchTimer = null;
|
|
3088
|
+
this.searchRequestId = 0;
|
|
3089
|
+
this.onChangedBound = () => this.onWorkflowChanged();
|
|
3090
|
+
}
|
|
3091
|
+
get agents() {
|
|
3092
|
+
return (this.chat?.members || []).filter((m) => m.isAgent);
|
|
3093
|
+
}
|
|
3094
|
+
get readonly() {
|
|
3095
|
+
return !this.step?.isActive || !!this.workflow?.submitInProgress;
|
|
3096
|
+
}
|
|
3097
|
+
get canCancel() {
|
|
3098
|
+
return !!this.workflow?.isDraft && !this.workflow?.submitInProgress && !!this.messenger;
|
|
3099
|
+
}
|
|
3100
|
+
get hasAtLeastOneOption() {
|
|
3101
|
+
const opts = this.currentOptions;
|
|
3102
|
+
return (opts.grammarAndFlow ||
|
|
3103
|
+
opts.characters ||
|
|
3104
|
+
opts.artifacts ||
|
|
3105
|
+
opts.locations ||
|
|
3106
|
+
opts.sanitizeImages);
|
|
3107
|
+
}
|
|
3108
|
+
get currentOptions() {
|
|
3109
|
+
return {
|
|
3110
|
+
grammarAndFlow: !!this.form.get('grammarAndFlow')?.value,
|
|
3111
|
+
characters: !!this.form.get('characters')?.value,
|
|
3112
|
+
artifacts: !!this.form.get('artifacts')?.value,
|
|
3113
|
+
locations: !!this.form.get('locations')?.value,
|
|
3114
|
+
sanitizeImages: !!this.form.get('sanitizeImages')?.value,
|
|
3115
|
+
};
|
|
3116
|
+
}
|
|
3117
|
+
ngOnInit() {
|
|
3118
|
+
this.workflow?.on(OzzyWorkflowClientEvents.CHANGED, this.onChangedBound);
|
|
3119
|
+
const agents = this.agents;
|
|
3120
|
+
if (agents.length === 1) {
|
|
3121
|
+
this.form.get('agentId')?.setValue(agents[0].id);
|
|
3122
|
+
}
|
|
3123
|
+
this.syncWithStep();
|
|
3124
|
+
}
|
|
3125
|
+
ngOnDestroy() {
|
|
3126
|
+
this.workflow?.off(OzzyWorkflowClientEvents.CHANGED, this.onChangedBound);
|
|
3127
|
+
this.clearSearchTimer();
|
|
3128
|
+
}
|
|
3129
|
+
onStoryFocus() {
|
|
3130
|
+
if (this.readonly) {
|
|
3131
|
+
return;
|
|
3132
|
+
}
|
|
3133
|
+
this.suggestionsOpened = true;
|
|
3134
|
+
if (!this.suggestions.length) {
|
|
3135
|
+
this.scheduleSearch(0);
|
|
3136
|
+
}
|
|
3137
|
+
}
|
|
3138
|
+
onStoryInput() {
|
|
3139
|
+
if (this.selectedStory) {
|
|
3140
|
+
this.selectedStory = null;
|
|
3141
|
+
this.form.get('storyId')?.setValue('');
|
|
3142
|
+
}
|
|
3143
|
+
this.suggestionsOpened = true;
|
|
3144
|
+
this.scheduleSearch(SEARCH_DEBOUNCE_MS);
|
|
3145
|
+
}
|
|
3146
|
+
onStoryKeydown(event) {
|
|
3147
|
+
if (!this.suggestionsOpened || !this.suggestions.length) {
|
|
3148
|
+
if (event.key === 'ArrowDown') {
|
|
3149
|
+
this.suggestionsOpened = true;
|
|
3150
|
+
this.scheduleSearch(0);
|
|
3151
|
+
}
|
|
3152
|
+
return;
|
|
3153
|
+
}
|
|
3154
|
+
switch (event.key) {
|
|
3155
|
+
case 'ArrowDown':
|
|
3156
|
+
event.preventDefault();
|
|
3157
|
+
this.highlightedIndex = (this.highlightedIndex + 1) % this.suggestions.length;
|
|
3158
|
+
break;
|
|
3159
|
+
case 'ArrowUp':
|
|
3160
|
+
event.preventDefault();
|
|
3161
|
+
this.highlightedIndex =
|
|
3162
|
+
(this.highlightedIndex - 1 + this.suggestions.length) % this.suggestions.length;
|
|
3163
|
+
break;
|
|
3164
|
+
case 'Enter':
|
|
3165
|
+
event.preventDefault();
|
|
3166
|
+
this.selectStory(this.suggestions[this.highlightedIndex]);
|
|
3167
|
+
break;
|
|
3168
|
+
case 'Escape':
|
|
3169
|
+
event.preventDefault();
|
|
3170
|
+
this.suggestionsOpened = false;
|
|
3171
|
+
break;
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
selectStory(story) {
|
|
3175
|
+
if (!story || this.readonly) {
|
|
3176
|
+
return;
|
|
3177
|
+
}
|
|
3178
|
+
this.selectedStory = story;
|
|
3179
|
+
this.form.patchValue({ storyId: story.id, storyQuery: story.name }, { emitEvent: false });
|
|
3180
|
+
this.form.get('storyId')?.markAsTouched();
|
|
3181
|
+
this.suggestionsOpened = false;
|
|
3182
|
+
}
|
|
3183
|
+
clearStory() {
|
|
3184
|
+
if (this.readonly) {
|
|
3185
|
+
return;
|
|
3186
|
+
}
|
|
3187
|
+
this.selectedStory = null;
|
|
3188
|
+
this.form.patchValue({ storyId: '', storyQuery: '' }, { emitEvent: false });
|
|
3189
|
+
this.suggestionsOpened = true;
|
|
3190
|
+
this.scheduleSearch(0);
|
|
3191
|
+
setTimeout(() => this.storyInput?.nativeElement.focus());
|
|
3192
|
+
}
|
|
3193
|
+
onOptionChanged() {
|
|
3194
|
+
this.optionsTouched = true;
|
|
3195
|
+
}
|
|
3196
|
+
onDocumentMouseDown(event) {
|
|
3197
|
+
if (this.suggestionsOpened && !this.host.nativeElement.contains(event.target)) {
|
|
3198
|
+
this.suggestionsOpened = false;
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
submit() {
|
|
3202
|
+
if (this.readonly) {
|
|
3203
|
+
return;
|
|
3204
|
+
}
|
|
3205
|
+
this.optionsTouched = true;
|
|
3206
|
+
if (this.form.invalid || !this.selectedStory || !this.hasAtLeastOneOption) {
|
|
3207
|
+
this.form.markAllAsTouched();
|
|
3208
|
+
return;
|
|
3209
|
+
}
|
|
3210
|
+
void this.workflow.submitStep({
|
|
3211
|
+
storyId: this.selectedStory.id,
|
|
3212
|
+
storyName: this.selectedStory.name,
|
|
3213
|
+
agentId: this.form.get('agentId')?.value,
|
|
3214
|
+
options: this.currentOptions,
|
|
3215
|
+
});
|
|
3216
|
+
}
|
|
3217
|
+
cancel() {
|
|
3218
|
+
if (!this.canCancel) {
|
|
3219
|
+
return;
|
|
3220
|
+
}
|
|
3221
|
+
this.messenger?.discardDraftWorkflow(this.workflow);
|
|
3222
|
+
}
|
|
3223
|
+
isInvalid(name) {
|
|
3224
|
+
const control = this.form.get(name);
|
|
3225
|
+
return !!control && control.invalid && control.touched;
|
|
3226
|
+
}
|
|
3227
|
+
scheduleSearch(delay) {
|
|
3228
|
+
this.clearSearchTimer();
|
|
3229
|
+
this.searchTimer = setTimeout(() => void this.search(), delay);
|
|
3230
|
+
}
|
|
3231
|
+
clearSearchTimer() {
|
|
3232
|
+
if (this.searchTimer) {
|
|
3233
|
+
clearTimeout(this.searchTimer);
|
|
3234
|
+
this.searchTimer = null;
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
async search() {
|
|
3238
|
+
if (!this.messenger) {
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
const requestId = ++this.searchRequestId;
|
|
3242
|
+
const query = this.form.get('storyQuery')?.value || '';
|
|
3243
|
+
this.searchInProgress = true;
|
|
3244
|
+
this.searchError = null;
|
|
3245
|
+
this.cdr.markForCheck();
|
|
3246
|
+
try {
|
|
3247
|
+
const stories = await this.messenger.ozzy.searchStories(query);
|
|
3248
|
+
if (requestId !== this.searchRequestId) {
|
|
3249
|
+
return;
|
|
3250
|
+
}
|
|
3251
|
+
this.suggestions = stories;
|
|
3252
|
+
this.highlightedIndex = 0;
|
|
3253
|
+
}
|
|
3254
|
+
catch (e) {
|
|
3255
|
+
if (requestId !== this.searchRequestId) {
|
|
3256
|
+
return;
|
|
3257
|
+
}
|
|
3258
|
+
this.suggestions = [];
|
|
3259
|
+
this.searchError = e?.friendlyMessage || e?.message || 'Failed to load stories.';
|
|
3260
|
+
}
|
|
3261
|
+
finally {
|
|
3262
|
+
if (requestId === this.searchRequestId) {
|
|
3263
|
+
this.searchInProgress = false;
|
|
3264
|
+
this.cdr.detectChanges();
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
onWorkflowChanged() {
|
|
3269
|
+
this.syncWithStep();
|
|
3270
|
+
this.cdr.detectChanges();
|
|
3271
|
+
}
|
|
3272
|
+
syncWithStep() {
|
|
3273
|
+
const output = this.step?.output;
|
|
3274
|
+
if (output?.storyId) {
|
|
3275
|
+
this.selectedStory = { id: output.storyId, name: output.storyName || output.storyId };
|
|
3276
|
+
this.form.patchValue({
|
|
3277
|
+
storyId: output.storyId,
|
|
3278
|
+
storyQuery: output.storyName || '',
|
|
3279
|
+
grammarAndFlow: output.options ? !!output.options.grammarAndFlow : true,
|
|
3280
|
+
characters: output.options ? !!output.options.characters : true,
|
|
3281
|
+
artifacts: output.options ? !!output.options.artifacts : true,
|
|
3282
|
+
locations: output.options ? !!output.options.locations : true,
|
|
3283
|
+
sanitizeImages: output.options && output.options.sanitizeImages !== undefined
|
|
3284
|
+
? !!output.options.sanitizeImages
|
|
3285
|
+
: true,
|
|
3286
|
+
agentId: output.agentId,
|
|
3287
|
+
}, { emitEvent: false });
|
|
3288
|
+
}
|
|
3289
|
+
if (this.readonly) {
|
|
3290
|
+
this.suggestionsOpened = false;
|
|
3291
|
+
this.form.disable({ emitEvent: false });
|
|
3292
|
+
}
|
|
3293
|
+
else {
|
|
3294
|
+
this.form.enable({ emitEvent: false });
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryRepairFormStepComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3298
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryRepairFormStepComponent, isStandalone: true, selector: "rtsee-story-repair-form-step", inputs: { step: "step", workflow: "workflow", chat: "chat", messenger: "messenger" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event)" } }, viewQueries: [{ propertyName: "storyInput", first: true, predicate: ["storyInput"], descendants: true }], ngImport: i0, template: "<form class=\"rts-storyteller-form\" [formGroup]=\"form\" (ngSubmit)=\"submit()\" autocomplete=\"off\">\n <div class=\"rts-storyteller-field\">\n <label class=\"rts-storyteller-label\" for=\"story-repair-story-{{ step.id }}\">Story</label>\n <div class=\"rts-st-autocomplete\">\n <span class=\"rts-st-autocomplete-icon pi\" [class.pi-search]=\"!searchInProgress\" [class.pi-spin]=\"searchInProgress\" [class.pi-spinner]=\"searchInProgress\"></span>\n <input #storyInput\n class=\"rts-storyteller-input rts-st-autocomplete-input\"\n [class.rts-storyteller-invalid]=\"isInvalid('storyId')\"\n [class.rts-st-autocomplete-selected]=\"!!selectedStory\"\n formControlName=\"storyQuery\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"suggestionsOpened\"\n placeholder=\"Search stories by name\u2026\"\n id=\"story-repair-story-{{ step.id }}\"\n (focus)=\"onStoryFocus()\"\n (input)=\"onStoryInput()\"\n (keydown)=\"onStoryKeydown($event)\"\n />\n @if (selectedStory && !readonly) {\n <button type=\"button\"\n class=\"rts-st-autocomplete-clear pi pi-times\"\n aria-label=\"Clear story\"\n id=\"story-repair-clear-{{ step.id }}\"\n (click)=\"clearStory()\"\n ></button>\n }\n\n @if (suggestionsOpened && !readonly) {\n <ul class=\"rts-st-autocomplete-panel\" role=\"listbox\">\n @if (searchError) {\n <li class=\"rts-st-autocomplete-empty rts-st-autocomplete-error\">{{ searchError }}</li>\n } @else if (!suggestions.length && !searchInProgress) {\n <li class=\"rts-st-autocomplete-empty\">No stories found</li>\n }\n @for (story of suggestions; track story.id; let i = $index) {\n <li class=\"rts-st-autocomplete-option\"\n role=\"option\"\n [class.rts-st-autocomplete-option-active]=\"i === highlightedIndex\"\n [attr.aria-selected]=\"story.id === selectedStory?.id\"\n (mouseenter)=\"highlightedIndex = i\"\n (mousedown)=\"$event.preventDefault(); selectStory(story)\"\n >\n @if (story.imageUrl) {\n <img class=\"rts-st-autocomplete-thumb\" [src]=\"story.imageUrl\" [alt]=\"story.name\" loading=\"lazy\" />\n } @else {\n <span class=\"rts-st-autocomplete-thumb rts-st-autocomplete-thumb-empty\">\uD83D\uDCD6</span>\n }\n <span class=\"rts-st-autocomplete-option-body\">\n <span class=\"rts-st-autocomplete-option-name\">{{ story.name }}</span>\n @if (story.totalSlides) {\n <span class=\"rts-st-autocomplete-option-meta\">{{ story.totalSlides }} slides</span>\n }\n </span>\n </li>\n }\n </ul>\n }\n </div>\n </div>\n\n @if (selectedStory) {\n <div class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Repair options</span>\n <div class=\"rts-st-repair-options-grid\">\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-grammar-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"grammarAndFlow\"\n id=\"story-repair-grammar-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Grammar & Flow</span>\n <span class=\"rts-st-checkbox-desc\">Fix typos, punctuation & improve readability across story, slides & entities</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-characters-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"characters\"\n id=\"story-repair-characters-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Characters</span>\n <span class=\"rts-st-checkbox-desc\">Add missing important characters and link them to slides</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-artifacts-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"artifacts\"\n id=\"story-repair-artifacts-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Artifacts</span>\n <span class=\"rts-st-checkbox-desc\">Add missing memorable objects and link them to slides</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-locations-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"locations\"\n id=\"story-repair-locations-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Locations</span>\n <span class=\"rts-st-checkbox-desc\">Add missing story locations and link them to slides</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-sanitize-images-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"sanitizeImages\"\n id=\"story-repair-sanitize-images-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Sanitize images</span>\n <span class=\"rts-st-checkbox-desc\">Properly name & upload story, slide, character, artifact, location & author images to the public bucket for SEO</span>\n </span>\n </label>\n </div>\n @if (!hasAtLeastOneOption) {\n <div class=\"rts-storyteller-error\">Please select at least one option to repair.</div>\n }\n </div>\n }\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Agent</span>\n @if (agents.length) {\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('agentId')\"\n formControlName=\"agentId\"\n id=\"story-repair-agent-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select an agent</option>\n @for (agent of agents; track agent.id) {\n <option [value]=\"agent.id\">\n {{ agent.name }}{{ agent.agentConfiguration?.model?.model ? ' \u00B7 ' + agent.agentConfiguration?.model?.model : '' }}\n </option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n } @else {\n <div class=\"rts-storyteller-hint\">There are no agentic members in this chat. Add an agent to continue.</div>\n }\n </label>\n\n @if (workflow.submitError) {\n <div class=\"rts-storyteller-error\">{{ workflow.submitError }}</div>\n }\n\n @if (step.isActive) {\n <div class=\"rts-storyteller-actions rts-st-translator-actions\">\n @if (canCancel) {\n <button class=\"rts-st-cancel\"\n type=\"button\"\n id=\"story-repair-cancel-{{ step.id }}\"\n (click)=\"cancel()\"\n >Cancel</button>\n }\n <button class=\"rts-storyteller-submit\"\n type=\"submit\"\n [disabled]=\"workflow.submitInProgress || !agents.length || !selectedStory || !hasAtLeastOneOption\"\n id=\"story-repair-submit-{{ step.id }}\"\n >\n @if (workflow.submitInProgress) {\n <span class=\"rts-storyteller-spinner\"></span> Repairing\u2026\n } @else {\n \uD83D\uDEE0\uFE0F Repair Story\n }\n </button>\n </div>\n }\n</form>\n", styles: [":host{display:block;--rts-st-accent: #8b5cf6;--rts-st-accent-2: #6366f1}.rts-storyteller-form{display:flex;flex-direction:column;gap:12px}.rts-storyteller-field{display:flex;flex-direction:column;gap:5px}.rts-storyteller-label{display:flex;justify-content:space-between;align-items:baseline;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-counter{font-weight:500;letter-spacing:0;text-transform:none}.rts-storyteller-input{width:100%;box-sizing:border-box;padding:9px 12px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));color:var(--rts-text-primary);font:inherit;font-size:13px;outline:none;transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.rts-storyteller-input:focus{border-color:var(--rts-st-accent);box-shadow:0 0 0 3px #8b5cf62e}.rts-storyteller-input:disabled{opacity:.75;cursor:default}.rts-storyteller-input.rts-storyteller-invalid{border-color:#f43f5e;box-shadow:0 0 0 3px #f43f5e1f}.rts-storyteller-textarea{min-height:80px;resize:vertical;line-height:1.5}.rts-storyteller-textarea-lg{min-height:160px;max-height:480px}.rts-storyteller-select-wrap{position:relative}.rts-storyteller-select{appearance:none;padding-right:32px;cursor:pointer}.rts-storyteller-select-caret{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:10px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-hint{font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-error{padding:6px 10px;border-radius:6px;font-size:12px;color:#f43f5e;background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}.rts-storyteller-actions{display:flex;justify-content:flex-end}.rts-storyteller-submit{display:inline-flex;align-items:center;gap:6px;padding:8px 18px;border:none;border-radius:9px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent) 60%,#a78bfa);background-size:160% 160%;box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,background-position .4s ease}.rts-storyteller-submit:hover:not(:disabled){transform:translateY(-1px);background-position:100% 0;box-shadow:0 6px 18px -4px #6366f1bf}.rts-storyteller-submit:disabled{opacity:.6;cursor:default;box-shadow:none}.rts-storyteller-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-st-spin .8s linear infinite}.rts-story-link-card{display:flex;align-items:center;gap:12px;padding:14px;border-radius:12px;text-decoration:none;color:inherit;background:linear-gradient(135deg,#6366f11a,#8b5cf60f);border:1px solid rgba(139,92,246,.3);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;animation:rts-st-pop .4s cubic-bezier(.2,.9,.3,1.3)}.rts-story-link-card:hover{transform:translateY(-2px);border-color:var(--rts-st-accent);box-shadow:0 10px 28px -12px #8b5cf699}.rts-story-link-card:hover .rts-story-link-arrow{transform:translate(3px)}.rts-story-link-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:42px;height:42px;border-radius:12px;font-size:20px;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent))}.rts-story-link-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.rts-story-link-kicker{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-st-accent)}.rts-story-link-title{font-size:15px;font-weight:600;color:var(--rts-text-primary)}.rts-story-link-description{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.rts-story-link-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-link-arrow{color:var(--rts-st-accent);transition:transform .2s ease}@keyframes rts-st-spin{to{transform:rotate(360deg)}}@keyframes rts-st-pop{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}\n", ".rts-st-autocomplete{position:relative}.rts-st-autocomplete-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:12px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-input{padding-left:32px;padding-right:32px}.rts-st-autocomplete-input.rts-st-autocomplete-selected{font-weight:600}.rts-st-autocomplete-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;padding:0;border:none;border-radius:50%;font-size:10px;cursor:pointer;color:var(--rts-text-secondary, #8a8fa3);background:transparent;transition:background .15s ease,color .15s ease}.rts-st-autocomplete-clear:hover{color:var(--rts-text-primary);background:#8b5cf626}.rts-st-autocomplete-panel{position:absolute;z-index:20;left:0;right:0;top:calc(100% + 4px);max-height:240px;margin:0;padding:4px;overflow-y:auto;list-style:none;border-radius:10px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-secondary, var(--rts-bg-primary, #1d1f2b));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 14px 32px -12px #00000073;animation:rts-st-panel-in .14s ease-out}.rts-st-autocomplete-option{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:7px;cursor:pointer;transition:background .12s ease}.rts-st-autocomplete-option.rts-st-autocomplete-option-active{background:linear-gradient(135deg,#6366f129,#8b5cf61a)}.rts-st-autocomplete-option[aria-selected=true] .rts-st-autocomplete-option-name{color:var(--rts-st-accent)}.rts-st-autocomplete-thumb{flex-shrink:0;width:30px;height:30px;border-radius:7px;object-fit:cover}.rts-st-autocomplete-thumb-empty{display:flex;align-items:center;justify-content:center;font-size:15px;background:#8b5cf624}.rts-st-autocomplete-option-body{display:flex;flex-direction:column;min-width:0}.rts-st-autocomplete-option-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;color:var(--rts-text-primary)}.rts-st-autocomplete-option-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-empty{padding:8px;font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-error{font-style:normal;color:#f43f5e}.rts-st-translator-actions{gap:8px}.rts-st-checkbox-row{display:flex;align-items:flex-start;gap:10px;padding:9px 11px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));cursor:pointer;-webkit-user-select:none;user-select:none;transition:border-color .15s ease,background .15s ease}.rts-st-checkbox-row:hover{border-color:#8b5cf673;background:#8b5cf60f}.rts-st-checkbox-input{margin-top:2px;width:15px;height:15px;flex-shrink:0;accent-color:var(--rts-st-accent, #8b5cf6);cursor:pointer}.rts-st-checkbox-body{display:flex;flex-direction:column;gap:2px;min-width:0}.rts-st-checkbox-title{font-size:13px;font-weight:600;color:var(--rts-text-primary)}.rts-st-checkbox-desc{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-cancel{padding:8px 16px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:transparent;color:var(--rts-text-secondary, #8a8fa3);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.rts-st-cancel:hover{color:var(--rts-text-primary);border-color:#f43f5e73;background:#f43f5e0f}@keyframes rts-st-panel-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n", ".rts-st-repair-options-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}@media (max-width: 480px){.rts-st-repair-options-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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.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"] }] }); }
|
|
3299
|
+
}
|
|
3300
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryRepairFormStepComponent, decorators: [{
|
|
3301
|
+
type: Component,
|
|
3302
|
+
args: [{ selector: 'rtsee-story-repair-form-step', standalone: true, imports: [ReactiveFormsModule], template: "<form class=\"rts-storyteller-form\" [formGroup]=\"form\" (ngSubmit)=\"submit()\" autocomplete=\"off\">\n <div class=\"rts-storyteller-field\">\n <label class=\"rts-storyteller-label\" for=\"story-repair-story-{{ step.id }}\">Story</label>\n <div class=\"rts-st-autocomplete\">\n <span class=\"rts-st-autocomplete-icon pi\" [class.pi-search]=\"!searchInProgress\" [class.pi-spin]=\"searchInProgress\" [class.pi-spinner]=\"searchInProgress\"></span>\n <input #storyInput\n class=\"rts-storyteller-input rts-st-autocomplete-input\"\n [class.rts-storyteller-invalid]=\"isInvalid('storyId')\"\n [class.rts-st-autocomplete-selected]=\"!!selectedStory\"\n formControlName=\"storyQuery\"\n type=\"text\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"suggestionsOpened\"\n placeholder=\"Search stories by name\u2026\"\n id=\"story-repair-story-{{ step.id }}\"\n (focus)=\"onStoryFocus()\"\n (input)=\"onStoryInput()\"\n (keydown)=\"onStoryKeydown($event)\"\n />\n @if (selectedStory && !readonly) {\n <button type=\"button\"\n class=\"rts-st-autocomplete-clear pi pi-times\"\n aria-label=\"Clear story\"\n id=\"story-repair-clear-{{ step.id }}\"\n (click)=\"clearStory()\"\n ></button>\n }\n\n @if (suggestionsOpened && !readonly) {\n <ul class=\"rts-st-autocomplete-panel\" role=\"listbox\">\n @if (searchError) {\n <li class=\"rts-st-autocomplete-empty rts-st-autocomplete-error\">{{ searchError }}</li>\n } @else if (!suggestions.length && !searchInProgress) {\n <li class=\"rts-st-autocomplete-empty\">No stories found</li>\n }\n @for (story of suggestions; track story.id; let i = $index) {\n <li class=\"rts-st-autocomplete-option\"\n role=\"option\"\n [class.rts-st-autocomplete-option-active]=\"i === highlightedIndex\"\n [attr.aria-selected]=\"story.id === selectedStory?.id\"\n (mouseenter)=\"highlightedIndex = i\"\n (mousedown)=\"$event.preventDefault(); selectStory(story)\"\n >\n @if (story.imageUrl) {\n <img class=\"rts-st-autocomplete-thumb\" [src]=\"story.imageUrl\" [alt]=\"story.name\" loading=\"lazy\" />\n } @else {\n <span class=\"rts-st-autocomplete-thumb rts-st-autocomplete-thumb-empty\">\uD83D\uDCD6</span>\n }\n <span class=\"rts-st-autocomplete-option-body\">\n <span class=\"rts-st-autocomplete-option-name\">{{ story.name }}</span>\n @if (story.totalSlides) {\n <span class=\"rts-st-autocomplete-option-meta\">{{ story.totalSlides }} slides</span>\n }\n </span>\n </li>\n }\n </ul>\n }\n </div>\n </div>\n\n @if (selectedStory) {\n <div class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Repair options</span>\n <div class=\"rts-st-repair-options-grid\">\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-grammar-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"grammarAndFlow\"\n id=\"story-repair-grammar-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Grammar & Flow</span>\n <span class=\"rts-st-checkbox-desc\">Fix typos, punctuation & improve readability across story, slides & entities</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-characters-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"characters\"\n id=\"story-repair-characters-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Characters</span>\n <span class=\"rts-st-checkbox-desc\">Add missing important characters and link them to slides</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-artifacts-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"artifacts\"\n id=\"story-repair-artifacts-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Artifacts</span>\n <span class=\"rts-st-checkbox-desc\">Add missing memorable objects and link them to slides</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-locations-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"locations\"\n id=\"story-repair-locations-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Locations</span>\n <span class=\"rts-st-checkbox-desc\">Add missing story locations and link them to slides</span>\n </span>\n </label>\n\n <label class=\"rts-st-checkbox-row\" for=\"story-repair-sanitize-images-{{ step.id }}\">\n <input type=\"checkbox\"\n class=\"rts-st-checkbox-input\"\n formControlName=\"sanitizeImages\"\n id=\"story-repair-sanitize-images-{{ step.id }}\"\n (change)=\"onOptionChanged()\"\n />\n <span class=\"rts-st-checkbox-body\">\n <span class=\"rts-st-checkbox-title\">Sanitize images</span>\n <span class=\"rts-st-checkbox-desc\">Properly name & upload story, slide, character, artifact, location & author images to the public bucket for SEO</span>\n </span>\n </label>\n </div>\n @if (!hasAtLeastOneOption) {\n <div class=\"rts-storyteller-error\">Please select at least one option to repair.</div>\n }\n </div>\n }\n\n <label class=\"rts-storyteller-field\">\n <span class=\"rts-storyteller-label\">Agent</span>\n @if (agents.length) {\n <div class=\"rts-storyteller-select-wrap\">\n <select class=\"rts-storyteller-input rts-storyteller-select\"\n [class.rts-storyteller-invalid]=\"isInvalid('agentId')\"\n formControlName=\"agentId\"\n id=\"story-repair-agent-{{ step.id }}\"\n >\n <option value=\"\" disabled>Select an agent</option>\n @for (agent of agents; track agent.id) {\n <option [value]=\"agent.id\">\n {{ agent.name }}{{ agent.agentConfiguration?.model?.model ? ' \u00B7 ' + agent.agentConfiguration?.model?.model : '' }}\n </option>\n }\n </select>\n <span class=\"rts-storyteller-select-caret pi pi-chevron-down\"></span>\n </div>\n } @else {\n <div class=\"rts-storyteller-hint\">There are no agentic members in this chat. Add an agent to continue.</div>\n }\n </label>\n\n @if (workflow.submitError) {\n <div class=\"rts-storyteller-error\">{{ workflow.submitError }}</div>\n }\n\n @if (step.isActive) {\n <div class=\"rts-storyteller-actions rts-st-translator-actions\">\n @if (canCancel) {\n <button class=\"rts-st-cancel\"\n type=\"button\"\n id=\"story-repair-cancel-{{ step.id }}\"\n (click)=\"cancel()\"\n >Cancel</button>\n }\n <button class=\"rts-storyteller-submit\"\n type=\"submit\"\n [disabled]=\"workflow.submitInProgress || !agents.length || !selectedStory || !hasAtLeastOneOption\"\n id=\"story-repair-submit-{{ step.id }}\"\n >\n @if (workflow.submitInProgress) {\n <span class=\"rts-storyteller-spinner\"></span> Repairing\u2026\n } @else {\n \uD83D\uDEE0\uFE0F Repair Story\n }\n </button>\n </div>\n }\n</form>\n", styles: [":host{display:block;--rts-st-accent: #8b5cf6;--rts-st-accent-2: #6366f1}.rts-storyteller-form{display:flex;flex-direction:column;gap:12px}.rts-storyteller-field{display:flex;flex-direction:column;gap:5px}.rts-storyteller-label{display:flex;justify-content:space-between;align-items:baseline;font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-counter{font-weight:500;letter-spacing:0;text-transform:none}.rts-storyteller-input{width:100%;box-sizing:border-box;padding:9px 12px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));color:var(--rts-text-primary);font:inherit;font-size:13px;outline:none;transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.rts-storyteller-input:focus{border-color:var(--rts-st-accent);box-shadow:0 0 0 3px #8b5cf62e}.rts-storyteller-input:disabled{opacity:.75;cursor:default}.rts-storyteller-input.rts-storyteller-invalid{border-color:#f43f5e;box-shadow:0 0 0 3px #f43f5e1f}.rts-storyteller-textarea{min-height:80px;resize:vertical;line-height:1.5}.rts-storyteller-textarea-lg{min-height:160px;max-height:480px}.rts-storyteller-select-wrap{position:relative}.rts-storyteller-select{appearance:none;padding-right:32px;cursor:pointer}.rts-storyteller-select-caret{position:absolute;right:12px;top:50%;transform:translateY(-50%);font-size:10px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-hint{font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-storyteller-error{padding:6px 10px;border-radius:6px;font-size:12px;color:#f43f5e;background:#f43f5e14;border:1px solid rgba(244,63,94,.25)}.rts-storyteller-actions{display:flex;justify-content:flex-end}.rts-storyteller-submit{display:inline-flex;align-items:center;gap:6px;padding:8px 18px;border:none;border-radius:9px;color:#fff;font-weight:600;font-size:13px;cursor:pointer;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent) 60%,#a78bfa);background-size:160% 160%;box-shadow:0 4px 14px -4px #6366f199;transition:transform .15s ease,box-shadow .15s ease,background-position .4s ease}.rts-storyteller-submit:hover:not(:disabled){transform:translateY(-1px);background-position:100% 0;box-shadow:0 6px 18px -4px #6366f1bf}.rts-storyteller-submit:disabled{opacity:.6;cursor:default;box-shadow:none}.rts-storyteller-spinner{width:11px;height:11px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:rts-st-spin .8s linear infinite}.rts-story-link-card{display:flex;align-items:center;gap:12px;padding:14px;border-radius:12px;text-decoration:none;color:inherit;background:linear-gradient(135deg,#6366f11a,#8b5cf60f);border:1px solid rgba(139,92,246,.3);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;animation:rts-st-pop .4s cubic-bezier(.2,.9,.3,1.3)}.rts-story-link-card:hover{transform:translateY(-2px);border-color:var(--rts-st-accent);box-shadow:0 10px 28px -12px #8b5cf699}.rts-story-link-card:hover .rts-story-link-arrow{transform:translate(3px)}.rts-story-link-icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:42px;height:42px;border-radius:12px;font-size:20px;background:linear-gradient(135deg,var(--rts-st-accent-2),var(--rts-st-accent))}.rts-story-link-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}.rts-story-link-kicker{font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--rts-st-accent)}.rts-story-link-title{font-size:15px;font-weight:600;color:var(--rts-text-primary)}.rts-story-link-description{font-size:12px;color:var(--rts-text-secondary, #8a8fa3);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.rts-story-link-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-story-link-arrow{color:var(--rts-st-accent);transition:transform .2s ease}@keyframes rts-st-spin{to{transform:rotate(360deg)}}@keyframes rts-st-pop{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}\n", ".rts-st-autocomplete{position:relative}.rts-st-autocomplete-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:12px;pointer-events:none;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-input{padding-left:32px;padding-right:32px}.rts-st-autocomplete-input.rts-st-autocomplete-selected{font-weight:600}.rts-st-autocomplete-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:22px;height:22px;padding:0;border:none;border-radius:50%;font-size:10px;cursor:pointer;color:var(--rts-text-secondary, #8a8fa3);background:transparent;transition:background .15s ease,color .15s ease}.rts-st-autocomplete-clear:hover{color:var(--rts-text-primary);background:#8b5cf626}.rts-st-autocomplete-panel{position:absolute;z-index:20;left:0;right:0;top:calc(100% + 4px);max-height:240px;margin:0;padding:4px;overflow-y:auto;list-style:none;border-radius:10px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-secondary, var(--rts-bg-primary, #1d1f2b));-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);box-shadow:0 14px 32px -12px #00000073;animation:rts-st-panel-in .14s ease-out}.rts-st-autocomplete-option{display:flex;align-items:center;gap:10px;padding:6px 8px;border-radius:7px;cursor:pointer;transition:background .12s ease}.rts-st-autocomplete-option.rts-st-autocomplete-option-active{background:linear-gradient(135deg,#6366f129,#8b5cf61a)}.rts-st-autocomplete-option[aria-selected=true] .rts-st-autocomplete-option-name{color:var(--rts-st-accent)}.rts-st-autocomplete-thumb{flex-shrink:0;width:30px;height:30px;border-radius:7px;object-fit:cover}.rts-st-autocomplete-thumb-empty{display:flex;align-items:center;justify-content:center;font-size:15px;background:#8b5cf624}.rts-st-autocomplete-option-body{display:flex;flex-direction:column;min-width:0}.rts-st-autocomplete-option-name{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:13px;font-weight:500;color:var(--rts-text-primary)}.rts-st-autocomplete-option-meta{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-empty{padding:8px;font-size:12px;font-style:italic;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-autocomplete-error{font-style:normal;color:#f43f5e}.rts-st-translator-actions{gap:8px}.rts-st-checkbox-row{display:flex;align-items:flex-start;gap:10px;padding:9px 11px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:var(--rts-bg-primary, rgba(127, 127, 160, .06));cursor:pointer;-webkit-user-select:none;user-select:none;transition:border-color .15s ease,background .15s ease}.rts-st-checkbox-row:hover{border-color:#8b5cf673;background:#8b5cf60f}.rts-st-checkbox-input{margin-top:2px;width:15px;height:15px;flex-shrink:0;accent-color:var(--rts-st-accent, #8b5cf6);cursor:pointer}.rts-st-checkbox-body{display:flex;flex-direction:column;gap:2px;min-width:0}.rts-st-checkbox-title{font-size:13px;font-weight:600;color:var(--rts-text-primary)}.rts-st-checkbox-desc{font-size:11px;color:var(--rts-text-secondary, #8a8fa3)}.rts-st-cancel{padding:8px 16px;border-radius:9px;border:1px solid var(--rts-border-dim, rgba(120, 120, 160, .25));background:transparent;color:var(--rts-text-secondary, #8a8fa3);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:color .15s ease,border-color .15s ease,background .15s ease}.rts-st-cancel:hover{color:var(--rts-text-primary);border-color:#f43f5e73;background:#f43f5e0f}@keyframes rts-st-panel-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}\n", ".rts-st-repair-options-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}@media (max-width: 480px){.rts-st-repair-options-grid{grid-template-columns:1fr}}\n"] }]
|
|
2871
3303
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { step: [{
|
|
2872
3304
|
type: Input
|
|
2873
3305
|
}], workflow: [{
|
|
@@ -2894,6 +3326,7 @@ class WorkflowStepsService {
|
|
|
2894
3326
|
{ name: 'storyteller-form-step', component: StorytellerFormStepComponent },
|
|
2895
3327
|
{ name: 'storyteller-story-link-step', component: StorytellerStoryLinkStepComponent },
|
|
2896
3328
|
{ name: 'story-translator-form-step', component: StoryTranslatorFormStepComponent },
|
|
3329
|
+
{ name: 'story-repair-form-step', component: StoryRepairFormStepComponent },
|
|
2897
3330
|
];
|
|
2898
3331
|
}
|
|
2899
3332
|
register(widget) {
|
|
@@ -3071,29 +3504,47 @@ class MessageComponent {
|
|
|
3071
3504
|
this.timeFormatService = timeFormatService;
|
|
3072
3505
|
this.widgetRef = null;
|
|
3073
3506
|
this.widgetHasMessageInput = false;
|
|
3507
|
+
this.currentWidgetName = null;
|
|
3074
3508
|
}
|
|
3075
3509
|
ngOnInit() { }
|
|
3076
3510
|
ngOnChanges(changes) {
|
|
3077
|
-
// The message instance can be replaced (e.g.
|
|
3078
|
-
if (changes['message'] && !changes['message'].firstChange
|
|
3079
|
-
if (this.
|
|
3080
|
-
this.
|
|
3511
|
+
// The message instance or widget type can be replaced (e.g. stream start -> media widget -> downsized versions)
|
|
3512
|
+
if (changes['message'] && !changes['message'].firstChange) {
|
|
3513
|
+
if (this.widgetHost && this.message?.widget !== this.currentWidgetName) {
|
|
3514
|
+
this.renderWidget();
|
|
3515
|
+
return;
|
|
3081
3516
|
}
|
|
3082
|
-
|
|
3083
|
-
this.
|
|
3084
|
-
|
|
3517
|
+
if (this.widgetRef) {
|
|
3518
|
+
if (this.widgetHasMessageInput) {
|
|
3519
|
+
this.widgetRef.setInput('message', this.message);
|
|
3520
|
+
}
|
|
3521
|
+
else {
|
|
3522
|
+
this.widgetRef.instance.message = this.message;
|
|
3523
|
+
if (typeof this.widgetRef.instance.ngOnChanges === 'function') {
|
|
3524
|
+
this.widgetRef.instance.ngOnChanges(changes);
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
this.widgetRef.changeDetectorRef.detectChanges();
|
|
3085
3528
|
}
|
|
3086
3529
|
}
|
|
3087
3530
|
}
|
|
3088
3531
|
ngAfterViewInit() {
|
|
3532
|
+
this.renderWidget();
|
|
3533
|
+
}
|
|
3534
|
+
renderWidget() {
|
|
3089
3535
|
/* eslint-disable */
|
|
3090
|
-
if (this.
|
|
3536
|
+
if (!this.widgetHost) {
|
|
3537
|
+
return;
|
|
3538
|
+
}
|
|
3539
|
+
const viewContainerRef = this.widgetHost.viewContainerRef;
|
|
3540
|
+
viewContainerRef.clear();
|
|
3541
|
+
this.widgetRef = null;
|
|
3542
|
+
this.currentWidgetName = this.message?.widget || null;
|
|
3543
|
+
if (this.message?.widget) {
|
|
3091
3544
|
const widget = this.widgetsService.getWidgetComponentByName(this.message.widget);
|
|
3092
3545
|
if (!widget) {
|
|
3093
3546
|
return;
|
|
3094
3547
|
}
|
|
3095
|
-
const viewContainerRef = this.widgetHost.viewContainerRef;
|
|
3096
|
-
viewContainerRef.clear();
|
|
3097
3548
|
const componentToShow = this.componentFactoryResolver.resolveComponentFactory(widget);
|
|
3098
3549
|
const componentRef = viewContainerRef.createComponent(componentToShow);
|
|
3099
3550
|
componentRef.instance.message = this.message;
|
|
@@ -3106,7 +3557,7 @@ class MessageComponent {
|
|
|
3106
3557
|
/* eslint-enable */
|
|
3107
3558
|
}
|
|
3108
3559
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessageComponent, deps: [{ token: MessageWidgetsService }, { token: i0.ComponentFactoryResolver }, { token: TimeFormatHelperService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3109
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessageComponent, isStandalone: true, selector: "rtsee-message", inputs: { chat: "chat", message: "message", member: "member", messenger: "messenger" }, viewQueries: [{ propertyName: "widgetHost", first: true, predicate: WidgetDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-message-container\" #rtsMessageContainer\n [ngClass]=\"{\n 'rts-message-from-me': message.from.id === messenger.clientId,\n 'rts-message-is-widget': !!message.widget\n }\">\n <div class=\"rts-messenger-message\">\n @if (message.widget) {\n <ng-template widgetHost></ng-template>\n }\n @if (!message.widget) {\n <p class=\"rts-messenger-message-text\"\n >{{ message.text }}</p>\n }\n <div class=\"rts-messenger-message-info\" #rtsMessageInfo>\n <rtsee-message-time-and-status [message]=\"message\"\n [inChat]=\"true\"\n [hideStatus]=\"message.from.id !== messenger.clientId\"\n ></rtsee-message-time-and-status>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MessageTimeAndStatusComponent, selector: "rtsee-message-time-and-status", inputs: ["message", "hideStatus", "inChat"] }, { kind: "directive", type: WidgetDirective, selector: "[widgetHost]" }] }); }
|
|
3560
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MessageComponent, isStandalone: true, selector: "rtsee-message", inputs: { chat: "chat", message: "message", member: "member", messenger: "messenger" }, viewQueries: [{ propertyName: "widgetHost", first: true, predicate: WidgetDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"rts-message-container\" #rtsMessageContainer\n data-ugc=\"true\"\n rel=\"ugc\"\n itemprop=\"comment\"\n itemscope\n itemtype=\"https://schema.org/Comment\"\n [ngClass]=\"{\n 'rts-message-from-me': message.from.id === messenger.clientId,\n 'rts-message-is-widget': !!message.widget\n }\">\n <div class=\"rts-messenger-message\">\n @if (message.widget) {\n <ng-template widgetHost></ng-template>\n }\n @if (!message.widget) {\n <p class=\"rts-messenger-message-text\"\n itemprop=\"text\"\n data-ugc=\"true\"\n rel=\"ugc\"\n >{{ message.text }}</p>\n }\n <div class=\"rts-messenger-message-info\" #rtsMessageInfo>\n <rtsee-message-time-and-status [message]=\"message\"\n [inChat]=\"true\"\n [hideStatus]=\"message.from.id !== messenger.clientId\"\n ></rtsee-message-time-and-status>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MessageTimeAndStatusComponent, selector: "rtsee-message-time-and-status", inputs: ["message", "hideStatus", "inChat"] }, { kind: "directive", type: WidgetDirective, selector: "[widgetHost]" }] }); }
|
|
3110
3561
|
}
|
|
3111
3562
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessageComponent, decorators: [{
|
|
3112
3563
|
type: Component,
|
|
@@ -3115,7 +3566,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
3115
3566
|
MessageTimeAndStatusComponent,
|
|
3116
3567
|
WidgetDirective,
|
|
3117
3568
|
RatingComponent,
|
|
3118
|
-
], standalone: true, template: "<div class=\"rts-message-container\" #rtsMessageContainer\n [ngClass]=\"{\n 'rts-message-from-me': message.from.id === messenger.clientId,\n 'rts-message-is-widget': !!message.widget\n }\">\n <div class=\"rts-messenger-message\">\n @if (message.widget) {\n <ng-template widgetHost></ng-template>\n }\n @if (!message.widget) {\n <p class=\"rts-messenger-message-text\"\n >{{ message.text }}</p>\n }\n <div class=\"rts-messenger-message-info\" #rtsMessageInfo>\n <rtsee-message-time-and-status [message]=\"message\"\n [inChat]=\"true\"\n [hideStatus]=\"message.from.id !== messenger.clientId\"\n ></rtsee-message-time-and-status>\n </div>\n </div>\n</div>\n" }]
|
|
3569
|
+
], standalone: true, template: "<div class=\"rts-message-container\" #rtsMessageContainer\n data-ugc=\"true\"\n rel=\"ugc\"\n itemprop=\"comment\"\n itemscope\n itemtype=\"https://schema.org/Comment\"\n [ngClass]=\"{\n 'rts-message-from-me': message.from.id === messenger.clientId,\n 'rts-message-is-widget': !!message.widget\n }\">\n <div class=\"rts-messenger-message\">\n @if (message.widget) {\n <ng-template widgetHost></ng-template>\n }\n @if (!message.widget) {\n <p class=\"rts-messenger-message-text\"\n itemprop=\"text\"\n data-ugc=\"true\"\n rel=\"ugc\"\n >{{ message.text }}</p>\n }\n <div class=\"rts-messenger-message-info\" #rtsMessageInfo>\n <rtsee-message-time-and-status [message]=\"message\"\n [inChat]=\"true\"\n [hideStatus]=\"message.from.id !== messenger.clientId\"\n ></rtsee-message-time-and-status>\n </div>\n </div>\n</div>\n" }]
|
|
3119
3570
|
}], ctorParameters: () => [{ type: MessageWidgetsService }, { type: i0.ComponentFactoryResolver }, { type: TimeFormatHelperService }], propDecorators: { chat: [{
|
|
3120
3571
|
type: Input
|
|
3121
3572
|
}], message: [{
|
|
@@ -3384,11 +3835,11 @@ class MessagesListComponent {
|
|
|
3384
3835
|
this.lastGroupedMessage = this.chat.messages[this.chat.messages.length - 1];
|
|
3385
3836
|
}
|
|
3386
3837
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessagesListComponent, deps: [{ token: TimeFormatHelperService }, { token: i2$1.ViewportScroller }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3387
|
-
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]=\"false\"\n (scrolledUp)=\"onScrolledToTop()\"\n (scroll)=\"onContainerScroll($event)\"\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
|
|
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]=\"false\"\n (scrolledUp)=\"onScrolledToTop()\"\n (scroll)=\"onContainerScroll($event)\"\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"] }] }); }
|
|
3388
3839
|
}
|
|
3389
3840
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MessagesListComponent, decorators: [{
|
|
3390
3841
|
type: Component,
|
|
3391
|
-
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]=\"false\"\n (scrolledUp)=\"onScrolledToTop()\"\n (scroll)=\"onContainerScroll($event)\"\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
|
|
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]=\"false\"\n (scrolledUp)=\"onScrolledToTop()\"\n (scroll)=\"onContainerScroll($event)\"\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" }]
|
|
3392
3843
|
}], ctorParameters: () => [{ type: TimeFormatHelperService }, { type: i2$1.ViewportScroller }, { type: Document, decorators: [{
|
|
3393
3844
|
type: Inject,
|
|
3394
3845
|
args: [DOCUMENT]
|
|
@@ -5210,8 +5661,9 @@ class StoryElementsSectionComponent {
|
|
|
5210
5661
|
if (this._illustrator) {
|
|
5211
5662
|
this._illustrator.off('changed', this.onIllustratorChanged);
|
|
5212
5663
|
}
|
|
5213
|
-
for (const [
|
|
5214
|
-
window.removeEventListener(RTSeeIllustrator.REQUESTED_GENERATION_SUCCEED,
|
|
5664
|
+
for (const [, listeners] of this.activeGenerationListeners.entries()) {
|
|
5665
|
+
window.removeEventListener(RTSeeIllustrator.REQUESTED_GENERATION_SUCCEED, listeners.succeed);
|
|
5666
|
+
window.removeEventListener(RTSeeIllustratorEvents.GENERATION_COMPLETED, listeners.completed);
|
|
5215
5667
|
}
|
|
5216
5668
|
this.activeGenerationListeners.clear();
|
|
5217
5669
|
}
|
|
@@ -5260,15 +5712,29 @@ class StoryElementsSectionComponent {
|
|
|
5260
5712
|
this.batchMode = false;
|
|
5261
5713
|
this.selectedItemIds.clear();
|
|
5262
5714
|
this.batchAdditionalPrompt = '';
|
|
5263
|
-
this.cdr.markForCheck();
|
|
5264
5715
|
for (const item of selectedItems) {
|
|
5265
|
-
const requestId = RTSeeCore.uuidv4();
|
|
5266
5716
|
this.generatingItemIds.add(item.id);
|
|
5267
|
-
|
|
5717
|
+
}
|
|
5718
|
+
this.cdr.markForCheck();
|
|
5719
|
+
const batchSpacingMs = 1200;
|
|
5720
|
+
for (let i = 0; i < selectedItems.length; i++) {
|
|
5721
|
+
const item = selectedItems[i];
|
|
5722
|
+
if (i > 0) {
|
|
5723
|
+
await new Promise((resolve) => setTimeout(resolve, batchSpacingMs));
|
|
5724
|
+
}
|
|
5725
|
+
const requestId = RTSeeCore.uuidv4();
|
|
5726
|
+
const cleanupListeners = () => {
|
|
5727
|
+
const entry = this.activeGenerationListeners.get(requestId);
|
|
5728
|
+
if (entry) {
|
|
5729
|
+
window.removeEventListener(RTSeeIllustrator.REQUESTED_GENERATION_SUCCEED, entry.succeed);
|
|
5730
|
+
window.removeEventListener(RTSeeIllustratorEvents.GENERATION_COMPLETED, entry.completed);
|
|
5731
|
+
this.activeGenerationListeners.delete(requestId);
|
|
5732
|
+
}
|
|
5733
|
+
};
|
|
5734
|
+
const succeedListener = async (e) => {
|
|
5268
5735
|
const customEvent = e;
|
|
5269
5736
|
if (customEvent.detail?.requestId === requestId && customEvent.detail?.imageUrl) {
|
|
5270
|
-
|
|
5271
|
-
this.activeGenerationListeners.delete(requestId);
|
|
5737
|
+
cleanupListeners();
|
|
5272
5738
|
this.generatingItemIds.delete(item.id);
|
|
5273
5739
|
const cleanUrl = sanitizeImageUrl(customEvent.detail.imageUrl);
|
|
5274
5740
|
try {
|
|
@@ -5293,8 +5759,20 @@ class StoryElementsSectionComponent {
|
|
|
5293
5759
|
}
|
|
5294
5760
|
}
|
|
5295
5761
|
};
|
|
5296
|
-
|
|
5297
|
-
|
|
5762
|
+
const completedListener = (e) => {
|
|
5763
|
+
const customEvent = e;
|
|
5764
|
+
if (customEvent.detail?.requestId === requestId && customEvent.detail?.success === false) {
|
|
5765
|
+
cleanupListeners();
|
|
5766
|
+
this.generatingItemIds.delete(item.id);
|
|
5767
|
+
this.cdr.markForCheck();
|
|
5768
|
+
}
|
|
5769
|
+
};
|
|
5770
|
+
window.addEventListener(RTSeeIllustrator.REQUESTED_GENERATION_SUCCEED, succeedListener);
|
|
5771
|
+
window.addEventListener(RTSeeIllustratorEvents.GENERATION_COMPLETED, completedListener);
|
|
5772
|
+
this.activeGenerationListeners.set(requestId, {
|
|
5773
|
+
succeed: succeedListener,
|
|
5774
|
+
completed: completedListener,
|
|
5775
|
+
});
|
|
5298
5776
|
const promptParts = [];
|
|
5299
5777
|
promptParts.push(`${this.editor.label}: ${item.name || ''}`);
|
|
5300
5778
|
if (item.visualDescription) {
|
|
@@ -5319,7 +5797,7 @@ class StoryElementsSectionComponent {
|
|
|
5319
5797
|
chatId: this.illustrator?.activeChatId || undefined,
|
|
5320
5798
|
agentId: this.illustrator?.activeAgentId || '',
|
|
5321
5799
|
prompt: entityPrompt,
|
|
5322
|
-
config: { ...config },
|
|
5800
|
+
config: { ...config, numberOfImages: 1 },
|
|
5323
5801
|
contextImages: [],
|
|
5324
5802
|
requestId,
|
|
5325
5803
|
};
|
|
@@ -6084,11 +6562,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
6084
6562
|
|
|
6085
6563
|
class RtseeEntityCommentsComponent {
|
|
6086
6564
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeEntityCommentsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6087
|
-
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\">\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"] }] }); }
|
|
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"] }] }); }
|
|
6088
6566
|
}
|
|
6089
6567
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeEntityCommentsComponent, decorators: [{
|
|
6090
6568
|
type: Component,
|
|
6091
|
-
args: [{ selector: 'rtsee-entity-comments', imports: [ChatComponent], template: "<div class=\"rtsee-entity-comments\">\n @if (messenger && chat) {\n <rtsee-chat [messenger]=\"messenger\"\n [chatData]=\"chat\"\n [entity]=\"entity\"\n ></rtsee-chat>\n }\n</div>\n" }]
|
|
6569
|
+
args: [{ selector: 'rtsee-entity-comments', imports: [ChatComponent], 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" }]
|
|
6092
6570
|
}], propDecorators: { messenger: [{
|
|
6093
6571
|
type: Input
|
|
6094
6572
|
}], chat: [{
|
|
@@ -6175,11 +6653,11 @@ class RateItemComponent {
|
|
|
6175
6653
|
return config ? config.name : '';
|
|
6176
6654
|
}
|
|
6177
6655
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RateItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6178
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RateItemComponent, isStandalone: true, selector: "rtsee-rate-item", inputs: { group: "group", rater: "rater", showActions: "showActions" }, outputs: { edit: "edit", delete: "delete" }, ngImport: i0, template: "<div
|
|
6656
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RateItemComponent, isStandalone: true, selector: "rtsee-rate-item", inputs: { group: "group", rater: "rater", showActions: "showActions" }, outputs: { edit: "edit", delete: "delete" }, ngImport: i0, template: "<div\n class=\"rtsee-rates-group-item\"\n data-ugc=\"true\"\n rel=\"ugc\"\n itemprop=\"review\"\n itemscope\n itemtype=\"https://schema.org/Review\"\n>\n <div class=\"rtsee-rates-group-header\">\n <div\n class=\"rtsee-rates-group-user-info\"\n itemprop=\"author\"\n itemscope\n itemtype=\"https://schema.org/Person\"\n >\n @if (group.peer?.imageUrl) {\n <img\n class=\"rtsee-rates-group-avatar\"\n [src]=\"group.peer.imageUrl\"\n alt=\"User avatar\"\n itemprop=\"image\"\n />\n } @else {\n <div class=\"rtsee-rates-group-avatar-fallback\">\n {{ (group.peer?.name || \"?\").substring(0, 1) }}\n </div>\n }\n <span class=\"rtsee-rates-group-peer-name\" itemprop=\"name\">{{\n group.peer?.name || group.peerId\n }}</span>\n </div>\n\n <div class=\"rtsee-rates-group-right-header\">\n <span\n class=\"rtsee-rates-group-date\"\n itemprop=\"datePublished\"\n [attr.content]=\"group.createdAt\"\n >{{\n group.createdAt | date: \"short\"\n }}</span>\n\n @if (showActions) {\n <div class=\"rtsee-rates-group-actions\">\n <p-button\n (click)=\"onEdit($event)\"\n [severity]=\"'secondary'\"\n [text]=\"true\"\n class=\"rtsee-rates-group-btn-edit\"\n >\n <span class=\"pi pi-pencil\"></span>\n </p-button>\n <p-button\n (click)=\"onDelete($event)\"\n [severity]=\"'danger'\"\n [text]=\"true\"\n class=\"rtsee-rates-group-btn-delete\"\n >\n <span class=\"pi pi-trash\"></span>\n </p-button>\n </div>\n }\n </div>\n </div>\n <div class=\"rtsee-rates-group-body\">\n @for (rate of group.rates; track rate.id) {\n <div class=\"rtsee-rates-group-rate-item-container\">\n <div class=\"rtsee-rates-group-rate-item\">\n <span class=\"rtsee-rates-group-rate-config-name\">{{\n getRatingConfigName(rate.configurationId)\n }}</span>\n <rtsee-rating [rate]=\"rate\"></rtsee-rating>\n </div>\n @if (rate.text) {\n <p class=\"rtsee-rates-group-rate-comment\" itemprop=\"reviewBody\" data-ugc=\"true\" rel=\"ugc\">\"{{ rate.text }}\"</p>\n }\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "component", type: RatingComponent, selector: "rtsee-rating", inputs: ["config", "rate"] }, { 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: DatePipe, name: "date" }] }); }
|
|
6179
6657
|
}
|
|
6180
6658
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RateItemComponent, decorators: [{
|
|
6181
6659
|
type: Component,
|
|
6182
|
-
args: [{ selector: 'rtsee-rate-item', imports: [RatingComponent, DatePipe, Button], template: "<div
|
|
6660
|
+
args: [{ selector: 'rtsee-rate-item', imports: [RatingComponent, DatePipe, Button], template: "<div\n class=\"rtsee-rates-group-item\"\n data-ugc=\"true\"\n rel=\"ugc\"\n itemprop=\"review\"\n itemscope\n itemtype=\"https://schema.org/Review\"\n>\n <div class=\"rtsee-rates-group-header\">\n <div\n class=\"rtsee-rates-group-user-info\"\n itemprop=\"author\"\n itemscope\n itemtype=\"https://schema.org/Person\"\n >\n @if (group.peer?.imageUrl) {\n <img\n class=\"rtsee-rates-group-avatar\"\n [src]=\"group.peer.imageUrl\"\n alt=\"User avatar\"\n itemprop=\"image\"\n />\n } @else {\n <div class=\"rtsee-rates-group-avatar-fallback\">\n {{ (group.peer?.name || \"?\").substring(0, 1) }}\n </div>\n }\n <span class=\"rtsee-rates-group-peer-name\" itemprop=\"name\">{{\n group.peer?.name || group.peerId\n }}</span>\n </div>\n\n <div class=\"rtsee-rates-group-right-header\">\n <span\n class=\"rtsee-rates-group-date\"\n itemprop=\"datePublished\"\n [attr.content]=\"group.createdAt\"\n >{{\n group.createdAt | date: \"short\"\n }}</span>\n\n @if (showActions) {\n <div class=\"rtsee-rates-group-actions\">\n <p-button\n (click)=\"onEdit($event)\"\n [severity]=\"'secondary'\"\n [text]=\"true\"\n class=\"rtsee-rates-group-btn-edit\"\n >\n <span class=\"pi pi-pencil\"></span>\n </p-button>\n <p-button\n (click)=\"onDelete($event)\"\n [severity]=\"'danger'\"\n [text]=\"true\"\n class=\"rtsee-rates-group-btn-delete\"\n >\n <span class=\"pi pi-trash\"></span>\n </p-button>\n </div>\n }\n </div>\n </div>\n <div class=\"rtsee-rates-group-body\">\n @for (rate of group.rates; track rate.id) {\n <div class=\"rtsee-rates-group-rate-item-container\">\n <div class=\"rtsee-rates-group-rate-item\">\n <span class=\"rtsee-rates-group-rate-config-name\">{{\n getRatingConfigName(rate.configurationId)\n }}</span>\n <rtsee-rating [rate]=\"rate\"></rtsee-rating>\n </div>\n @if (rate.text) {\n <p class=\"rtsee-rates-group-rate-comment\" itemprop=\"reviewBody\" data-ugc=\"true\" rel=\"ugc\">\"{{ rate.text }}\"</p>\n }\n </div>\n }\n </div>\n</div>\n" }]
|
|
6183
6661
|
}], propDecorators: { group: [{
|
|
6184
6662
|
type: Input
|
|
6185
6663
|
}], rater: [{
|
|
@@ -6296,11 +6774,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
6296
6774
|
|
|
6297
6775
|
class RatingSectionComponent {
|
|
6298
6776
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RatingSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6299
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: RatingSectionComponent, isStandalone: true, selector: "rtsee-rating-section", inputs: { rater: "rater", entity: "entity" }, ngImport: i0, template: "<div class=\"rtsee-rating-section\">\n <rtsee-rater [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rater>\n <rtsee-rates-list [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rates-list>\n</div>\n", dependencies: [{ kind: "component", type: RaterComponent, selector: "rtsee-rater", inputs: ["entity", "rater"] }, { kind: "component", type: RatesListComponent, selector: "rtsee-rates-list", inputs: ["rater", "entity"] }] }); }
|
|
6777
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: RatingSectionComponent, isStandalone: true, selector: "rtsee-rating-section", inputs: { rater: "rater", entity: "entity" }, ngImport: i0, template: "<div class=\"rtsee-rating-section\" data-ugc=\"true\" rel=\"ugc\" aria-label=\"User ratings and reviews\">\n <rtsee-rater [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rater>\n <rtsee-rates-list [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rates-list>\n</div>\n", dependencies: [{ kind: "component", type: RaterComponent, selector: "rtsee-rater", inputs: ["entity", "rater"] }, { kind: "component", type: RatesListComponent, selector: "rtsee-rates-list", inputs: ["rater", "entity"] }] }); }
|
|
6300
6778
|
}
|
|
6301
6779
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RatingSectionComponent, decorators: [{
|
|
6302
6780
|
type: Component,
|
|
6303
|
-
args: [{ selector: 'rtsee-rating-section', imports: [RaterComponent, RatesListComponent], template: "<div class=\"rtsee-rating-section\">\n <rtsee-rater [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rater>\n <rtsee-rates-list [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rates-list>\n</div>\n" }]
|
|
6781
|
+
args: [{ selector: 'rtsee-rating-section', imports: [RaterComponent, RatesListComponent], template: "<div class=\"rtsee-rating-section\" data-ugc=\"true\" rel=\"ugc\" aria-label=\"User ratings and reviews\">\n <rtsee-rater [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rater>\n <rtsee-rates-list [rater]=\"rater\"\n [entity]=\"entity\"\n ></rtsee-rates-list>\n</div>\n" }]
|
|
6304
6782
|
}], propDecorators: { rater: [{
|
|
6305
6783
|
type: Input
|
|
6306
6784
|
}], entity: [{
|
|
@@ -6539,11 +7017,11 @@ class StoryDetailsComponent {
|
|
|
6539
7017
|
return stars;
|
|
6540
7018
|
}
|
|
6541
7019
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6542
|
-
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/CreativeWork\"\n>\n @if (story.imageUrl) {\n <meta itemprop=\"image\" [attr.content]=\"story.imageUrl\" />\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 class=\"rtsee-story-details-cover-rating\">\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\">{{\n story.rating\n }}</span>\n @if (story.ratesCount !== null) {\n <span class=\"rtsee-story-details-rating-count\">\n <span>(</span>\n <span>{{ presentation.labels[RTSeeTextLabelKeys.FEEDBACKS_LABEL] }}:</span>\n <span> </span>\n <span>{{ 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\">\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\">\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"] }] }); }
|
|
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"] }] }); }
|
|
6543
7021
|
}
|
|
6544
7022
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryDetailsComponent, decorators: [{
|
|
6545
7023
|
type: Component,
|
|
6546
|
-
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/CreativeWork\"\n>\n @if (story.imageUrl) {\n <meta itemprop=\"image\" [attr.content]=\"story.imageUrl\" />\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 class=\"rtsee-story-details-cover-rating\">\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\">{{\n story.rating\n }}</span>\n @if (story.ratesCount !== null) {\n <span class=\"rtsee-story-details-rating-count\">\n <span>(</span>\n <span>{{ presentation.labels[RTSeeTextLabelKeys.FEEDBACKS_LABEL] }}:</span>\n <span> </span>\n <span>{{ 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\">\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\">\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" }]
|
|
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" }]
|
|
6547
7025
|
}], propDecorators: { story: [{
|
|
6548
7026
|
type: Input
|
|
6549
7027
|
}], presentation: [{
|
|
@@ -6623,7 +7101,7 @@ class RtseeNavComponent {
|
|
|
6623
7101
|
return false;
|
|
6624
7102
|
}
|
|
6625
7103
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeNavComponent, deps: [{ token: RTSeeAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
6626
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RtseeNavComponent, isStandalone: true, selector: "rtsee-nav", inputs: { config: "config", rtsee: "rtsee" }, ngImport: i0, template: "<div class=\"rtsee-nav\">\n @if (config.siteLogo) {\n <div class=\"rtsee-site-logo\">\n <p-image [src]=\"config.siteLogo.src\" class=\"rtsee-site-logo-image\"></p-image>\n <p-divider class=\"rtsee-site-logo-divider\" />\n </div>\n }\n <div class=\"rtsee-nav-bar\">\n @for (route of config.routes; track route.name) {\n <a [routerLink]=\"route.link\"\n routerLinkActive=\"rtsee-nav-item-active\"\n [ngClass]=\"{'rtsee-nav-item-hidden': !route.isEnabled || !route.iconClassName}\"\n [routerLinkActiveOptions]=\"{ exact: route.exactActiveLinkMatcher || false }\"\n class=\"rtsee-nav-item\"\n [pTooltip]=\"route.name\"\n >\n <span [ngClass]=\"route.iconClassName\"\n class=\"rtsee-nav-item-icon\" >\n </span>\n </a>\n }\n <p-avatar [image]=\"rtsee.socketConnection?.myPeer?.imageUrl\"\n class=\"rtsee-nav-item rtsee-nav-image rtsee-nav-profile\"\n [routerLink]=\"profileLink\"\n routerLinkActive=\"rtsee-nav-item-active\"\n [routerLinkActiveOptions]=\"{exact: true}\"\n [queryParams]=\"queryParams\"\n ></p-avatar>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "component", type: Image, selector: "p-image", inputs: ["imageClass", "imageStyle", "styleClass", "src", "srcSet", "sizes", "previewImageSrc", "previewImageSrcSet", "previewImageSizes", "alt", "width", "height", "loading", "preview", "showTransitionOptions", "hideTransitionOptions", "appendTo"], outputs: ["onShow", "onHide", "onImageError"] }, { kind: "component", type: Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }] }); }
|
|
7104
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RtseeNavComponent, isStandalone: true, selector: "rtsee-nav", inputs: { config: "config", rtsee: "rtsee" }, ngImport: i0, template: "<div class=\"rtsee-nav\">\n @if (config.siteLogo) {\n <div class=\"rtsee-site-logo\">\n <p-image [src]=\"config.siteLogo.src\" class=\"rtsee-site-logo-image\"></p-image>\n <p-divider class=\"rtsee-site-logo-divider\" />\n </div>\n }\n <div class=\"rtsee-nav-bar\">\n @for (route of config.routes; track route.name) {\n <a [routerLink]=\"route.link\"\n routerLinkActive=\"rtsee-nav-item-active\"\n [ngClass]=\"{'rtsee-nav-item-hidden': !route.isEnabled || !route.iconClassName}\"\n [routerLinkActiveOptions]=\"{ exact: route.exactActiveLinkMatcher || false }\"\n class=\"rtsee-nav-item\"\n [pTooltip]=\"route.name\"\n >\n <span [ngClass]=\"route.iconClassName\"\n class=\"rtsee-nav-item-icon\" >\n </span>\n </a>\n }\n <p-avatar [image]=\"rtsee.socketConnection?.myPeer?.imageUrl\"\n class=\"rtsee-nav-item rtsee-nav-image rtsee-nav-profile\"\n [routerLink]=\"profileLink\"\n routerLinkActive=\"rtsee-nav-item-active\"\n [routerLinkActiveOptions]=\"{exact: true}\"\n [queryParams]=\"queryParams\"\n ></p-avatar>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "component", type: Image$1, selector: "p-image", inputs: ["imageClass", "imageStyle", "styleClass", "src", "srcSet", "sizes", "previewImageSrc", "previewImageSrcSet", "previewImageSizes", "alt", "width", "height", "loading", "preview", "showTransitionOptions", "hideTransitionOptions", "appendTo"], outputs: ["onShow", "onHide", "onImageError"] }, { kind: "component", type: Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }] }); }
|
|
6627
7105
|
}
|
|
6628
7106
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RtseeNavComponent, decorators: [{
|
|
6629
7107
|
type: Component,
|
|
@@ -6632,7 +7110,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
6632
7110
|
RouterLinkActive,
|
|
6633
7111
|
NgClass,
|
|
6634
7112
|
Avatar,
|
|
6635
|
-
Image,
|
|
7113
|
+
Image$1,
|
|
6636
7114
|
Divider,
|
|
6637
7115
|
Tooltip,
|
|
6638
7116
|
], standalone: true, template: "<div class=\"rtsee-nav\">\n @if (config.siteLogo) {\n <div class=\"rtsee-site-logo\">\n <p-image [src]=\"config.siteLogo.src\" class=\"rtsee-site-logo-image\"></p-image>\n <p-divider class=\"rtsee-site-logo-divider\" />\n </div>\n }\n <div class=\"rtsee-nav-bar\">\n @for (route of config.routes; track route.name) {\n <a [routerLink]=\"route.link\"\n routerLinkActive=\"rtsee-nav-item-active\"\n [ngClass]=\"{'rtsee-nav-item-hidden': !route.isEnabled || !route.iconClassName}\"\n [routerLinkActiveOptions]=\"{ exact: route.exactActiveLinkMatcher || false }\"\n class=\"rtsee-nav-item\"\n [pTooltip]=\"route.name\"\n >\n <span [ngClass]=\"route.iconClassName\"\n class=\"rtsee-nav-item-icon\" >\n </span>\n </a>\n }\n <p-avatar [image]=\"rtsee.socketConnection?.myPeer?.imageUrl\"\n class=\"rtsee-nav-item rtsee-nav-image rtsee-nav-profile\"\n [routerLink]=\"profileLink\"\n routerLinkActive=\"rtsee-nav-item-active\"\n [routerLinkActiveOptions]=\"{exact: true}\"\n [queryParams]=\"queryParams\"\n ></p-avatar>\n </div>\n</div>\n" }]
|