@vishu1301/script-writing 0.4.4 → 0.4.6

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.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
1
+ import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
2
2
  import { ArrowRightLeft, MessageCircle, Brackets, UserRound, Sparkles, Clapperboard, ArrowRight, User, ChevronRight, Upload, Save, FileDown, Cog } from 'lucide-react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import * as pdfjs from 'pdfjs-dist';
@@ -220,9 +220,6 @@ function PdfImporter({ onScriptImported, children }) {
220
220
  }
221
221
  function ScreenplayEditorView({
222
222
  blocks,
223
- pages,
224
- isPageSplitEnabled,
225
- togglePageSplit,
226
223
  refs,
227
224
  focusedBlockId,
228
225
  showSuggestions,
@@ -230,7 +227,6 @@ function ScreenplayEditorView({
230
227
  characterExtensions,
231
228
  locations,
232
229
  characters,
233
- sceneNumbers,
234
230
  handleBlockTextChange,
235
231
  handleSceneTypeChange,
236
232
  handleTimeOfDayChange,
@@ -285,131 +281,56 @@ function ScreenplayEditorView({
285
281
  type
286
282
  );
287
283
  }) }),
288
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-12 w-full items-center pb-24", children: pages.map((pageBlocks, pageIndex) => /* @__PURE__ */ jsxs(
284
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-12 w-full items-center pb-24", children: /* @__PURE__ */ jsx(
289
285
  "div",
290
286
  {
291
287
  className: "relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 ring-1 ring-zinc-200/50 rounded-sm md:rounded-md pl-[1.5in] py-[1in] pr-[1in] flex flex-col w-[210mm] min-h-[297mm] shrink-0",
292
288
  style: {
293
289
  fontFamily: "var(--font-courier-prime, 'Courier New', Courier, monospace)"
294
290
  },
295
- children: [
296
- pageBlocks.map((block) => {
297
- var _a, _b;
298
- return /* @__PURE__ */ jsx(
299
- "div",
300
- {
301
- "data-block-id": block.id,
302
- className: `relative rounded-sm transition-all duration-200 outline-none ${focusedBlockId === block.id ? "bg-zinc-100/50" : "bg-transparent"}`,
303
- children: block.type === "SCENE_HEADING" ? /* @__PURE__ */ jsxs(Fragment, { children: [
304
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-1 bg-transparent", children: [
305
- /* @__PURE__ */ jsx(
306
- "input",
307
- {
308
- className: "absolute -left-16 top-2 w-12 text-right text-zinc-400 font-semibold select-none bg-transparent outline-none focus:ring-1 focus:ring-blue-400 rounded-sm",
309
- spellCheck: false,
310
- value: block.sceneNumber || "",
311
- onChange: (e) => handleSceneNumberChange(
312
- block.id,
313
- e.target.value.toUpperCase()
314
- ),
315
- onFocus: () => handleFocus(block.id),
316
- onBlur: () => handleBlur(block.id),
317
- onKeyDown: (e) => {
318
- if (e.key === "Enter" || e.key === "Backspace") {
319
- e.stopPropagation();
320
- }
321
- },
322
- "aria-label": "Scene Number"
323
- }
324
- ),
325
- /* @__PURE__ */ jsxs(
326
- "select",
327
- {
328
- className: "rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer w-fit transition-colors",
329
- "aria-label": "Scene Type",
330
- value: (_a = block.sceneType) != null ? _a : "INT.",
331
- onChange: (e) => handleSceneTypeChange(block.id, e.target.value),
332
- children: [
333
- /* @__PURE__ */ jsx("option", { children: "INT." }),
334
- /* @__PURE__ */ jsx("option", { children: "EXT." }),
335
- /* @__PURE__ */ jsx("option", { children: "INT/EXT." })
336
- ]
337
- }
338
- ),
339
- /* @__PURE__ */ jsx(
340
- "div",
341
- {
342
- ref: (el) => {
343
- if (!el) return;
344
- refs.current[block.id] = el;
345
- },
346
- contentEditable: true,
347
- suppressContentEditableWarning: true,
348
- "aria-label": `Scene Heading: ${block.text}`,
349
- "aria-haspopup": "listbox",
350
- "aria-expanded": focusedBlockId === block.id && showSuggestions && locations.length > 0,
351
- spellCheck: false,
352
- className: "min-w-[3rem] py-1 outline-none text-base font-bold uppercase tracking-widest break-all bg-transparent",
353
- onInput: (e) => handleBlockTextChange(
354
- block.id,
355
- e.target.innerText
356
- ),
357
- onKeyDown: (e) => handleKeyDown(e, block.id, block.text),
358
- onFocus: () => handleFocus(block.id),
359
- onBlur: () => handleBlur(block.id)
360
- }
361
- ),
362
- /* @__PURE__ */ jsx("span", { className: "text-zinc-400/80 font-bold", children: "-" }),
363
- /* @__PURE__ */ jsx(
364
- "select",
365
- {
366
- className: "rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer transition-colors",
367
- "aria-label": "Time of Day",
368
- value: (_b = block.timeOfDay) != null ? _b : "DAY",
369
- onChange: (e) => handleTimeOfDayChange(block.id, e.target.value),
370
- children: timeOfDayOptions.map((t) => /* @__PURE__ */ jsx("option", { children: t }, t))
371
- }
372
- )
373
- ] }),
374
- focusedBlockId === block.id && showSuggestions && locations.length > 0 && /* @__PURE__ */ jsx(
375
- "div",
291
+ children: blocks.map((block) => {
292
+ var _a, _b;
293
+ return /* @__PURE__ */ jsx(
294
+ "div",
295
+ {
296
+ "data-block-id": block.id,
297
+ className: `relative rounded-sm transition-all duration-200 outline-none ${focusedBlockId === block.id ? "bg-zinc-100/50" : "bg-transparent"}`,
298
+ children: block.type === "SCENE_HEADING" ? /* @__PURE__ */ jsxs(Fragment, { children: [
299
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-1 bg-transparent", children: [
300
+ /* @__PURE__ */ jsx(
301
+ "input",
376
302
  {
377
- role: "listbox",
378
- id: `suggestions-${block.id}`,
379
- className: "absolute top-[calc(100%+6px)] left-0 min-w-[240px] z-50 bg-white border border-slate-200/80 shadow-xl shadow-slate-200/40 rounded-xl py-1 overflow-hidden animate-in fade-in zoom-in-95 duration-150",
380
- children: /* @__PURE__ */ jsx("div", { className: "max-h-60 overflow-y-auto custom-scrollbar", children: locations.filter(
381
- (loc) => loc.startsWith(block.text.toUpperCase()) && loc !== block.text.toUpperCase()
382
- ).map((loc) => /* @__PURE__ */ jsxs(
383
- "div",
384
- {
385
- role: "option",
386
- className: "group flex items-center justify-between px-4 py-2.5 cursor-pointer transition-all duration-150 hover:bg-slate-50 active:bg-slate-100",
387
- onMouseDown: (e) => {
388
- e.preventDefault();
389
- const element = refs.current[block.id];
390
- if (element) {
391
- element.innerText = loc;
392
- handleBlockTextChange(block.id, loc);
393
- element.focus();
394
- const range = document.createRange();
395
- const sel = window.getSelection();
396
- range.selectNodeContents(element);
397
- range.collapse(false);
398
- sel == null ? void 0 : sel.removeAllRanges();
399
- sel == null ? void 0 : sel.addRange(range);
400
- }
401
- handleBlur(block.id);
402
- },
403
- children: [
404
- /* @__PURE__ */ jsx("span", { className: "text-[12px] font-semibold tracking-wide text-slate-600 uppercase line-clamp-1", children: loc }),
405
- /* @__PURE__ */ jsx(ArrowRight, { className: "w-3.5 h-3.5 text-slate-300 opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200" })
406
- ]
407
- },
408
- loc
409
- )) })
303
+ className: "absolute -left-16 top-2 w-12 text-right text-zinc-400 font-semibold select-none bg-transparent outline-none focus:ring-1 focus:ring-blue-400 rounded-sm",
304
+ spellCheck: false,
305
+ value: block.sceneNumber || "",
306
+ onChange: (e) => handleSceneNumberChange(
307
+ block.id,
308
+ e.target.value.toUpperCase()
309
+ ),
310
+ onFocus: () => handleFocus(block.id),
311
+ onBlur: () => handleBlur(block.id),
312
+ onKeyDown: (e) => {
313
+ if (e.key === "Enter" || e.key === "Backspace") {
314
+ e.stopPropagation();
315
+ }
316
+ },
317
+ "aria-label": "Scene Number"
410
318
  }
411
- )
412
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
319
+ ),
320
+ /* @__PURE__ */ jsxs(
321
+ "select",
322
+ {
323
+ className: "rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer w-fit transition-colors",
324
+ "aria-label": "Scene Type",
325
+ value: (_a = block.sceneType) != null ? _a : "INT.",
326
+ onChange: (e) => handleSceneTypeChange(block.id, e.target.value),
327
+ children: [
328
+ /* @__PURE__ */ jsx("option", { children: "INT." }),
329
+ /* @__PURE__ */ jsx("option", { children: "EXT." }),
330
+ /* @__PURE__ */ jsx("option", { children: "INT/EXT." })
331
+ ]
332
+ }
333
+ ),
413
334
  /* @__PURE__ */ jsx(
414
335
  "div",
415
336
  {
@@ -419,100 +340,168 @@ function ScreenplayEditorView({
419
340
  },
420
341
  contentEditable: true,
421
342
  suppressContentEditableWarning: true,
422
- "aria-label": `${blockStyles[block.type].label} text`,
423
- "aria-multiline": block.type === "ACTION" || block.type === "DIALOGUE",
343
+ "aria-label": `Scene Heading: ${block.text}`,
344
+ "aria-haspopup": "listbox",
345
+ "aria-expanded": focusedBlockId === block.id && showSuggestions && locations.length > 0,
424
346
  spellCheck: false,
425
- className: `block outline-none w-full min-h-[2.5rem] px-4 py-2 break-words ${blockStyles[block.type].className}`,
347
+ className: "min-w-[3rem] py-1 outline-none text-base font-bold uppercase tracking-widest break-all bg-transparent",
426
348
  onInput: (e) => handleBlockTextChange(
427
349
  block.id,
428
350
  e.target.innerText
429
351
  ),
430
352
  onKeyDown: (e) => handleKeyDown(e, block.id, block.text),
431
353
  onFocus: () => handleFocus(block.id),
432
- onBlur: () => handleBlur(block.id),
433
- style: blockStyles[block.type].inputStyle
354
+ onBlur: () => handleBlur(block.id)
434
355
  }
435
356
  ),
436
- focusedBlockId === block.id && block.type === "CHARACTER" && showSuggestions && characters.length > 0 && /* @__PURE__ */ jsx(
437
- "div",
438
- {
439
- role: "listbox",
440
- id: `suggestions-${block.id}`,
441
- className: "absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200",
442
- children: /* @__PURE__ */ jsx("div", { className: "max-h-56 overflow-y-auto custom-scrollbar", children: characters.filter(
443
- (char) => char.startsWith(block.text.toUpperCase()) && char !== block.text.toUpperCase()
444
- ).map((char) => /* @__PURE__ */ jsxs(
445
- "div",
446
- {
447
- role: "option",
448
- className: "group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100",
449
- onMouseDown: (e) => {
450
- e.preventDefault();
451
- const element = refs.current[block.id];
452
- if (element) {
453
- element.innerText = char;
454
- handleBlockTextChange(block.id, char);
455
- element.focus();
456
- const range = document.createRange();
457
- const sel = window.getSelection();
458
- range.selectNodeContents(element);
459
- range.collapse(false);
460
- sel == null ? void 0 : sel.removeAllRanges();
461
- sel == null ? void 0 : sel.addRange(range);
462
- }
463
- handleBlur(block.id);
464
- },
465
- children: [
466
- /* @__PURE__ */ jsx(User, { className: "w-3.5 h-3.5 text-slate-300 group-hover:text-sky-500 transition-colors mr-3" }),
467
- /* @__PURE__ */ jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: char }),
468
- /* @__PURE__ */ jsx(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" })
469
- ]
470
- },
471
- char
472
- )) })
473
- }
474
- ),
475
- focusedBlockId === block.id && block.type === "CHARACTER" && showExtensionSuggestions && characterExtensions && /* @__PURE__ */ jsx(
476
- "div",
357
+ /* @__PURE__ */ jsx("span", { className: "text-zinc-400/80 font-bold", children: "-" }),
358
+ /* @__PURE__ */ jsx(
359
+ "select",
477
360
  {
478
- role: "listbox",
479
- id: `extension-suggestions-${block.id}`,
480
- className: "absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200",
481
- children: /* @__PURE__ */ jsx("div", { className: "max-h-56 overflow-y-auto custom-scrollbar", children: characterExtensions.filter((ext) => {
482
- const openParenIndex = block.text.lastIndexOf("(");
483
- const query = openParenIndex > -1 ? block.text.substring(openParenIndex + 1).toUpperCase() : "";
484
- return ext.toUpperCase().includes(query);
485
- }).map((ext) => /* @__PURE__ */ jsxs(
486
- "div",
487
- {
488
- role: "option",
489
- className: "group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100",
490
- onMouseDown: (e) => {
491
- e.preventDefault();
492
- handleSelectCharacterExtension(ext);
493
- },
494
- children: [
495
- /* @__PURE__ */ jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: ext }),
496
- /* @__PURE__ */ jsx(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" })
497
- ]
498
- },
499
- ext
500
- )) })
361
+ className: "rounded-md text-zinc-800 font-bold px-1.5 py-1 appearance-none bg-transparent hover:bg-zinc-200/50 outline-none cursor-pointer transition-colors",
362
+ "aria-label": "Time of Day",
363
+ value: (_b = block.timeOfDay) != null ? _b : "DAY",
364
+ onChange: (e) => handleTimeOfDayChange(block.id, e.target.value),
365
+ children: timeOfDayOptions.map((t) => /* @__PURE__ */ jsx("option", { children: t }, t))
501
366
  }
502
367
  )
503
- ] })
504
- },
505
- block.id + "-" + block.type
506
- );
507
- }),
508
- isPageSplitEnabled && /* @__PURE__ */ jsxs("div", { className: "absolute bottom-10 right-16 md:right-20 text-zinc-400 font-semibold text-sm select-none pointer-events-none", children: [
509
- pageIndex + 1,
510
- "."
511
- ] })
512
- ]
513
- },
514
- pageIndex
515
- )) }),
368
+ ] }),
369
+ focusedBlockId === block.id && showSuggestions && locations.length > 0 && /* @__PURE__ */ jsx(
370
+ "div",
371
+ {
372
+ role: "listbox",
373
+ id: `suggestions-${block.id}`,
374
+ className: "absolute top-[calc(100%+6px)] left-0 min-w-[240px] z-50 bg-white border border-slate-200/80 shadow-xl shadow-slate-200/40 rounded-xl py-1 overflow-hidden animate-in fade-in zoom-in-95 duration-150",
375
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-60 overflow-y-auto custom-scrollbar", children: locations.filter(
376
+ (loc) => loc.startsWith(block.text.toUpperCase()) && loc !== block.text.toUpperCase()
377
+ ).map((loc) => /* @__PURE__ */ jsxs(
378
+ "div",
379
+ {
380
+ role: "option",
381
+ className: "group flex items-center justify-between px-4 py-2.5 cursor-pointer transition-all duration-150 hover:bg-slate-50 active:bg-slate-100",
382
+ onMouseDown: (e) => {
383
+ e.preventDefault();
384
+ const element = refs.current[block.id];
385
+ if (element) {
386
+ element.innerText = loc;
387
+ handleBlockTextChange(block.id, loc);
388
+ element.focus();
389
+ const range = document.createRange();
390
+ const sel = window.getSelection();
391
+ range.selectNodeContents(element);
392
+ range.collapse(false);
393
+ sel == null ? void 0 : sel.removeAllRanges();
394
+ sel == null ? void 0 : sel.addRange(range);
395
+ }
396
+ handleBlur(block.id);
397
+ },
398
+ children: [
399
+ /* @__PURE__ */ jsx("span", { className: "text-[12px] font-semibold tracking-wide text-slate-600 uppercase line-clamp-1", children: loc }),
400
+ /* @__PURE__ */ jsx(ArrowRight, { className: "w-3.5 h-3.5 text-slate-300 opacity-0 -translate-x-2 group-hover:opacity-100 group-hover:translate-x-0 transition-all duration-200" })
401
+ ]
402
+ },
403
+ loc
404
+ )) })
405
+ }
406
+ )
407
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
408
+ /* @__PURE__ */ jsx(
409
+ "div",
410
+ {
411
+ ref: (el) => {
412
+ if (!el) return;
413
+ refs.current[block.id] = el;
414
+ },
415
+ contentEditable: true,
416
+ suppressContentEditableWarning: true,
417
+ "aria-label": `${blockStyles[block.type].label} text`,
418
+ "aria-multiline": block.type === "ACTION" || block.type === "DIALOGUE",
419
+ spellCheck: false,
420
+ className: `block outline-none w-full min-h-[2.5rem] px-4 py-2 break-words ${blockStyles[block.type].className}`,
421
+ onInput: (e) => handleBlockTextChange(
422
+ block.id,
423
+ e.target.innerText
424
+ ),
425
+ onKeyDown: (e) => handleKeyDown(e, block.id, block.text),
426
+ onFocus: () => handleFocus(block.id),
427
+ onBlur: () => handleBlur(block.id),
428
+ style: blockStyles[block.type].inputStyle
429
+ }
430
+ ),
431
+ focusedBlockId === block.id && block.type === "CHARACTER" && showSuggestions && characters.length > 0 && /* @__PURE__ */ jsx(
432
+ "div",
433
+ {
434
+ role: "listbox",
435
+ id: `suggestions-${block.id}`,
436
+ className: "absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200",
437
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-56 overflow-y-auto custom-scrollbar", children: characters.filter(
438
+ (char) => char.startsWith(block.text.toUpperCase()) && char !== block.text.toUpperCase()
439
+ ).map((char) => /* @__PURE__ */ jsxs(
440
+ "div",
441
+ {
442
+ role: "option",
443
+ className: "group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100",
444
+ onMouseDown: (e) => {
445
+ e.preventDefault();
446
+ const element = refs.current[block.id];
447
+ if (element) {
448
+ element.innerText = char;
449
+ handleBlockTextChange(block.id, char);
450
+ element.focus();
451
+ const range = document.createRange();
452
+ const sel = window.getSelection();
453
+ range.selectNodeContents(element);
454
+ range.collapse(false);
455
+ sel == null ? void 0 : sel.removeAllRanges();
456
+ sel == null ? void 0 : sel.addRange(range);
457
+ }
458
+ handleBlur(block.id);
459
+ },
460
+ children: [
461
+ /* @__PURE__ */ jsx(User, { className: "w-3.5 h-3.5 text-slate-300 group-hover:text-sky-500 transition-colors mr-3" }),
462
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: char }),
463
+ /* @__PURE__ */ jsx(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" })
464
+ ]
465
+ },
466
+ char
467
+ )) })
468
+ }
469
+ ),
470
+ focusedBlockId === block.id && block.type === "CHARACTER" && showExtensionSuggestions && characterExtensions && /* @__PURE__ */ jsx(
471
+ "div",
472
+ {
473
+ role: "listbox",
474
+ id: `extension-suggestions-${block.id}`,
475
+ className: "absolute top-[calc(100%+8px)] left-1/2 -translate-x-1/2 w-72 z-50 bg-white border border-slate-200 shadow-2xl shadow-slate-200/60 rounded-xl py-2 overflow-hidden animate-in fade-in zoom-in-95 duration-200",
476
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-56 overflow-y-auto custom-scrollbar", children: characterExtensions.filter((ext) => {
477
+ const openParenIndex = block.text.lastIndexOf("(");
478
+ const query = openParenIndex > -1 ? block.text.substring(openParenIndex + 1).toUpperCase() : "";
479
+ return ext.toUpperCase().includes(query);
480
+ }).map((ext) => /* @__PURE__ */ jsxs(
481
+ "div",
482
+ {
483
+ role: "option",
484
+ className: "group flex items-center px-4 py-2.5 cursor-pointer transition-colors duration-150 hover:bg-slate-50 active:bg-slate-100",
485
+ onMouseDown: (e) => {
486
+ e.preventDefault();
487
+ handleSelectCharacterExtension(ext);
488
+ },
489
+ children: [
490
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-[11px] font-bold tracking-[0.1em] text-slate-600 uppercase text-left", children: ext }),
491
+ /* @__PURE__ */ jsx(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" })
492
+ ]
493
+ },
494
+ ext
495
+ )) })
496
+ }
497
+ )
498
+ ] })
499
+ },
500
+ block.id + "-" + block.type
501
+ );
502
+ })
503
+ }
504
+ ) }),
516
505
  /* @__PURE__ */ jsxs("div", { className: "fixed bottom-6 right-6 flex flex-col items-end gap-4 z-50", children: [
517
506
  /* @__PURE__ */ jsx(PdfImporter, { onScriptImported: handleScriptImport, children: /* @__PURE__ */ jsxs(Fragment, { children: [
518
507
  /* @__PURE__ */ jsx(Upload, { className: "w-5 h-5" }),
@@ -544,46 +533,24 @@ function ScreenplayEditorView({
544
533
  ),
545
534
  isRulesOpen && /* @__PURE__ */ jsxs("div", { className: "bg-white/80 backdrop-blur-md rounded-xl shadow-lg border border-zinc-200/50 p-4 text-xs text-zinc-700 select-none font-sans overflow-hidden transition-all duration-300 w-64 origin-bottom-right animate-in fade-in zoom-in-95", children: [
546
535
  /* @__PURE__ */ jsx("h4", { className: "font-bold text-zinc-800 mb-3 text-sm", children: "Settings & Shortcuts" }),
547
- /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
548
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-6", children: [
549
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-zinc-800", children: "A4 Page Split" }),
550
- /* @__PURE__ */ jsx(
551
- "button",
552
- {
553
- type: "button",
554
- role: "switch",
555
- "aria-checked": isPageSplitEnabled,
556
- onClick: togglePageSplit,
557
- className: `${isPageSplitEnabled ? "bg-zinc-900" : "bg-zinc-300"} relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none`,
558
- children: /* @__PURE__ */ jsx(
559
- "span",
560
- {
561
- "aria-hidden": "true",
562
- className: `${isPageSplitEnabled ? "translate-x-4" : "translate-x-0"} pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out`
563
- }
564
- )
565
- }
566
- )
536
+ /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: /* @__PURE__ */ jsxs("ul", { className: "space-y-1.5", children: [
537
+ /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-6", children: [
538
+ /* @__PURE__ */ jsx("span", { children: "New Block" }),
539
+ /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Enter" })
567
540
  ] }),
568
- /* @__PURE__ */ jsx("div", { className: "space-y-1.5 pt-3 border-t border-zinc-200/50", children: /* @__PURE__ */ jsxs("ul", { className: "space-y-1.5", children: [
569
- /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-6", children: [
570
- /* @__PURE__ */ jsx("span", { children: "New Block" }),
571
- /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Enter" })
572
- ] }),
573
- /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-6", children: [
574
- /* @__PURE__ */ jsx("span", { children: "Delete Block" }),
575
- /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Backspace" })
576
- ] }),
577
- /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-6", children: [
578
- /* @__PURE__ */ jsx("span", { children: "Change Type" }),
579
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
580
- /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Ctrl" }),
581
- /* @__PURE__ */ jsx("span", { children: "+" }),
582
- /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "\u2191/\u2193" })
583
- ] })
541
+ /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-6", children: [
542
+ /* @__PURE__ */ jsx("span", { children: "Delete Block" }),
543
+ /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Backspace" })
544
+ ] }),
545
+ /* @__PURE__ */ jsxs("li", { className: "flex items-center justify-between gap-6", children: [
546
+ /* @__PURE__ */ jsx("span", { children: "Change Type" }),
547
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
548
+ /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "Ctrl" }),
549
+ /* @__PURE__ */ jsx("span", { children: "+" }),
550
+ /* @__PURE__ */ jsx("kbd", { className: "px-2 py-1 text-xs font-semibold text-zinc-800 bg-zinc-200/70 border border-zinc-300/70 rounded-md", children: "\u2191/\u2193" })
584
551
  ] })
585
- ] }) })
586
- ] })
552
+ ] })
553
+ ] }) }) })
587
554
  ] }),
