@vishu1301/script-writing 0.5.0 → 0.5.2

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.d.cts CHANGED
@@ -21,7 +21,11 @@ declare const blockStyles: Record<BlockType, {
21
21
  inputStyle: React.CSSProperties;
22
22
  }>;
23
23
 
24
- declare function useScreenplayEditor(): {
24
+ interface UseScreenplayEditorOptions {
25
+ initialUrl?: string;
26
+ fetchOptions?: RequestInit;
27
+ }
28
+ declare function useScreenplayEditor(options?: UseScreenplayEditorOptions): {
25
29
  blocks: Block[];
26
30
  refs: React.RefObject<Record<string, HTMLDivElement | null>>;
27
31
  focusedBlockId: string;
@@ -41,6 +45,7 @@ declare function useScreenplayEditor(): {
41
45
  handleSceneNumberChange: (id: string, newNumber: string) => void;
42
46
  handleFocus: (id: string) => void;
43
47
  handleBlur: (id: string) => void;
48
+ loadFromUrl: (url: string, fetchOptions?: RequestInit) => Promise<void>;
44
49
  };
45
50
 
46
51
  type ScreenplayEditorViewProps = ReturnType<typeof useScreenplayEditor> & {
package/dist/index.d.ts CHANGED
@@ -21,7 +21,11 @@ declare const blockStyles: Record<BlockType, {
21
21
  inputStyle: React.CSSProperties;
22
22
  }>;
23
23
 
24
- declare function useScreenplayEditor(): {
24
+ interface UseScreenplayEditorOptions {
25
+ initialUrl?: string;
26
+ fetchOptions?: RequestInit;
27
+ }
28
+ declare function useScreenplayEditor(options?: UseScreenplayEditorOptions): {
25
29
  blocks: Block[];
26
30
  refs: React.RefObject<Record<string, HTMLDivElement | null>>;
27
31
  focusedBlockId: string;
@@ -41,6 +45,7 @@ declare function useScreenplayEditor(): {
41
45
  handleSceneNumberChange: (id: string, newNumber: string) => void;
42
46
  handleFocus: (id: string) => void;
43
47
  handleBlur: (id: string) => void;
48
+ loadFromUrl: (url: string, fetchOptions?: RequestInit) => Promise<void>;
44
49
  };
45
50
 
46
51
  type ScreenplayEditorViewProps = ReturnType<typeof useScreenplayEditor> & {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
1
+ import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
2
2
  import { ArrowRightLeft, MessageCircle, Brackets, UserRound, Sparkles, Clapperboard, ArrowRight, User, ChevronRight, Upload, Save, FileDown, RefreshCcw, Cog } from 'lucide-react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import * as pdfjs from 'pdfjs-dist';
@@ -306,6 +306,16 @@ function ScreenplayEditorView({
306
306
  handleSceneNumberChange
307
307
  }) {
308
308
  const [isRulesOpen, setIsRulesOpen] = useState(false);
309
+ useEffect(() => {
310
+ const fontId = "google-font-courier-prime";
311
+ if (!document.getElementById(fontId)) {
312
+ const link = document.createElement("link");
313
+ link.id = fontId;
314
+ link.rel = "stylesheet";
315
+ link.href = "https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=swap";
316
+ document.head.appendChild(link);
317
+ }
318
+ }, []);
309
319
  return /* @__PURE__ */ jsxs(Fragment, { children: [
310
320
  /* @__PURE__ */ jsx("div", { className: "sticky top-6 z-50 bg-white backdrop-blur-xl border border-white/10 rounded-full shadow-2xl flex gap-1 max-w-fit p-1.5 mb-12 select-none overflow-x-auto custom-scrollbar", children: blockTypes.map((type) => {
311
321
  var _a;
@@ -350,7 +360,7 @@ function ScreenplayEditorView({
350
360
  {
351
361
  className: "relative bg-[#fdfdfc] shadow-2xl shadow-zinc-300/60 border border-zinc-100 rounded-sm md:rounded-md pl-[1.5in] py-[1in] pr-[1in] flex flex-col w-[210mm] min-h-[297mm] shrink-0",
352
362
  style: {
353
- fontFamily: "'Courier Prime', 'Courier New', Courier, monospace",
363
+ fontFamily: "var(--font-courier-prime, 'Courier Prime', 'Courier New', Courier, monospace)",
354
364
  paddingLeft: "1.5in",
355
365
  paddingRight: "1in",
356
366
  paddingTop: "1in",
@@ -914,7 +924,7 @@ function setCaretPosition(element, offset) {
914
924
  sel.removeAllRanges();
915
925
  sel.addRange(range);
916
926
  }
917
- function useScreenplayEditor() {
927
+ function useScreenplayEditor(options) {
918
928
  const [blocks, setBlocks] = useState(initialBlocks);
919
929
  const refs = useRef({});
920
930
  const [focusedBlockId, setFocusedBlockId] = useState(
@@ -924,6 +934,7 @@ function useScreenplayEditor() {
924
934
  const [showSuggestions, setShowSuggestions] = useState(false);
925
935
  const [showExtensionSuggestions, setShowExtensionSuggestions] = useState(false);
926
936
  const blurTimeout = useRef(null);
937
+ const loadedUrlRef = useRef(null);
927
938
  const characterExtensions = useMemo(
928
939
  () => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
929
940
  []
@@ -1353,6 +1364,92 @@ function useScreenplayEditor() {
1353
1364
  setShowExtensionSuggestions(false);
1354
1365
  }, 200);
1355
1366
  }, []);
1367
+ const loadFromUrl = useCallback(
1368
+ async (url, fetchOptions = {}) => {
1369
+ var _a;
1370
+ try {
1371
+ const response = await fetch(url, fetchOptions);
1372
+ if (!response.ok) {
1373
+ throw new Error(
1374
+ `[useScreenplayEditor] Failed to fetch script. HTTP Status: ${response.status}`
1375
+ );
1376
+ }
1377
+ let text = await response.text();
1378
+ let preParsedBlocks = void 0;
1379
+ let scriptContent = text;
1380
+ if (text.includes('class="divtype') || url.toLowerCase().includes(".sbx")) {
1381
+ if (text.includes("&lt;div")) {
1382
+ const textarea = document.createElement("textarea");
1383
+ textarea.innerHTML = text;
1384
+ text = textarea.value;
1385
+ }
1386
+ const parser = new DOMParser();
1387
+ const doc = parser.parseFromString(text, "text/html");
1388
+ const divs = Array.from(doc.querySelectorAll("div"));
1389
+ const parsed = [];
1390
+ const typeMap = {
1391
+ divtype0: "SCENE_HEADING",
1392
+ divtype2: "ACTION",
1393
+ divtype3: "CHARACTER",
1394
+ divtype4: "PARENTHETICAL",
1395
+ divtype5: "DIALOGUE",
1396
+ divtype6: "TRANSITION"
1397
+ };
1398
+ divs.forEach((div) => {
1399
+ var _a2;
1400
+ let divText = ((_a2 = div.textContent) == null ? void 0 : _a2.trim()) || "";
1401
+ if (!divText) return;
1402
+ let type = "ACTION";
1403
+ for (const className of Array.from(div.classList)) {
1404
+ if (typeMap[className]) {
1405
+ type = typeMap[className];
1406
+ break;
1407
+ }
1408
+ }
1409
+ const block = { type, text: divText };
1410
+ if (type === "SCENE_HEADING") {
1411
+ const sceneNum = div.getAttribute("data-scene");
1412
+ if (sceneNum) block.sceneNumber = sceneNum;
1413
+ let parsedText = divText;
1414
+ const typeMatch = parsedText.match(/^(INT\/EXT|INT|EXT)\.?\s+/i);
1415
+ if (typeMatch) {
1416
+ let sType = typeMatch[1].toUpperCase();
1417
+ if (!sType.endsWith(".")) sType += ".";
1418
+ block.sceneType = sType;
1419
+ parsedText = parsedText.substring(typeMatch[0].length).trim();
1420
+ }
1421
+ const timeMatch = parsedText.match(/\s+-\s+([^-]+)$/);
1422
+ if (timeMatch) {
1423
+ block.timeOfDay = timeMatch[1].trim().toUpperCase();
1424
+ parsedText = parsedText.substring(0, timeMatch.index).trim();
1425
+ }
1426
+ block.text = parsedText;
1427
+ }
1428
+ parsed.push(block);
1429
+ });
1430
+ if (parsed.length > 0) {
1431
+ preParsedBlocks = parsed;
1432
+ scriptContent = "";
1433
+ }
1434
+ }
1435
+ const filename = ((_a = url.split("/").pop()) == null ? void 0 : _a.replace(/\.sbx$/i, "")) || "Imported from URL";
1436
+ handleScriptImport(filename, scriptContent, preParsedBlocks);
1437
+ } catch (error) {
1438
+ console.error(
1439
+ "[useScreenplayEditor] Error loading script from URL:",
1440
+ error
1441
+ );
1442
+ throw error;
1443
+ }
1444
+ },
1445
+ [handleScriptImport]
1446
+ );
1447
+ useEffect(() => {
1448
+ if ((options == null ? void 0 : options.initialUrl) && options.initialUrl !== loadedUrlRef.current) {
1449
+ loadedUrlRef.current = options.initialUrl;
1450
+ loadFromUrl(options.initialUrl, options.fetchOptions);
1451
+ }
1452
+ }, [options == null ? void 0 : options.initialUrl, options == null ? void 0 : options.fetchOptions, loadFromUrl]);
1356
1453
  return {
1357
1454
  blocks,
1358
1455
  refs,
@@ -1372,7 +1469,8 @@ function useScreenplayEditor() {
1372
1469
  handleScriptImport,
1373
1470
  handleSceneNumberChange,
1374
1471
  handleFocus,
1375
- handleBlur
1472
+ handleBlur,
1473
+ loadFromUrl
1376
1474
  };
1377
1475
  }
1378
1476
  var handleSaveAsPdf = (blocks, sceneNumbers) => {