@vishu1301/script-writing 1.2.2 → 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.d.cts CHANGED
@@ -72,7 +72,7 @@ interface ScriptBreakdown {
72
72
  scene_number: string;
73
73
  content: string;
74
74
  }
75
- type ElementCategory = "CAST" | "PROP" | "COSTUME" | "VEHICLE" | "SET_PROP" | "EXTRA" | "LOCATION" | "OTHER";
75
+ type ElementCategory = "CAST" | "PROP" | "COSTUME" | "VEHICLE" | "SET_PROP" | "EXTRA" | "LOCATION" | "SUBLOCATION" | "OTHER";
76
76
  interface Tag {
77
77
  id?: string;
78
78
  scene_id?: string | number;
@@ -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, removeTag, clearSelection, menuPlacement, menuRef, subLocations, addSubLocation, removeSubLocation, 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, }: {
95
95
  blocks: Block[];
96
96
  characters: string[];
97
97
  isLoading: boolean;
@@ -107,13 +107,11 @@ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, scene
107
107
  } | null;
108
108
  handleMouseUp: () => void;
109
109
  addTag: (c: ElementCategory) => void;
110
+ updateTag?: (id: string, categoryId: ElementCategory) => void;
110
111
  removeTag: (e: React__default.MouseEvent, id?: string) => void;
111
112
  clearSelection: () => void;
112
113
  menuPlacement: "top" | "bottom";
113
114
  menuRef: React__default.RefObject<HTMLDivElement | null>;
114
- subLocations: string[];
115
- addSubLocation: (loc: string) => void;
116
- removeSubLocation: (loc: string) => void;
117
115
  sceneBrief: string;
118
116
  setSceneBrief: (brief: string) => void;
119
117
  onSummarize?: () => void;
@@ -126,6 +124,7 @@ interface UseScriptBreakdownSceneOptions {
126
124
  onAISummarize?: (scene: any) => void;
127
125
  onTagAdded?: (tag: Tag) => void;
128
126
  onTagRemoved?: (tagId: string) => void;
127
+ onTagUpdated?: (tagId: string, categoryId: ElementCategory) => void;
129
128
  preLoadedTags?: Tag[];
130
129
  }
