From 31e0848c954fdbf6d412667259f1bfa93cfc3ea6 Mon Sep 17 00:00:00 2001 From: Jack Merrill Date: Tue, 22 Apr 2025 17:00:56 -0400 Subject: [PATCH] rework markdown rendering and TTS --- app/auth/callback/route.ts | 1 - app/dashboard/documents/[id]/page.tsx | 99 +++++----- app/layout.tsx | 7 +- bun.lockb | Bin 196712 -> 222392 bytes components/KokoroReader.tsx | 158 ++++----------- components/MarkdownRenderer.tsx | 106 +++++++++++ components/TTSProvider.tsx | 265 ++++++++++++++++++++++++++ components/nav-actions.tsx | 38 ++-- components/ui/slider.tsx | 63 ++++++ lib/utils.ts | 42 ++++ package.json | 6 +- utils/supabase/middleware.ts | 12 +- 12 files changed, 606 insertions(+), 191 deletions(-) create mode 100644 components/MarkdownRenderer.tsx create mode 100644 components/TTSProvider.tsx create mode 100644 components/ui/slider.tsx diff --git a/app/auth/callback/route.ts b/app/auth/callback/route.ts index ebafd99..bad936f 100644 --- a/app/auth/callback/route.ts +++ b/app/auth/callback/route.ts @@ -14,7 +14,6 @@ export async function GET(request: Request) { const supabase = await createClient(); await supabase.auth.exchangeCodeForSession(code); } - console.log("code", code); if (redirectTo) { return NextResponse.redirect(`${origin}${redirectTo}`); } diff --git a/app/dashboard/documents/[id]/page.tsx b/app/dashboard/documents/[id]/page.tsx index 7309060..10136c6 100644 --- a/app/dashboard/documents/[id]/page.tsx +++ b/app/dashboard/documents/[id]/page.tsx @@ -1,5 +1,4 @@ import { AppSidebar } from "@/components/app-sidebar"; -import KokoroReader from "@/components/KokoroReader"; import { NavActions } from "@/components/nav-actions"; import { Breadcrumb, @@ -7,12 +6,7 @@ import { BreadcrumbList, BreadcrumbPage, } from "@/components/ui/breadcrumb"; -import { Button } from "@/components/ui/button"; -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover"; + import { Separator } from "@/components/ui/separator"; import { SidebarInset, @@ -20,18 +14,23 @@ import { SidebarTrigger, } from "@/components/ui/sidebar"; import { createClient } from "@/utils/supabase/server"; -import { Speech } from "lucide-react"; import { redirect } from "next/navigation"; -import { remark } from "remark"; -import remarkHtml from "remark-html"; + +import { TTSProvider } from "@/components/TTSProvider"; +import MarkdownRenderer from "@/components/MarkdownRenderer"; export default async function DocumentPage(props: { params: { id: string } }) { const supabase = await createClient(); const { data: { user }, + error: userError, } = await supabase.auth.getUser(); + if (userError) { + console.error("Error fetching user:", userError); + } + if (!user) { return redirect("/login"); } @@ -66,44 +65,46 @@ export default async function DocumentPage(props: { params: { id: string } }) { const pages = (document.ocr_data as any).map((page: any) => page.markdown); - const processedContent = await remark() - .use(remarkHtml) - .process(pages.join("\n")); + // Here we simply recreate the pages string: + const rawContent = + (document?.ocr_data as any)?.map((page: any) => page.markdown).join("\n") || + ""; return ( - { - return { - name: d.file_name, - url: `/dashboard/documents/${d.id}`, - emoji: "📄", - }; - })} - /> - -
-
- - - - - - - {document.file_name || "Document Details"} - - - - -
-
- -
-
-
+ { + return { + name: d.file_name, + url: `/dashboard/documents/${d.id}`, + emoji: "📄", + }; + })} + /> + +
+
+ + + + + + + {document.file_name || "Document Details"} + + + + +
+
+ +
+
+ {/*
-
+ >
*/} +
+ +
+
+
); } diff --git a/app/layout.tsx b/app/layout.tsx index 430e63b..5e93219 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -8,6 +8,7 @@ import { ThemeProvider } from "next-themes"; import Link from "next/link"; import "./globals.css"; import { Toaster } from "@/components/ui/sonner"; +import { TooltipProvider } from "@/components/ui/tooltip"; const defaultUrl = process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` @@ -15,8 +16,8 @@ const defaultUrl = process.env.VERCEL_URL export const metadata = { metadataBase: new URL(defaultUrl), - title: "Next.js and Supabase Starter Kit", - description: "The fastest way to build apps with Next.js and Supabase", + title: "Neuroread", + description: "The easiest way to read articles and papers.", }; const geistSans = Geist({ @@ -38,7 +39,7 @@ export default function RootLayout({ enableSystem disableTransitionOnChange > - {children} + {children} diff --git a/bun.lockb b/bun.lockb index bacc2ec0544caecfd63bde37e2e070efc5339692..84a569d43abc9596cdd6ff8d6b3c31ac9febdb07 100755 GIT binary patch delta 51690 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 a+_gE_%()S-w_mEjADoni@-O4fZv8*kIBl2! diff --git a/components/KokoroReader.tsx b/components/KokoroReader.tsx index 90faccf..6c38a84 100644 --- a/components/KokoroReader.tsx +++ b/components/KokoroReader.tsx @@ -1,7 +1,7 @@ "use client"; import { useRef, useState, useEffect } from "react"; import { Button } from "./ui/button"; -import { Play } from "lucide-react"; +import { Loader, Pause, Play } from "lucide-react"; import { Accordion, AccordionContent, @@ -9,93 +9,54 @@ import { AccordionTrigger, } from "./ui/accordion"; import { Label } from "./ui/label"; +import { useTTS } from "./TTSProvider"; export default function KokoroReader({ pages }: { pages: any[] }) { - // Create a reference to the worker object. - const worker = useRef(null); + const { + voices, + selectedSpeaker, + setSelectedSpeaker, + skipToSentence, + currentSentence, + setCurrentSentence, + playSentence, + playInOrder, + status, + } = useTTS(); - const [inputText, setInputText] = useState( - "Life is like a box of chocolates. You never know what you're gonna get." - ); - const [selectedSpeaker, setSelectedSpeaker] = useState("af_heart"); + const [playing, setPlaying] = useState(false); - const [voices, setVoices] = useState([]); - const [status, setStatus] = useState<"ready" | "running" | null>(null); - const [error, setError] = useState(null); - const [loadingMessage, setLoadingMessage] = useState("Loading..."); - - const [results, setResults] = useState<{ text: string; src: string }[]>([]); - - // We use the `useEffect` hook to setup the worker as soon as the `App` component is mounted. useEffect(() => { - // Create the worker if it does not yet exist. - console.log("Initializing worker..."); - worker.current ??= new Worker("/workers/kokoro-worker.js", { - type: "module", - }); + setCurrentSentence(0); // this might just jumpstart the audio + }, [status === "ready"]); - console.log("Worker initialized"); + const play = () => { + if (playing) { + setPlaying(false); + return; + } - // Create a callback function for messages from the worker thread. - const onMessageReceived = (e: any) => { - switch (e.data.status) { - case "device": - setLoadingMessage(`Loading model (device="${e.data.device}")`); - break; - case "ready": - setStatus("ready"); - setVoices(e.data.voices); - break; - case "error": - setError(e.data.data); - break; - case "complete": - const { audio, text } = e.data; - // Generation complete: re-enable the "Generate" button - setResults((prev) => [{ text, src: audio }, ...prev]); - setStatus("ready"); - break; - } - }; - - console.log("onmessagereceived"); - - const onErrorReceived = (e: any) => { - console.error("Worker error:", e); - setError(e.message); - }; - - console.log("Attaching event listeners to worker"); - - // Attach the callback function as an event listener. - worker.current.addEventListener("message", onMessageReceived); - worker.current.addEventListener("error", onErrorReceived); - - console.log(worker.current); - // Define a cleanup function for when the component is unmounted. - return () => { - worker.current!.removeEventListener("message", onMessageReceived); - worker.current!.removeEventListener("error", onErrorReceived); - }; - }, []); - - const handleSubmit = (e: any) => { - e.preventDefault(); - setStatus("running"); - - worker.current!.postMessage({ - type: "generate", - text: inputText.trim(), - voice: selectedSpeaker, - }); + setPlaying(true); + playInOrder(currentSentence || 0); }; return (
-
@@ -123,53 +84,6 @@ export default function KokoroReader({ pages }: { pages: any[] }) {
- {/*
-
-