@vishu1301/script-writing 1.5.7 → 1.5.8

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 CHANGED
@@ -6286,8 +6286,182 @@ function useShotBreakdownScene(options) {
6286
6286
  menuRef
6287
6287
  };
6288
6288
  }
6289
+ function SceneScriptView({
6290
+ blocks,
6291
+ isLoading = false,
6292
+ sceneNumber,
6293
+ title
6294
+ }) {
6295
+ const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
6296
+ react.useEffect(() => {
6297
+ const fontId = "google-font-courier-prime";
6298
+ const styleId = "screenplay-editor-force-v4";
6299
+ if (!document.getElementById(fontId)) {
6300
+ const link = document.createElement("link");
6301
+ link.id = fontId;
6302
+ link.rel = "stylesheet";
6303
+ link.href = "https://fonts.googleapis.com/css2?family=Courier+Prime:ital,wght@0,400;0,700;1,400;1,700&display=swap";
6304
+ document.head.appendChild(link);
6305
+ }
6306
+ if (!document.getElementById(styleId)) {
6307
+ const style = document.createElement("style");
6308
+ style.id = styleId;
6309
+ style.textContent = `
6310
+ [data-scene-script-view] *,
6311
+ [data-scene-script-view] div,
6312
+ [data-scene-script-view] span {
6313
+ font-family: ${COURIER_STACK} !important;
6314
+ -webkit-font-smoothing: antialiased;
6315
+ }
6316
+ `;
6317
+ document.head.appendChild(style);
6318
+ }
6319
+ }, [COURIER_STACK]);
6320
+ if (isLoading) {
6321
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-32 gap-4", children: [
6322
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "w-8 h-8 animate-spin text-zinc-400" }),
6323
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-zinc-500 animate-pulse", children: "Loading script..." })
6324
+ ] });
6325
+ }
6326
+ return /* @__PURE__ */ jsxRuntime.jsx(
6327
+ "div",
6328
+ {
6329
+ className: "relative bg-[#fdfdfc] shadow-[0_10px_30px_rgba(0,0,0,0.04),0_1px_8px_rgba(0,0,0,0.02)] border border-zinc-100 rounded-sm md:rounded-md flex flex-col w-full max-w-[210mm] min-h-auto shrink-0 pb-24",
6330
+ style: {
6331
+ fontFamily: COURIER_STACK,
6332
+ paddingLeft: "1.5in",
6333
+ paddingRight: "1in",
6334
+ paddingTop: "1in",
6335
+ paddingBottom: "1in",
6336
+ lineHeight: "1.2"
6337
+ },
6338
+ "data-scene-script-view": "true",
6339
+ children: blocks.map((block) => /* @__PURE__ */ jsxRuntime.jsx(
6340
+ "div",
6341
+ {
6342
+ className: `relative break-words w-full px-4 py-2 ${blockStyles[block.type].className}`,
6343
+ style: __spreadProps(__spreadValues({}, blockStyles[block.type].inputStyle), {
6344
+ minHeight: "1.5rem"
6345
+ }),
6346
+ children: block.type === "SCENE_HEADING" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6347
+ block.sceneNumber && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -left-16 text-zinc-400 font-bold select-none", children: block.sceneNumber }),
6348
+ block.sceneType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold", children: block.sceneType }),
6349
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold", children: block.text }),
6350
+ block.timeOfDay && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6351
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400", children: "-" }),
6352
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-bold", children: block.timeOfDay })
6353
+ ] })
6354
+ ] }) : block.text
6355
+ },
6356
+ block.id
6357
+ ))
6358
+ }
6359
+ );
6360
+ }
6361
+ function useSceneScript(options) {
6362
+ const [sceneContent, setSceneContent] = react.useState(null);
6363
+ const [isLoading, setIsLoading] = react.useState(true);
6364
+ const [error, setError] = react.useState(null);
6365
+ react.useEffect(() => {
6366
+ let isMounted = true;
6367
+ setIsLoading(true);
6368
+ setError(null);
6369
+ const fetchScene = async () => {
6370
+ try {
6371
+ const response = await fetch(options.scene_url, options.fetchOptions);
6372
+ if (response.ok) {
6373
+ const text = await response.text();
6374
+ if (isMounted) {
6375
+ setSceneContent(text);
6376
+ }
6377
+ } else {
6378
+ if (isMounted) {
6379
+ setError(`Failed to fetch scene: ${response.statusText}`);
6380
+ }
6381
+ }
6382
+ } catch (err) {
6383
+ if (isMounted) {
6384
+ setError(err instanceof Error ? err.message : "An unknown error occurred");
6385
+ }
6386
+ } finally {
6387
+ if (isMounted) {
6388
+ setIsLoading(false);
6389
+ }
6390
+ }
6391
+ };
6392
+ fetchScene();
6393
+ return () => {
6394
+ isMounted = false;
6395
+ };
6396
+ }, [options.scene_url]);
6397
+ const blocks = react.useMemo(() => {
6398
+ if (!sceneContent) return [];
6399
+ const parser = new DOMParser();
6400
+ const doc = parser.parseFromString(sceneContent, "text/html");
6401
+ const divs = Array.from(doc.querySelectorAll("div"));
6402
+ const parsedBlocks = [];
6403
+ const typeMap = {
6404
+ divtype0: "SCENE_HEADING",
6405
+ divtype2: "ACTION",
6406
+ divtype3: "CHARACTER",
6407
+ divtype4: "PARENTHETICAL",
6408
+ divtype5: "DIALOGUE",
6409
+ divtype6: "TRANSITION"
6410
+ };
6411
+ divs.forEach((div) => {
6412
+ var _a;
6413
+ const divText = ((_a = div.textContent) == null ? void 0 : _a.trim()) || "";
6414
+ if (!divText && !div.classList.contains("divtype0")) return;
6415
+ let type = "ACTION";
6416
+ for (const className of Array.from(div.classList)) {
6417
+ if (typeMap[className]) {
6418
+ type = typeMap[className];
6419
+ break;
6420
+ }
6421
+ }
6422
+ const idAttr = div.getAttribute("id");
6423
+ const blockId = idAttr && idAttr.startsWith("par") ? idAttr.substring(3) : idAttr || uuid();
6424
+ let sceneNumber;
6425
+ let sceneType;
6426
+ let timeOfDay;
6427
+ let blockText = divText;
6428
+ if (type === "SCENE_HEADING") {
6429
+ const typeMatch = blockText.match(/^(INT\.?\/EXT\.?|INT\.?|EXT\.?|I\/E)\s+/i);
6430
+ if (typeMatch) {
6431
+ const matchedType = typeMatch[1].toUpperCase();
6432
+ if (matchedType.includes("INT") && matchedType.includes("EXT")) sceneType = "INT/EXT.";
6433
+ else if (matchedType.includes("EXT")) sceneType = "EXT.";
6434
+ else sceneType = "INT.";
6435
+ blockText = blockText.substring(typeMatch[0].length).trim();
6436
+ }
6437
+ const timeMatch = blockText.match(/\s+-\s+(DAY|NIGHT|MORNING|EVENING|AFTERNOON|LATER|MOMENTS LATER|CONTINUOUS)$/i);
6438
+ if (timeMatch) {
6439
+ timeOfDay = timeMatch[1].toUpperCase();
6440
+ blockText = blockText.substring(0, timeMatch.index).trim();
6441
+ }
6442
+ blockText = blockText.replace(/^-+\s*|\s*-+$/g, "").trim();
6443
+ }
6444
+ parsedBlocks.push({
6445
+ id: blockId,
6446
+ type,
6447
+ text: blockText,
6448
+ sceneNumber,
6449
+ sceneType,
6450
+ timeOfDay
6451
+ });
6452
+ });
6453
+ return parsedBlocks;
6454
+ }, [sceneContent]);
6455
+ return {
6456
+ blocks,
6457
+ isLoading,
6458
+ error,
6459
+ sceneContent
6460
+ };
6461
+ }
6289
6462
 
6290
6463
  exports.CATEGORIES = CATEGORIES;
6464
+ exports.SceneScriptView = SceneScriptView;
6291
6465
  exports.ScreenplayEditorView = ScreenplayEditorView;
6292
6466
  exports.ScriptBreakdownSceneView = ScriptBreakdownSceneView;
6293
6467
  exports.ShotBreakdownView = ShotBreakdownView;
@@ -6306,6 +6480,7 @@ exports.lens_options = lens_options;
6306
6480
  exports.scene_types = scene_types;
6307
6481
  exports.shot_types = shot_types;
6308
6482
  exports.timeOfDayOptions = timeOfDayOptions;
6483
+ exports.useSceneScript = useSceneScript;
6309
6484
  exports.useScreenplayEditor = useScreenplayEditor;
6310
6485
  exports.useScriptBreakdownScene = useScriptBreakdownScene;
6311
6486
  exports.useShotBreakdownScene = useShotBreakdownScene;