131
130
  declare function useScriptBreakdownScene(options: UseScriptBreakdownSceneOptions): {
@@ -145,13 +144,11 @@ declare function useScriptBreakdownScene(options: UseScriptBreakdownSceneOptions
145
144
  } | null;
146
145
  handleMouseUp: () => void;
147
146
  addTag: (categoryId: ElementCategory) => Promise<void>;
147
+ updateTag: (id: string, categoryId: ElementCategory) => Promise<void>;
148
148
  removeTag: (e: React.MouseEvent, id: string) => Promise<void>;
149
149
  clearSelection: () => void;
150
150
  menuPlacement: "bottom" | "top";
151
151
  menuRef: React$1.RefObject<HTMLDivElement | null>;
152
- subLocations: string[];
153
- addSubLocation: (subLocation: string) => void;
154
- removeSubLocation: (subLocation: string) => void;
155
152
  sceneBrief: string;
156
153
  setSceneBrief: React$1.Dispatch<React$1.SetStateAction<string>>;
157
154
  handleAISummarize: () => Promise<any>;
package/dist/index.d.ts CHANGED
@@ -72,7 +72,7 @@ interface ScriptBreakdown {
72
72
  scene_number: string;
73
73
  content: string;
74
74
  }
75
- type ElementCategory = "CAST" | "PROP" | "COSTUME" | "VEHICLE" | "SET_PROP" | "EXTRA" | "LOCATION" | "OTHER";
75
+ type ElementCategory = "CAST" | "PROP" | "COSTUME" | "VEHICLE" | "SET_PROP" | "EXTRA" | "LOCATION" | "SUBLOCATION" | "OTHER";
76
76
  interface Tag {
77
77
  id?: string;
78
78
  scene_id?: string | number;
@@ -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, removeTag, clearSelection, menuPlacement, menuRef, subLocations, addSubLocation, removeSubLocation, 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, }: {
95
95
  blocks: Block[];
96
96
  characters: string[];
97
97
  isLoading: boolean;
@@ -107,13 +107,11 @@ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, scene
107
107
  } | null;
108
108
  handleMouseUp: () => void;
109
109
  addTag: (c: ElementCategory) => void;
110
+ updateTag?: (id: string, categoryId: ElementCategory) => void;
110
111
  removeTag: (e: React__default.MouseEvent, id?: string) => void;
111
112
  clearSelection: () => void;
112
113
  menuPlacement: "top" | "bottom";
113
114
  menuRef: React__default.RefObject<HTMLDivElement | null>;
114
- subLocations: string[];
115
- addSubLocation: (loc: string) => void;
116
- removeSubLocation: (loc: string) => void;
117
115
  sceneBrief: string;
118
116
  setSceneBrief: (brief: string) => void;
119
117
  onSummarize?: () => void;
@@ -126,6 +124,7 @@ interface UseScriptBreakdownSceneOptions {
126
124
  onAISummarize?: (scene: any) => void;
127
125
  onTagAdded?: (tag: Tag) => void;
128
126
  onTagRemoved?: (tagId: string) => void;
127
+ onTagUpdated?: (tagId: string, categoryId: ElementCategory) => void;
129
128
  preLoadedTags?: Tag[];
130
129
  }
131
130
  declare function useScriptBreakdownScene(options: UseScriptBreakdownSceneOptions): {
@@ -145,13 +144,11 @@ declare function useScriptBreakdownScene(options: UseScriptBreakdownSceneOptions
145
144
  } | null;
146
145
  handleMouseUp: () => void;
147
146
  addTag: (categoryId: ElementCategory) => Promise<void>;
147
+ updateTag: (id: string, categoryId: ElementCategory) => Promise<void>;
148
148
  removeTag: (e: React.MouseEvent, id: string) => Promise<void>;
149
149
  clearSelection: () => void;
150
150
  menuPlacement: "bottom" | "top";
151
151
  menuRef: React$1.RefObject<HTMLDivElement | null>;
152
- subLocations: string[];
153
- addSubLocation: (subLocation: string) => void;
154
- removeSubLocation: (subLocation: string) => void;
155
152
  sceneBrief: string;
156
153
  setSceneBrief: React$1.Dispatch<React$1.SetStateAction<string>>;
157
154
  handleAISummarize: () => Promise<any>;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
2
- import { ArrowRightLeft, MessageCircle, Brackets, UserRound, Sparkles, Clapperboard, Upload, Lock, Unlock, Save, FileDown, RefreshCcw, Cog, ArrowRight, User, ChevronRight, Loader2, AlignLeft, Tags, Plus, X } from 'lucide-react';
2
+ import { ArrowRightLeft, MessageCircle, Brackets, UserRound, Sparkles, Clapperboard, Upload, Lock, Unlock, Save, FileDown, RefreshCcw, Cog, ArrowRight, User, ChevronRight, Loader2, AlignLeft, Tags } from 'lucide-react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import * as pdfjs from 'pdfjs-dist';
5
5
  import jsPDF from 'jspdf';
@@ -1728,6 +1728,7 @@ var CATEGORIES = [
1728
1728
  { id: "SET_PROP", label: "Set Prop", color: "#00C853", hex: "#69F0AE" },
1729
1729
  { id: "EXTRA", label: "Extra", color: "#00B8D4", hex: "#62EFFF" },
1730
1730
  { id: "LOCATION", label: "Location", color: "#FFB300", hex: "#FFE082" },
1731
+ { id: "SUBLOCATION", label: "Sublocation", color: "#004CFF", hex: "#004CFF" },
1731
1732
  { id: "OTHER", label: "Other", color: "#9E9E9E", hex: "#E0E0E0" }
1732
1733
  ];
1733
1734
  var PopcornIcon = ({ isSummarizing }) => /* @__PURE__ */ jsxs(
@@ -1915,31 +1916,17 @@ function ScriptBreakdownSceneView({
1915
1916
  selectionMenu,
1916
1917
  handleMouseUp,
1917
1918
  addTag,
1919
+ updateTag,
1918
1920
  removeTag,
1919
1921
  clearSelection,
1920
1922
  menuPlacement,
1921
1923
  menuRef,
1922
- subLocations,
1923
- addSubLocation,
1924
- removeSubLocation,
1925
1924
  sceneBrief,
1926
1925
  setSceneBrief,
1927
1926
  onSummarize,
1928
1927
  isSummarizing
1929
1928
  }) {
1930
1929
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
1931
- const [isSubLocOpen, setIsSubLocOpen] = useState(false);
1932
- const [subLocInput, setSubLocInput] = useState("");
1933
- const subLocPopoverRef = useRef(null);
1934
- useEffect(() => {
1935
- const handleClickOutside = (e) => {
1936
- if (isSubLocOpen && subLocPopoverRef.current && !subLocPopoverRef.current.contains(e.target)) {
1937
- setIsSubLocOpen(false);
1938
- }
1939
- };
1940
- document.addEventListener("mousedown", handleClickOutside);
1941
- return () => document.removeEventListener("mousedown", handleClickOutside);
1942
- }, [isSubLocOpen]);
1943
1930
  useEffect(() => {
1944
1931
  const fontId = "google-font-courier-prime";
1945
1932
  const styleId = "screenplay-editor-force-v4";
@@ -2083,11 +2070,20 @@ function ScriptBreakdownSceneView({
2083
2070
  ] }),
2084
2071
  /* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-1", children: [
2085
2072
  CATEGORIES.filter(
2086
- (cat) => !(cat.id === "LOCATION" && hasLocationTag)
2073
+ (cat) => !(cat.id === "LOCATION" && hasLocationTag) && !(cat.id === "SUBLOCATION" && !hasLocationTag)
2087
2074
  ).map((cat) => /* @__PURE__ */ jsxs(
2088
2075
  "button",
2089
2076
  {
2090
- onClick: () => addTag(cat.id),
2077
+ onClick: () => {
2078
+ const existingTag = tags.find(
2079
+ (t) => t.block_id === block.id && t.start_index === selectionMenu.startIndex && t.end_index === selectionMenu.endIndex
2080
+ );
2081
+ if (existingTag && existingTag.id) {
2082
+ updateTag == null ? void 0 : updateTag(existingTag.id, cat.id);
2083
+ } else {
2084
+ addTag(cat.id);
2085
+ }
2086
+ },
2091
2087
  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]",
2092
2088
  style: { color: cat.color },
2093
2089
  children: [
@@ -2174,6 +2170,7 @@ function ScriptBreakdownSceneView({
2174
2170
  /* @__PURE__ */ 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 })
2175
2171
  ] }),
2176
2172
  tags.length > 0 ? /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-8", children: CATEGORIES.map((cat) => {
2173
+ if (cat.id === "SUBLOCATION" && !hasLocationTag) return null;
2177
2174
  const catTags = Array.from(
2178
2175
  new Map(
2179
2176
  tags.filter((t) => t.category_id === cat.id).map((tag) => [tag.name.toLowerCase(), tag])
@@ -2191,88 +2188,15 @@ function ScriptBreakdownSceneView({
2191
2188
  ),
2192
2189
  cat.label
2193
2190
  ] }),
2194
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
2195
- catTags.map((tag, index) => /* @__PURE__ */ jsx(
2196
- "span",
2197
- {
2198
- 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",
2199
- style: { color: cat.color },
2200
- children: tag.name
2201
- },
2202
- index
2203
- )),
2204
- cat.id === "LOCATION" && /* @__PURE__ */ jsxs(
2205
- "div",
2206
- {
2207
- className: "relative flex items-center",
2208
- ref: subLocPopoverRef,
2209
- children: [
2210
- /* @__PURE__ */ jsx(
2211
- "button",
2212
- {
2213
- onClick: () => setIsSubLocOpen(!isSubLocOpen),
2214
- className: "flex items-center justify-center w-5 h-5 rounded-full hover:bg-slate-200 transition-colors",
2215
- title: "Add Sub Location",
2216
- children: /* @__PURE__ */ jsx(Plus, { className: "w-3 h-3 text-slate-500" })
2217
- }
2218
- ),
2219
- isSubLocOpen && /* @__PURE__ */ 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: [
2220
- /* @__PURE__ */ jsx("p", { className: "text-[9px] font-extrabold tracking-[0.2em] text-slate-400 uppercase mb-2 px-1", children: "Add Sub Location" }),
2221
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
2222
- /* @__PURE__ */ jsx(
2223
- "input",
2224
- {
2225
- type: "text",
2226
- value: subLocInput,
2227
- onChange: (e) => setSubLocInput(e.target.value),
2228
- onKeyDown: (e) => {
2229
- if (e.key === "Enter") {
2230
- addSubLocation(subLocInput);
2231
- setSubLocInput("");
2232
- setIsSubLocOpen(false);
2233
- }
2234
- },
2235
- 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",
2236
- placeholder: "Sub location...",
2237
- autoFocus: true
2238
- }
2239
- ),
2240
- /* @__PURE__ */ jsx(
2241
- "button",
2242
- {
2243
- onClick: () => {
2244
- addSubLocation(subLocInput);
2245
- setSubLocInput("");
2246
- setIsSubLocOpen(false);
2247
- },
2248
- 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",
2249
- children: "Add"
2250
- }
2251
- )
2252
- ] })
2253
- ] })
2254
- ]
2255
- }
2256
- ),
2257
- cat.id === "LOCATION" && subLocations.map((subLoc) => /* @__PURE__ */ jsxs(
2258
- "span",
2259
- {
2260
- 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",
2261
- children: [
2262
- subLoc,
2263
- /* @__PURE__ */ jsx(
2264
- "button",
2265
- {
2266
- onClick: () => removeSubLocation(subLoc),
2267
- 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",
2268
- children: /* @__PURE__ */ jsx(X, { className: "w-2.5 h-2.5" })
2269
- }
2270
- )
2271
- ]
2272
- },
2273
- `sub-${subLoc}`
2274
- ))
2275
- ] })
2191
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: catTags.map((tag, index) => /* @__PURE__ */ jsx(
2192
+ "span",
2193
+ {
2194
+ 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",
2195
+ style: { color: cat.color },
2196
+ children: tag.name
2197
+ },
2198
+ index
2199
+ )) })
2276
2200
  ] }, cat.id);