588
555
  /* @__PURE__ */ jsx(
589
556
  "button",
@@ -871,19 +838,6 @@ function useScreenplayEditor() {
871
838
  const [showSuggestions, setShowSuggestions] = useState(false);
872
839
  const [showExtensionSuggestions, setShowExtensionSuggestions] = useState(false);
873
840
  const blurTimeout = useRef(null);
874
- const [isPageSplitEnabled, setIsPageSplitEnabled] = useState(false);
875
- const [pageBreaks, setPageBreaks] = useState([]);
876
- const focusStateRef = useRef(null);
877
- const togglePageSplit = useCallback(() => {
878
- if (focusedBlockId && document.activeElement && document.activeElement.hasAttribute("contenteditable")) {
879
- const el = refs.current[focusedBlockId];
880
- if (el) {
881
- const offset = getCaretCharacterOffsetWithin(el);
882
- focusStateRef.current = { id: focusedBlockId, offset };
883
- }
884
- }
885
- setIsPageSplitEnabled((prev) => !prev);
886
- }, [focusedBlockId]);
887
841
  const characterExtensions = useMemo(
888
842
  () => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
889
843
  []
@@ -930,17 +884,6 @@ function useScreenplayEditor() {
930
884
  });
931
885
  return map;
932
886
  }, [blocks]);
