@vishu1301/script-writing 1.2.1 → 1.2.3

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
@@ -1753,6 +1753,7 @@ var CATEGORIES = [
1753
1753
  { id: "SET_PROP", label: "Set Prop", color: "#00C853", hex: "#69F0AE" },
1754
1754
  { id: "EXTRA", label: "Extra", color: "#00B8D4", hex: "#62EFFF" },
1755
1755
  { id: "LOCATION", label: "Location", color: "#FFB300", hex: "#FFE082" },
1756
+ { id: "SUBLOCATION", label: "Sublocation", color: "#004CFF", hex: "#004CFF" },
1756
1757
  { id: "OTHER", label: "Other", color: "#9E9E9E", hex: "#E0E0E0" }
1757
1758
  ];
1758
1759
  var PopcornIcon = ({ isSummarizing }) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1940,31 +1941,17 @@ function ScriptBreakdownSceneView({
1940
1941
  selectionMenu,
1941
1942
  handleMouseUp,
1942
1943
  addTag,
1944
+ updateTag,
1943
1945
  removeTag,
1944
1946
  clearSelection,
1945
1947
  menuPlacement,
1946
1948
  menuRef,
1947
- subLocations,
1948
- addSubLocation,
1949
- removeSubLocation,
1950
1949
  sceneBrief,
1951
1950
  setSceneBrief,
1952
1951
  onSummarize,
1953
1952
  isSummarizing
1954
1953
  }) {
1955
1954
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
1956
- const [isSubLocOpen, setIsSubLocOpen] = react.useState(false);
1957
- const [subLocInput, setSubLocInput] = react.useState("");
1958
- const subLocPopoverRef = react.useRef(null);
1959
- react.useEffect(() => {
1960
- const handleClickOutside = (e) => {
1961
- if (isSubLocOpen && subLocPopoverRef.current && !subLocPopoverRef.current.contains(e.target)) {
1962
- setIsSubLocOpen(false);
1963
- }
1964
- };
1965
- document.addEventListener("mousedown", handleClickOutside);
1966
- return () => document.removeEventListener("mousedown", handleClickOutside);
1967
- }, [isSubLocOpen]);
1968
1955
  react.useEffect(() => {
1969
1956
  const fontId = "google-font-courier-prime";
1970
1957
  const styleId = "screenplay-editor-force-v4";
@@ -2108,11 +2095,20 @@ function ScriptBreakdownSceneView({
2108
2095
  ] }),
2109
2096
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative z-10 flex flex-col gap-1", children: [
2110
2097
  CATEGORIES.filter(
2111
- (cat) => !(cat.id === "LOCATION" && hasLocationTag)
2098
+ (cat) => !(cat.id === "LOCATION" && hasLocationTag) && !(cat.id === "SUBLOCATION" && !hasLocationTag)
2112
2099
  ).map((cat) => /* @__PURE__ */ jsxRuntime.jsxs(
2113
2100
  "button",
2114
2101
  {
2115
- onClick: () => addTag(cat.id),
2102
+ onClick: () => {
2103
+ const existingTag = tags.find(
2104
+ (t) => t.block_id === block.id && t.start_index === selectionMenu.startIndex && t.end_index === selectionMenu.endIndex
2105
+ );
2106
+ if (existingTag && existingTag.id) {
2107
+ updateTag == null ? void 0 : updateTag(existingTag.id, cat.id);
2108
+ } else {
2109
+ addTag(cat.id);
2110
+ }
2111
+ },
2116
2112
  className: "group w-full text-[12px] font-bold px-3 py-2 rounded-xl transition-all duration-300 text-left flex items-center justify-between hover:bg-white/80 hover:shadow-[0_2px_10px_rgb(0,0,0,0.02)] active:scale-[0.98]",
2117
2113
  style: { color: cat.color },
2118
2114
  children: [
@@ -2199,6 +2195,7 @@ function ScriptBreakdownSceneView({
2199
2195
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto bg-slate-100/80 text-slate-500 px-2.5 py-1 rounded-lg text-[10px] font-bold tracking-widest border border-slate-200/50 shadow-inner", children: tags.length })
2200
2196
  ] }),
2201
2197
  tags.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-8", children: CATEGORIES.map((cat) => {
2198
+ if (cat.id === "SUBLOCATION" && !hasLocationTag) return null;
2202
2199
  const catTags = Array.from(
2203
2200
  new Map(
2204
2201
  tags.filter((t) => t.category_id === cat.id).map((tag) => [tag.name.toLowerCase(), tag])
@@ -2216,88 +2213,15 @@ function ScriptBreakdownSceneView({
2216
2213
  ),
2217
2214
  cat.label
2218
2215
  ] }),
2219
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
2220
- catTags.map((tag, index) => /* @__PURE__ */ jsxRuntime.jsx(
2221
- "span",
2222
- {
2223
- className: "text-[11px] font-bold px-3 py-1.5 rounded-xl bg-white/80 backdrop-blur-md border border-white shadow-[0_4px_15px_rgb(0,0,0,0.03)] hover:shadow-[0_4px_20px_rgb(0,0,0,0.06)] hover:-translate-y-0.5 transition-all duration-300 cursor-default",
2224
- style: { color: cat.color },
2225
- children: tag.name
2226
- },
2227
- index
2228
- )),
2229
- cat.id === "LOCATION" && /* @__PURE__ */ jsxRuntime.jsxs(
2230
- "div",
2231
- {
2232
- className: "relative flex items-center",
2233
- ref: subLocPopoverRef,
2234
- children: [
2235
- /* @__PURE__ */ jsxRuntime.jsx(
2236
- "button",
2237
- {
2238
- onClick: () => setIsSubLocOpen(!isSubLocOpen),
2239
- className: "flex items-center justify-center w-5 h-5 rounded-full hover:bg-slate-200 transition-colors",
2240
- title: "Add Sub Location",
2241
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "w-3 h-3 text-slate-500" })
2242
- }
2243
- ),
2244
- isSubLocOpen && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute left-0 top-full mt-2 w-56 bg-white backdrop-blur-2xl shadow-[0_10px_40px_rgb(0,0,0,0.06)] border border-white rounded-[1.5rem] p-3 z-50 animate-in fade-in zoom-in-95", children: [
2245
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[9px] font-extrabold tracking-[0.2em] text-slate-400 uppercase mb-2 px-1", children: "Add Sub Location" }),
2246
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 items-center", children: [
2247
- /* @__PURE__ */ jsxRuntime.jsx(
2248
- "input",
2249
- {
2250
- type: "text",
2251
- value: subLocInput,
2252
- onChange: (e) => setSubLocInput(e.target.value),
2253
- onKeyDown: (e) => {
2254
- if (e.key === "Enter") {
2255
- addSubLocation(subLocInput);
2256
- setSubLocInput("");
2257
- setIsSubLocOpen(false);
2258
- }
2259
- },
2260
- className: "w-full text-xs px-3 py-2 bg-white/50 border border-white/60 rounded-xl outline-none focus:bg-white/80 focus:border-white transition-all text-slate-700 font-bold shadow-[0_2px_10px_rgb(0,0,0,0.02)] placeholder:font-medium placeholder:text-slate-400",
2261
- placeholder: "Sub location...",
2262
- autoFocus: true
2263
- }
2264
- ),
2265
- /* @__PURE__ */ jsxRuntime.jsx(
2266
- "button",
2267
- {
2268
- onClick: () => {
2269
- addSubLocation(subLocInput);
2270
- setSubLocInput("");
2271
- setIsSubLocOpen(false);
2272
- },
2273
- className: "flex items-center justify-center shrink-0 bg-slate-800 text-white px-3.5 py-2 rounded-xl text-[11px] font-bold hover:bg-slate-700 hover:shadow-md transition-all active:scale-95",
2274
- children: "Add"
2275
- }
2276
- )
2277
- ] })
2278
- ] })
2279
- ]
2280
- }
2281
- ),
2282
- cat.id === "LOCATION" && subLocations.map((subLoc) => /* @__PURE__ */ jsxRuntime.jsxs(
2283
- "span",
2284
- {
2285
- className: "group flex items-center gap-1.5 text-[11px] font-bold px-3 py-1.5 rounded-xl bg-white backdrop-blur-md border border-slate-200/50 shadow-[0_4px_15px_rgb(0,0,0,0.03)] transition-all duration-300 cursor-default text-slate-500",
2286
- children: [
2287
- subLoc,
2288
- /* @__PURE__ */ jsxRuntime.jsx(
2289
- "button",
2290
- {
2291
- onClick: () => removeSubLocation(subLoc),
2292
- className: "w-3.5 h-3.5 rounded-full hover:bg-slate-300/50 flex items-center justify-center transition-colors opacity-0 group-hover:opacity-100",
2293
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-2.5 h-2.5" })
2294
- }
2295
- )
2296
- ]
2297
- },
2298
- `sub-${subLoc}`
2299
- ))
2300
- ] })
2216
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: catTags.map((tag, index) => /* @__PURE__ */ jsxRuntime.jsx(
2217
+ "span",
2218
+ {
2219
+ className: "text-[11px] font-bold px-3 py-1.5 rounded-xl bg-white/80 backdrop-blur-md border border-white shadow-[0_4px_15px_rgb(0,0,0,0.03)] hover:shadow-[0_4px_20px_rgb(0,0,0,0.06)] hover:-translate-y-0.5 transition-all duration-300 cursor-default",
2220
+ style: { color: cat.color },
2221
+ children: tag.name
2222
+ },
2223
+ index
2224
+ )) })
2301
2225
  ] }, cat.id);
