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