diff --git a/src/app/(app)/html/[id]/layout.tsx b/src/app/(app)/html/[id]/layout.tsx
index 45189a7..3cadc04 100644
--- a/src/app/(app)/html/[id]/layout.tsx
+++ b/src/app/(app)/html/[id]/layout.tsx
@@ -4,14 +4,11 @@ import type { ReactNode } from 'react';
import { ConfigProvider } from '@/contexts/ConfigContext';
import { TTSProvider } from '@/contexts/TTSContext';
-import { HTMLProvider } from '@/contexts/HTMLContext';
export default function HtmlReaderLayout({ children }: { children: ReactNode }) {
return (
-
- {children}
-
+ {children}
);
}
diff --git a/src/app/(app)/html/[id]/page.tsx b/src/app/(app)/html/[id]/page.tsx
index 7d84452..00d441b 100644
--- a/src/app/(app)/html/[id]/page.tsx
+++ b/src/app/(app)/html/[id]/page.tsx
@@ -3,7 +3,6 @@
import { useParams, useRouter } from "next/navigation";
import Link from 'next/link';
import { useCallback, useEffect, useRef, useState } from 'react';
-import { useHTML } from '@/contexts/HTMLContext';
import { DocumentSkeleton } from '@/components/documents/DocumentSkeleton';
import { HTMLViewer } from '@/components/views/HTMLViewer';
import { DocumentSettings } from '@/components/documents/DocumentSettings';
@@ -16,11 +15,12 @@ import { DocumentHeaderMenu } from '@/components/documents/DocumentHeaderMenu';
import { SegmentsSidebar } from '@/components/reader/SegmentsSidebar';
import { RateLimitBanner } from '@/components/auth/RateLimitBanner';
import { useAuthRateLimit } from '@/contexts/AuthRateLimitContext';
+import { useHtmlDocument } from './useHtmlDocument';
export default function HTMLPage() {
const { id } = useParams();
const router = useRouter();
- const { setCurrentDocument, currDocName, clearCurrDoc } = useHTML();
+ const { setCurrentDocument, currDocData, currDocName, clearCurrDoc } = useHtmlDocument();
const { stop } = useTTS();
const { isAtLimit } = useAuthRateLimit();
const [error, setError] = useState(null);
@@ -168,7 +168,7 @@ export default function HTMLPage() {
) : (
-
+
)}
diff --git a/src/app/(app)/html/[id]/useHtmlDocument.ts b/src/app/(app)/html/[id]/useHtmlDocument.ts
new file mode 100644
index 0000000..22dec1f
--- /dev/null
+++ b/src/app/(app)/html/[id]/useHtmlDocument.ts
@@ -0,0 +1,70 @@
+'use client';
+
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+
+import { useTTS } from '@/contexts/TTSContext';
+import { getDocumentMetadata } from '@/lib/client/api/documents';
+import { ensureCachedDocument } from '@/lib/client/cache/documents';
+
+interface HtmlDocumentState {
+ currDocData: string | undefined;
+ currDocName: string | undefined;
+ currDocText: string | undefined;
+ setCurrentDocument: (id: string) => Promise;
+ clearCurrDoc: () => void;
+}
+
+export function useHtmlDocument(): HtmlDocumentState {
+ const { setText: setTTSText, stop } = useTTS();
+ const setTTSTextRef = useRef(setTTSText);
+
+ const [currDocData, setCurrDocData] = useState();
+ const [currDocName, setCurrDocName] = useState();
+ const [currDocText, setCurrDocText] = useState();
+
+ useEffect(() => {
+ setTTSTextRef.current = setTTSText;
+ }, [setTTSText]);
+
+ const clearCurrDoc = useCallback(() => {
+ setCurrDocData(undefined);
+ setCurrDocName(undefined);
+ setCurrDocText(undefined);
+ stop();
+ }, [stop]);
+
+ const setCurrentDocument = useCallback(async (id: string): Promise => {
+ try {
+ const meta = await getDocumentMetadata(id);
+ if (!meta) {
+ console.error('Document not found on server');
+ return;
+ }
+
+ const doc = await ensureCachedDocument(meta);
+ if (doc.type !== 'html') {
+ console.error('Document is not an HTML/TXT/MD document');
+ return;
+ }
+
+ setCurrDocName(doc.name);
+ setCurrDocData(doc.data);
+ setCurrDocText(doc.data);
+ setTTSTextRef.current(doc.data);
+ } catch (error) {
+ console.error('Failed to get HTML document:', error);
+ clearCurrDoc();
+ }
+ }, [clearCurrDoc]);
+
+ return useMemo(
+ () => ({
+ currDocData,
+ currDocName,
+ currDocText,
+ setCurrentDocument,
+ clearCurrDoc,
+ }),
+ [currDocData, currDocName, currDocText, setCurrentDocument, clearCurrDoc],
+ );
+}
diff --git a/src/components/views/HTMLViewer.tsx b/src/components/views/HTMLViewer.tsx
index 959ee79..2657191 100644
--- a/src/components/views/HTMLViewer.tsx
+++ b/src/components/views/HTMLViewer.tsx
@@ -3,15 +3,15 @@
import { useRef } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
-import { useHTML } from '@/contexts/HTMLContext';
import { DocumentSkeleton } from '@/components/documents/DocumentSkeleton';
interface HTMLViewerProps {
className?: string;
+ currDocData?: string;
+ currDocName?: string;
}
-export function HTMLViewer({ className = '' }: HTMLViewerProps) {
- const { currDocData, currDocName } = useHTML();
+export function HTMLViewer({ className = '', currDocData, currDocName }: HTMLViewerProps) {
const containerRef = useRef(null);
if (!currDocData) {
diff --git a/src/contexts/HTMLContext.tsx b/src/contexts/HTMLContext.tsx
deleted file mode 100644
index 350d0c7..0000000
--- a/src/contexts/HTMLContext.tsx
+++ /dev/null
@@ -1,119 +0,0 @@
-'use client';
-
-import {
- createContext,
- useContext,
- useState,
- ReactNode,
- useCallback,
- useMemo,
- useEffect,
- useRef,
-} from 'react';
-import { getDocumentMetadata } from '@/lib/client/api/documents';
-import { ensureCachedDocument } from '@/lib/client/cache/documents';
-import { useTTS } from '@/contexts/TTSContext';
-
-interface HTMLContextType {
- currDocData: string | undefined;
- currDocName: string | undefined;
- currDocText: string | undefined;
- setCurrentDocument: (id: string) => Promise;
- clearCurrDoc: () => void;
-}
-
-const HTMLContext = createContext(undefined);
-
-/**
- * Provider component for HTML/Markdown functionality
- * Manages the state and operations for HTML document handling
- * @param {Object} props - Component props
- * @param {ReactNode} props.children - Child components to be wrapped by the provider
- */
-export function HTMLProvider({ children }: { children: ReactNode }) {
- const { setText: setTTSText, stop } = useTTS();
- const setTTSTextRef = useRef(setTTSText);
-
- // Current document state
- const [currDocData, setCurrDocData] = useState();
- const [currDocName, setCurrDocName] = useState();
- const [currDocText, setCurrDocText] = useState();
-
- useEffect(() => {
- setTTSTextRef.current = setTTSText;
- }, [setTTSText]);
-
- /**
- * Clears all current document state and stops any active TTS
- */
- const clearCurrDoc = useCallback(() => {
- setCurrDocData(undefined);
- setCurrDocName(undefined);
- setCurrDocText(undefined);
- stop();
- }, [stop]);
-
- /**
- * Sets the current document based on its ID
- * @param {string} id - The unique identifier of the document
- * @throws {Error} When document data is empty or retrieval fails
- */
- const setCurrentDocument = useCallback(async (id: string): Promise => {
- try {
- const meta = await getDocumentMetadata(id);
- if (!meta) {
- console.error('Document not found on server');
- return;
- }
-
- const doc = await ensureCachedDocument(meta);
- if (doc.type !== 'html') {
- console.error('Document is not an HTML/TXT/MD document');
- return;
- }
-
- setCurrDocName(doc.name);
- setCurrDocData(doc.data);
- setCurrDocText(doc.data); // Use the same text for TTS
- setTTSTextRef.current(doc.data);
- } catch (error) {
- console.error('Failed to get HTML document:', error);
- clearCurrDoc();
- }
- }, [clearCurrDoc]);
-
-
-
- const contextValue = useMemo(() => ({
- currDocData,
- currDocName,
- currDocText,
- setCurrentDocument,
- clearCurrDoc,
- }), [
- currDocData,
- currDocName,
- currDocText,
- setCurrentDocument,
- clearCurrDoc,
- ]);
-
- return (
-
- {children}
-
- );
-}
-
-/**
- * Custom hook to consume the HTML context
- * @returns {HTMLContextType} The HTML context value
- * @throws {Error} When used outside of HTMLProvider
- */
-export function useHTML() {
- const context = useContext(HTMLContext);
- if (context === undefined) {
- throw new Error('useHTML must be used within an HTMLProvider');
- }
- return context;
-}