2277
2201
  }) }) : /* @__PURE__ */ 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." })
2278
2202
  ] })
@@ -2285,7 +2209,6 @@ function useScriptBreakdownScene(options) {
2285
2209
  const autoTaggedSceneRef = useRef(null);
2286
2210
  const [scene, setScene] = useState(null);
2287
2211
  const [menuPlacement, setMenuPlacement] = useState("top");
2288
- const [subLocations, setSubLocations] = useState([]);
2289
2212
  const [sceneBrief, setSceneBrief] = useState("");
2290
2213
  const [isSummarizing, setIsSummarizing] = useState(false);
2291
2214
  const [isLoading, setIsLoading] = useState(true);
@@ -2403,20 +2326,7 @@ function useScriptBreakdownScene(options) {
2403
2326
  console.error("Failed to summarize scene:", res);
2404
2327
  }
2405
2328
  };
2406
- const addSubLocation = useCallback(
2407
- (subLocation) => {
2408
- const trimmed = subLocation.trim();
2409
- if (trimmed && !subLocations.includes(trimmed)) {
2410
- setSubLocations((prev) => [...prev, trimmed]);
2411
- }
2412
- },
2413
- [subLocations]
2414
- );
2415
- const removeSubLocation = useCallback((subLocation) => {
2416
- setSubLocations((prev) => prev.filter((loc) => loc !== subLocation));
2417
- }, []);
2418
2329
  useEffect(() => {
2419
- setSubLocations([]);
2420
2330
  setSceneBrief("");
2421
2331
  autoTaggedSceneRef.current = null;
2422
2332
  }, [options.scene_url]);
