@vishu1301/script-writing 1.2.3 → 1.2.5

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
@@ -91,7 +91,7 @@ declare const CATEGORIES: {
91
91
  hex: string;
92
92
  }[];
93
93
 
94
- declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, sceneNumber, tags, selectionMenu, handleMouseUp, addTag, updateTag, removeTag, clearSelection, menuPlacement, menuRef, sceneBrief, setSceneBrief, onSummarize, isSummarizing, }: {
94
+ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, sceneNumber, tags, selectionMenu, handleMouseUp, addTag, updateTag, removeTag, clearSelection, menuPlacement, menuRef, sceneBrief, setSceneBrief, onSummarize, isSummarizing, aiSummarized, }: {
95
95
  blocks: Block[];
96
96
  characters: string[];
97
97
  isLoading: boolean;
@@ -116,6 +116,7 @@ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, scene
116
116
  setSceneBrief: (brief: string) => void;
117
117
  onSummarize?: () => void;
118
118
  isSummarizing?: boolean;
119
+ aiSummarized?: boolean;
119
120
  }): react_jsx_runtime.JSX.Element;
120
121
 
121
122
  interface UseScriptBreakdownSceneOptions {
@@ -123,6 +124,7 @@ interface UseScriptBreakdownSceneOptions {
123
124
  fetchOptions?: RequestInit;
124
125
  onAISummarize?: (scene: any) => void;
125
126
  onTagAdded?: (tag: Tag) => void;
127
+ onTagsBulkAdded?: (tags: Tag[], summary?: string) => Promise<void>;
126
128
  onTagRemoved?: (tagId: string) => void;
127
129
  onTagUpdated?: (tagId: string, categoryId: ElementCategory) => void;
128
130
  preLoadedTags?: Tag[];
package/dist/index.d.ts CHANGED
@@ -91,7 +91,7 @@ declare const CATEGORIES: {
91
91
  hex: string;
92
92
  }[];
93
93
 
94
- declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, sceneNumber, tags, selectionMenu, handleMouseUp, addTag, updateTag, removeTag, clearSelection, menuPlacement, menuRef, sceneBrief, setSceneBrief, onSummarize, isSummarizing, }: {
94
+ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, sceneNumber, tags, selectionMenu, handleMouseUp, addTag, updateTag, removeTag, clearSelection, menuPlacement, menuRef, sceneBrief, setSceneBrief, onSummarize, isSummarizing, aiSummarized, }: {
95
95
  blocks: Block[];
96
96
  characters: string[];
97
97
  isLoading: boolean;
@@ -116,6 +116,7 @@ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, scene
116
116
  setSceneBrief: (brief: string) => void;
117
117
  onSummarize?: () => void;
118
118
  isSummarizing?: boolean;
119
+ aiSummarized?: boolean;
119
120
  }): react_jsx_runtime.JSX.Element;
120
121
 
