@vishu1301/script-writing 1.2.3 → 1.2.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 CHANGED
@@ -2333,9 +2333,122 @@ function useScriptBreakdownScene(options) {
2333
2333
  end_index: aiTag.end_index
2334
2334
  });
2335
2335
  });
2336
+ if (newTags.length > 0) {
2337
+ const originalTags = tags;
2338
+ setTags((prev) => {
2339
+ const merged = [...prev];
2340
+ newTags.forEach((newTag) => {
2341
+ const isOverlapping = merged.some(
2342
+ (t) => t.block_id === newTag.block_id && newTag.end_index > t.start_index && newTag.start_index < t.end_index
2343
+ );
2344
+ if (!isOverlapping) {
2345
+ merged.push(newTag);
2346
+ }
2347
+ });
2348
+ return merged;
2349
+ });
2350
+ try {
2351
+ if (options.onTagsBulkAdded) {
2352
+ await options.onTagsBulkAdded(newTags, parsedSummaryData.summarise);
2353
+ }
2354
+ } catch (error2) {
2355
+ console.error("Failed to bulk add AI-generated tags:", error2);
2356
+ setTags(originalTags);
2357
+ }
2358
+ }
2359
+ return data;
2360
+ } else {
2361
+ setIsSummarizing(false);
2362
+ console.error("Failed to summarize scene:", res);
2363
+ }
2364
+ };
2365
+ const bulkCreateTags = react.useCallback(async () => {
2366
+ if (blocks.length === 0) return;
2367
+ const newTags = [];
2368
+ const seenCharacters = /* @__PURE__ */ new Set();
2369
+ const timeOfDays = ["DAY", "NIGHT"];
2370
+ const isTimeOfDay = (str) => timeOfDays.includes(str.toUpperCase());
2371
+ blocks.forEach((block) => {
2372
+ if (block.type === "CHARACTER") {
2373
+ const text = block.text.trim();
2374
+ const parenIndex = text.indexOf("(");
2375
+ const charName = parenIndex > -1 ? text.substring(0, parenIndex).trim() : text;
2376
+ if (charName && !seenCharacters.has(charName.toUpperCase())) {
2377
+ seenCharacters.add(charName.toUpperCase());
2378
+ const startIndex = text.indexOf(charName);
2379
+ if (startIndex !== -1) {
2380
+ newTags.push({
2381
+ id: uuid(),
2382
+ block_id: block.id,
2383
+ category_id: "CAST",
2384
+ name: charName,
2385
+ start_index: startIndex,
2386
+ end_index: startIndex + charName.length
2387
+ });
2388
+ }
2389
+ }
2390
+ } else if (block.type === "SCENE_HEADING") {
2391
+ const text = block.text.trim();
2392
+ const typeMatch = text.match(
2393
+ /^(INT\/EXT|INT\.?\/EXT\.?|INT\.EXT\.?|INT|EXT|I\/E)\.?\s+/i
2394
+ );
2395
+ let remainingText = text;
2396
+ let offset = 0;
2397
+ if (typeMatch) {
2398
+ offset = typeMatch[0].length;
2399
+ remainingText = text.substring(offset);
2400
+ }
2401
+ const parts = remainingText.split(/\s+-\s+/);
2402
+ if (parts.length > 0) {
2403
+ const locationName = parts[0].trim();
2404
+ const locStart = text.indexOf(locationName, offset);
2405
+ if (locStart !== -1 && locationName) {
2406
+ newTags.push({
2407
+ id: uuid(),
2408
+ block_id: block.id,
2409
+ category_id: "LOCATION",
2410
+ name: locationName,
2411
+ start_index: locStart,
2412
+ end_index: locStart + locationName.length
2413
+ });
2414
+ }
2415
+ if (parts.length > 1) {
2416
+ const secondPart = parts[1].trim();
2417
+ const isLast = parts.length === 2;
2418
+ if (!isLast || !isTimeOfDay(secondPart)) {
2419
+ const subLocStart = text.indexOf(
2420
+ secondPart,
2421
+ locStart + locationName.length
2422
+ );
2423
+ if (subLocStart !== -1 && secondPart) {
2424
+ newTags.push({
2425
+ id: uuid(),
2426
+ block_id: block.id,
2427
+ category_id: "SUBLOCATION",
2428
+ name: secondPart,
2429
+ start_index: subLocStart,
2430
+ end_index: subLocStart + secondPart.length
2431
+ });
2432
+ }
2433
+ }
2434
+ }
2435
+ }
2436
+ }
2437
+ });
2438
+ if (newTags.length > 0) {
2439
+ const originalTags = tags;
2336
2440
  setTags((prev) => {
2337
2441
  const merged = [...prev];
2442
+ const existingChars = new Set(
2443
+ merged.filter(
2444
+ (t) => t.category_id === "CHARACTER" || t.category_id === "CAST"
2445
+ ).map((t) => t.name.toUpperCase())
2446
+ );
2338
2447
  newTags.forEach((newTag) => {
2448
+ if (newTag.category_id === "CHARACTER") {
2449
+ if (existingChars.has(newTag.name.toUpperCase())) return;
2450
+ existingChars.add(newTag.name.toUpperCase());
2451
+ }
2339
2452
  const isOverlapping = merged.some(
2340
2453
  (t) => t.block_id === newTag.block_id && newTag.end_index > t.start_index && newTag.start_index < t.end_index
2341
2454
  );
@@ -2345,12 +2458,16 @@ function useScriptBreakdownScene(options) {
2345
2458
  });
2346
2459
  return merged;
2347
2460
  });
2348
- return data;
2349
- } else {
2350
- setIsSummarizing(false);
2351
- console.error("Failed to summarize scene:", res);
2461
+ try {
2462
+ if (options.onTagsBulkAdded) {
2463
+ await options.onTagsBulkAdded(newTags);
2464
+ }
2465
+ } catch (error2) {
2466
+ console.error("Failed to bulk create tags:", error2);
2467
+ setTags(originalTags);
2468
+ }
2352
2469
  }
2353
- };
2470
+ }, [blocks, tags, options.onTagsBulkAdded]);
2354
2471
  react.useEffect(() => {
2355
2472
  setSceneBrief("");
2356
2473
  autoTaggedSceneRef.current = null;
@@ -2365,6 +2482,18 @@ function useScriptBreakdownScene(options) {
2365
2482
  });
2366
2483
  }
2367
2484
  }, [options.preLoadedTags]);
2485
+ react.useEffect(() => {
2486
+ const doBulkCreate = async () => {
2487
+ if (blocks.length > 0 && !autoTaggedSceneRef.current) {
2488
+ const hasPreloadedTags = options.preLoadedTags && options.preLoadedTags.length > 0;
2489
+ if (!hasPreloadedTags) {
2490
+ autoTaggedSceneRef.current = options.scene_url;
2491
+ await bulkCreateTags();
2492
+ }
2493
+ }
2494
+ };
2495
+ doBulkCreate();
2496
+ }, [blocks, options.scene_url, options.preLoadedTags, bulkCreateTags]);
2368
2497
  const clearSelection = react.useCallback(() => {
2369
2498
  var _a;
2370
2499
  setSelectionMenu(null);