-
- {title.slice(0, 2).toUpperCase()} {id}
+
+
+
+
+
+ {title.slice(0, 2).toUpperCase()} {id}
+
-
-
-
{title}
-
{description}
-
-
-
+
+
{title}
+
{description}
+
+
+
+
+
+
+ handleDeleteSpace(id)}
+ className="w-4 cursor-pointer"
+ />
-
+
);
}
diff --git a/apps/web/app/(dash)/chat/chatWindow.tsx b/apps/web/app/(dash)/chat/chatWindow.tsx
index 3d7ca295..60acd16d 100644
--- a/apps/web/app/(dash)/chat/chatWindow.tsx
+++ b/apps/web/app/(dash)/chat/chatWindow.tsx
@@ -6,7 +6,7 @@ import QueryInput from "./chatQueryInput";
import { cn } from "@repo/ui/lib/utils";
import { motion } from "framer-motion";
import { useRouter } from "next/navigation";
-import { ChatHistory, sourcesZod } from "@repo/shared-types";
+import { type ChatHistory, sourcesZod } from "@repo/shared-types";
import {
Accordion,
AccordionContent,
@@ -23,7 +23,11 @@ import { codeLanguageSubset } from "@/lib/constants";
import { toast } from "sonner";
import Link from "next/link";
import { createChatObject } from "@/app/actions/doers";
-import { ClipboardIcon } from "@heroicons/react/24/outline";
+import {
+ ClipboardIcon,
+ SpeakerWaveIcon,
+ SpeakerXMarkIcon,
+} from "@heroicons/react/24/outline";
function ChatWindow({
q,
@@ -51,6 +55,8 @@ function ChatWindow({
}) {
const [layout, setLayout] = useState<"chat" | "initial">("chat");
const [chatHistory, setChatHistory] = useState
(initialChat);
+ const [speakingIdx, setSpeakingIdx] = useState(null);
+ const speechSynth: SpeechSynthesis = window.speechSynthesis;
const removeJustificationFromText = (text: string) => {
// remove everything after the first "" word
@@ -66,12 +72,31 @@ function ChatWindow({
return text;
};
+ const handleTTS = (text: string, idx: number) => {
+ if (speakingIdx != null) return stopTTS();
+ if (!text) return;
+ const utterThis: SpeechSynthesisUtterance = new SpeechSynthesisUtterance(
+ text,
+ );
+ utterThis.lang = "en-US";
+ speechSynth.speak(utterThis);
+ setSpeakingIdx(idx);
+ utterThis.onend = () => {
+ setSpeakingIdx(null);
+ };
+ };
+
+ const stopTTS = () => {
+ speechSynth.cancel();
+ setSpeakingIdx(null);
+ };
+
const router = useRouter();
const getAnswer = async (
query: string,
spaces: string[],
- proMode: boolean = false,
+ proMode = false,
) => {
if (query.trim() === "from_loading" || query.trim().length === 0) {
return;
@@ -263,10 +288,10 @@ function ChatWindow({