diff --git a/app/src/components/Generation/FloatingGenerateBox.tsx b/app/src/components/Generation/FloatingGenerateBox.tsx
index d09d489f1..1dc2e0d35 100644
--- a/app/src/components/Generation/FloatingGenerateBox.tsx
+++ b/app/src/components/Generation/FloatingGenerateBox.tsx
@@ -153,10 +153,7 @@ export function FloatingGenerateBox({
| 'kokoro'
| 'qwen_custom_voice';
useEffect(() => {
- if (selectedProfile?.language) {
- form.setValue('language', selectedProfile.language as LanguageCode);
- }
- // Auto-switch engine to match the profile
+ // 1. Auto-switch engine to match the profile FIRST
const engine = selectedProfile?.default_engine ?? selectedProfile?.preset_engine;
if (engine) {
form.setValue('engine', engine as EngineValue);
@@ -168,6 +165,11 @@ export function FloatingGenerateBox({
form.setValue('engine', 'qwen');
}
}
+
+ // 2. Set language AFTER engine has been switched so language dropdown receives valid options
+ if (selectedProfile?.language) {
+ form.setValue('language', selectedProfile.language as LanguageCode);
+ }
// Pre-fill effects from profile defaults
if (
selectedProfile?.effects_chain &&
diff --git a/app/src/components/History/HistoryTable.tsx b/app/src/components/History/HistoryTable.tsx
index aeeae4ece..391a6e032 100644
--- a/app/src/components/History/HistoryTable.tsx
+++ b/app/src/components/History/HistoryTable.tsx
@@ -459,7 +459,7 @@ export function HistoryTable() {
diff --git a/app/src/components/MainEditor/MainEditor.tsx b/app/src/components/MainEditor/MainEditor.tsx
index 042c593f8..73b6a096c 100644
--- a/app/src/components/MainEditor/MainEditor.tsx
+++ b/app/src/components/MainEditor/MainEditor.tsx
@@ -1,4 +1,4 @@
-import { Sparkles, Upload } from 'lucide-react';
+import { Search, Sparkles, Upload, X } from 'lucide-react';
import { useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FloatingGenerateBox } from '@/components/Generation/FloatingGenerateBox';
@@ -12,6 +12,7 @@ import {
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
+import { Input } from '@/components/ui/input';
import { useToast } from '@/components/ui/use-toast';
import { ProfileList } from '@/components/VoiceProfiles/ProfileList';
@@ -30,6 +31,7 @@ export function MainEditor() {
const fileInputRef = useRef(null);
const [importDialogOpen, setImportDialogOpen] = useState(false);
const [selectedFile, setSelectedFile] = useState(null);
+ const [search, setSearch] = useState('');
const { toast } = useToast();
const handleImportClick = () => {
@@ -40,6 +42,7 @@ export function MainEditor() {
const file = e.target.files?.[0];
if (file) {
if (!file.name.endsWith('.voicebox.zip')) {
+ e.target.value = '';
toast({
title: t('main.import.invalidTitle'),
description: t('main.import.invalidDescription'),
@@ -78,12 +81,12 @@ export function MainEditor() {
};
return (
-