import { ArrowUpIcon, CheckIcon, LoaderIcon, MicIcon, PauseIcon, PlayIcon, StepForwardIcon, TypeIcon, WandIcon, XIcon, } from "lucide-react"; import { Button, Textarea } from "@renderer/components/ui"; import { useContext, useEffect, useRef, useState } from "react"; import { LiveAudioVisualizer } from "react-audio-visualize"; import { AppSettingsProviderContext, ChatSessionProviderContext, HotKeysSettingsProviderContext, } from "@renderer/context"; import { t } from "i18next"; import autosize from "autosize"; import { ChatSuggestionButton } from "@renderer/components"; import { useHotkeys } from "react-hotkeys-hook"; import { ChatTypeEnum } from "@/types/enums"; export const ChatInput = () => { const { chat, submitting, startRecording, stopRecording, cancelRecording, togglePauseResume, isRecording, mediaRecorder, recordingTime, isPaused, askAgent, onCreateMessage, shadowing, } = useContext(ChatSessionProviderContext); const { EnjoyApp } = useContext(AppSettingsProviderContext); const inputRef = useRef(null); const submitRef = useRef(null); const [inputMode, setInputMode] = useState<"text" | "audio">("text"); const [content, setContent] = useState(""); const { currentHotkeys } = useContext(HotKeysSettingsProviderContext); useEffect(() => { if (!inputRef.current) return; autosize(inputRef.current); inputRef.current.addEventListener("keypress", (event) => { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); submitRef.current?.click(); } }); inputRef.current.focus(); return () => { inputRef.current?.removeEventListener("keypress", () => {}); autosize.destroy(inputRef.current); }; }, [inputRef.current]); useEffect(() => { EnjoyApp.cacheObjects .get(`chat-input-mode-${chat.id}`) .then((cachedInputMode) => { if (cachedInputMode) { setInputMode(cachedInputMode as typeof inputMode); } }); }, []); useEffect(() => { EnjoyApp.cacheObjects.set(`chat-input-mode-${chat.id}`, inputMode); }, [inputMode]); useHotkeys( currentHotkeys.StartOrStopRecording, () => { if (shadowing) return; if (isRecording) { stopRecording(); } else { startRecording(); } }, { preventDefault: true, } ); useHotkeys( currentHotkeys.PlayNextSegment, () => { if (shadowing) return; askAgent({ force: true }); }, { preventDefault: true, } ); if (isRecording) { return (
{Math.floor(recordingTime / 60)}: {String(recordingTime % 60).padStart(2, "0")}
); } if (inputMode === "text") { return (