@rtsee/ngx 0.0.106 → 0.0.108
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.
|
@@ -18,7 +18,7 @@ import { RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
|
|
|
18
18
|
import { Divider } from 'primeng/divider';
|
|
19
19
|
import * as i1$1 from '@angular/common/http';
|
|
20
20
|
import { RTSeeChatMemberRoles, RTSeeIllustratorEvents, RTSeeChatTypes, OzzyTaskStatus } from '@rtsee/common';
|
|
21
|
-
import { ManageAgentForm, RTSeeForm, RTSeeFormFieldRadioGroup, RTSeeFormField, RTSeeFormFieldImageUploader, RTSeeRater } from '@rtsee/utilities-ui';
|
|
21
|
+
import { sanitizeImageUrl, ManageAgentForm, RTSeeForm, RTSeeFormFieldRadioGroup, RTSeeFormField, RTSeeFormFieldImageUploader, RTSeeRater } from '@rtsee/utilities-ui';
|
|
22
22
|
import { InputText } from 'primeng/inputtext';
|
|
23
23
|
import { InputGroup } from 'primeng/inputgroup';
|
|
24
24
|
import { Textarea } from 'primeng/textarea';
|
|
@@ -711,7 +711,7 @@ class RTSeeImageUploaderComponent {
|
|
|
711
711
|
if (response.reviewingGeneratedImage && response.imageUrl) {
|
|
712
712
|
// 1. If RTSeeIllustrator is in reviewingGeneratedImage mode, apply currently reviewed image to ImageUploader
|
|
713
713
|
this.submittingFromPainting = true;
|
|
714
|
-
this.imageUploader.applyImageUrl(response.imageUrl);
|
|
714
|
+
this.imageUploader.applyImageUrl(sanitizeImageUrl(response.imageUrl));
|
|
715
715
|
// and if Imageuploader is part of the form it should immediately submit the form
|
|
716
716
|
setTimeout(() => {
|
|
717
717
|
this.submitParentForm();
|
|
@@ -1880,6 +1880,20 @@ class MediaWidgetComponent {
|
|
|
1880
1880
|
this.showAll = !this.showAll;
|
|
1881
1881
|
this.updateVisibleImages();
|
|
1882
1882
|
}
|
|
1883
|
+
sendToIllustrator(event, img) {
|
|
1884
|
+
event.stopPropagation();
|
|
1885
|
+
event.preventDefault();
|
|
1886
|
+
if (typeof window !== 'undefined' && img?.url) {
|
|
1887
|
+
const cleanUrl = sanitizeImageUrl(img.url);
|
|
1888
|
+
window.dispatchEvent(new CustomEvent(RTSeeIllustratorEvents.SET_IMAGE_FOR_REVIEW, {
|
|
1889
|
+
detail: {
|
|
1890
|
+
imageUrl: cleanUrl,
|
|
1891
|
+
prompt: img.name || (typeof this.message.text === 'string' ? this.message.text : '') || '',
|
|
1892
|
+
source: 'messenger',
|
|
1893
|
+
},
|
|
1894
|
+
}));
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1883
1897
|
updateVisibleImages() {
|
|
1884
1898
|
const all = this.message.images || [];
|
|
1885
1899
|
if (this.showAll || all.length <= this.MAX_GRID) {
|
|
@@ -1892,11 +1906,11 @@ class MediaWidgetComponent {
|
|
|
1892
1906
|
}
|
|
1893
1907
|
}
|
|
1894
1908
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MediaWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1895
|
-
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" }, 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.url) {\n <div class=\"rts-media-image-wrapper\">\n <img [src]=\"img.url\" [alt]=\"img.name\" class=\"rts-media-image\" loading=\"lazy\" />\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}.rts-video-player{width: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-2{grid-template-columns:1fr 1fr}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e)}.rts-media-image{width:100%;height:auto;max-height:280px;object-fit:cover;display:block;transition:transform .2s ease;cursor:pointer}.rts-media-image:hover{transform:scale(1.02)}.rts-media-grid-1 .rts-media-image{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"] }] }); }
|
|
1909
|
+
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" }, 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.url) {\n <div class=\"rts-media-image-wrapper\">\n <img [src]=\"img.url\" [alt]=\"img.name\" class=\"rts-media-image\" loading=\"lazy\" />\n <button\n type=\"button\"\n class=\"rts-media-btn-paint\"\n title=\"Send image to Illustrator\"\n (click)=\"sendToIllustrator($event, img)\"\n >\n <i class=\"pi pi-palette\"></i>\n <span>+ paint</span>\n </button>\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}.rts-video-player{width: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-2{grid-template-columns:1fr 1fr}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e)}.rts-media-btn-paint{position:absolute;top:8px;right:8px;z-index:5;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-image{width:100%;height:auto;max-height:280px;object-fit:cover;display:block;transition:transform .2s ease;cursor:pointer}.rts-media-image:hover{transform:scale(1.02)}.rts-media-grid-1 .rts-media-image{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"] }] }); }
|
|
1896
1910
|
}
|
|
1897
1911
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MediaWidgetComponent, decorators: [{
|
|
1898
1912
|
type: Component,
|
|
1899
|
-
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.url) {\n <div class=\"rts-media-image-wrapper\">\n <img [src]=\"img.url\" [alt]=\"img.name\" class=\"rts-media-image\" loading=\"lazy\" />\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}.rts-video-player{width: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-2{grid-template-columns:1fr 1fr}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e)}.rts-media-image{width:100%;height:auto;max-height:280px;object-fit:cover;display:block;transition:transform .2s ease;cursor:pointer}.rts-media-image:hover{transform:scale(1.02)}.rts-media-grid-1 .rts-media-image{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"] }]
|
|
1913
|
+
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.url) {\n <div class=\"rts-media-image-wrapper\">\n <img [src]=\"img.url\" [alt]=\"img.name\" class=\"rts-media-image\" loading=\"lazy\" />\n <button\n type=\"button\"\n class=\"rts-media-btn-paint\"\n title=\"Send image to Illustrator\"\n (click)=\"sendToIllustrator($event, img)\"\n >\n <i class=\"pi pi-palette\"></i>\n <span>+ paint</span>\n </button>\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}.rts-video-player{width: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-2{grid-template-columns:1fr 1fr}.rts-media-grid-4{grid-template-columns:1fr 1fr;grid-template-rows:auto auto}.rts-media-image-wrapper{position:relative;overflow:hidden;border-radius:6px;background:var(--rts-bg-secondary, #1e1e2e)}.rts-media-btn-paint{position:absolute;top:8px;right:8px;z-index:5;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-image{width:100%;height:auto;max-height:280px;object-fit:cover;display:block;transition:transform .2s ease;cursor:pointer}.rts-media-image:hover{transform:scale(1.02)}.rts-media-grid-1 .rts-media-image{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"] }]
|
|
1900
1914
|
}], propDecorators: { message: [{
|
|
1901
1915
|
type: Input
|
|
1902
1916
|
}], messenger: [{
|
|
@@ -3928,11 +3942,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
3928
3942
|
* All the logic lives in RTSeeStoryElementsEditor.
|
|
3929
3943
|
*/
|
|
3930
3944
|
class StoryElementsSectionComponent {
|
|
3931
|
-
|
|
3945
|
+
set illustrator(val) {
|
|
3946
|
+
if (this._illustrator) {
|
|
3947
|
+
this._illustrator.off('changed', this.onIllustratorChanged);
|
|
3948
|
+
}
|
|
3949
|
+
this._illustrator = val;
|
|
3950
|
+
if (this._illustrator) {
|
|
3951
|
+
this._illustrator.on('changed', this.onIllustratorChanged);
|
|
3952
|
+
}
|
|
3953
|
+
this.cdr.markForCheck();
|
|
3954
|
+
}
|
|
3955
|
+
get illustrator() {
|
|
3956
|
+
return this._illustrator;
|
|
3957
|
+
}
|
|
3958
|
+
constructor(cdr) {
|
|
3959
|
+
this.cdr = cdr;
|
|
3932
3960
|
this.icon = "pi pi-box";
|
|
3933
3961
|
this.collapsed = false;
|
|
3934
3962
|
this.canDetach = true;
|
|
3935
3963
|
this.toggled = new EventEmitter();
|
|
3964
|
+
this.onIllustratorChanged = () => {
|
|
3965
|
+
this.cdr.markForCheck();
|
|
3966
|
+
};
|
|
3967
|
+
}
|
|
3968
|
+
ngOnDestroy() {
|
|
3969
|
+
if (this._illustrator) {
|
|
3970
|
+
this._illustrator.off('changed', this.onIllustratorChanged);
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
async applyReviewedImageToItem(event, item) {
|
|
3974
|
+
event.stopPropagation();
|
|
3975
|
+
event.preventDefault();
|
|
3976
|
+
const imageUrl = sanitizeImageUrl(this._illustrator?.currentGeneratedImageUrl);
|
|
3977
|
+
if (!imageUrl)
|
|
3978
|
+
return;
|
|
3979
|
+
this.cdr.markForCheck();
|
|
3980
|
+
try {
|
|
3981
|
+
await item.save({ imageUrl });
|
|
3982
|
+
if (this.editor.expanded && this.editor.expanded.id === item.id && this.editor.form) {
|
|
3983
|
+
const imageField = this.editor.form.fields.find((f) => f.name === 'imageUrl' || f.type === 'image-uploader');
|
|
3984
|
+
if (imageField) {
|
|
3985
|
+
imageField.value = imageUrl;
|
|
3986
|
+
if (imageField.imageUploader) {
|
|
3987
|
+
imageField.imageUploader.uploadedPhotoPreview = imageUrl;
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3992
|
+
catch (e) {
|
|
3993
|
+
console.error(`Failed to apply image to ${this.editor.label}:`, e);
|
|
3994
|
+
}
|
|
3995
|
+
finally {
|
|
3996
|
+
this.cdr.markForCheck();
|
|
3997
|
+
}
|
|
3936
3998
|
}
|
|
3937
3999
|
submit() {
|
|
3938
4000
|
this.editor.submit();
|
|
@@ -3956,13 +4018,13 @@ class StoryElementsSectionComponent {
|
|
|
3956
4018
|
trackById(index, item) {
|
|
3957
4019
|
return item.id || `new-${index}`;
|
|
3958
4020
|
}
|
|
3959
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryElementsSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3960
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryElementsSectionComponent, isStandalone: true, selector: "rtsee-story-elements-section", inputs: { editor: "editor", title: "title", icon: "icon", collapsed: "collapsed", canDetach: "canDetach" }, outputs: { toggled: "toggled" }, ngImport: i0, template: "<section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': collapsed }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\"\n class=\"rtsee-ise-section-toggle\"\n [attr.aria-expanded]=\"!collapsed\"\n [id]=\"'rtsee-ise-toggle-' + editor.section\"\n (click)=\"toggled.emit()\">\n <i class=\"rtsee-ise-section-icon\" [ngClass]=\"icon\"></i>\n <h3 class=\"rtsee-ise-section-title\">{{ title }}</h3>\n <span class=\"rtsee-ise-section-count\">{{ editor.items.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!collapsed) {\n <div class=\"rtsee-ise-section-body\">\n <div class=\"rtsee-ise-thumbs-grid\">\n @for (item of editor.items; track trackById($index, item)) {\n <div class=\"rtsee-ise-thumb-card-container\" style=\"position: relative; display: flex; flex-direction: column;\">\n <button type=\"button\"\n class=\"rtsee-ise-thumb\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isExpanded(item) }\"\n [id]=\"'rtsee-ise-' + editor.section + '-' + item.id\"\n (click)=\"editor.expand(item)\">\n <div class=\"rtsee-ise-thumb-image\">\n @if (item.imageUrl) {\n <img [src]=\"item.imageUrl\" [alt]=\"item.name\" loading=\"lazy\" />\n } @else {\n <i [ngClass]=\"icon\"></i>\n }\n </div>\n <div class=\"rtsee-ise-thumb-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ item.name }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ item.getTruncatedDescription(90) }}</span>\n </div>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 8px; right: 8px;\"\n title=\"Add {{ item.name }} to Illustrator context\"\n (click)=\"addToIllustrator($event, item)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n </div>\n }\n\n <button type=\"button\"\n class=\"rtsee-ise-thumb rtsee-ise-thumb--add\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isCreating }\"\n [id]=\"'rtsee-ise-add-' + editor.section\"\n (click)=\"editor.expandNew()\">\n <i class=\"pi pi-plus\"></i>\n <span>New {{ editor.label }}</span>\n </button>\n </div>\n\n @if (editor.expanded && editor.form) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n <div class=\"rtsee-ise-expanded-header\">\n <h4>{{ editor.expanded.isNew ? 'New ' + editor.label : editor.expanded.name }}</h4>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n @if (!editor.expanded.isNew) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add to Illustrator context\"\n (click)=\"addToIllustrator($event, editor.expanded)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8 Illustrator</span>\n </button>\n }\n <button type=\"button\" class=\"rtsee-ise-icon-button\" (click)=\"editor.collapse()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n\n @if (editor.error) {\n <div class=\"rtsee-ise-error\">{{ editor.error }}</div>\n }\n\n <rtsee-form [form]=\"editor.form\" (formSubmit)=\"submit()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\"\n [label]=\"editor.expanded.isNew ? 'Create' : 'Save'\"\n [loading]=\"editor.saveInProgress\"\n [disabled]=\"editor.busy\" />\n <p-button label=\"Cancel\"\n severity=\"secondary\"\n (click)=\"editor.collapse()\"\n [disabled]=\"editor.busy\" />\n @if (!editor.expanded.isNew) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n @if (canDetach) {\n <p-button label=\"Remove from story\"\n icon=\"pi pi-minus-circle\"\n severity=\"secondary\"\n [text]=\"true\"\n (click)=\"editor.detach(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n <p-button label=\"Delete\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n [loading]=\"editor.removeInProgress\"\n (click)=\"editor.delete(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n</section>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: FormComponent, selector: "rtsee-form", inputs: ["form"], outputs: ["formSubmit"] }] }); }
|
|
4021
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryElementsSectionComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4022
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StoryElementsSectionComponent, isStandalone: true, selector: "rtsee-story-elements-section", inputs: { editor: "editor", title: "title", icon: "icon", collapsed: "collapsed", canDetach: "canDetach", illustrator: "illustrator" }, outputs: { toggled: "toggled" }, ngImport: i0, template: "<section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': collapsed }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\"\n class=\"rtsee-ise-section-toggle\"\n [attr.aria-expanded]=\"!collapsed\"\n [id]=\"'rtsee-ise-toggle-' + editor.section\"\n (click)=\"toggled.emit()\">\n <i class=\"rtsee-ise-section-icon\" [ngClass]=\"icon\"></i>\n <h3 class=\"rtsee-ise-section-title\">{{ title }}</h3>\n <span class=\"rtsee-ise-section-count\">{{ editor.items.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!collapsed) {\n <div class=\"rtsee-ise-section-body\">\n <div class=\"rtsee-ise-thumbs-grid\">\n @for (item of editor.items; track trackById($index, item)) {\n <div class=\"rtsee-ise-thumb-card-container\" style=\"position: relative; display: flex; flex-direction: column;\">\n <button type=\"button\"\n class=\"rtsee-ise-thumb\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isExpanded(item) }\"\n [id]=\"'rtsee-ise-' + editor.section + '-' + item.id\"\n (click)=\"editor.expand(item)\">\n <div class=\"rtsee-ise-thumb-image\">\n @if (item.imageUrl) {\n <img [src]=\"item.imageUrl\" [alt]=\"item.name\" loading=\"lazy\" />\n } @else {\n <i [ngClass]=\"icon\"></i>\n }\n </div>\n <div class=\"rtsee-ise-thumb-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ item.name }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ item.getTruncatedDescription(90) }}</span>\n </div>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 8px; right: 8px;\"\n title=\"Add {{ item.name }} to Illustrator context\"\n (click)=\"addToIllustrator($event, item)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n @if (illustrator?.reviewingGeneratedImage && illustrator?.currentGeneratedImageUrl) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-quick-apply\"\n style=\"position: absolute; bottom: 8px; right: 8px;\"\n [disabled]=\"item.saveInProgress\"\n [title]=\"'Apply reviewed image to ' + item.name\"\n (click)=\"applyReviewedImageToItem($event, item)\">\n @if (item.saveInProgress) {\n <i class=\"pi pi-spin pi-spinner\"></i>\n } @else {\n <i class=\"pi pi-plus\"></i>\n }\n </button>\n }\n </div>\n }\n\n <button type=\"button\"\n class=\"rtsee-ise-thumb rtsee-ise-thumb--add\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isCreating }\"\n [id]=\"'rtsee-ise-add-' + editor.section\"\n (click)=\"editor.expandNew()\">\n <i class=\"pi pi-plus\"></i>\n <span>New {{ editor.label }}</span>\n </button>\n </div>\n\n @if (editor.expanded && editor.form) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n <div class=\"rtsee-ise-expanded-header\">\n <h4>{{ editor.expanded.isNew ? 'New ' + editor.label : editor.expanded.name }}</h4>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n @if (!editor.expanded.isNew) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add to Illustrator context\"\n (click)=\"addToIllustrator($event, editor.expanded)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8 Illustrator</span>\n </button>\n }\n <button type=\"button\" class=\"rtsee-ise-icon-button\" (click)=\"editor.collapse()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n\n @if (editor.error) {\n <div class=\"rtsee-ise-error\">{{ editor.error }}</div>\n }\n\n <rtsee-form [form]=\"editor.form\" (formSubmit)=\"submit()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\"\n [label]=\"editor.expanded.isNew ? 'Create' : 'Save'\"\n [loading]=\"editor.saveInProgress\"\n [disabled]=\"editor.busy\" />\n <p-button label=\"Cancel\"\n severity=\"secondary\"\n (click)=\"editor.collapse()\"\n [disabled]=\"editor.busy\" />\n @if (!editor.expanded.isNew) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n @if (canDetach) {\n <p-button label=\"Remove from story\"\n icon=\"pi pi-minus-circle\"\n severity=\"secondary\"\n [text]=\"true\"\n (click)=\"editor.detach(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n <p-button label=\"Delete\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n [loading]=\"editor.removeInProgress\"\n (click)=\"editor.delete(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n</section>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: FormComponent, selector: "rtsee-form", inputs: ["form"], outputs: ["formSubmit"] }] }); }
|
|
3961
4023
|
}
|
|
3962
4024
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StoryElementsSectionComponent, decorators: [{
|
|
3963
4025
|
type: Component,
|
|
3964
|
-
args: [{ selector: "rtsee-story-elements-section", standalone: true, imports: [NgClass, Button, FormComponent], template: "<section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': collapsed }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\"\n class=\"rtsee-ise-section-toggle\"\n [attr.aria-expanded]=\"!collapsed\"\n [id]=\"'rtsee-ise-toggle-' + editor.section\"\n (click)=\"toggled.emit()\">\n <i class=\"rtsee-ise-section-icon\" [ngClass]=\"icon\"></i>\n <h3 class=\"rtsee-ise-section-title\">{{ title }}</h3>\n <span class=\"rtsee-ise-section-count\">{{ editor.items.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!collapsed) {\n <div class=\"rtsee-ise-section-body\">\n <div class=\"rtsee-ise-thumbs-grid\">\n @for (item of editor.items; track trackById($index, item)) {\n <div class=\"rtsee-ise-thumb-card-container\" style=\"position: relative; display: flex; flex-direction: column;\">\n <button type=\"button\"\n class=\"rtsee-ise-thumb\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isExpanded(item) }\"\n [id]=\"'rtsee-ise-' + editor.section + '-' + item.id\"\n (click)=\"editor.expand(item)\">\n <div class=\"rtsee-ise-thumb-image\">\n @if (item.imageUrl) {\n <img [src]=\"item.imageUrl\" [alt]=\"item.name\" loading=\"lazy\" />\n } @else {\n <i [ngClass]=\"icon\"></i>\n }\n </div>\n <div class=\"rtsee-ise-thumb-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ item.name }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ item.getTruncatedDescription(90) }}</span>\n </div>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 8px; right: 8px;\"\n title=\"Add {{ item.name }} to Illustrator context\"\n (click)=\"addToIllustrator($event, item)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n </div>\n }\n\n <button type=\"button\"\n class=\"rtsee-ise-thumb rtsee-ise-thumb--add\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isCreating }\"\n [id]=\"'rtsee-ise-add-' + editor.section\"\n (click)=\"editor.expandNew()\">\n <i class=\"pi pi-plus\"></i>\n <span>New {{ editor.label }}</span>\n </button>\n </div>\n\n @if (editor.expanded && editor.form) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n <div class=\"rtsee-ise-expanded-header\">\n <h4>{{ editor.expanded.isNew ? 'New ' + editor.label : editor.expanded.name }}</h4>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n @if (!editor.expanded.isNew) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add to Illustrator context\"\n (click)=\"addToIllustrator($event, editor.expanded)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8 Illustrator</span>\n </button>\n }\n <button type=\"button\" class=\"rtsee-ise-icon-button\" (click)=\"editor.collapse()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n\n @if (editor.error) {\n <div class=\"rtsee-ise-error\">{{ editor.error }}</div>\n }\n\n <rtsee-form [form]=\"editor.form\" (formSubmit)=\"submit()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\"\n [label]=\"editor.expanded.isNew ? 'Create' : 'Save'\"\n [loading]=\"editor.saveInProgress\"\n [disabled]=\"editor.busy\" />\n <p-button label=\"Cancel\"\n severity=\"secondary\"\n (click)=\"editor.collapse()\"\n [disabled]=\"editor.busy\" />\n @if (!editor.expanded.isNew) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n @if (canDetach) {\n <p-button label=\"Remove from story\"\n icon=\"pi pi-minus-circle\"\n severity=\"secondary\"\n [text]=\"true\"\n (click)=\"editor.detach(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n <p-button label=\"Delete\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n [loading]=\"editor.removeInProgress\"\n (click)=\"editor.delete(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n</section>\n" }]
|
|
3965
|
-
}], propDecorators: { editor: [{
|
|
4026
|
+
args: [{ selector: "rtsee-story-elements-section", standalone: true, imports: [NgClass, Button, FormComponent], template: "<section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': collapsed }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\"\n class=\"rtsee-ise-section-toggle\"\n [attr.aria-expanded]=\"!collapsed\"\n [id]=\"'rtsee-ise-toggle-' + editor.section\"\n (click)=\"toggled.emit()\">\n <i class=\"rtsee-ise-section-icon\" [ngClass]=\"icon\"></i>\n <h3 class=\"rtsee-ise-section-title\">{{ title }}</h3>\n <span class=\"rtsee-ise-section-count\">{{ editor.items.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!collapsed) {\n <div class=\"rtsee-ise-section-body\">\n <div class=\"rtsee-ise-thumbs-grid\">\n @for (item of editor.items; track trackById($index, item)) {\n <div class=\"rtsee-ise-thumb-card-container\" style=\"position: relative; display: flex; flex-direction: column;\">\n <button type=\"button\"\n class=\"rtsee-ise-thumb\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isExpanded(item) }\"\n [id]=\"'rtsee-ise-' + editor.section + '-' + item.id\"\n (click)=\"editor.expand(item)\">\n <div class=\"rtsee-ise-thumb-image\">\n @if (item.imageUrl) {\n <img [src]=\"item.imageUrl\" [alt]=\"item.name\" loading=\"lazy\" />\n } @else {\n <i [ngClass]=\"icon\"></i>\n }\n </div>\n <div class=\"rtsee-ise-thumb-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ item.name }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ item.getTruncatedDescription(90) }}</span>\n </div>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 8px; right: 8px;\"\n title=\"Add {{ item.name }} to Illustrator context\"\n (click)=\"addToIllustrator($event, item)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n @if (illustrator?.reviewingGeneratedImage && illustrator?.currentGeneratedImageUrl) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-quick-apply\"\n style=\"position: absolute; bottom: 8px; right: 8px;\"\n [disabled]=\"item.saveInProgress\"\n [title]=\"'Apply reviewed image to ' + item.name\"\n (click)=\"applyReviewedImageToItem($event, item)\">\n @if (item.saveInProgress) {\n <i class=\"pi pi-spin pi-spinner\"></i>\n } @else {\n <i class=\"pi pi-plus\"></i>\n }\n </button>\n }\n </div>\n }\n\n <button type=\"button\"\n class=\"rtsee-ise-thumb rtsee-ise-thumb--add\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': editor.isCreating }\"\n [id]=\"'rtsee-ise-add-' + editor.section\"\n (click)=\"editor.expandNew()\">\n <i class=\"pi pi-plus\"></i>\n <span>New {{ editor.label }}</span>\n </button>\n </div>\n\n @if (editor.expanded && editor.form) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n <div class=\"rtsee-ise-expanded-header\">\n <h4>{{ editor.expanded.isNew ? 'New ' + editor.label : editor.expanded.name }}</h4>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n @if (!editor.expanded.isNew) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add to Illustrator context\"\n (click)=\"addToIllustrator($event, editor.expanded)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8 Illustrator</span>\n </button>\n }\n <button type=\"button\" class=\"rtsee-ise-icon-button\" (click)=\"editor.collapse()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n </div>\n </div>\n\n @if (editor.error) {\n <div class=\"rtsee-ise-error\">{{ editor.error }}</div>\n }\n\n <rtsee-form [form]=\"editor.form\" (formSubmit)=\"submit()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\"\n [label]=\"editor.expanded.isNew ? 'Create' : 'Save'\"\n [loading]=\"editor.saveInProgress\"\n [disabled]=\"editor.busy\" />\n <p-button label=\"Cancel\"\n severity=\"secondary\"\n (click)=\"editor.collapse()\"\n [disabled]=\"editor.busy\" />\n @if (!editor.expanded.isNew) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n @if (canDetach) {\n <p-button label=\"Remove from story\"\n icon=\"pi pi-minus-circle\"\n severity=\"secondary\"\n [text]=\"true\"\n (click)=\"editor.detach(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n <p-button label=\"Delete\"\n icon=\"pi pi-trash\"\n severity=\"danger\"\n [text]=\"true\"\n [loading]=\"editor.removeInProgress\"\n (click)=\"editor.delete(editor.expanded)\"\n [disabled]=\"editor.busy\" />\n }\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n</section>\n" }]
|
|
4027
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { editor: [{
|
|
3966
4028
|
type: Input,
|
|
3967
4029
|
args: [{ required: true }]
|
|
3968
4030
|
}], title: [{
|
|
@@ -3976,6 +4038,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
3976
4038
|
type: Input
|
|
3977
4039
|
}], toggled: [{
|
|
3978
4040
|
type: Output
|
|
4041
|
+
}], illustrator: [{
|
|
4042
|
+
type: Input
|
|
3979
4043
|
}] } });
|
|
3980
4044
|
|
|
3981
4045
|
class IllustratorComponent {
|
|
@@ -4091,21 +4155,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4091
4155
|
* Rendering only, the orchestration lives in RTSeeInteractiveStoryEditorVm.
|
|
4092
4156
|
*/
|
|
4093
4157
|
class InteractiveStoryEditorComponent {
|
|
4094
|
-
constructor() {
|
|
4158
|
+
constructor(cdr) {
|
|
4159
|
+
this.cdr = cdr;
|
|
4095
4160
|
/** set to false when the vm is initialized by the host */
|
|
4096
4161
|
this.autoInit = true;
|
|
4097
4162
|
this.sections = RTSeeStoryEditorSection;
|
|
4098
4163
|
this.illustrator = new RTSeeIllustrator();
|
|
4164
|
+
this.slideUpdatingIds = new Set();
|
|
4165
|
+
this.onIllustratorChanged = () => {
|
|
4166
|
+
this.cdr.markForCheck();
|
|
4167
|
+
};
|
|
4099
4168
|
}
|
|
4100
4169
|
ngOnInit() {
|
|
4101
4170
|
if (this.autoInit && !this.vm.story) {
|
|
4102
4171
|
void this.vm.init();
|
|
4103
4172
|
}
|
|
4173
|
+
this.illustrator.on('changed', this.onIllustratorChanged);
|
|
4104
4174
|
}
|
|
4105
4175
|
ngOnDestroy() {
|
|
4176
|
+
this.illustrator.off('changed', this.onIllustratorChanged);
|
|
4106
4177
|
this.vm.collapseSlide();
|
|
4107
4178
|
this.illustrator.destroy();
|
|
4108
4179
|
}
|
|
4180
|
+
isSlideUpdating(id) {
|
|
4181
|
+
return this.slideUpdatingIds.has(id);
|
|
4182
|
+
}
|
|
4183
|
+
async applyReviewedImageToSlide(event, slide) {
|
|
4184
|
+
event.stopPropagation();
|
|
4185
|
+
event.preventDefault();
|
|
4186
|
+
const imageUrl = sanitizeImageUrl(this.illustrator.currentGeneratedImageUrl);
|
|
4187
|
+
if (!imageUrl || !slide.id)
|
|
4188
|
+
return;
|
|
4189
|
+
this.slideUpdatingIds.add(slide.id);
|
|
4190
|
+
this.cdr.markForCheck();
|
|
4191
|
+
try {
|
|
4192
|
+
await this.vm.updateSlideImage(slide, imageUrl);
|
|
4193
|
+
}
|
|
4194
|
+
catch (e) {
|
|
4195
|
+
console.error('Failed to apply image to slide:', e);
|
|
4196
|
+
}
|
|
4197
|
+
finally {
|
|
4198
|
+
this.slideUpdatingIds.delete(slide.id);
|
|
4199
|
+
this.cdr.markForCheck();
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4109
4202
|
submitDetails() {
|
|
4110
4203
|
this.vm.detailsForm?.submit();
|
|
4111
4204
|
}
|
|
@@ -4279,8 +4372,8 @@ class InteractiveStoryEditorComponent {
|
|
|
4279
4372
|
trackSlide(index, slide) {
|
|
4280
4373
|
return slide.id || `slide-${index}`;
|
|
4281
4374
|
}
|
|
4282
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InteractiveStoryEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4283
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InteractiveStoryEditorComponent, isStandalone: true, selector: "rtsee-interactive-story-editor", inputs: { vm: "vm", autoInit: "autoInit" }, ngImport: i0, template: "<div class=\"rtsee-interactive-story-editor\" [style.padding-bottom]=\"illustrator.expanded ? '460px' : '72px'\">\n @if (vm.initInProgress) {\n <div class=\"rtsee-ise-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading story\u2026</span>\n </div>\n } @else if (vm.initError) {\n <div class=\"rtsee-ise-error\">{{ vm.initError }}</div>\n } @else if (vm.story) {\n <header class=\"rtsee-ise-header\">\n <span class=\"rtsee-ise-eyebrow\">{{ vm.isNewStory ? 'New story' : 'Story editor' }}</span>\n <h2 class=\"rtsee-ise-heading\">{{ vm.story.name || 'Untitled story' }}</h2>\n </header>\n\n <!-- 1. Details -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.details) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-details\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.details)\"\n (click)=\"vm.toggleSection(sections.details)\">\n <i class=\"rtsee-ise-section-icon pi pi-book\"></i>\n <h3 class=\"rtsee-ise-section-title\">Story details</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.details)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-details-card\" id=\"rtsee-ise-details-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.detailsExpanded }\"\n (click)=\"vm.toggleDetails()\">\n <div class=\"rtsee-ise-details-image\">\n @if (vm.story.imageUrl) {\n <img [src]=\"vm.story.imageUrl\" [alt]=\"vm.story.name\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n </div>\n <div class=\"rtsee-ise-details-body\">\n <span class=\"rtsee-ise-details-name\">{{ vm.story.name || 'Untitled story' }}</span>\n <p class=\"rtsee-ise-details-description\">{{ vm.story.getTruncatedDescription(220) || 'No description yet' }}</p>\n @if (vm.story.tags.length) {\n <div class=\"rtsee-ise-chips\">\n @for (tag of vm.story.tags; track tag.id) {\n <span class=\"rtsee-ise-chip\">{{ tag.name }}</span>\n }\n </div>\n }\n </div>\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.detailsExpanded && vm.detailsForm) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.detailsError) {\n <div class=\"rtsee-ise-error\">{{ vm.detailsError }}</div>\n }\n <rtsee-form [form]=\"vm.detailsForm\" (formSubmit)=\"submitDetails()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" [label]=\"vm.isNewStory ? 'Create story' : 'Save'\"\n [loading]=\"vm.detailsSaveInProgress\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n <p-button label=\"Cancel\" severity=\"secondary\"\n (click)=\"vm.collapseDetails()\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 2-4. Characters, artifacts, locations -->\n <rtsee-story-elements-section [editor]=\"vm.charactersEditor\"\n title=\"Characters\"\n icon=\"pi pi-user\"\n [collapsed]=\"vm.isCollapsed(sections.characters)\"\n (toggled)=\"vm.toggleSection(sections.characters)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.artifactsEditor\"\n title=\"Artifacts\"\n icon=\"pi pi-star\"\n [collapsed]=\"vm.isCollapsed(sections.artifacts)\"\n (toggled)=\"vm.toggleSection(sections.artifacts)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.locationsEditor\"\n title=\"Locations\"\n icon=\"pi pi-map-marker\"\n [collapsed]=\"vm.isCollapsed(sections.locations)\"\n (toggled)=\"vm.toggleSection(sections.locations)\" />\n\n <!-- 5. Slides -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.slides) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-slides\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.slides)\"\n (click)=\"vm.toggleSection(sections.slides)\">\n <i class=\"rtsee-ise-section-icon pi pi-images\"></i>\n <h3 class=\"rtsee-ise-section-title\">Slides</h3>\n <span class=\"rtsee-ise-section-count\">{{ vm.slides.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.slides)) {\n <div class=\"rtsee-ise-section-body\">\n @if (vm.isNewStory) {\n <p class=\"rtsee-ise-hint\">Save the story details first to add slides.</p>\n } @else {\n <div class=\"rtsee-ise-slides-strip\">\n @for (slide of vm.slides; track trackSlide($index, slide)) {\n <div class=\"rtsee-ise-slide-thumb-wrapper\" style=\"position: relative; display: inline-flex;\">\n <button type=\"button\" class=\"rtsee-ise-slide-thumb\"\n [id]=\"'rtsee-ise-slide-' + slide.id\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.isSlideExpanded(slide) }\"\n [attr.aria-label]=\"'Slide ' + slide.slideNumber\"\n (click)=\"vm.expandSlide(slide)\">\n @if (slide.imageUrl) {\n <img [src]=\"slide.imageUrl\" [alt]=\"slide.name\" loading=\"lazy\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n <span class=\"rtsee-ise-slide-number\">{{ slide.slideNumber }}</span>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator rtsee-ise-btn-add-context\"\n style=\"position: absolute; top: 4px; left: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} context (characters, locations, artifacts) to Illustrator\"\n (click)=\"addSlideEntitiesToContext($event, slide)\">\n <i class=\"pi pi-plus\"></i>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 4px; right: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} to Illustrator context\"\n (click)=\"addSlideToContext($event, slide)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n </div>\n }\n <button type=\"button\" class=\"rtsee-ise-slide-thumb rtsee-ise-slide-thumb--add\"\n id=\"rtsee-ise-add-slide\"\n [disabled]=\"vm.slidesLoadInProgress\"\n (click)=\"vm.expandNewSlide()\">\n <i class=\"pi pi-plus\"></i>\n </button>\n </div>\n\n @if (vm.activeSlide) {\n <div class=\"rtsee-ise-expanded\">\n <rtsee-manage-slide [manageSlide]=\"vm.activeSlide\" />\n </div>\n }\n }\n </div>\n }\n </section>\n\n <!-- 6. Author -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.author) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-author\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.author)\"\n (click)=\"vm.toggleSection(sections.author)\">\n <i class=\"rtsee-ise-section-icon pi pi-pen-to-square\"></i>\n <h3 class=\"rtsee-ise-section-title\">Author</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.author)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-author-card\" id=\"rtsee-ise-author-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.authorExpanded }\"\n (click)=\"vm.toggleAuthor()\">\n <div class=\"rtsee-ise-avatar\">\n @if (vm.author?.imageUrl) {\n <img [src]=\"vm.author?.imageUrl\" [alt]=\"vm.author?.name\" />\n } @else {\n <i class=\"pi pi-user\"></i>\n }\n </div>\n <div class=\"rtsee-ise-author-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ vm.author?.name || 'No author assigned' }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ vm.author?.description || 'Click to pick or create an author' }}</span>\n </div>\n @if (vm.author) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add Author to Illustrator context\"\n (click)=\"addAuthorToContext($event)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n }\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.authorExpanded) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.authorError) {\n <div class=\"rtsee-ise-error\">{{ vm.authorError }}</div>\n }\n\n @if (vm.newAuthor && vm.newAuthorForm) {\n <h4 class=\"rtsee-ise-subheading\">New author</h4>\n <rtsee-form [form]=\"vm.newAuthorForm\" (formSubmit)=\"submitNewAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Create & assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"Back\" severity=\"secondary\"\n (click)=\"vm.cancelNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n </div>\n </rtsee-form>\n } @else if (vm.authorForm) {\n <rtsee-form [form]=\"vm.authorForm\" (formSubmit)=\"submitAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"New author\" icon=\"pi pi-plus\" severity=\"secondary\"\n (click)=\"vm.startNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n @if (vm.author) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n <p-button label=\"Clear\" icon=\"pi pi-times\" severity=\"danger\" [text]=\"true\"\n (click)=\"vm.assignAuthor(null)\"\n [disabled]=\"vm.authorSaveInProgress\" />\n }\n </div>\n </rtsee-form>\n }\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 7. NanoBanana Illustrator Overlay -->\n <rtsee-illustrator [illustrator]=\"illustrator\" />\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: FormComponent, selector: "rtsee-form", inputs: ["form"], outputs: ["formSubmit"] }, { kind: "component", type: ManageSlideComponent, selector: "rtsee-manage-slide", inputs: ["manageSlide"] }, { kind: "component", type: StoryElementsSectionComponent, selector: "rtsee-story-elements-section", inputs: ["editor", "title", "icon", "collapsed", "canDetach"], outputs: ["toggled"] }, { kind: "component", type: IllustratorComponent, selector: "rtsee-illustrator", inputs: ["illustrator"] }] }); }
|
|
4375
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InteractiveStoryEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4376
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InteractiveStoryEditorComponent, isStandalone: true, selector: "rtsee-interactive-story-editor", inputs: { vm: "vm", autoInit: "autoInit" }, ngImport: i0, template: "<div class=\"rtsee-interactive-story-editor\" [style.padding-bottom]=\"illustrator.expanded ? '460px' : '72px'\">\n @if (vm.initInProgress) {\n <div class=\"rtsee-ise-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading story\u2026</span>\n </div>\n } @else if (vm.initError) {\n <div class=\"rtsee-ise-error\">{{ vm.initError }}</div>\n } @else if (vm.story) {\n <header class=\"rtsee-ise-header\">\n <span class=\"rtsee-ise-eyebrow\">{{ vm.isNewStory ? 'New story' : 'Story editor' }}</span>\n <h2 class=\"rtsee-ise-heading\">{{ vm.story.name || 'Untitled story' }}</h2>\n </header>\n\n <!-- 1. Details -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.details) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-details\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.details)\"\n (click)=\"vm.toggleSection(sections.details)\">\n <i class=\"rtsee-ise-section-icon pi pi-book\"></i>\n <h3 class=\"rtsee-ise-section-title\">Story details</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.details)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-details-card\" id=\"rtsee-ise-details-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.detailsExpanded }\"\n (click)=\"vm.toggleDetails()\">\n <div class=\"rtsee-ise-details-image\">\n @if (vm.story.imageUrl) {\n <img [src]=\"vm.story.imageUrl\" [alt]=\"vm.story.name\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n </div>\n <div class=\"rtsee-ise-details-body\">\n <span class=\"rtsee-ise-details-name\">{{ vm.story.name || 'Untitled story' }}</span>\n <p class=\"rtsee-ise-details-description\">{{ vm.story.getTruncatedDescription(220) || 'No description yet' }}</p>\n @if (vm.story.tags.length) {\n <div class=\"rtsee-ise-chips\">\n @for (tag of vm.story.tags; track tag.id) {\n <span class=\"rtsee-ise-chip\">{{ tag.name }}</span>\n }\n </div>\n }\n </div>\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.detailsExpanded && vm.detailsForm) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.detailsError) {\n <div class=\"rtsee-ise-error\">{{ vm.detailsError }}</div>\n }\n <rtsee-form [form]=\"vm.detailsForm\" (formSubmit)=\"submitDetails()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" [label]=\"vm.isNewStory ? 'Create story' : 'Save'\"\n [loading]=\"vm.detailsSaveInProgress\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n <p-button label=\"Cancel\" severity=\"secondary\"\n (click)=\"vm.collapseDetails()\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 2-4. Characters, artifacts, locations -->\n <rtsee-story-elements-section [editor]=\"vm.charactersEditor\"\n title=\"Characters\"\n icon=\"pi pi-user\"\n [illustrator]=\"illustrator\"\n [collapsed]=\"vm.isCollapsed(sections.characters)\"\n (toggled)=\"vm.toggleSection(sections.characters)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.artifactsEditor\"\n title=\"Artifacts\"\n icon=\"pi pi-star\"\n [illustrator]=\"illustrator\"\n [collapsed]=\"vm.isCollapsed(sections.artifacts)\"\n (toggled)=\"vm.toggleSection(sections.artifacts)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.locationsEditor\"\n title=\"Locations\"\n icon=\"pi pi-map-marker\"\n [illustrator]=\"illustrator\"\n [collapsed]=\"vm.isCollapsed(sections.locations)\"\n (toggled)=\"vm.toggleSection(sections.locations)\" />\n\n <!-- 5. Slides -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.slides) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-slides\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.slides)\"\n (click)=\"vm.toggleSection(sections.slides)\">\n <i class=\"rtsee-ise-section-icon pi pi-images\"></i>\n <h3 class=\"rtsee-ise-section-title\">Slides</h3>\n <span class=\"rtsee-ise-section-count\">{{ vm.slides.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.slides)) {\n <div class=\"rtsee-ise-section-body\">\n @if (vm.isNewStory) {\n <p class=\"rtsee-ise-hint\">Save the story details first to add slides.</p>\n } @else {\n <div class=\"rtsee-ise-slides-strip\">\n @for (slide of vm.slides; track trackSlide($index, slide)) {\n <div class=\"rtsee-ise-slide-thumb-wrapper\" style=\"position: relative; display: inline-flex;\">\n <button type=\"button\" class=\"rtsee-ise-slide-thumb\"\n [id]=\"'rtsee-ise-slide-' + slide.id\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.isSlideExpanded(slide) }\"\n [attr.aria-label]=\"'Slide ' + slide.slideNumber\"\n (click)=\"vm.expandSlide(slide)\">\n @if (slide.imageUrl) {\n <img [src]=\"slide.imageUrl\" [alt]=\"slide.name\" loading=\"lazy\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n <span class=\"rtsee-ise-slide-number\">{{ slide.slideNumber }}</span>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator rtsee-ise-btn-add-context\"\n style=\"position: absolute; top: 4px; left: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} context (characters, locations, artifacts) to Illustrator\"\n (click)=\"addSlideEntitiesToContext($event, slide)\">\n <i class=\"pi pi-plus\"></i>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 4px; right: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} to Illustrator context\"\n (click)=\"addSlideToContext($event, slide)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n @if (illustrator.reviewingGeneratedImage && illustrator.currentGeneratedImageUrl) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-quick-apply\"\n style=\"position: absolute; bottom: 4px; right: 4px;\"\n [disabled]=\"isSlideUpdating(slide.id)\"\n [title]=\"'Apply reviewed image to Slide ' + slide.slideNumber\"\n (click)=\"applyReviewedImageToSlide($event, slide)\">\n @if (isSlideUpdating(slide.id)) {\n <i class=\"pi pi-spin pi-spinner\"></i>\n } @else {\n <i class=\"pi pi-plus\"></i>\n }\n </button>\n }\n </div>\n }\n <button type=\"button\" class=\"rtsee-ise-slide-thumb rtsee-ise-slide-thumb--add\"\n id=\"rtsee-ise-add-slide\"\n [disabled]=\"vm.slidesLoadInProgress\"\n (click)=\"vm.expandNewSlide()\">\n <i class=\"pi pi-plus\"></i>\n </button>\n </div>\n\n @if (vm.activeSlide) {\n <div class=\"rtsee-ise-expanded\">\n <rtsee-manage-slide [manageSlide]=\"vm.activeSlide\" />\n </div>\n }\n }\n </div>\n }\n </section>\n\n <!-- 6. Author -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.author) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-author\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.author)\"\n (click)=\"vm.toggleSection(sections.author)\">\n <i class=\"rtsee-ise-section-icon pi pi-pen-to-square\"></i>\n <h3 class=\"rtsee-ise-section-title\">Author</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.author)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-author-card\" id=\"rtsee-ise-author-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.authorExpanded }\"\n (click)=\"vm.toggleAuthor()\">\n <div class=\"rtsee-ise-avatar\">\n @if (vm.author?.imageUrl) {\n <img [src]=\"vm.author?.imageUrl\" [alt]=\"vm.author?.name\" />\n } @else {\n <i class=\"pi pi-user\"></i>\n }\n </div>\n <div class=\"rtsee-ise-author-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ vm.author?.name || 'No author assigned' }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ vm.author?.description || 'Click to pick or create an author' }}</span>\n </div>\n @if (vm.author) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add Author to Illustrator context\"\n (click)=\"addAuthorToContext($event)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n }\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.authorExpanded) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.authorError) {\n <div class=\"rtsee-ise-error\">{{ vm.authorError }}</div>\n }\n\n @if (vm.newAuthor && vm.newAuthorForm) {\n <h4 class=\"rtsee-ise-subheading\">New author</h4>\n <rtsee-form [form]=\"vm.newAuthorForm\" (formSubmit)=\"submitNewAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Create & assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"Back\" severity=\"secondary\"\n (click)=\"vm.cancelNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n </div>\n </rtsee-form>\n } @else if (vm.authorForm) {\n <rtsee-form [form]=\"vm.authorForm\" (formSubmit)=\"submitAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"New author\" icon=\"pi pi-plus\" severity=\"secondary\"\n (click)=\"vm.startNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n @if (vm.author) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n <p-button label=\"Clear\" icon=\"pi pi-times\" severity=\"danger\" [text]=\"true\"\n (click)=\"vm.assignAuthor(null)\"\n [disabled]=\"vm.authorSaveInProgress\" />\n }\n </div>\n </rtsee-form>\n }\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 7. NanoBanana Illustrator Overlay -->\n <rtsee-illustrator [illustrator]=\"illustrator\" />\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: FormComponent, selector: "rtsee-form", inputs: ["form"], outputs: ["formSubmit"] }, { kind: "component", type: ManageSlideComponent, selector: "rtsee-manage-slide", inputs: ["manageSlide"] }, { kind: "component", type: StoryElementsSectionComponent, selector: "rtsee-story-elements-section", inputs: ["editor", "title", "icon", "collapsed", "canDetach", "illustrator"], outputs: ["toggled"] }, { kind: "component", type: IllustratorComponent, selector: "rtsee-illustrator", inputs: ["illustrator"] }] }); }
|
|
4284
4377
|
}
|
|
4285
4378
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InteractiveStoryEditorComponent, decorators: [{
|
|
4286
4379
|
type: Component,
|
|
@@ -4291,8 +4384,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
4291
4384
|
ManageSlideComponent,
|
|
4292
4385
|
StoryElementsSectionComponent,
|
|
4293
4386
|
IllustratorComponent,
|
|
4294
|
-
], template: "<div class=\"rtsee-interactive-story-editor\" [style.padding-bottom]=\"illustrator.expanded ? '460px' : '72px'\">\n @if (vm.initInProgress) {\n <div class=\"rtsee-ise-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading story\u2026</span>\n </div>\n } @else if (vm.initError) {\n <div class=\"rtsee-ise-error\">{{ vm.initError }}</div>\n } @else if (vm.story) {\n <header class=\"rtsee-ise-header\">\n <span class=\"rtsee-ise-eyebrow\">{{ vm.isNewStory ? 'New story' : 'Story editor' }}</span>\n <h2 class=\"rtsee-ise-heading\">{{ vm.story.name || 'Untitled story' }}</h2>\n </header>\n\n <!-- 1. Details -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.details) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-details\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.details)\"\n (click)=\"vm.toggleSection(sections.details)\">\n <i class=\"rtsee-ise-section-icon pi pi-book\"></i>\n <h3 class=\"rtsee-ise-section-title\">Story details</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.details)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-details-card\" id=\"rtsee-ise-details-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.detailsExpanded }\"\n (click)=\"vm.toggleDetails()\">\n <div class=\"rtsee-ise-details-image\">\n @if (vm.story.imageUrl) {\n <img [src]=\"vm.story.imageUrl\" [alt]=\"vm.story.name\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n </div>\n <div class=\"rtsee-ise-details-body\">\n <span class=\"rtsee-ise-details-name\">{{ vm.story.name || 'Untitled story' }}</span>\n <p class=\"rtsee-ise-details-description\">{{ vm.story.getTruncatedDescription(220) || 'No description yet' }}</p>\n @if (vm.story.tags.length) {\n <div class=\"rtsee-ise-chips\">\n @for (tag of vm.story.tags; track tag.id) {\n <span class=\"rtsee-ise-chip\">{{ tag.name }}</span>\n }\n </div>\n }\n </div>\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.detailsExpanded && vm.detailsForm) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.detailsError) {\n <div class=\"rtsee-ise-error\">{{ vm.detailsError }}</div>\n }\n <rtsee-form [form]=\"vm.detailsForm\" (formSubmit)=\"submitDetails()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" [label]=\"vm.isNewStory ? 'Create story' : 'Save'\"\n [loading]=\"vm.detailsSaveInProgress\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n <p-button label=\"Cancel\" severity=\"secondary\"\n (click)=\"vm.collapseDetails()\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 2-4. Characters, artifacts, locations -->\n <rtsee-story-elements-section [editor]=\"vm.charactersEditor\"\n title=\"Characters\"\n icon=\"pi pi-user\"\n [collapsed]=\"vm.isCollapsed(sections.characters)\"\n (toggled)=\"vm.toggleSection(sections.characters)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.artifactsEditor\"\n title=\"Artifacts\"\n icon=\"pi pi-star\"\n [collapsed]=\"vm.isCollapsed(sections.artifacts)\"\n (toggled)=\"vm.toggleSection(sections.artifacts)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.locationsEditor\"\n title=\"Locations\"\n icon=\"pi pi-map-marker\"\n [collapsed]=\"vm.isCollapsed(sections.locations)\"\n (toggled)=\"vm.toggleSection(sections.locations)\" />\n\n <!-- 5. Slides -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.slides) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-slides\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.slides)\"\n (click)=\"vm.toggleSection(sections.slides)\">\n <i class=\"rtsee-ise-section-icon pi pi-images\"></i>\n <h3 class=\"rtsee-ise-section-title\">Slides</h3>\n <span class=\"rtsee-ise-section-count\">{{ vm.slides.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.slides)) {\n <div class=\"rtsee-ise-section-body\">\n @if (vm.isNewStory) {\n <p class=\"rtsee-ise-hint\">Save the story details first to add slides.</p>\n } @else {\n <div class=\"rtsee-ise-slides-strip\">\n @for (slide of vm.slides; track trackSlide($index, slide)) {\n <div class=\"rtsee-ise-slide-thumb-wrapper\" style=\"position: relative; display: inline-flex;\">\n <button type=\"button\" class=\"rtsee-ise-slide-thumb\"\n [id]=\"'rtsee-ise-slide-' + slide.id\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.isSlideExpanded(slide) }\"\n [attr.aria-label]=\"'Slide ' + slide.slideNumber\"\n (click)=\"vm.expandSlide(slide)\">\n @if (slide.imageUrl) {\n <img [src]=\"slide.imageUrl\" [alt]=\"slide.name\" loading=\"lazy\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n <span class=\"rtsee-ise-slide-number\">{{ slide.slideNumber }}</span>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator rtsee-ise-btn-add-context\"\n style=\"position: absolute; top: 4px; left: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} context (characters, locations, artifacts) to Illustrator\"\n (click)=\"addSlideEntitiesToContext($event, slide)\">\n <i class=\"pi pi-plus\"></i>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 4px; right: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} to Illustrator context\"\n (click)=\"addSlideToContext($event, slide)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n </div>\n }\n <button type=\"button\" class=\"rtsee-ise-slide-thumb rtsee-ise-slide-thumb--add\"\n id=\"rtsee-ise-add-slide\"\n [disabled]=\"vm.slidesLoadInProgress\"\n (click)=\"vm.expandNewSlide()\">\n <i class=\"pi pi-plus\"></i>\n </button>\n </div>\n\n @if (vm.activeSlide) {\n <div class=\"rtsee-ise-expanded\">\n <rtsee-manage-slide [manageSlide]=\"vm.activeSlide\" />\n </div>\n }\n }\n </div>\n }\n </section>\n\n <!-- 6. Author -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.author) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-author\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.author)\"\n (click)=\"vm.toggleSection(sections.author)\">\n <i class=\"rtsee-ise-section-icon pi pi-pen-to-square\"></i>\n <h3 class=\"rtsee-ise-section-title\">Author</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.author)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-author-card\" id=\"rtsee-ise-author-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.authorExpanded }\"\n (click)=\"vm.toggleAuthor()\">\n <div class=\"rtsee-ise-avatar\">\n @if (vm.author?.imageUrl) {\n <img [src]=\"vm.author?.imageUrl\" [alt]=\"vm.author?.name\" />\n } @else {\n <i class=\"pi pi-user\"></i>\n }\n </div>\n <div class=\"rtsee-ise-author-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ vm.author?.name || 'No author assigned' }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ vm.author?.description || 'Click to pick or create an author' }}</span>\n </div>\n @if (vm.author) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add Author to Illustrator context\"\n (click)=\"addAuthorToContext($event)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n }\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.authorExpanded) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.authorError) {\n <div class=\"rtsee-ise-error\">{{ vm.authorError }}</div>\n }\n\n @if (vm.newAuthor && vm.newAuthorForm) {\n <h4 class=\"rtsee-ise-subheading\">New author</h4>\n <rtsee-form [form]=\"vm.newAuthorForm\" (formSubmit)=\"submitNewAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Create & assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"Back\" severity=\"secondary\"\n (click)=\"vm.cancelNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n </div>\n </rtsee-form>\n } @else if (vm.authorForm) {\n <rtsee-form [form]=\"vm.authorForm\" (formSubmit)=\"submitAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"New author\" icon=\"pi pi-plus\" severity=\"secondary\"\n (click)=\"vm.startNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n @if (vm.author) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n <p-button label=\"Clear\" icon=\"pi pi-times\" severity=\"danger\" [text]=\"true\"\n (click)=\"vm.assignAuthor(null)\"\n [disabled]=\"vm.authorSaveInProgress\" />\n }\n </div>\n </rtsee-form>\n }\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 7. NanoBanana Illustrator Overlay -->\n <rtsee-illustrator [illustrator]=\"illustrator\" />\n }\n</div>\n" }]
|
|
4295
|
-
}], propDecorators: { vm: [{
|
|
4387
|
+
], template: "<div class=\"rtsee-interactive-story-editor\" [style.padding-bottom]=\"illustrator.expanded ? '460px' : '72px'\">\n @if (vm.initInProgress) {\n <div class=\"rtsee-ise-loading\">\n <i class=\"pi pi-spin pi-spinner\"></i>\n <span>Loading story\u2026</span>\n </div>\n } @else if (vm.initError) {\n <div class=\"rtsee-ise-error\">{{ vm.initError }}</div>\n } @else if (vm.story) {\n <header class=\"rtsee-ise-header\">\n <span class=\"rtsee-ise-eyebrow\">{{ vm.isNewStory ? 'New story' : 'Story editor' }}</span>\n <h2 class=\"rtsee-ise-heading\">{{ vm.story.name || 'Untitled story' }}</h2>\n </header>\n\n <!-- 1. Details -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.details) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-details\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.details)\"\n (click)=\"vm.toggleSection(sections.details)\">\n <i class=\"rtsee-ise-section-icon pi pi-book\"></i>\n <h3 class=\"rtsee-ise-section-title\">Story details</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.details)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-details-card\" id=\"rtsee-ise-details-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.detailsExpanded }\"\n (click)=\"vm.toggleDetails()\">\n <div class=\"rtsee-ise-details-image\">\n @if (vm.story.imageUrl) {\n <img [src]=\"vm.story.imageUrl\" [alt]=\"vm.story.name\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n </div>\n <div class=\"rtsee-ise-details-body\">\n <span class=\"rtsee-ise-details-name\">{{ vm.story.name || 'Untitled story' }}</span>\n <p class=\"rtsee-ise-details-description\">{{ vm.story.getTruncatedDescription(220) || 'No description yet' }}</p>\n @if (vm.story.tags.length) {\n <div class=\"rtsee-ise-chips\">\n @for (tag of vm.story.tags; track tag.id) {\n <span class=\"rtsee-ise-chip\">{{ tag.name }}</span>\n }\n </div>\n }\n </div>\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.detailsExpanded && vm.detailsForm) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.detailsError) {\n <div class=\"rtsee-ise-error\">{{ vm.detailsError }}</div>\n }\n <rtsee-form [form]=\"vm.detailsForm\" (formSubmit)=\"submitDetails()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" [label]=\"vm.isNewStory ? 'Create story' : 'Save'\"\n [loading]=\"vm.detailsSaveInProgress\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n <p-button label=\"Cancel\" severity=\"secondary\"\n (click)=\"vm.collapseDetails()\"\n [disabled]=\"vm.detailsSaveInProgress\" />\n </div>\n </rtsee-form>\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 2-4. Characters, artifacts, locations -->\n <rtsee-story-elements-section [editor]=\"vm.charactersEditor\"\n title=\"Characters\"\n icon=\"pi pi-user\"\n [illustrator]=\"illustrator\"\n [collapsed]=\"vm.isCollapsed(sections.characters)\"\n (toggled)=\"vm.toggleSection(sections.characters)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.artifactsEditor\"\n title=\"Artifacts\"\n icon=\"pi pi-star\"\n [illustrator]=\"illustrator\"\n [collapsed]=\"vm.isCollapsed(sections.artifacts)\"\n (toggled)=\"vm.toggleSection(sections.artifacts)\" />\n\n <rtsee-story-elements-section [editor]=\"vm.locationsEditor\"\n title=\"Locations\"\n icon=\"pi pi-map-marker\"\n [illustrator]=\"illustrator\"\n [collapsed]=\"vm.isCollapsed(sections.locations)\"\n (toggled)=\"vm.toggleSection(sections.locations)\" />\n\n <!-- 5. Slides -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.slides) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-slides\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.slides)\"\n (click)=\"vm.toggleSection(sections.slides)\">\n <i class=\"rtsee-ise-section-icon pi pi-images\"></i>\n <h3 class=\"rtsee-ise-section-title\">Slides</h3>\n <span class=\"rtsee-ise-section-count\">{{ vm.slides.length }}</span>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.slides)) {\n <div class=\"rtsee-ise-section-body\">\n @if (vm.isNewStory) {\n <p class=\"rtsee-ise-hint\">Save the story details first to add slides.</p>\n } @else {\n <div class=\"rtsee-ise-slides-strip\">\n @for (slide of vm.slides; track trackSlide($index, slide)) {\n <div class=\"rtsee-ise-slide-thumb-wrapper\" style=\"position: relative; display: inline-flex;\">\n <button type=\"button\" class=\"rtsee-ise-slide-thumb\"\n [id]=\"'rtsee-ise-slide-' + slide.id\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.isSlideExpanded(slide) }\"\n [attr.aria-label]=\"'Slide ' + slide.slideNumber\"\n (click)=\"vm.expandSlide(slide)\">\n @if (slide.imageUrl) {\n <img [src]=\"slide.imageUrl\" [alt]=\"slide.name\" loading=\"lazy\" />\n } @else {\n <i class=\"pi pi-image\"></i>\n }\n <span class=\"rtsee-ise-slide-number\">{{ slide.slideNumber }}</span>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator rtsee-ise-btn-add-context\"\n style=\"position: absolute; top: 4px; left: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} context (characters, locations, artifacts) to Illustrator\"\n (click)=\"addSlideEntitiesToContext($event, slide)\">\n <i class=\"pi pi-plus\"></i>\n </button>\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n style=\"position: absolute; top: 4px; right: 4px;\"\n title=\"Add Slide {{ slide.slideNumber }} to Illustrator context\"\n (click)=\"addSlideToContext($event, slide)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n @if (illustrator.reviewingGeneratedImage && illustrator.currentGeneratedImageUrl) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-quick-apply\"\n style=\"position: absolute; bottom: 4px; right: 4px;\"\n [disabled]=\"isSlideUpdating(slide.id)\"\n [title]=\"'Apply reviewed image to Slide ' + slide.slideNumber\"\n (click)=\"applyReviewedImageToSlide($event, slide)\">\n @if (isSlideUpdating(slide.id)) {\n <i class=\"pi pi-spin pi-spinner\"></i>\n } @else {\n <i class=\"pi pi-plus\"></i>\n }\n </button>\n }\n </div>\n }\n <button type=\"button\" class=\"rtsee-ise-slide-thumb rtsee-ise-slide-thumb--add\"\n id=\"rtsee-ise-add-slide\"\n [disabled]=\"vm.slidesLoadInProgress\"\n (click)=\"vm.expandNewSlide()\">\n <i class=\"pi pi-plus\"></i>\n </button>\n </div>\n\n @if (vm.activeSlide) {\n <div class=\"rtsee-ise-expanded\">\n <rtsee-manage-slide [manageSlide]=\"vm.activeSlide\" />\n </div>\n }\n }\n </div>\n }\n </section>\n\n <!-- 6. Author -->\n <section class=\"rtsee-ise-section\" [ngClass]=\"{ 'rtsee-ise-section--collapsed': vm.isCollapsed(sections.author) }\">\n <header class=\"rtsee-ise-section-header\">\n <button type=\"button\" class=\"rtsee-ise-section-toggle\" id=\"rtsee-ise-toggle-author\"\n [attr.aria-expanded]=\"!vm.isCollapsed(sections.author)\"\n (click)=\"vm.toggleSection(sections.author)\">\n <i class=\"rtsee-ise-section-icon pi pi-pen-to-square\"></i>\n <h3 class=\"rtsee-ise-section-title\">Author</h3>\n <i class=\"pi pi-chevron-down rtsee-ise-chevron\"></i>\n </button>\n </header>\n\n @if (!vm.isCollapsed(sections.author)) {\n <div class=\"rtsee-ise-section-body\">\n <button type=\"button\" class=\"rtsee-ise-author-card\" id=\"rtsee-ise-author-card\"\n [ngClass]=\"{ 'rtsee-ise-thumb--active': vm.authorExpanded }\"\n (click)=\"vm.toggleAuthor()\">\n <div class=\"rtsee-ise-avatar\">\n @if (vm.author?.imageUrl) {\n <img [src]=\"vm.author?.imageUrl\" [alt]=\"vm.author?.name\" />\n } @else {\n <i class=\"pi pi-user\"></i>\n }\n </div>\n <div class=\"rtsee-ise-author-body\">\n <span class=\"rtsee-ise-thumb-name\">{{ vm.author?.name || 'No author assigned' }}</span>\n <span class=\"rtsee-ise-thumb-description\">{{ vm.author?.description || 'Click to pick or create an author' }}</span>\n </div>\n @if (vm.author) {\n <button type=\"button\"\n class=\"rtsee-ise-btn-add-illustrator\"\n title=\"Add Author to Illustrator context\"\n (click)=\"addAuthorToContext($event)\">\n <i class=\"pi pi-palette\"></i>\n <span>+\uD83C\uDFA8</span>\n </button>\n }\n <i class=\"pi pi-pencil rtsee-ise-details-edit\"></i>\n </button>\n\n @if (vm.authorExpanded) {\n <div class=\"rtsee-ise-expanded rtsee-form-container\">\n @if (vm.authorError) {\n <div class=\"rtsee-ise-error\">{{ vm.authorError }}</div>\n }\n\n @if (vm.newAuthor && vm.newAuthorForm) {\n <h4 class=\"rtsee-ise-subheading\">New author</h4>\n <rtsee-form [form]=\"vm.newAuthorForm\" (formSubmit)=\"submitNewAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Create & assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"Back\" severity=\"secondary\"\n (click)=\"vm.cancelNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n </div>\n </rtsee-form>\n } @else if (vm.authorForm) {\n <rtsee-form [form]=\"vm.authorForm\" (formSubmit)=\"submitAuthor()\">\n <div class=\"rtsee-ise-actions\">\n <p-button type=\"submit\" label=\"Assign\"\n [loading]=\"vm.authorSaveInProgress\"\n [disabled]=\"vm.authorSaveInProgress\" />\n <p-button label=\"New author\" icon=\"pi pi-plus\" severity=\"secondary\"\n (click)=\"vm.startNewAuthor()\"\n [disabled]=\"vm.authorSaveInProgress\" />\n @if (vm.author) {\n <span class=\"rtsee-ise-actions-spacer\"></span>\n <p-button label=\"Clear\" icon=\"pi pi-times\" severity=\"danger\" [text]=\"true\"\n (click)=\"vm.assignAuthor(null)\"\n [disabled]=\"vm.authorSaveInProgress\" />\n }\n </div>\n </rtsee-form>\n }\n </div>\n }\n </div>\n }\n </section>\n\n <!-- 7. NanoBanana Illustrator Overlay -->\n <rtsee-illustrator [illustrator]=\"illustrator\" />\n }\n</div>\n" }]
|
|
4388
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { vm: [{
|
|
4296
4389
|
type: Input,
|
|
4297
4390
|
args: [{ required: true }]
|
|
4298
4391
|
}], autoInit: [{
|