-
Notifications
You must be signed in to change notification settings - Fork 538
Empty chat redesign #1287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Empty chat redesign #1287
Changes from all commits
c439a19
c44ef2f
233472b
120e529
959d21f
c620274
586f41b
835c948
507ff73
6b22c5c
dfcb383
75a94e2
3ae39d1
7d5ea43
baa0eca
4a9a029
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,10 @@ import { useEffect } from "react"; | |||||
| import { useForm } from "react-hook-form"; | ||||||
| import { z } from "zod"; | ||||||
|
|
||||||
| // Add these imports for file operations | ||||||
| // import { message } from "@tauri-apps/plugin-dialog"; | ||||||
| // import { writeFile } from "@tauri-apps/plugin-fs"; | ||||||
|
|
||||||
| import { commands as dbCommands } from "@hypr/plugin-db"; | ||||||
| import { commands as localSttCommands, SupportedModel } from "@hypr/plugin-local-stt"; | ||||||
| import { Button } from "@hypr/ui/components/ui/button"; | ||||||
|
|
@@ -137,6 +141,10 @@ export function STTView({ | |||||
| }: STTViewProps) { | ||||||
| const queryClient = useQueryClient(); | ||||||
|
|
||||||
| // Add drag and drop state | ||||||
| // const [isDragOver, setIsDragOver] = useState(false); | ||||||
| // const [isUploading, setIsUploading] = useState(false); | ||||||
|
|
||||||
| const currentSTTModel = useQuery({ | ||||||
| queryKey: ["current-stt-model"], | ||||||
| queryFn: () => localSttCommands.getCurrentModel(), | ||||||
|
|
@@ -243,6 +251,71 @@ export function STTView({ | |||||
| onError: console.error, | ||||||
| }); | ||||||
|
|
||||||
| /* | ||||||
| const handleDragOver = useCallback((e: React.DragEvent) => { | ||||||
| e.preventDefault(); | ||||||
| e.stopPropagation(); | ||||||
| setIsDragOver(true); | ||||||
| }, []); | ||||||
|
|
||||||
| const handleDragLeave = useCallback((e: React.DragEvent) => { | ||||||
| e.preventDefault(); | ||||||
| e.stopPropagation(); | ||||||
| setIsDragOver(false); | ||||||
| }, []); | ||||||
|
|
||||||
| const handleFileDrop = useCallback(async (e: React.DragEvent) => { | ||||||
| e.preventDefault(); | ||||||
| e.stopPropagation(); | ||||||
| setIsDragOver(false); | ||||||
|
|
||||||
| const file = e.dataTransfer.files[0]; | ||||||
| if (!file) { | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| // Validate file extension | ||||||
| const fileName = file.name.toLowerCase(); | ||||||
| if (!fileName.endsWith(".bin") && !fileName.endsWith(".ggml")) { | ||||||
| await message( | ||||||
| "Please drop a valid STT model file (Comming Soon)", | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo in user-facing string: "Comming" should be "Coming". Prompt for AI agents
Suggested change
|
||||||
| { title: "Invalid File Type", kind: "error" }, | ||||||
| ); | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| setIsUploading(true); | ||||||
| try { | ||||||
| // Get the STT models directory | ||||||
| const modelsDir = await localSttCommands.modelsDir(); | ||||||
| const targetPath = `${modelsDir}/${file.name}`; | ||||||
|
|
||||||
| // Read the file content as array buffer | ||||||
| const fileContent = await file.arrayBuffer(); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading the whole model file into memory before writing can exhaust memory for large (>800 MB) models; use a streaming copy instead. Prompt for AI agents |
||||||
| const uint8Array = new Uint8Array(fileContent); | ||||||
|
|
||||||
| // Write the file to the models directory | ||||||
| await writeFile(targetPath, uint8Array); | ||||||
|
|
||||||
| await message(`Model file "${file.name}" copied successfully!`, { | ||||||
| title: "File Copied", | ||||||
| kind: "info", | ||||||
| }); | ||||||
|
|
||||||
| // This invalidation will trigger the automatic refresh | ||||||
| queryClient.invalidateQueries({ queryKey: ["stt-model-download-status"] }); | ||||||
| } catch (error) { | ||||||
| console.error("Error copying model file:", error); | ||||||
| await message(`Failed to copy model file: ${error instanceof Error ? error.message : String(error)}`, { | ||||||
| title: "Copy Failed", | ||||||
| kind: "error", | ||||||
| }); | ||||||
| } finally { | ||||||
| setIsUploading(false); | ||||||
| } | ||||||
| }, [queryClient]); | ||||||
| */ | ||||||
|
|
||||||
| return ( | ||||||
| <div className="space-y-6"> | ||||||
| <div className="flex items-center gap-2"> | ||||||
|
|
@@ -262,6 +335,9 @@ export function STTView({ | |||||
| </div> | ||||||
|
|
||||||
| <div className="max-w-2xl"> | ||||||
| <h3 className="text-sm font-semibold mb-3 text-gray-700"> | ||||||
| Default | ||||||
| </h3> | ||||||
| <div className="space-y-2"> | ||||||
| {modelsToShow.map((model) => ( | ||||||
| <div | ||||||
|
|
@@ -392,6 +468,42 @@ export function STTView({ | |||||
| </div> | ||||||
| </div> | ||||||
|
|
||||||
| { | ||||||
| /* | ||||||
| <div className="max-w-2xl"> | ||||||
| <h3 className="text-sm font-semibold mb-3 text-gray-700"> | ||||||
| Custom | ||||||
| </h3> | ||||||
| <div | ||||||
| className={cn( | ||||||
| "border-2 border-dashed rounded-lg p-8 text-center transition-colors", | ||||||
| isDragOver | ||||||
| ? "border-blue-400 bg-blue-50" | ||||||
| : "border-gray-300 bg-gray-50 hover:border-gray-400", | ||||||
| isUploading && "opacity-50 pointer-events-none", | ||||||
| )} | ||||||
| onDragOver={handleDragOver} | ||||||
| onDragLeave={handleDragLeave} | ||||||
| onDrop={handleFileDrop} | ||||||
| > | ||||||
| {isUploading | ||||||
| ? ( | ||||||
| <div className="flex items-center justify-center gap-2"> | ||||||
| <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600"></div> | ||||||
| <p className="text-gray-600 text-sm"> | ||||||
| Copying model file... | ||||||
| </p> | ||||||
| </div> | ||||||
| ) | ||||||
| : ( | ||||||
| <p className="text-gray-500 text-sm"> | ||||||
| Drag and drop your own STT mode file (.ggml or .bin format) | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo in helper text: "STT mode file" should be "STT model file". Prompt for AI agents
Suggested change
|
||||||
| </p> | ||||||
| )} | ||||||
| </div> | ||||||
| </div> | ||||||
| */ | ||||||
| } | ||||||
| <div className="max-w-2xl"> | ||||||
| <div className="border rounded-lg p-4"> | ||||||
| <h3 className="text-sm font-semibold mb-4"> | ||||||
|
|
@@ -421,7 +533,7 @@ export function STTView({ | |||||
| field.onChange(newValue); | ||||||
| aiConfigMutation.mutate({ redemptionTimeMs: newValue }); | ||||||
| }} | ||||||
| className="w-[100%]" | ||||||
| className="w-[100%] [&>.relative>.absolute]:bg-gray-400 [&>.relative>span[data-state='active']]:bg-gray-300 [&>.relative>span]:border-gray-200" | ||||||
| /> | ||||||
| </div> | ||||||
| </FormControl> | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
userIdis referenced inside theuseCallbackbut is missing from the dependency array, so the memoizedhandleButtonClickmay use a staleuserIdvalue and send incorrect analytics data. (Based on your team's feedback about always including all hook dependencies to avoid stale closures.)Prompt for AI agents