933
- useCallback(() => {
934
- let count = 1;
935
- setBlocks(
936
- (prev) => prev.map((b) => {
937
- if (b.type === "SCENE_HEADING") {
938
- return __spreadProps(__spreadValues({}, b), { sceneNumber: String(count++) });
939
- }
940
- return b;
941
- })
942
- );
943
- }, []);
944
887
  useEffect(() => {
945
888
  if (newBlockId && refs.current[newBlockId]) {
946
889
  const block = blocks.find((b) => b.id === newBlockId);
@@ -985,98 +928,6 @@ function useScreenplayEditor() {
985
928
  document.removeEventListener("mousedown", handleClickOutside);
986
929
  };
987
930
  }, []);
988
- useEffect(() => {
989
- if (!isPageSplitEnabled) {
990
- setPageBreaks([]);
991
- return;
992
- }
993
- const saveFocus = () => {
994
- if (focusedBlockId && document.activeElement && document.activeElement.hasAttribute("contenteditable")) {
995
- const el = refs.current[focusedBlockId];
996
- if (el) {
997
- const offset = getCaretCharacterOffsetWithin(el);
998
- focusStateRef.current = { id: focusedBlockId, offset };
999
- }
1000
- } else {
1001
- focusStateRef.current = null;
1002
- }
1003
- };
1004
- const timeoutId = setTimeout(() => {
1005
- let currentHeight = 0;
1006
- let hasSceneOnCurrentPage = false;
1007
- const A4_HEIGHT = 960;
1008
- const newPageBreaks = [];
1009
- blocks.forEach((block) => {
1010
- const el = refs.current[block.id];
1011
- if (el) {
1012
- const measureEl = document.querySelector(`[data-block-id="${block.id}"]`) || el;
1013
- const style = window.getComputedStyle(measureEl);
1014
- const marginTop = parseFloat(style.marginTop) || 0;
1015
- const marginBottom = parseFloat(style.marginBottom) || 0;
1016
- const height = measureEl.getBoundingClientRect().height + marginTop + marginBottom;
1017
- let breakPage = false;
1018
- if (currentHeight + height > A4_HEIGHT) {
1019
- breakPage = true;
1020
- } else if (block.type === "SCENE_HEADING") {
1021
- if (hasSceneOnCurrentPage) {
1022
- breakPage = true;
1023
- } else if (currentHeight > A4_HEIGHT - 120) {
1024
- breakPage = true;
1025
- }
1026
- }
1027
- if (breakPage && currentHeight > 0) {
1028
- newPageBreaks.push(block.id);
1029
- currentHeight = height;
1030
- hasSceneOnCurrentPage = block.type === "SCENE_HEADING";
1031
- } else {
1032
- currentHeight += height;
1033
- if (block.type === "SCENE_HEADING") {
1034
- hasSceneOnCurrentPage = true;
1035
- }
1036
- }
1037
- }
1038
- });
1039
- setPageBreaks((prev) => {
1040
- if (prev.length !== newPageBreaks.length) {
1041
- saveFocus();
1042
- return newPageBreaks;
1043
- }
1044
- for (let i = 0; i < prev.length; i++) {
1045
- if (prev[i] !== newPageBreaks[i]) {
1046
- saveFocus();
1047
- return newPageBreaks;
1048
- }
1049
- }
1050
- return prev;
1051
- });
1052
- }, 300);
1053
- return () => clearTimeout(timeoutId);
1054
- }, [blocks, isPageSplitEnabled, focusedBlockId]);
1055
- const pages = useMemo(() => {
1056
- if (!isPageSplitEnabled || pageBreaks.length === 0) return [blocks];
1057
- const result = [];
1058
- let currentPage = [];
1059
- for (const block of blocks) {
1060
- if (pageBreaks.includes(block.id) && currentPage.length > 0) {
1061
- result.push(currentPage);
1062
- currentPage = [];
1063
- }
1064
- currentPage.push(block);
1065
- }
1066
- if (currentPage.length > 0) result.push(currentPage);
1067
- return result;
1068
- }, [blocks, isPageSplitEnabled, pageBreaks]);
1069
- useEffect(() => {
1070
- if (focusStateRef.current) {
1071
- const { id, offset } = focusStateRef.current;
1072
- const el = refs.current[id];
1073
- if (el && document.activeElement !== el) {
1074
- el.focus();
1075
- setCaretPosition(el, offset);
1076
- }
1077
- focusStateRef.current = null;
1078
- }
1079
- }, [pages]);
1080
931
  const handleBlockTextChange = useCallback(
1081
932
  (id, text) => {
1082
933
  const block = blocks.find((b) => b.id === id);
@@ -1406,9 +1257,6 @@ function useScreenplayEditor() {
1406
1257
  }, []);
1407
1258
  return {
1408
1259
  blocks,
1409
- pages,
1410
- isPageSplitEnabled,
1411
- togglePageSplit,
1412
1260
  refs,
1413
1261
  focusedBlockId,
1414
1262
  showSuggestions,