2302
2226
  }) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-medium text-slate-400 italic bg-white/40 p-6 rounded-[2rem] border border-white border-dashed text-center shadow-[0_4px_20px_rgb(0,0,0,0.02)]", children: "Highlight text to tag elements." })
2303
2227
  ] })
@@ -2310,7 +2234,6 @@ function useScriptBreakdownScene(options) {
2310
2234
  const autoTaggedSceneRef = react.useRef(null);
2311
2235
  const [scene, setScene] = react.useState(null);
2312
2236
  const [menuPlacement, setMenuPlacement] = react.useState("top");
2313
- const [subLocations, setSubLocations] = react.useState([]);
2314
2237
  const [sceneBrief, setSceneBrief] = react.useState("");
2315
2238
  const [isSummarizing, setIsSummarizing] = react.useState(false);
2316
2239
  const [isLoading, setIsLoading] = react.useState(true);
@@ -2428,28 +2351,20 @@ function useScriptBreakdownScene(options) {
2428
2351
  console.error("Failed to summarize scene:", res);
2429
2352
  }
2430
2353
  };
2431
- const addSubLocation = react.useCallback(
2432
- (subLocation) => {
2433
- const trimmed = subLocation.trim();
2434
- if (trimmed && !subLocations.includes(trimmed)) {
2435
- setSubLocations((prev) => [...prev, trimmed]);
2436
- }
2437
- },
2438
- [subLocations]
2439
- );
2440
- const removeSubLocation = react.useCallback((subLocation) => {
2441
- setSubLocations((prev) => prev.filter((loc) => loc !== subLocation));
2442
- }, []);
2443
2354
  react.useEffect(() => {
2444
- setSubLocations([]);
2445
2355
  setSceneBrief("");
2446
2356
  autoTaggedSceneRef.current = null;
2447
2357
  }, [options.scene_url]);
