@vishu1301/script-writing 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +335 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +336 -126
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -74,12 +74,12 @@ var blockTypes = [
|
|
|
74
74
|
];
|
|
75
75
|
var uuid = () => Math.random().toString(36).slice(2, 9);
|
|
76
76
|
var icons = {
|
|
77
|
-
SCENE_HEADING: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
78
|
-
ACTION: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
79
|
-
CHARACTER: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
80
|
-
PARENTHETICAL: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
81
|
-
DIALOGUE: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
82
|
-
TRANSITION: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
77
|
+
SCENE_HEADING: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Type, { className: "w-5 h-5" }),
|
|
78
|
+
ACTION: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlignLeft, { className: "w-5 h-5" }),
|
|
79
|
+
CHARACTER: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-5 h-5" }),
|
|
80
|
+
PARENTHETICAL: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Parentheses, { className: "w-5 h-5" }),
|
|
81
|
+
DIALOGUE: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareText, { className: "w-5 h-5" }),
|
|
82
|
+
TRANSITION: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CornerDownRight, { className: "w-5 h-5" })
|
|
83
83
|
};
|
|
84
84
|
var blockStyles = {
|
|
85
85
|
SCENE_HEADING: {
|
|
@@ -346,9 +346,18 @@ function ScreenplayEditorView({
|
|
|
346
346
|
handleScriptImport,
|
|
347
347
|
onSave,
|
|
348
348
|
onSaveAsPdf,
|
|
349
|
-
onSaveAsSbx,
|
|
350
349
|
onSyncWithCloud,
|
|
351
|
-
handleSceneNumberChange
|
|
350
|
+
handleSceneNumberChange,
|
|
351
|
+
handleEnhance,
|
|
352
|
+
handleApproveEnhance,
|
|
353
|
+
handleRejectEnhance,
|
|
354
|
+
enhancingBlockId,
|
|
355
|
+
enhancementSuggestion,
|
|
356
|
+
isEnhancing,
|
|
357
|
+
showUnsavedPopover,
|
|
358
|
+
syncScreenplay,
|
|
359
|
+
ignoreChanges,
|
|
360
|
+
isLoading = false
|
|
352
361
|
}) {
|
|
353
362
|
const [isRulesOpen, setIsRulesOpen] = react.useState(false);
|
|
354
363
|
const rulesRef = react.useRef(null);
|
|
@@ -392,9 +401,15 @@ function ScreenplayEditorView({
|
|
|
392
401
|
document.head.appendChild(style);
|
|
393
402
|
}
|
|
394
403
|
}, [COURIER_STACK]);
|
|
404
|
+
if (isLoading) {
|
|
405
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-[100] flex items-center justify-center bg-white/80 transition-opacity", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-3", children: [
|
|
406
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-8 h-8 text-zinc-400 animate-spin" }),
|
|
407
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-zinc-500 text-sm font-medium", children: "Loading script..." })
|
|
408
|
+
] }) });
|
|
409
|
+
}
|
|
395
410
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
396
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-2 sm:top-6 z-50 mx-auto w-full max-w-
|
|
397
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center
|
|
411
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-2 sm:top-6 z-50 mx-auto w-full max-w-full rounded-[2.5rem] sm:rounded-[2rem] bg-gradient-to-b from-white/90 to-white/70 border border-white/60 shadow-[0_14px_34px_rgba(16,37,54,0.06),0_2px_8px_rgba(16,37,54,0.03)] backdrop-blur-xl flex items-center justify-between px-2 py-1.5 sm:px-3 sm:py-2 mb-6 sm:mb-12 select-none transition-all", children: [
|
|
412
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 overflow-x-auto pr-2 flex-1 no-scrollbar rounded-full p-1 bg-gradient-to-b from-white/80 to-blumine-50 border border-blumine-200 shadow-inner", children: blockTypes.map((type) => {
|
|
398
413
|
var _a;
|
|
399
414
|
const selected = ((_a = blocks.find((b) => b.id === focusedBlockId)) == null ? void 0 : _a.type) === type;
|
|
400
415
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -402,67 +417,37 @@ function ScreenplayEditorView({
|
|
|
402
417
|
{
|
|
403
418
|
type: "button",
|
|
404
419
|
disabled: isLocked,
|
|
405
|
-
className: `group flex shrink-0 items-center gap-2 sm:gap-2.5 px-3 py-1.5 sm:px-4 sm:py-2 rounded-full font-semibold text-xs sm:text-sm transition-all duration-300 ease-out active:scale-95 ${selected ? "bg-zinc-900 text-white shadow-md shadow-zinc-900/20" : "text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900"} ${isLocked ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
406
420
|
onClick: () => handleBlockTypeChange(type),
|
|
421
|
+
className: `group flex shrink-0 items-center gap-2 px-3 sm:px-4 h-[40px] sm:h-[42px] rounded-full font-medium text-xs sm:text-sm transition-all duration-200 ease-out active:scale-95 whitespace-nowrap ${selected ? "bg-gradient-to-b from-white to-blumine-100 text-blumine-500 shadow-[0_6px_14px_rgba(24,88,122,0.15)] border border-blumine-200" : "text-blumine-500 hover:bg-white"} ${isLocked ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
407
422
|
children: [
|
|
408
423
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
409
|
-
"
|
|
424
|
+
"div",
|
|
410
425
|
{
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
id: `block-type-${type}`,
|
|
414
|
-
className: "sr-only",
|
|
415
|
-
"aria-label": blockStyles[type].label,
|
|
416
|
-
checked: selected,
|
|
417
|
-
readOnly: true
|
|
426
|
+
className: `flex items-center justify-center transition-opacity duration-200 ${selected ? "opacity-100" : "opacity-70 group-hover:opacity-100"}`,
|
|
427
|
+
children: icons[type]
|
|
418
428
|
}
|
|
419
429
|
),
|
|
420
|
-
/* @__PURE__ */ jsxRuntime.
|
|
421
|
-
"label",
|
|
422
|
-
{
|
|
423
|
-
htmlFor: `block-type-${type}`,
|
|
424
|
-
className: "flex items-center gap-2 cursor-pointer pointer-events-none",
|
|
425
|
-
children: [
|
|
426
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
427
|
-
"div",
|
|
428
|
-
{
|
|
429
|
-
className: `${selected ? "opacity-100" : "opacity-70 group-hover:opacity-100"} transition-opacity duration-200 flex items-center justify-center`,
|
|
430
|
-
children: icons[type]
|
|
431
|
-
}
|
|
432
|
-
),
|
|
433
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap hidden lg:inline tracking-wide", children: blockStyles[type].label })
|
|
434
|
-
]
|
|
435
|
-
}
|
|
436
|
-
)
|
|
430
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden lg:inline tracking-wide", children: blockStyles[type].label })
|
|
437
431
|
]
|
|
438
432
|
},
|
|
439
433
|
type
|
|
440
434
|
);
|
|
441
435
|
}) }),
|
|
442
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
443
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[1px] h-6 bg-
|
|
436
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 shrink-0 ml-2 sm:ml-0 pl-2 sm:pl-1 border-l sm:border-none border-blumine-200/70", children: [
|
|
437
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block w-[1px] h-6 bg-blumine-200 rounded-full mx-1" }),
|
|
444
438
|
showPdfImport && !isLocked && /* @__PURE__ */ jsxRuntime.jsx(
|
|
445
439
|
PdfImporter,
|
|
446
440
|
{
|
|
447
441
|
disabled: isLocked,
|
|
448
442
|
onScriptImported: handleScriptImport,
|
|
449
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
450
|
-
"div",
|
|
451
|
-
{
|
|
452
|
-
title: "Import Script",
|
|
453
|
-
className: "flex items-center justify-center",
|
|
454
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" })
|
|
455
|
-
}
|
|
456
|
-
)
|
|
443
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center rounded-full text-blumine-500 hover:text-blumine-900 hover:bg-white/70 transition active:scale-95", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Upload, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" }) })
|
|
457
444
|
}
|
|
458
445
|
),
|
|
459
446
|
onToggleLock && /* @__PURE__ */ jsxRuntime.jsx(
|
|
460
447
|
"button",
|
|
461
448
|
{
|
|
462
449
|
onClick: onToggleLock,
|
|
463
|
-
className: `
|
|
464
|
-
title: isLocked ? "Unlock Script" : "Lock Script",
|
|
465
|
-
"aria-label": isLocked ? "Unlock Script" : "Lock Script",
|
|
450
|
+
className: `w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center rounded-full transition-all duration-200 active:scale-95 ${isLocked ? "text-rose-500 bg-rose-50/60" : "text-blumine-500 hover:text-blumine-900 hover:bg-white/70"}`,
|
|
466
451
|
children: isLocked ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Lock, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Unlock, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" })
|
|
467
452
|
}
|
|
468
453
|
),
|
|
@@ -470,9 +455,7 @@ function ScreenplayEditorView({
|
|
|
470
455
|
"button",
|
|
471
456
|
{
|
|
472
457
|
onClick: onSave,
|
|
473
|
-
className: "
|
|
474
|
-
title: "Save Script",
|
|
475
|
-
"aria-label": "Save Script",
|
|
458
|
+
className: "w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center rounded-full text-blumine-500 hover:text-blumine-900 hover:bg-white/70 transition active:scale-95",
|
|
476
459
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" })
|
|
477
460
|
}
|
|
478
461
|
),
|
|
@@ -480,9 +463,7 @@ function ScreenplayEditorView({
|
|
|
480
463
|
"button",
|
|
481
464
|
{
|
|
482
465
|
onClick: onSaveAsPdf,
|
|
483
|
-
className: "
|
|
484
|
-
title: "Save as PDF",
|
|
485
|
-
"aria-label": "Save Script as PDF",
|
|
466
|
+
className: "w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center rounded-full text-blumine-500 hover:text-blumine-900 hover:bg-white/70 transition active:scale-95",
|
|
486
467
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileDown, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" })
|
|
487
468
|
}
|
|
488
469
|
),
|
|
@@ -490,9 +471,7 @@ function ScreenplayEditorView({
|
|
|
490
471
|
"button",
|
|
491
472
|
{
|
|
492
473
|
onClick: onSyncWithCloud,
|
|
493
|
-
className: "
|
|
494
|
-
title: "Sync with Cloud",
|
|
495
|
-
"aria-label": "Sync with Cloud",
|
|
474
|
+
className: "w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center rounded-full text-blumine-500 hover:text-blumine-900 hover:bg-white/70 transition active:scale-95",
|
|
496
475
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcw, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" })
|
|
497
476
|
}
|
|
498
477
|
),
|
|
@@ -501,35 +480,65 @@ function ScreenplayEditorView({
|
|
|
501
480
|
"button",
|
|
502
481
|
{
|
|
503
482
|
onClick: () => setIsRulesOpen(!isRulesOpen),
|
|
504
|
-
className: `
|
|
505
|
-
title: "Settings & Shortcuts",
|
|
506
|
-
"aria-label": "Toggle Settings",
|
|
483
|
+
className: `w-9 h-9 sm:w-10 sm:h-10 flex items-center justify-center rounded-full transition-all duration-200 active:scale-95 ${isRulesOpen ? "bg-gradient-to-b from-white to-blumine-100 text-blumine-500 shadow-md border border-blumine-100" : "text-blumine-500 hover:text-blumine-900 hover:bg-white/70"}`,
|
|
507
484
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Cog, { className: "w-4 h-4 sm:w-[18px] sm:h-[18px]" })
|
|
508
485
|
}
|
|
509
486
|
),
|
|
510
|
-
isRulesOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute
|
|
511
|
-
/* @__PURE__ */ jsxRuntime.
|
|
512
|
-
|
|
513
|
-
"
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-zinc-600", children: "New Block" }),
|
|
518
|
-
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-[11px] font-bold text-zinc-700 bg-white border border-zinc-200/80 shadow-[0_2px_4px_rgb(0,0,0,0.02)] rounded-md", children: "Enter" })
|
|
519
|
-
] }),
|
|
520
|
-
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center justify-between gap-6", children: [
|
|
521
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-zinc-600", children: "Delete Block" }),
|
|
522
|
-
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-[11px] font-bold text-zinc-700 bg-white border border-zinc-200/80 shadow-[0_2px_4px_rgb(0,0,0,0.02)] rounded-md", children: "Backspace" })
|
|
523
|
-
] }),
|
|
524
|
-
/* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-center justify-between gap-6", children: [
|
|
525
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-zinc-600", children: "Change Type" }),
|
|
526
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
527
|
-
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-[11px] font-bold text-zinc-700 bg-white border border-zinc-200/80 shadow-[0_2px_4px_rgb(0,0,0,0.02)] rounded-md", children: "Ctrl" }),
|
|
528
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400 font-medium", children: "+" }),
|
|
529
|
-
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "px-2 py-1 text-[11px] font-bold text-zinc-700 bg-white border border-zinc-200/80 shadow-[0_2px_4px_rgb(0,0,0,0.02)] rounded-md", children: "\u2191/\u2193" })
|
|
530
|
-
] })
|
|
487
|
+
isRulesOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute -right-2 top-[calc(100%+14px)] w-[332px] max-w-[90vw] p-3 rounded-[24px] bg-white border border-blumine-200/70 shadow-[0_18px_40px_rgba(16,37,54,0.08),0_3px_10px_rgba(16,37,54,0.04)] backdrop-blur-xl origin-top-right animate-in fade-in zoom-in-95 z-50", children: [
|
|
488
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-2 right-5 w-4 h-4 rotate-45 bg-white border-l border-t border-blumine-200/70" }),
|
|
489
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between mb-3 px-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
|
|
490
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 flex items-center justify-center rounded-xl bg-gradient-to-b from-white to-blumine-50 text-blumine-500 border border-blumine-200/70 shadow-inner", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Cog, { className: "w-4 h-4" }) }),
|
|
491
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
492
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-[15px] font-semibold text-blumine-900 leading-tight", children: "Settings & Shortcuts" }),
|
|
493
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-blumine-500 mt-1", children: "Writing flow & editor controls" })
|
|
531
494
|
] })
|
|
532
|
-
] }) })
|
|
495
|
+
] }) }),
|
|
496
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: [
|
|
497
|
+
{
|
|
498
|
+
title: "New Block",
|
|
499
|
+
desc: "Insert the next section",
|
|
500
|
+
key: ["Enter"]
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
title: "Delete Block",
|
|
504
|
+
desc: "Remove selected section",
|
|
505
|
+
key: ["Backspace \u{1F860}"]
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
title: "Change Type",
|
|
509
|
+
desc: "Cycle block styles",
|
|
510
|
+
key: ["Ctrl", "+", "\u2191/\u2193"]
|
|
511
|
+
}
|
|
512
|
+
].map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
513
|
+
"div",
|
|
514
|
+
{
|
|
515
|
+
className: "flex items-center justify-between gap-4 p-3 rounded-[18px] bg-gradient-to-b from-white to-blumine-50/50 border border-blumine-200/60 shadow-[inset_0_1px_0_rgba(255,255,255,0.8)]",
|
|
516
|
+
children: [
|
|
517
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0", children: [
|
|
518
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-blumine-800", children: item.title }),
|
|
519
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-blumine-500 truncate", children: item.desc })
|
|
520
|
+
] }),
|
|
521
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0", children: item.key.map(
|
|
522
|
+
(k, i) => k === "+" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
523
|
+
"span",
|
|
524
|
+
{
|
|
525
|
+
className: "text-blumine-400 text-xs font-semibold",
|
|
526
|
+
children: "+"
|
|
527
|
+
},
|
|
528
|
+
i
|
|
529
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
530
|
+
"kbd",
|
|
531
|
+
{
|
|
532
|
+
className: "min-w-[28px] px-2 py-1 text-[11px] font-bold text-primary bg-gradient-to-b from-white to-blumine-100 border border-blumine-200/70 rounded-full text-center shadow-[inset_0_1px_0_rgba(255,255,255,0.9)]",
|
|
533
|
+
children: k
|
|
534
|
+
},
|
|
535
|
+
i
|
|
536
|
+
)
|
|
537
|
+
) })
|
|
538
|
+
]
|
|
539
|
+
},
|
|
540
|
+
item.title
|
|
541
|
+
)) })
|
|
533
542
|
] })
|
|
534
543
|
] })
|
|
535
544
|
] })
|
|
@@ -729,7 +738,7 @@ function ScreenplayEditorView({
|
|
|
729
738
|
handleBlur(block.id);
|
|
730
739
|
},
|
|
731
740
|
children: [
|
|
732
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-3.5 h-3.5 text-slate-300 group-hover:text-
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-3.5 h-3.5 text-slate-300 group-hover:text-blumine-500 transition-colors mr-3" }),
|
|
733
742
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: char }),
|
|
734
743
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "w-3 h-3 text-slate-200 opacity-0 group-hover:opacity-100 transition-all -translate-x-1 group-hover:translate-x-0" })
|
|
735
744
|
]
|
|
@@ -765,6 +774,64 @@ function ScreenplayEditorView({
|
|
|
765
774
|
ext
|
|
766
775
|
)) })
|
|
767
776
|
}
|
|
777
|
+
),
|
|
778
|
+
focusedBlockId === block.id && !enhancingBlockId && (block.type === "ACTION" || block.type === "DIALOGUE") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
779
|
+
"button",
|
|
780
|
+
{
|
|
781
|
+
onClick: () => handleEnhance(block),
|
|
782
|
+
className: "absolute -right-12 top-1/2 -translate-y-1/2 flex items-center justify-center w-8 h-8 rounded-xl border border-blumine-200/50 bg-white text-blumine-500 hover:border-blumine-400/60 hover:bg-blumine-50/90 hover:ring-2 hover:ring-blumine-100 hover:scale-105 active:scale-95 transition-all duration-200 group/enhance animate-in fade-in slide-in-from-left-2",
|
|
783
|
+
title: "Enhance with AI",
|
|
784
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "w-4 h-4 group-hover/enhance:animate-pulse transition-colors" })
|
|
785
|
+
}
|
|
786
|
+
),
|
|
787
|
+
enhancingBlockId === block.id && (enhancementSuggestion || isEnhancing) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
788
|
+
"div",
|
|
789
|
+
{
|
|
790
|
+
className: "absolute left-0 right-0 -top-4 -translate-y-full z-[30] animate-in fade-in zoom-in-95 slide-in-from-bottom-4 duration-300",
|
|
791
|
+
style: { width: "calc(100% + 2rem)", left: "-1rem" },
|
|
792
|
+
children: [
|
|
793
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full rounded-[2rem] bg-white border border-white/60 shadow-[0_14px_34px_rgba(16,37,54,0.1),0_2px_8px_rgba(16,37,54,0.05)] backdrop-blur-xl p-2 select-none transition-all", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
794
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between pl-1", children: [
|
|
795
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
796
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-9 h-9 flex items-center justify-center rounded-full bg-blumine-50 text-blumine-500 border border-blumine-100 shadow-inner", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "w-4 h-4" }) }),
|
|
797
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
798
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] font-bold text-zinc-900 uppercase tracking-wider leading-none", children: "AI Suggestion" }),
|
|
799
|
+
!isEnhancing && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-zinc-500 mt-1 font-medium", children: "Refining your screenplay dialogue" })
|
|
800
|
+
] })
|
|
801
|
+
] }),
|
|
802
|
+
!isEnhancing && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
803
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
804
|
+
"button",
|
|
805
|
+
{
|
|
806
|
+
onClick: handleRejectEnhance,
|
|
807
|
+
className: "px-3 py-2 rounded-full text-xs font-bold text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 transition-all active:scale-95",
|
|
808
|
+
children: "Discard"
|
|
809
|
+
}
|
|
810
|
+
),
|
|
811
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
812
|
+
"button",
|
|
813
|
+
{
|
|
814
|
+
onClick: handleApproveEnhance,
|
|
815
|
+
className: "px-4 py-2 rounded-full text-xs font-bold bg-blumine-500 text-white hover:bg-blumine-600 shadow-lg shadow-blumine-500/20 transition-all active:scale-95 flex items-center gap-1.5",
|
|
816
|
+
children: [
|
|
817
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-3.5 h-3.5" }),
|
|
818
|
+
"Apply Changes"
|
|
819
|
+
]
|
|
820
|
+
}
|
|
821
|
+
)
|
|
822
|
+
] })
|
|
823
|
+
] }),
|
|
824
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden rounded-[1.25rem] bg-zinc-50/50 border border-zinc-100 p-4 min-h-[4rem]", children: isEnhancing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2.5 py-1", children: [
|
|
825
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3.5 w-3/4 bg-zinc-200/60 animate-pulse rounded-full" }),
|
|
826
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-3.5 w-1/2 bg-zinc-200/60 animate-pulse rounded-full" })
|
|
827
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
828
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-zinc-400 line-through decoration-zinc-300 italic", children: block.text }),
|
|
829
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-zinc-800 font-medium leading-relaxed", children: enhancementSuggestion })
|
|
830
|
+
] }) })
|
|
831
|
+
] }) }),
|
|
832
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -bottom-1.5 left-1/2 -translate-x-1/2 w-3.5 h-3.5 bg-white border-r border-b border-zinc-200/50 rotate-45" })
|
|
833
|
+
]
|
|
834
|
+
}
|
|
768
835
|
)
|
|
769
836
|
] })
|
|
770
837
|
},
|
|
@@ -772,7 +839,43 @@ function ScreenplayEditorView({
|
|
|
772
839
|
);
|
|
773
840
|
})
|
|
774
841
|
}
|
|
775
|
-
) })
|
|
842
|
+
) }),
|
|
843
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
844
|
+
"div",
|
|
845
|
+
{
|
|
846
|
+
className: `sticky bottom-0 left-1/2 -translate-x-1/2 z-[100] transition-all duration-500 ease-in-out ${showUnsavedPopover ? "translate-y-0 opacity-100 scale-100" : "translate-y-full opacity-0 scale-95 pointer-events-none"}`,
|
|
847
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-full rounded-[2.5rem] bg-white border-white/60 shadow-[0_14px_34px_rgba(16,37,54,0.06),0_2px_8px_rgba(16,37,54,0.03)] backdrop-blur-xl flex items-center justify-between px-2 py-1.5 sm:px-3 sm:py-2 mb-6 sm:mb-12 select-none transition-all", children: [
|
|
848
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
849
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 flex items-center justify-center rounded-[2.5rem] bg-blumine-50 text-blumine-500 border border-blumine-100 shadow-inner", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { className: "w-5 h-5" }) }),
|
|
850
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mr-5", children: [
|
|
851
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold text-zinc-900 leading-none", children: "Unsaved Changes" }),
|
|
852
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-zinc-500 mt-1 font-medium", children: "You have changes that haven't been saved yet." })
|
|
853
|
+
] })
|
|
854
|
+
] }),
|
|
855
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 w-full sm:w-auto", children: [
|
|
856
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
857
|
+
"button",
|
|
858
|
+
{
|
|
859
|
+
onClick: ignoreChanges,
|
|
860
|
+
className: "flex-1 sm:flex-none px-4 py-2 rounded-[2.5rem] text-xs font-bold text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900 transition-all active:scale-95 whitespace-nowrap",
|
|
861
|
+
children: "Ignore"
|
|
862
|
+
}
|
|
863
|
+
),
|
|
864
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
865
|
+
"button",
|
|
866
|
+
{
|
|
867
|
+
onClick: syncScreenplay,
|
|
868
|
+
className: "flex-1 sm:flex-none px-5 py-2 rounded-[2.5rem] text-xs font-bold bg-blumine-500 text-white hover:bg-blumine-600 shadow-lg shadow-blumine-500/25 transition-all active:scale-95 flex items-center justify-center gap-2 whitespace-nowrap",
|
|
869
|
+
children: [
|
|
870
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCcw, { className: "w-4 h-4" }),
|
|
871
|
+
"Sync to Cloud"
|
|
872
|
+
]
|
|
873
|
+
}
|
|
874
|
+
)
|
|
875
|
+
] })
|
|
876
|
+
] })
|
|
877
|
+
}
|
|
878
|
+
)
|
|
776
879
|
] });
|
|
777
880
|
}
|
|
778
881
|
|
|
@@ -980,6 +1083,31 @@ function parseScreenplayText(content) {
|
|
|
980
1083
|
}
|
|
981
1084
|
return blocks.length > 0 ? blocks : [createNewBlock("SCENE_HEADING")];
|
|
982
1085
|
}
|
|
1086
|
+
function serializeToSbx(blocks) {
|
|
1087
|
+
const typeToDivClass = {
|
|
1088
|
+
SCENE_HEADING: "divtype0",
|
|
1089
|
+
ACTION: "divtype2",
|
|
1090
|
+
CHARACTER: "divtype3",
|
|
1091
|
+
PARENTHETICAL: "divtype4",
|
|
1092
|
+
DIALOGUE: "divtype5",
|
|
1093
|
+
TRANSITION: "divtype6",
|
|
1094
|
+
GENERAL: "divtype2"
|
|
1095
|
+
};
|
|
1096
|
+
return blocks.map((block) => {
|
|
1097
|
+
const divClass = typeToDivClass[block.type] || "divtype2";
|
|
1098
|
+
let text = block.text || "";
|
|
1099
|
+
let extraAttributes = "";
|
|
1100
|
+
if (block.type === "SCENE_HEADING") {
|
|
1101
|
+
text = `${block.sceneType || "INT."} ${text} - ${block.timeOfDay || "DAY"}`.toUpperCase();
|
|
1102
|
+
if (block.sceneNumber) {
|
|
1103
|
+
extraAttributes = ` data-scene="${block.sceneNumber}"`;
|
|
1104
|
+
}
|
|
1105
|
+
} else if (block.type === "CHARACTER" || block.type === "TRANSITION") {
|
|
1106
|
+
text = text.toUpperCase();
|
|
1107
|
+
}
|
|
1108
|
+
return `<div class="${divClass}" id="par${block.id}"${extraAttributes}>${text}</div>`;
|
|
1109
|
+
}).join("");
|
|
1110
|
+
}
|
|
983
1111
|
|
|
984
1112
|
// app/hook/use-screenplay-editor.ts
|
|
985
1113
|
var initialBlocks = [
|
|
@@ -1048,13 +1176,23 @@ function useScreenplayEditor(options) {
|
|
|
1048
1176
|
const [newBlockId, setNewBlockId] = react.useState(null);
|
|
1049
1177
|
const [showSuggestions, setShowSuggestions] = react.useState(false);
|
|
1050
1178
|
const [showExtensionSuggestions, setShowExtensionSuggestions] = react.useState(false);
|
|
1179
|
+
const [isLoading, setIsLoading] = react.useState(!!(options == null ? void 0 : options.initialUrl));
|
|
1180
|
+
const [enhancingBlockId, setEnhancingBlockId] = react.useState(null);
|
|
1181
|
+
const [enhancementSuggestion, setEnhancementSuggestion] = react.useState(null);
|
|
1182
|
+
const [isEnhancing, setIsEnhancing] = react.useState(false);
|
|
1183
|
+
const [hasUnsavedChanges, setHasUnsavedChanges] = react.useState(false);
|
|
1184
|
+
const [showUnsavedPopover, setShowUnsavedPopover] = react.useState(false);
|
|
1185
|
+
const popoverTimeoutRef = react.useRef(null);
|
|
1051
1186
|
const blurTimeout = react.useRef(null);
|
|
1187
|
+
const isInitialLoadRef = react.useRef(true);
|
|
1052
1188
|
const loadedUrlRef = react.useRef(null);
|
|
1053
1189
|
const lastSavedContent = react.useRef(null);
|
|
1054
1190
|
const onSaveRef = react.useRef(options == null ? void 0 : options.onSave);
|
|
1191
|
+
const onSyncWithCloudRef = react.useRef(options == null ? void 0 : options.onSyncWithCloud);
|
|
1055
1192
|
react.useEffect(() => {
|
|
1056
1193
|
onSaveRef.current = options == null ? void 0 : options.onSave;
|
|
1057
|
-
|
|
1194
|
+
onSyncWithCloudRef.current = options == null ? void 0 : options.onSyncWithCloud;
|
|
1195
|
+
}, [options == null ? void 0 : options.onSave, options == null ? void 0 : options.onSyncWithCloud]);
|
|
1058
1196
|
const characterExtensions = react.useMemo(
|
|
1059
1197
|
() => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
|
|
1060
1198
|
[]
|
|
@@ -1441,29 +1579,7 @@ function useScreenplayEditor(options) {
|
|
|
1441
1579
|
});
|
|
1442
1580
|
setBlocks(finalizedBlocks);
|
|
1443
1581
|
if (onSaveRef.current) {
|
|
1444
|
-
const
|
|
1445
|
-
SCENE_HEADING: "divtype0",
|
|
1446
|
-
ACTION: "divtype2",
|
|
1447
|
-
CHARACTER: "divtype3",
|
|
1448
|
-
PARENTHETICAL: "divtype4",
|
|
1449
|
-
DIALOGUE: "divtype5",
|
|
1450
|
-
TRANSITION: "divtype6",
|
|
1451
|
-
GENERAL: "divtype2"
|
|
1452
|
-
};
|
|
1453
|
-
const sbxData = finalizedBlocks.map((block) => {
|
|
1454
|
-
const divClass = typeToDivClass[block.type] || "divtype2";
|
|
1455
|
-
let text = block.text || "";
|
|
1456
|
-
let extraAttributes = "";
|
|
1457
|
-
if (block.type === "SCENE_HEADING") {
|
|
1458
|
-
text = `${block.sceneType || "INT."} ${text} - ${block.timeOfDay || "DAY"}`.toUpperCase();
|
|
1459
|
-
if (block.sceneNumber) {
|
|
1460
|
-
extraAttributes = ` data-scene="${block.sceneNumber}"`;
|
|
1461
|
-
}
|
|
1462
|
-
} else if (block.type === "CHARACTER" || block.type === "TRANSITION") {
|
|
1463
|
-
text = text.toUpperCase();
|
|
1464
|
-
}
|
|
1465
|
-
return `<div class="${divClass}" id="par${block.id}"${extraAttributes}>${text}</div>`;
|
|
1466
|
-
}).join("");
|
|
1582
|
+
const sbxData = serializeToSbx(finalizedBlocks);
|
|
1467
1583
|
if (sbxData !== lastSavedContent.current) {
|
|
1468
1584
|
lastSavedContent.current = sbxData;
|
|
1469
1585
|
if (!isInitialLoad) {
|
|
@@ -1516,9 +1632,22 @@ function useScreenplayEditor(options) {
|
|
|
1516
1632
|
setShowExtensionSuggestions(false);
|
|
1517
1633
|
}, 200);
|
|
1518
1634
|
}, []);
|
|
1635
|
+
const syncScreenplay = react.useCallback(() => {
|
|
1636
|
+
if (!onSyncWithCloudRef.current) return;
|
|
1637
|
+
onSyncWithCloudRef.current(blocks, sceneNumbers);
|
|
1638
|
+
lastSavedContent.current = serializeToSbx(blocks);
|
|
1639
|
+
setHasUnsavedChanges(false);
|
|
1640
|
+
setShowUnsavedPopover(false);
|
|
1641
|
+
if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
|
|
1642
|
+
}, [blocks, sceneNumbers]);
|
|
1643
|
+
const ignoreChanges = react.useCallback(() => {
|
|
1644
|
+
setShowUnsavedPopover(false);
|
|
1645
|
+
if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
|
|
1646
|
+
}, []);
|
|
1519
1647
|
const loadFromUrl = react.useCallback(
|
|
1520
1648
|
async (url, fetchOptions = {}, isInitialLoad) => {
|
|
1521
1649
|
var _a;
|
|
1650
|
+
setIsLoading(true);
|
|
1522
1651
|
try {
|
|
1523
1652
|
const response = await fetch(url, fetchOptions);
|
|
1524
1653
|
if (!response.ok) {
|
|
@@ -1595,16 +1724,42 @@ function useScreenplayEditor(options) {
|
|
|
1595
1724
|
preParsedBlocks,
|
|
1596
1725
|
isInitialLoad
|
|
1597
1726
|
);
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
"[useScreenplayEditor] Error loading script from URL:",
|
|
1601
|
-
error
|
|
1602
|
-
);
|
|
1603
|
-
throw error;
|
|
1727
|
+
} finally {
|
|
1728
|
+
setIsLoading(false);
|
|
1604
1729
|
}
|
|
1605
1730
|
},
|
|
1606
1731
|
[handleScriptImport]
|
|
1607
1732
|
);
|
|
1733
|
+
react.useEffect(() => {
|
|
1734
|
+
if (isLoading) {
|
|
1735
|
+
isInitialLoadRef.current = true;
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
const currentSbx = serializeToSbx(blocks);
|
|
1739
|
+
if (isInitialLoadRef.current) {
|
|
1740
|
+
if (lastSavedContent.current === null) {
|
|
1741
|
+
lastSavedContent.current = currentSbx;
|
|
1742
|
+
}
|
|
1743
|
+
isInitialLoadRef.current = false;
|
|
1744
|
+
return;
|
|
1745
|
+
}
|
|
1746
|
+
const hasActualChanges = lastSavedContent.current !== null && currentSbx !== lastSavedContent.current;
|
|
1747
|
+
if (hasActualChanges) {
|
|
1748
|
+
setHasUnsavedChanges(true);
|
|
1749
|
+
if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
|
|
1750
|
+
setShowUnsavedPopover(false);
|
|
1751
|
+
popoverTimeoutRef.current = setTimeout(() => {
|
|
1752
|
+
setShowUnsavedPopover(true);
|
|
1753
|
+
}, 1e3);
|
|
1754
|
+
} else {
|
|
1755
|
+
setHasUnsavedChanges(false);
|
|
1756
|
+
setShowUnsavedPopover(false);
|
|
1757
|
+
if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
|
|
1758
|
+
}
|
|
1759
|
+
return () => {
|
|
1760
|
+
if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
|
|
1761
|
+
};
|
|
1762
|
+
}, [blocks, isLoading]);
|
|
1608
1763
|
react.useEffect(() => {
|
|
1609
1764
|
if ((options == null ? void 0 : options.initialUrl) && options.initialUrl !== loadedUrlRef.current) {
|
|
1610
1765
|
loadedUrlRef.current = options.initialUrl;
|
|
@@ -1621,6 +1776,7 @@ function useScreenplayEditor(options) {
|
|
|
1621
1776
|
locations,
|
|
1622
1777
|
characters,
|
|
1623
1778
|
sceneNumbers,
|
|
1779
|
+
isLoading,
|
|
1624
1780
|
handleBlockTextChange,
|
|
1625
1781
|
handleSceneTypeChange,
|
|
1626
1782
|
handleTimeOfDayChange,
|
|
@@ -1631,6 +1787,61 @@ function useScreenplayEditor(options) {
|
|
|
1631
1787
|
handleSceneNumberChange,
|
|
1632
1788
|
handleFocus,
|
|
1633
1789
|
handleBlur,
|
|
1790
|
+
handleEnhance: async (block) => {
|
|
1791
|
+
if (isEnhancing || enhancingBlockId || !(options == null ? void 0 : options.enhanceContentUrl))
|
|
1792
|
+
return;
|
|
1793
|
+
setEnhancingBlockId(block.id);
|
|
1794
|
+
setIsEnhancing(true);
|
|
1795
|
+
setEnhancementSuggestion(null);
|
|
1796
|
+
try {
|
|
1797
|
+
const res = await fetch(options == null ? void 0 : options.enhanceContentUrl, {
|
|
1798
|
+
method: "POST",
|
|
1799
|
+
headers: {
|
|
1800
|
+
"Content-Type": "application/json"
|
|
1801
|
+
},
|
|
1802
|
+
body: JSON.stringify({
|
|
1803
|
+
mode: block.type.toLowerCase(),
|
|
1804
|
+
script: block.text,
|
|
1805
|
+
language: "English"
|
|
1806
|
+
})
|
|
1807
|
+
});
|
|
1808
|
+
const data = await res.json();
|
|
1809
|
+
const content = data.data;
|
|
1810
|
+
setEnhancementSuggestion(content);
|
|
1811
|
+
} catch (error) {
|
|
1812
|
+
console.error("Failed to enhance block:", error);
|
|
1813
|
+
if (error) {
|
|
1814
|
+
setIsEnhancing(false);
|
|
1815
|
+
}
|
|
1816
|
+
} finally {
|
|
1817
|
+
setIsEnhancing(false);
|
|
1818
|
+
}
|
|
1819
|
+
},
|
|
1820
|
+
handleApproveEnhance: () => {
|
|
1821
|
+
if (enhancingBlockId && enhancementSuggestion) {
|
|
1822
|
+
setBlocks(
|
|
1823
|
+
(bs) => updateBlock(
|
|
1824
|
+
bs,
|
|
1825
|
+
enhancingBlockId,
|
|
1826
|
+
"text",
|
|
1827
|
+
enhancementSuggestion
|
|
1828
|
+
)
|
|
1829
|
+
);
|
|
1830
|
+
}
|
|
1831
|
+
setEnhancingBlockId(null);
|
|
1832
|
+
setEnhancementSuggestion(null);
|
|
1833
|
+
},
|
|
1834
|
+
handleRejectEnhance: () => {
|
|
1835
|
+
setEnhancingBlockId(null);
|
|
1836
|
+
setEnhancementSuggestion(null);
|
|
1837
|
+
},
|
|
1838
|
+
enhancingBlockId,
|
|
1839
|
+
enhancementSuggestion,
|
|
1840
|
+
isEnhancing,
|
|
1841
|
+
hasUnsavedChanges,
|
|
1842
|
+
showUnsavedPopover,
|
|
1843
|
+
syncScreenplay,
|
|
1844
|
+
ignoreChanges,
|
|
1634
1845
|
loadFromUrl
|
|
1635
1846
|
};
|
|
1636
1847
|
}
|
|
@@ -4321,7 +4532,7 @@ function ShotBreakdownView({
|
|
|
4321
4532
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-slate-50 border border-slate-100 mb-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "h-4 w-4 text-slate-300" }) }),
|
|
4322
4533
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold text-slate-700", children: "No shots created" }),
|
|
4323
4534
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-slate-500 mt-1 max-w-[160px] leading-relaxed", children: "Highlight text in the screenplay to add your first shot." })
|
|
4324
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2.5 overflow-y-auto overflow-x-hidden pb-4 pr-2 custom-scrollbar", children: shots.map((shot) => {
|
|
4535
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full max-h-[calc(100vh-200px)] flex-col gap-2.5 overflow-y-auto overflow-x-hidden pb-4 pr-2 custom-scrollbar", children: shots.map((shot) => {
|
|
4325
4536
|
const isActive = toggledShotId === shot.id;
|
|
4326
4537
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4327
4538
|
"div",
|
|
@@ -4330,13 +4541,13 @@ function ShotBreakdownView({
|
|
|
4330
4541
|
var _a2;
|
|
4331
4542
|
return setToggledShotId(isActive ? null : (_a2 = shot.id) != null ? _a2 : null);
|
|
4332
4543
|
},
|
|
4333
|
-
className: `group relative cursor-pointer rounded-xl border transition-all duration-300 overflow-hidden ${isActive ? "border-slate-900 bg-slate-50 shadow-[0_6px_20px_rgba(0,0,0,0.06)]" : "border-slate-200 bg-white hover:border-slate-300 hover:shadow-[0_4px_14px_rgba(0,0,0,0.05)]"}`,
|
|
4544
|
+
className: `group relative flex-shrink-0 cursor-pointer rounded-xl border transition-all duration-300 overflow-hidden ${isActive ? "border-slate-900 bg-slate-50 shadow-[0_6px_20px_rgba(0,0,0,0.06)]" : "border-slate-200 bg-white hover:border-slate-300 hover:shadow-[0_4px_14px_rgba(0,0,0,0.05)]"}`,
|
|
4334
4545
|
children: [
|
|
4335
4546
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4336
4547
|
"div",
|
|
4337
4548
|
{
|
|
4338
4549
|
className: `absolute left-0 top-0 h-full w-[3px] transition-all duration-300
|
|
4339
|
-
|
|
4550
|
+
${isActive ? "bg-slate-900" : "bg-transparent group-hover:bg-slate-300"}`
|
|
4340
4551
|
}
|
|
4341
4552
|
),
|
|
4342
4553
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 px-4 py-3.5", children: [
|
|
@@ -4346,7 +4557,7 @@ function ShotBreakdownView({
|
|
|
4346
4557
|
"span",
|
|
4347
4558
|
{
|
|
4348
4559
|
className: `text-[11px] font-semibold tracking-wide uppercase
|
|
4349
|
-
|
|
4560
|
+
${isActive ? "text-slate-900" : "text-slate-500"}`,
|
|
4350
4561
|
children: [
|
|
4351
4562
|
"Shot ",
|
|
4352
4563
|
shot.shot_number
|
|
@@ -4358,7 +4569,7 @@ function ShotBreakdownView({
|
|
|
4358
4569
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4359
4570
|
"span",
|
|
4360
4571
|
{
|
|
4361
|
-
className: `rounded-md px-2 py-0.5 text-[
|
|
4572
|
+
className: `rounded-md px-2 py-0.5 text-[8px] font-bold uppercase tracking-wider ${isActive ? "bg-slate-900 text-white" : "bg-slate-100 text-slate-500 group-hover:bg-slate-200"}`,
|
|
4362
4573
|
children: shot.shot_type
|
|
4363
4574
|
}
|
|
4364
4575
|
)
|
|
@@ -4370,8 +4581,8 @@ function ShotBreakdownView({
|
|
|
4370
4581
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4371
4582
|
"div",
|
|
4372
4583
|
{
|
|
4373
|
-
className: `grid transition-all duration-300 ease-in-out ${isActive ? "grid-rows-[
|
|
4374
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-3 pb-
|
|
4584
|
+
className: `grid transition-all duration-300 ease-in-out ${isActive ? "grid-rows-[1fr] opacity-100 mt-2" : "grid-rows-[0fr] opacity-0"}`,
|
|
4585
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-3 pb-1 border-t border-slate-200/70 flex gap-2", children: [
|
|
4375
4586
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4376
4587
|
"button",
|
|
4377
4588
|
{
|
|
@@ -4730,9 +4941,8 @@ function useShotBreakdownScene(options) {
|
|
|
4730
4941
|
if (res && res.ok) {
|
|
4731
4942
|
const data = await res.json();
|
|
4732
4943
|
setIsSummarizing(false);
|
|
4733
|
-
console.log(data);
|
|
4734
4944
|
const newShots = [];
|
|
4735
|
-
data.data.forEach((aiShot) => {
|
|
4945
|
+
data.data[0].forEach((aiShot) => {
|
|
4736
4946
|
var _a2;
|
|
4737
4947
|
const newShot = {
|
|
4738
4948
|
id: aiShot.id || uuid(),
|
|
@@ -4770,7 +4980,7 @@ function useShotBreakdownScene(options) {
|
|
|
4770
4980
|
if (newShots.length > 0) {
|
|
4771
4981
|
setShots((prev) => [...prev, ...newShots]);
|
|
4772
4982
|
if (options.onShotsBulkAdded) {
|
|
4773
|
-
await options.onShotsBulkAdded(newShots);
|
|
4983
|
+
await options.onShotsBulkAdded(newShots, data.data[1]);
|
|
4774
4984
|
}
|
|
4775
4985
|
}
|
|
4776
4986
|
} else {
|