summaryrefslogtreecommitdiff
path: root/src/zoom/hooks
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-05-15 20:32:25 +0700
committerpolwex <polwex@sortug.com>2025-05-15 20:32:25 +0700
commitfd86dc15734f3b7126d88f0130897c597100e30a (patch)
tree253890a5f0bde7bc460904ce1743581f53a23d5b /src/zoom/hooks
parent3d4b740e5a512db8fbdd934af2fbc9585fa00f0f (diff)
m
Diffstat (limited to 'src/zoom/hooks')
-rw-r--r--src/zoom/hooks/useZoom.tsx131
1 files changed, 131 insertions, 0 deletions
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);