import { useEffect, useState } from "react"; import { useMutation, useQuery } from "@tanstack/react-query"; import { Cpu, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { useToast } from "@/hooks/use-toast"; import { apiRequest, getErrorMessage, queryClient } from "@/lib/queryClient"; interface QwenConfig { url: string; hasApiKey: boolean; } interface QwenTestResult { ok: boolean; error?: string; model?: string; device?: string; voices?: number; } /** * Réglages du service Qwen3-TTS : voix locale gratuite, idéalement sur un * serveur avec carte graphique (ex. Unraid). C'est le service FFmpeg qui * l'appelle : le test vérifie donc la connexion depuis celui-ci. */ export function QwenSettingsCard() { const { toast } = useToast(); const [url, setUrl] = useState(""); const [apiKey, setApiKey] = useState(""); const [test, setTest] = useState(null); const { data: config } = useQuery({ queryKey: ["/api/settings/qwen"] }); useEffect(() => { if (config) setUrl(config.url); }, [config]); const refresh = () => { queryClient.invalidateQueries({ queryKey: ["/api/settings/qwen"] }); // Le choix du moteur « Qwen » dépend de la disponibilité du service queryClient.invalidateQueries({ queryKey: ["/api/reels/voices"] }); }; const save = useMutation({ mutationFn: () => apiRequest("POST", "/api/settings/qwen", { url, apiKey }), onSuccess: () => { refresh(); setApiKey(""); toast({ title: "Configuration sauvegardée", description: "Service Qwen TTS enregistré" }); }, onError: (error) => toast({ title: "Erreur", description: getErrorMessage(error, "Impossible de sauvegarder la configuration Qwen"), variant: "destructive", }), }); const remove = useMutation({ mutationFn: () => apiRequest("DELETE", "/api/settings/qwen"), onSuccess: () => { refresh(); setUrl(""); setApiKey(""); setTest(null); toast({ title: "Configuration supprimée", description: "Service Qwen TTS retiré" }); }, }); const runTest = useMutation({ mutationFn: async () => { const response = await apiRequest("POST", "/api/settings/qwen/test", { url, apiKey }); return (await response.json()) as QwenTestResult; }, onSuccess: setTest, onError: (error) => setTest({ ok: false, error: getErrorMessage(error, "Test impossible") }), }); return ( Qwen TTS (voix locale) Voix française gratuite et expressive, générée par votre propre serveur (idéalement avec carte graphique NVIDIA, ex. Unraid). Voir qwen-tts/docker-compose.gpu.yml.
setUrl(e.target.value)} placeholder="http://192.168.1.20:8001" data-testid="input-qwen-url" />
setApiKey(e.target.value)} placeholder={config?.hasApiKey ? "••••••••••••••••" : "Clé définie sur le serveur Qwen"} data-testid="input-qwen-api-key" /> {config?.hasApiKey && (

✓ Clé enregistrée (laisser vide pour la garder)

)}
{test && (

{test.ok ? `✓ Connecté : ${test.device ?? "?"} — ${test.model ?? ""} (${test.voices ?? 0} voix)` : `✗ ${test.error}`}

)}
{config?.url && ( )}
); }