@vishu1301/script-writing 1.1.5 → 1.1.7

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
@@ -120,12 +120,12 @@ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, scene
120
120
  isSummarizing?: boolean;
121
121
  }): react_jsx_runtime.JSX.Element;
122
122
 
123
- declare function useScriptBreakdownScene(sceneNumber: string): {
124
- scene: ScriptBreakdown | undefined;
123
+ declare function useScriptBreakdownScene(scene_url: string, fetchOptions?: RequestInit, onAISummarize?: (scene: any) => void, onTagAdded?: (tag: Tag) => void, onTagRemoved?: (tagId: string) => void, preLoadedTags?: Tag[]): {
124
+ scene: any;
125
125
  blocks: Block[];
126
126
  characters: string[];
127
127
  isLoading: boolean;
128
- error: Error | null;
128
+ error: boolean;
129
129
  tags: Tag[];
130
130
  selectionMenu: {
131
131
  blockId: string;
@@ -136,10 +136,10 @@ declare function useScriptBreakdownScene(sceneNumber: string): {
136
136
  left: number;
137
137
  } | null;
138
138
  handleMouseUp: () => void;
139
- addTag: (categoryId: ElementCategory) => void;
140
- removeTag: (e: React.MouseEvent, id: string) => void;
139
+ addTag: (categoryId: ElementCategory) => Promise<void>;
140
+ removeTag: (e: React.MouseEvent, id: string) => Promise<void>;
141
141
  clearSelection: () => void;
142
- menuPlacement: "top" | "bottom";
142
+ menuPlacement: "bottom" | "top";
143
143
  menuRef: React$1.RefObject<HTMLDivElement | null>;
144
144
  subLocations: string[];
145
145
  addSubLocation: (subLocation: string) => void;
package/dist/index.d.ts CHANGED
@@ -120,12 +120,12 @@ declare function ScriptBreakdownSceneView({ blocks, characters, isLoading, scene
120
120
  isSummarizing?: boolean;
121
121
  }): react_jsx_runtime.JSX.Element;
122
122
 
123
- declare function useScriptBreakdownScene(sceneNumber: string): {
124
- scene: ScriptBreakdown | undefined;
123
+ declare function useScriptBreakdownScene(scene_url: string, fetchOptions?: RequestInit, onAISummarize?: (scene: any) => void, onTagAdded?: (tag: Tag) => void, onTagRemoved?: (tagId: string) => void, preLoadedTags?: Tag[]): {
124
+ scene: any;
125
125
  blocks: Block[];
126
126
  characters: string[];
127
127
  isLoading: boolean;
128
- error: Error | null;
128
+ error: boolean;
129
129
  tags: Tag[];
130
130
  selectionMenu: {
131
131
  blockId: string;
@@ -136,10 +136,10 @@ declare function useScriptBreakdownScene(sceneNumber: string): {
136
136
  left: number;
137
137
  } | null;
138
138
  handleMouseUp: () => void;
139
- addTag: (categoryId: ElementCategory) => void;
140
- removeTag: (e: React.MouseEvent, id: string) => void;
139
+ addTag: (categoryId: ElementCategory) => Promise<void>;
140
+ removeTag: (e: React.MouseEvent, id: string) => Promise<void>;
141
141
  clearSelection: () => void;
142
- menuPlacement: "top" | "bottom";
142
+ menuPlacement: "bottom" | "top";
143
143
  menuRef: React$1.RefObject<HTMLDivElement | null>;
144
144
  subLocations: string[];
145
145
  addSubLocation: (subLocation: string) => void;
package/dist/index.js CHANGED
@@ -1730,6 +1730,166 @@ var CATEGORIES = [
1730
1730
  { id: "LOCATION", label: "Location", color: "#FFB300", hex: "#FFE082" },
1731
1731
  { id: "OTHER", label: "Other", color: "#9E9E9E", hex: "#E0E0E0" }
1732
1732
  ];
1733
+ var PopcornIcon = ({ isSummarizing }) => /* @__PURE__ */ jsxs(
1734
+ "svg",
1735
+ {
1736
+ xmlns: "http://www.w3.org/2000/svg",
1737
+ width: "24",
1738
+ height: "24",
1739
+ viewBox: "0 0 24 24",
1740
+ fill: "none",
1741
+ strokeLinecap: "round",
1742
+ strokeLinejoin: "round",
1743
+ className: `w-6 h-6 transition-all duration-500 ${isSummarizing ? "animate-cook" : "group-hover:scale-110 group-hover:-rotate-12"}`,
1744
+ children: [
1745
+ /* @__PURE__ */ jsx(
1746
+ "path",
1747
+ {
1748
+ d: "M18 8a2 2 0 0 0 0-4 2 2 0 0 0-4 0 2 2 0 0 0-4 0 2 2 0 0 0-4 0 2 2 0 0 0 0 4",
1749
+ className: "stroke-yellow-400",
1750
+ strokeWidth: "2"
1751
+ }
1752
+ ),
1753
+ /* @__PURE__ */ jsxs("g", { className: "stroke-red-500", strokeWidth: "2", children: [
1754
+ /* @__PURE__ */ jsx("path", { d: "M20 8c.5 0 .9.4.8 1l-2.6 12c-.1.5-.7 1-1.2 1H7c-.6 0-1.1-.4-1.2-1L3.2 9c-.1-.6.3-1 .8-1Z" }),
1755
+ /* @__PURE__ */ jsx("path", { d: "M10 22 9 8", className: "stroke-red-500", strokeWidth: "1" }),
1756
+ /* @__PURE__ */ jsx("path", { d: "m14 22 1-14", className: "stroke-red-500", strokeWidth: "1" })
1757
+ ] })
1758
+ ]
1759
+ }
1760
+ );
1761
+ var SummarizeButton = ({
1762
+ onSummarize,
1763
+ isSummarizing
1764
+ }) => {
1765
+ return /* @__PURE__ */ jsxs(
1766
+ "button",
1767
+ {
1768
+ onClick: onSummarize,
1769
+ disabled: isSummarizing,
1770
+ className: `group relative w-full py-4 px-8 rounded-[3rem] transition-all duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] border ${isSummarizing ? "bg-zinc-100 border-zinc-300 opacity-100 cursor-wait shadow-inner" : "bg-gradient-to-b from-white via-zinc-50 to-zinc-100 border-white/70 shadow-[0_10px_30px_-10px_rgba(0,0,0,0.12),inset_0_1px_0_rgba(255,255,255,0.8)] hover:shadow-[0_20px_50px_-15px_rgba(139,92,246,0.3)] hover:-translate-y-[2px] active:scale-[0.98]"}`,
1771
+ children: [
1772
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition duration-700", children: /* @__PURE__ */ jsx("span", { className: "absolute inset-0 bg-[conic-gradient(from_0deg_at_50%_50%,#c084fc,transparent_60%,#fb7185,transparent_90%)] blur-3xl opacity-20 animate-[spin_10s_linear_infinite]" }) }),
1773
+ /* @__PURE__ */ jsx(
1774
+ "span",
1775
+ {
1776
+ className: `absolute inset-0 transition-opacity duration-700 bg-[radial-gradient(circle_at_50%_50%,rgba(139,92,246,0.1),transparent_70%)] ${isSummarizing ? "opacity-100" : "opacity-0"}`
1777
+ }
1778
+ ),
1779
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center gap-4", children: [
1780
+ /* @__PURE__ */ jsx("style", { children: `
1781
+ @keyframes kernel-pop {
1782
+ 0% { transform: translate(0, 0) scale(0) rotate(0deg); opacity: 0; }
1783
+ 10% { opacity: 1; transform: translate(var(--tx1), var(--ty1)) scale(1.3) rotate(45deg); }
1784
+ 40% { transform: translate(var(--tx2), var(--ty2)) scale(1) rotate(180deg); opacity: 1; }
1785
+ 100% { transform: translate(var(--tx3), var(--ty3)) scale(0.4) rotate(360deg); opacity: 0; }
1786
+ }
1787
+ @keyframes icon-cook {
1788
+ 0%, 100% { transform: scale(1.1) translateY(0); }
1789
+ 50% { transform: scale(0.9, 1.1) translateY(-3px) rotate(3deg); }
1790
+ }
1791
+ .animate-kernel {
1792
+ animation: kernel-pop var(--dur) cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
1793
+ animation-delay: var(--delay);
1794
+ filter: drop-shadow(0 4px 6px rgba(0,0,0,0.15)); /* Added shadow for visibility */
1795
+ }
1796
+ .animate-cook { animation: icon-cook 0.3s ease-in-out infinite; }
1797
+ ` }),
1798
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center", children: [
1799
+ /* @__PURE__ */ jsx(PopcornIcon, { isSummarizing }),
1800
+ isSummarizing && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 pointer-events-none", children: [
1801
+ /* @__PURE__ */ jsx(
1802
+ "svg",
1803
+ {
1804
+ className: "animate-kernel absolute w-4 h-4",
1805
+ style: {
1806
+ "--dur": "1.2s",
1807
+ "--delay": "0s",
1808
+ "--tx1": "-18px",
1809
+ "--ty1": "-22px",
1810
+ "--tx2": "-28px",
1811
+ "--ty2": "-28px",
1812
+ "--tx3": "-38px",
1813
+ "--ty3": "12px"
1814
+ },
1815
+ viewBox: "0 0 24 24",
1816
+ children: /* @__PURE__ */ jsx(
1817
+ "path",
1818
+ {
1819
+ d: "M12 2a4 4 0 0 0-4 4 4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 4-4 4 4 0 0 0-4-4 4 4 0 0 0-4-4z",
1820
+ fill: "#FBBF24",
1821
+ stroke: "#F59E0B",
1822
+ strokeWidth: "0.5"
1823
+ }
1824
+ )
1825
+ }
1826
+ ),
1827
+ /* @__PURE__ */ jsx(
1828
+ "svg",
1829
+ {
1830
+ className: "animate-kernel absolute w-3.5 h-3.5",
1831
+ style: {
1832
+ "--dur": "1.5s",
1833
+ "--delay": "0.3s",
1834
+ "--tx1": "18px",
1835
+ "--ty1": "-28px",
1836
+ "--tx2": "28px",
1837
+ "--ty2": "-38px",
1838
+ "--tx3": "38px",
1839
+ "--ty3": "18px"
1840
+ },
1841
+ viewBox: "0 0 24 24",
1842
+ children: /* @__PURE__ */ jsx(
1843
+ "path",
1844
+ {
1845
+ d: "M12 3c-2 0-3 1-4 2-1-1-3-1-4 1-1 2 0 4 1 5-1 1-1 3 1 4 2 1 4 0 6-1 2 1 4 2 6 1 2-1 2-3 1-4 1-1 2-3 1-5-1-2-3-2-4-1-1-1-2-2-4-2z",
1846
+ fill: "#FDE68A",
1847
+ stroke: "#FBBF24",
1848
+ strokeWidth: "0.5"
1849
+ }
1850
+ )
1851
+ }
1852
+ ),
1853
+ /* @__PURE__ */ jsx(
1854
+ "svg",
1855
+ {
1856
+ className: "animate-kernel absolute w-4 h-4",
1857
+ style: {
1858
+ "--dur": "1.8s",
1859
+ "--delay": "0.7s",
1860
+ "--tx1": "-2px",
1861
+ "--ty1": "-28px",
1862
+ "--tx2": "5px",
1863
+ "--ty2": "-48px",
1864
+ "--tx3": "10px",
1865
+ "--ty3": "18px"
1866
+ },
1867
+ viewBox: "0 0 24 24",
1868
+ children: /* @__PURE__ */ jsx(
1869
+ "path",
1870
+ {
1871
+ d: "M12 2a4 4 0 0 0-4 4 4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 4-4 4 4 0 0 0-4-4 4 4 0 0 0-4-4z",
1872
+ fill: "#FEF3C7"
1873
+ }
1874
+ )
1875
+ }
1876
+ )
1877
+ ] })
1878
+ ] }),
1879
+ /* @__PURE__ */ jsx(
1880
+ "span",
1881
+ {
1882
+ className: `text-[12px] font-bold tracking-[0.25em] uppercase transition-all duration-300 ${isSummarizing ? "text-violet-700" : "text-zinc-500 group-hover:text-zinc-900"}`,
1883
+ children: isSummarizing ? "Summarizing..." : "Summarize Scene"
1884
+ }
1885
+ )
1886
+ ] }),
1887
+ /* @__PURE__ */ jsx("span", { className: "absolute bottom-0 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-white/40 to-transparent" })
1888
+ ]
1889
+ }
1890
+ );
1891
+ };
1892
+ var summarize_button_default = SummarizeButton;
1733
1893
  function ScriptBreakdownSceneView({
1734
1894
  blocks,
1735
1895
  characters,
@@ -1975,7 +2135,7 @@ function ScriptBreakdownSceneView({
1975
2135
  value: sceneBrief,
1976
2136
  onChange: (e) => setSceneBrief(e.target.value),
1977
2137
  placeholder: "Write a brief description or notes for this scene...",
1978
- className: "w-full min-h-[120px] bg-transparent outline-none resize-y text-zinc-700 placeholder:text-zinc-400 text-sm md:text-base custom-scrollbar font-sans",
2138
+ className: "w-full min-h-[120px] bg-transparent outline-none resize-y text-zinc-700 placeholder:text-zinc-400 text-sm md:text-base custom-scrollbar font-sans select-none",
1979
2139
  style: {
1980
2140
  lineHeight: "1.6"
1981
2141
  }
@@ -1983,27 +2143,15 @@ function ScriptBreakdownSceneView({
1983
2143
  ) })
1984
2144
  ] })