2448
2358
  react.useEffect(() => {
2449
2359
  if (options.preLoadedTags && options.preLoadedTags.length > 0) {
2450
- setTags(options.preLoadedTags);
2360
+ setTags((prev) => {
2361
+ if (JSON.stringify(prev) === JSON.stringify(options.preLoadedTags)) {
2362
+ return prev;
2363
+ }
2364
+ return options.preLoadedTags || [];
2365
+ });
2451
2366
  }
2452
- }, []);
2367
+ }, [options.preLoadedTags]);
2453
2368
  const clearSelection = react.useCallback(() => {
2454
2369
  var _a;
2455
2370
  setSelectionMenu(null);
@@ -2576,6 +2491,25 @@ function useScriptBreakdownScene(options) {
2576
2491
  setTags((prev) => [...prev, tagToRemove]);
2577
2492
  }
2578
2493
  };
2494
+ const updateTag = async (id, categoryId) => {
2495
+ var _a;
2496
+ const tagToUpdate = tags.find((t) => t.id === id);
2497
+ if (!tagToUpdate) return;
2498
+ setTags(
2499
+ (prev) => prev.map((t) => t.id === id ? __spreadProps(__spreadValues({}, t), { category_id: categoryId }) : t)
2500
+ );
2501
+ clearSelection();
2502
+ try {
2503
+ await ((_a = options.onTagUpdated) == null ? void 0 : _a.call(options, id, categoryId));
2504
+ } catch (error2) {
2505
+ console.error("Failed to update tag:", error2);
2506
+ setTags(
2507
+ (prev) => prev.map(
2508
+ (t) => t.id === id ? __spreadProps(__spreadValues({}, t), { category_id: tagToUpdate.category_id }) : t
2509
+ )
2510
+ );
2511
+ }
2512
+ };
2579
2513
  return {
2580
2514
  scene,
2581
2515
  blocks,
@@ -2586,13 +2520,11 @@ function useScriptBreakdownScene(options) {
2586
2520
  selectionMenu,
2587
2521
  handleMouseUp,
2588
2522
  addTag,
2523
+ updateTag,
2589
2524
  removeTag,
2590
2525
  clearSelection,
2591
2526
  menuPlacement,
2592
2527
  menuRef,
2593
- subLocations,
2594
- addSubLocation,
2595
- removeSubLocation,
2596
2528
  sceneBrief,
2597
2529
  setSceneBrief,
2598
2530
  handleAISummarize,