121
122
  interface UseScriptBreakdownSceneOptions {
@@ -123,6 +124,7 @@ interface UseScriptBreakdownSceneOptions {
123
124
  fetchOptions?: RequestInit;
124
125
  onAISummarize?: (scene: any) => void;
125
126
  onTagAdded?: (tag: Tag) => void;
127
+ onTagsBulkAdded?: (tags: Tag[], summary?: string) => Promise<void>;
126
128
  onTagRemoved?: (tagId: string) => void;
127
129
  onTagUpdated?: (tagId: string, categoryId: ElementCategory) => void;
128
130
  preLoadedTags?: Tag[];
package/dist/index.js CHANGED
@@ -1924,7 +1924,8 @@ function ScriptBreakdownSceneView({
1924
1924
  sceneBrief,
1925
1925
  setSceneBrief,
1926
1926
  onSummarize,
1927
- isSummarizing
1927
+ isSummarizing,
1928
+ aiSummarized = false
1928
1929
  }) {
1929
1930
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
1930
1931
  useEffect(() => {
@@ -2156,7 +2157,7 @@ function ScriptBreakdownSceneView({
2156
2157
  ] })
2157
2158
  ] }),
2158
2159
  /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col gap-6 sticky top-6", children: [
2159
- /* @__PURE__ */ jsx(
2160
+ !aiSummarized && /* @__PURE__ */ jsx(
2160
2161
  summarize_button_default,
2161
2162
  {
2162
2163
  isSummarizing,
@@ -2308,9 +2309,122 @@ function useScriptBreakdownScene(options) {
2308
2309
  end_index: aiTag.end_index
2309
2310
  });
2310
2311
  });
2312
+ if (newTags.length > 0) {
2313
+ const originalTags = tags;
2314
+ setTags((prev) => {
2315
+ const merged = [...prev];
2316
+ newTags.forEach((newTag) => {
2317
+ const isOverlapping = merged.some(
2318
+ (t) => t.block_id === newTag.block_id && newTag.end_index > t.start_index && newTag.start_index < t.end_index
2319
+ );
2320
+ if (!isOverlapping) {
2321
+ merged.push(newTag);
2322
+ }
2323
+ });
2324
+ return merged;
2325
+ });
2326
+ try {
2327
+ if (options.onTagsBulkAdded) {
2328
+ await options.onTagsBulkAdded(newTags, parsedSummaryData.summarise);
2329
+ }
2330
+ } catch (error2) {
2331
+ console.error("Failed to bulk add AI-generated tags:", error2);
2332
+ setTags(originalTags);
2333
+ }
2334
+ }
2335
+ return data;
2336
+ } else {
2337
+ setIsSummarizing(false);
2338
+ console.error("Failed to summarize scene:", res);
2339
+ }
2340
+ };
2341
+ const bulkCreateTags = useCallback(async () => {
2342
+ if (blocks.length === 0) return;
2343
+ const newTags = [];
2344
+ const seenCharacters = /* @__PURE__ */ new Set();
2345
+ const timeOfDays = ["DAY", "NIGHT"];
2346
+ const isTimeOfDay = (str) => timeOfDays.includes(str.toUpperCase());
2347
+ blocks.forEach((block) => {
2348
+ if (block.type === "CHARACTER") {
2349
+ const text = block.text.trim();
2350
+ const parenIndex = text.indexOf("(");
2351
+ const charName = parenIndex > -1 ? text.substring(0, parenIndex).trim() : text;
2352
+ if (charName && !seenCharacters.has(charName.toUpperCase())) {
2353
+ seenCharacters.add(charName.toUpperCase());
2354
+ const startIndex = text.indexOf(charName);
2355
+ if (startIndex !== -1) {
2356
+ newTags.push({
2357
+ id: uuid(),
2358
+ block_id: block.id,
2359
+ category_id: "CAST",
2360
+ name: charName,
2361
+ start_index: startIndex,
2362
+ end_index: startIndex + charName.length
2363
+ });
2364
+ }
2365
+ }
2366
+ } else if (block.type === "SCENE_HEADING") {
2367
+ const text = block.text.trim();
2368
+ const typeMatch = text.match(
2369
+ /^(INT\/EXT|INT\.?\/EXT\.?|INT\.EXT\.?|INT|EXT|I\/E)\.?\s+/i
2370
+ );
2371
+ let remainingText = text;
2372
+ let offset = 0;
2373
+ if (typeMatch) {
2374
+ offset = typeMatch[0].length;
2375
+ remainingText = text.substring(offset);
2376
+ }
2377
+ const parts = remainingText.split(/\s+-\s+/);
2378
+ if (parts.length > 0) {
2379
+ const locationName = parts[0].trim();
2380
+ const locStart = text.indexOf(locationName, offset);
2381
+ if (locStart !== -1 && locationName) {
2382
+ newTags.push({
2383
+ id: uuid(),
2384
+ block_id: block.id,
2385
+ category_id: "LOCATION",
2386
+ name: locationName,
2387
+ start_index: locStart,
2388
+ end_index: locStart + locationName.length
2389
+ });
2390
+ }
2391
+ if (parts.length > 1) {
2392
+ const secondPart = parts[1].trim();
2393
+ const isLast = parts.length === 2;
2394
+ if (!isLast || !isTimeOfDay(secondPart)) {
2395
+ const subLocStart = text.indexOf(
2396
+ secondPart,
2397
+ locStart + locationName.length
2398
+ );
2399
+ if (subLocStart !== -1 && secondPart) {
2400
+ newTags.push({
2401
+ id: uuid(),
2402
+ block_id: block.id,
2403
+ category_id: "SUBLOCATION",
2404
+ name: secondPart,
2405
+ start_index: subLocStart,
2406
+ end_index: subLocStart + secondPart.length
2407
+ });
2408
+ }
2409
+ }
2410
+ }
2411
+ }
2412
+ }
2413
+ });
2414
+ if (newTags.length > 0) {
2415
+ const originalTags = tags;
2311
2416
  setTags((prev) => {
2312
2417
  const merged = [...prev];
2418
+ const existingChars = new Set(
2419
+ merged.filter(
2420
+ (t) => t.category_id === "CHARACTER" || t.category_id === "CAST"
2421
+ ).map((t) => t.name.toUpperCase())
2422
+ );
2313
2423
  newTags.forEach((newTag) => {
2424
+ if (newTag.category_id === "CHARACTER") {
2425
+ if (existingChars.has(newTag.name.toUpperCase())) return;
2426
+ existingChars.add(newTag.name.toUpperCase());
2427
+ }
2314
2428
  const isOverlapping = merged.some(
2315
2429
  (t) => t.block_id === newTag.block_id && newTag.end_index > t.start_index && newTag.start_index < t.end_index
2316
2430
  );
@@ -2320,12 +2434,16 @@ function useScriptBreakdownScene(options) {
2320
2434
  });
2321
2435
  return merged;
2322
2436
  });
2323
- return data;
2324
- } else {
2325
- setIsSummarizing(false);
2326
- console.error("Failed to summarize scene:", res);
2437
+ try {
2438
+ if (options.onTagsBulkAdded) {
2439
+ await options.onTagsBulkAdded(newTags);
2440
+ }
2441
+ } catch (error2) {
2442
+ console.error("Failed to bulk create tags:", error2);
2443
+ setTags(originalTags);
2444
+ }
2327
2445
  }
2328
- };
2446
+ }, [blocks, tags, options.onTagsBulkAdded]);
2329
2447
  useEffect(() => {
2330
2448
  setSceneBrief("");
2331
2449
  autoTaggedSceneRef.current = null;
@@ -2340,6 +2458,20 @@ function useScriptBreakdownScene(options) {
2340
2458
  });
2341
2459
  }
2342
2460
  }, [options.preLoadedTags]);
2461
+ useEffect(() => {
2462
+ const doBulkCreate = async () => {
2463
+ if (blocks.length > 0 && !autoTaggedSceneRef.current) {
2464
+ const hasPreloadedTags = options.preLoadedTags && options.preLoadedTags.length > 0;
2465
+ if (hasPreloadedTags) {
2466
+ autoTaggedSceneRef.current = options.scene_url;
2467
+ return;
2468
+ }
2469
+ autoTaggedSceneRef.current = options.scene_url;
2470
+ await bulkCreateTags();
2471
+ }
2472
+ };
2473
+ doBulkCreate();
2474
+ }, [blocks, options.scene_url, options.preLoadedTags, bulkCreateTags]);
2343
2475
  const clearSelection = useCallback(() => {
2344
2476
  var _a;
2345
2477
  setSelectionMenu(null);