1985
2145
  ] }),
1986
- /* @__PURE__ */ jsxs("div", { className: "w-full lg:w-80 flex-shrink-0 flex flex-col gap-6 sticky top-6", children: [
1987
- /* @__PURE__ */ jsxs(
1988
- "button",
2146
+ /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col gap-6 sticky top-6", children: [
2147
+ /* @__PURE__ */ jsx(
2148
+ summarize_button_default,
1989
2149
  {
1990
- onClick: onSummarize,
1991
- disabled: isSummarizing,
1992
- className: `group relative w-full py-4 px-6 rounded-[3rem] overflow-hidden bg-gradient-to-b from-white via-zinc-50 to-zinc-100 border border-white/70 shadow-[0_10px_30px_-10px_rgba(0,0,0,0.15),inset_0_1px_0_rgba(255,255,255,0.9)] transition-all duration-500 ease-[cubic-bezier(0.22,1,0.36,1)] ${isSummarizing ? "opacity-70 cursor-wait" : "hover:shadow-[0_20px_50px_-15px_rgba(139,92,246,0.35)] hover:-translate-y-[2px] active:scale-[0.97]"}`,
1993
- children: [
1994
- /* @__PURE__ */ jsx("span", { className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition duration-700", children: /* @__PURE__ */ jsx("span", { className: "absolute inset-0 bg-[conic-gradient(from_180deg_at_50%_50%,#8b5cf6,transparent_40%,#d946ef,transparent_70%)] blur-2xl opacity-30 animate-[spin_6s_linear_infinite]" }) }),
1995
- /* @__PURE__ */ jsx("span", { className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition duration-500 bg-[radial-gradient(circle_at_50%_40%,rgba(139,92,246,0.18),transparent_70%)]" }),
1996
- /* @__PURE__ */ jsx("span", { className: "absolute inset-[1px] rounded-[inherit] bg-gradient-to-b from-white/90 to-transparent pointer-events-none" }),
1997
- /* @__PURE__ */ jsx("span", { className: "absolute inset-0 overflow-hidden", children: /* @__PURE__ */ jsx("span", { className: "absolute -left-[100%] top-0 h-full w-[60%] bg-gradient-to-r from-transparent via-white/60 to-transparent skew-x-[-20deg] group-hover:left-[120%] transition-all duration-[1200ms]" }) }),
1998
- /* @__PURE__ */ jsx("span", { className: "absolute inset-[2px] rounded-[inherit] opacity-0 group-hover:opacity-100 bg-gradient-to-r from-violet-200/40 via-white/40 to-fuchsia-200/40 blur-md transition duration-500" }),
1999
- /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center gap-3", children: [
2000
- isSummarizing ? /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 text-violet-500 animate-spin" }) : /* @__PURE__ */ jsx(Sparkles, { className: "w-4 h-4 text-violet-500 transition-all duration-500 group-hover:-rotate-12 group-hover:scale-125" }),
2001
- /* @__PURE__ */ jsx("span", { className: "text-[11px] font-semibold tracking-[0.32em] uppercase text-zinc-800 group-hover:text-zinc-950 transition-all duration-300", children: isSummarizing ? "Summarizing..." : "Summarize Scene" })
2002
- ] })
2003
- ]
2150
+ isSummarizing,
2151
+ onSummarize
2004
2152
  }
2005
2153
  ),
2006
- /* @__PURE__ */ jsxs("div", { className: "bg-white/50 backdrop-blur-2xl border border-white shadow-[0_8px_30px_rgb(0,0,0,0.04)] rounded-[2.5rem] p-8", children: [
2154
+ /* @__PURE__ */ jsxs("div", { className: "bg-white/50 backdrop-blur-2xl border border-white shadow-[0_8px_30px_rgb(0,0,0,0.04)] rounded-[2.5rem] p-8 w-full", children: [
2007
2155
  /* @__PURE__ */ jsxs("h3", { className: "text-xs font-extrabold text-slate-800 uppercase tracking-[0.25em] mb-8 flex items-center gap-3", children: [
2008
2156
  /* @__PURE__ */ jsx("span", { className: "flex items-center justify-center w-8 h-8 rounded-full bg-white/80 shadow-[0_4px_15px_rgb(0,0,0,0.04)] border border-white", children: /* @__PURE__ */ jsx(Tags, { className: "w-3.5 h-3.5 text-slate-500" }) }),
2009
2157
  "Tags",
@@ -2115,96 +2263,39 @@ function ScriptBreakdownSceneView({
2115
2263
  ] })
2116
2264
  ] }) });
2117
2265
  }
2118
- function useScriptBreakdown({
2119
- scenes
2120
- }) {
2121
- const [parsedScenes, setParsedScenes] = useState(scenes || []);
2122
- const [isLoading, setIsLoading] = useState(false);
2123
- const [error, setError] = useState(null);
2124
- const [hasFetchedFallback, setHasFetchedFallback] = useState(false);
2125
- useEffect(() => {
2126
- if (scenes && scenes.length > 0) {
2127
- setParsedScenes(scenes);
2128
- return;
2129
- }
2130
- if (hasFetchedFallback) return;
2131
- const fetchFallback = async () => {
2132
- setIsLoading(true);
2133
- setHasFetchedFallback(true);
2134
- try {
2135
- const response = await fetch(
2136
- "https://pub-4c2073ce6f434c4e92ed33f8e1c7f9ea.r2.dev/screenplay%20(1).sbx"
2137
- );
2138
- if (!response.ok) {
2139
- throw new Error(
2140
- `Failed to fetch fallback script: ${response.status}`
2141
- );
2142
- }
2143
- let text = await response.text();
2144
- if (text.includes("&lt;div")) {
2145
- const textarea = document.createElement("textarea");
2146
- textarea.innerHTML = text;
2147
- text = textarea.value;
2148
- }
2149
- const parser = new DOMParser();
2150
- const doc = parser.parseFromString(text, "text/html");
2151
- const divs = Array.from(doc.querySelectorAll("div"));
2152
- const extractedScenes = [];
2153
- let currentSceneNumber = "1";
2154
- let currentContent = "";
2155
- let hasSeenFirstSceneHeading = false;
2156
- divs.forEach((div) => {
2157
- var _a;
2158
- const isSceneHeading = div.classList.contains("divtype0");
2159
- const divText = ((_a = div.textContent) == null ? void 0 : _a.trim()) || "";
2160
- if (!divText) return;
2161
- if (isSceneHeading) {
2162
- if (hasSeenFirstSceneHeading) {
2163
- extractedScenes.push({
2164
- scene_number: currentSceneNumber,
2165
- content: currentContent.trim()
2166
- });
2167
- currentContent = "";
2168
- }
2169
- hasSeenFirstSceneHeading = true;
2170
- currentSceneNumber = div.getAttribute("data-scene") || String(extractedScenes.length + 1);
2171
- }
2172
- currentContent += div.outerHTML + "\n";
2173
- });
2174
- if (currentContent.trim()) {
2175
- extractedScenes.push({
2176
- scene_number: currentSceneNumber,
2177
- content: currentContent.trim()
2178
- });
2179
- }
2180
- setParsedScenes(extractedScenes);
2181
- } catch (err) {
2182
- console.error("Error fetching fallback script:", err);
2183
- setError(err instanceof Error ? err : new Error("Unknown error"));
2184
- } finally {
2185
- setIsLoading(false);
2186
- }
2187
- };
2188
- fetchFallback();
2189
- }, [scenes, hasFetchedFallback]);
2190
- return { scenes: parsedScenes, isLoading, error };
2191
- }
2192
- var use_script_breakdown_default = useScriptBreakdown;
2193
-
2194
- // app/hook/use-script-breakdown-scene.ts
2195
- function useScriptBreakdownScene(sceneNumber) {
2196
- const { scenes, isLoading, error } = use_script_breakdown_default({ scenes: [] });
2197
- const [tags, setTags] = useState([]);
2266
+ function useScriptBreakdownScene(scene_url, fetchOptions, onAISummarize, onTagAdded, onTagRemoved, preLoadedTags) {
2267
+ const [tags, setTags] = useState(preLoadedTags || []);
2198
2268
  const [selectionMenu, setSelectionMenu] = useState(null);
2199
2269
  const autoTaggedSceneRef = useRef(null);
2270
+ const [scene, setScene] = useState(null);
2200
2271
  const [menuPlacement, setMenuPlacement] = useState("top");
2201
2272
  const [subLocations, setSubLocations] = useState([]);
2202
2273
  const [sceneBrief, setSceneBrief] = useState("");
2203
2274
  const [isSummarizing, setIsSummarizing] = useState(false);
2275
+ const [isLoading, setIsLoading] = useState(true);
2276
+ const [error, setError] = useState(false);
2204
2277
  const menuRef = useRef(null);
2205
- const scene = useMemo(() => {
2206
- return scenes.find((s) => s.scene_number === sceneNumber);
2207
- }, [scenes, sceneNumber]);
2278
+ useEffect(() => {
2279
+ setIsLoading(true);
2280
+ const fetchScene = async () => {
2281
+ try {
2282
+ const response = await fetch(scene_url, fetchOptions);
2283
+ if (response.ok) {
2284
+ const text = await response.text();
2285
+ setScene({ content: text });
2286
+ } else {
2287
+ console.error("Failed to fetch scene:", response);
2288
+ setError(true);
2289
+ }
2290
+ setIsLoading(false);
2291
+ } catch (error2) {
2292
+ setError(true);
2293
+ setIsLoading(false);
2294
+ console.error("Error fetching scene:", error2);
2295
+ }
2296
+ };
2297
+ fetchScene();
2298
+ }, []);
2208
2299
  const blocks = useMemo(() => {
2209
2300
  if (!scene || !scene.content) return [];
2210
2301
  const parser = new DOMParser();
@@ -2246,24 +2337,15 @@ function useScriptBreakdownScene(sceneNumber) {
2246
2337
  }, [blocks]);
2247
2338
  const handleAISummarize = async () => {
2248
2339
  setIsSummarizing(true);
2249
- const res = await fetch(
2250
- "https://nonfibrous-extrafloral-verlene.ngrok-free.dev/extract",
2251
- {
2252
- method: "POST",
2253
- headers: {
2254
- "Content-Type": "application/json",
2255
- "ngrok-skip-browser-warning": "true"
2256
- },
2257
- body: JSON.stringify({
2258
- script: (scene == null ? void 0 : scene.content) || ""
2259
- })
2260
- }
2261
- );
2340
+ const res = await (onAISummarize == null ? void 0 : onAISummarize(scene.content));
2262
2341
  if (res.ok) {
2263
2342
  const data = await res.json();
2264
2343
  setIsSummarizing(false);
2265
- const parsedData = JSON.parse(data.data) || [];
2266
- console.log("AI Tags:", parsedData);
2344
+ const normalData = JSON.parse(data.data);
2345
+ const parsedData = Array.isArray(normalData) ? normalData[0] : [];
2346
+ const summary = Array.isArray(normalData) ? normalData[1] : "";
2347
+ const parsedSummaryData = summary[0];
2348
+ setSceneBrief(parsedSummaryData.summarise);
2267
2349
  const newTags = [];
2268
2350
  parsedData.forEach((aiTag) => {
2269
2351
  if (!aiTag.block_id || !aiTag.category_id || typeof aiTag.start_index !== "number" || typeof aiTag.end_index !== "number") {
@@ -2312,9 +2394,9 @@ function useScriptBreakdownScene(sceneNumber) {
2312
2394
  setSubLocations([]);
2313
2395
  setSceneBrief("");
2314
2396
  autoTaggedSceneRef.current = null;
2315
- }, [sceneNumber]);
2397
+ }, [scene_url]);
2316
2398
  useEffect(() => {
2317
- if (blocks.length > 0 && characters.length > 0 && autoTaggedSceneRef.current !== sceneNumber) {
2399
+ if (blocks.length > 0 && characters.length > 0 && autoTaggedSceneRef.current !== scene) {
2318
2400
  const autoTags = [];
2319
2401
  const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2320
2402
  const sortedChars = [...characters].sort((a, b) => b.length - a.length);
@@ -2344,9 +2426,9 @@ function useScriptBreakdownScene(sceneNumber) {
2344
2426
  });
2345
2427
  });
2346
2428
  setTags(autoTags);
2347
- autoTaggedSceneRef.current = sceneNumber;
2429
+ autoTaggedSceneRef.current = scene;
2348
2430
  }
2349
- }, [blocks, characters, sceneNumber]);
2431
+ }, [blocks, characters, scene]);
2350
2432
  const clearSelection = useCallback(() => {
2351
2433
  var _a;
2352
2434
  setSelectionMenu(null);
@@ -2433,7 +2515,7 @@ function useScriptBreakdownScene(sceneNumber) {
2433
2515
  });
2434
2516
  }
2435
2517
  };
2436
- const addTag = (categoryId) => {
2518
+ const addTag = async (categoryId) => {
2437
2519
  if (!selectionMenu) return;
2438
2520
  const newTag = {
2439
2521
  id: uuid(),
@@ -2450,12 +2532,26 @@ function useScriptBreakdownScene(sceneNumber) {
2450
2532
  return [...filtered, newTag];
2451
2533
  });
2452
2534
  clearSelection();
2535
+ try {
2536
+ await (onTagAdded == null ? void 0 : onTagAdded(newTag));
2537
+ } catch (error2) {
2538
+ console.error("Failed to add tag:", error2);
2539
+ setTags((prev) => prev.filter((t) => t.id !== newTag.id));
2540
+ }
2453
2541
  };
2454
- const removeTag = (e, id) => {
2542
+ const removeTag = async (e, id) => {
2455
2543
  e.stopPropagation();
2456
2544
  e.preventDefault();
2545
+ const tagToRemove = tags.find((t) => t.id === id);
2546
+ if (!tagToRemove) return;
2457
2547
  setTags((prev) => prev.filter((t) => t.id !== id));
2458
2548
  clearSelection();
2549
+ try {
2550
+ await (onTagRemoved == null ? void 0 : onTagRemoved(id));
2551
+ } catch (error2) {
2552
+ console.error("Failed to remove tag:", error2);
2553
+ setTags((prev) => [...prev, tagToRemove]);
2554
+ }
2459
2555
  };
2460
2556
  return {
2461
2557
  scene,