@@ -2556,6 +2466,25 @@ function useScriptBreakdownScene(options) {
2556
2466
  setTags((prev) => [...prev, tagToRemove]);
2557
2467
  }
2558
2468
  };
2469
+ const updateTag = async (id, categoryId) => {
2470
+ var _a;
2471
+ const tagToUpdate = tags.find((t) => t.id === id);
2472
+ if (!tagToUpdate) return;
2473
+ setTags(
2474
+ (prev) => prev.map((t) => t.id === id ? __spreadProps(__spreadValues({}, t), { category_id: categoryId }) : t)
2475
+ );
2476
+ clearSelection();
2477
+ try {
2478
+ await ((_a = options.onTagUpdated) == null ? void 0 : _a.call(options, id, categoryId));
2479
+ } catch (error2) {
2480
+ console.error("Failed to update tag:", error2);
2481
+ setTags(
2482
+ (prev) => prev.map(
2483
+ (t) => t.id === id ? __spreadProps(__spreadValues({}, t), { category_id: tagToUpdate.category_id }) : t
2484
+ )
2485
+ );
2486
+ }
2487
+ };
2559
2488
  return {
2560
2489
  scene,
2561
2490
  blocks,
@@ -2566,13 +2495,11 @@ function useScriptBreakdownScene(options) {
2566
2495
  selectionMenu,
2567
2496
  handleMouseUp,
2568
2497
  addTag,
2498
+ updateTag,
2569
2499
  removeTag,
2570
2500
  clearSelection,
2571
2501
  menuPlacement,
2572
2502
  menuRef,
2573
- subLocations,
2574
- addSubLocation,
2575
- removeSubLocation,
2576
2503
  sceneBrief,
2577
2504
  setSceneBrief,
2578
2505
  handleAISummarize,