From fd86dc15734f3b7126d88f0130897c597100e30a Mon Sep 17 00:00:00 2001
From: polwex <polwex@sortug.com>
Date: Thu, 15 May 2025 20:32:25 +0700
Subject: m

---
 src/zoom/hooks/useZoom.tsx | 131 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)
 create mode 100644 src/zoom/hooks/useZoom.tsx

(limited to 'src/zoom/hooks/useZoom.tsx')

diff --git a/src/zoom/hooks/useZoom.tsx b/src/zoom/hooks/useZoom.tsx
new file mode 100644
index 0000000..e3fb0c4
--- /dev/null
+++ b/src/zoom/hooks/useZoom.tsx
@@ -0,0 +1,131 @@
+"use client";
+import React, { createContext, useState, useContext, ReactNode } from "react";
+import { ViewLevel, ViewState } from "../logic/types";
+
+// Type definitions for the context
+interface ZoomContextType {
+  viewState: ViewState;
+  setLevel: (level: ViewLevel) => void;
+  setParagraphIndex: (idx: number | null) => void;
+  setSentenceIndex: (idx: number | null) => void;
+  setClauseIndex: (idx: number | null) => void;
+  setWordIndex: (idx: number | null) => void;
+  setSyllableIndex: (idx: number | null) => void;
+  setPhonemeIndex: (idx: number | null) => void;
+  navigateBack: () => void;
+  handleElementClick: (e: React.MouseEvent, idx: number) => void;
+}
+
+// Create the context with default empty values
+const ZoomContext = createContext<ZoomContextType>({
+  viewState: {
+    level: "text",
+    pIndex: null,
+    sIndex: null,
+    cIndex: null,
+    wIndex: null,
+    yIndex: null,
+    fIndex: null,
+  },
+  setLevel: () => {},
+  setParagraphIndex: () => {},
+  setSentenceIndex: () => {},
+  setClauseIndex: () => {},
+  setWordIndex: () => {},
+  setSyllableIndex: () => {},
+  setPhonemeIndex: () => {},
+  navigateBack: () => {},
+  handleElementClick: () => {},
+});
+
+// Provider component
+export const ZoomProvider: React.FC<{ children: ReactNode }> = ({
+  children,
+}) => {
+  const [viewState, setViewState] = useState<ViewState>({
+    level: "text",
+    pIndex: null,
+    sIndex: null,
+    cIndex: null,
+    wIndex: null,
+    yIndex: null,
+    fIndex: null,
+  });
+
+  // Helper functions to update individual parts of the state
+  const setLevel = (level: ViewLevel) =>
+    setViewState((prev) => ({ ...prev, level }));
+  const setParagraphIndex = (pIndex: number | null) =>
+    setViewState((prev) => ({ ...prev, pIndex }));
+  const setSentenceIndex = (sIndex: number | null) =>
+    setViewState((prev) => ({ ...prev, sIndex }));
+  const setClauseIndex = (cIndex: number | null) =>
+    setViewState((prev) => ({ ...prev, cIndex }));
+  const setWordIndex = (wIndex: number | null) =>
+    setViewState((prev) => ({ ...prev, wIndex }));
+  const setSyllableIndex = (yIndex: number | null) =>
+    setViewState((prev) => ({ ...prev, yIndex }));
+  const setPhonemeIndex = (fIndex: number | null) =>
+    setViewState((prev) => ({ ...prev, fIndex }));
+
+  // Handle navigation levels
+  const navigateBack = () => {
+    const { level } = viewState;
+
+    if (level === "paragraph") {
+      setViewState((prev) => ({ ...prev, level: "text", pIndex: null }));
+    } else if (level === "sentence") {
+      setViewState((prev) => ({ ...prev, level: "paragraph", sIndex: null }));
+    } else if (level === "clause") {
+      setViewState((prev) => ({ ...prev, level: "sentence", cIndex: null }));
+    } else if (level === "word") {
+      setViewState((prev) => ({ ...prev, level: "clause", wIndex: null }));
+    } else if (level === "syllable") {
+      setViewState((prev) => ({ ...prev, level: "word", yIndex: null }));
+    } else if (level === "phoneme") {
+      setViewState((prev) => ({ ...prev, level: "syllable", fIndex: null }));
+    }
+  };
+
+  // Handle clicks on elements to navigate forward
+  const handleElementClick = (e: React.MouseEvent, idx: number) => {
+    e.stopPropagation();
+    const { level } = viewState;
+
+    if (level === "text") {
+      setViewState((prev) => ({ ...prev, level: "paragraph", pIndex: idx }));
+    } else if (level === "paragraph") {
+      setViewState((prev) => ({ ...prev, level: "sentence", sIndex: idx }));
+    } else if (level === "sentence") {
+      setViewState((prev) => ({ ...prev, level: "clause", cIndex: idx }));
+    } else if (level === "clause") {
+      setViewState((prev) => ({ ...prev, level: "word", wIndex: idx }));
+    } else if (level === "word") {
+      setViewState((prev) => ({ ...prev, level: "syllable", yIndex: idx }));
+    } else if (level === "syllable") {
+      setViewState((prev) => ({ ...prev, level: "phoneme", fIndex: idx }));
+    }
+  };
+
+  return (
+    <ZoomContext.Provider
+      value={{
+        viewState,
+        setLevel,
+        setParagraphIndex,
+        setSentenceIndex,
+        setClauseIndex,
+        setWordIndex,
+        setSyllableIndex,
+        setPhonemeIndex,
+        navigateBack,
+        handleElementClick,
+      }}
+    >
+      {children}
+    </ZoomContext.Provider>
+  );
+};
+
+// Custom hook to use the zoom context
+export const useZoom = () => useContext(ZoomContext);
-- 
cgit v1.2.3

