Integrar LibreTranslate para traducao automatica
This commit is contained in:
109
frontend/src/hooks/useTranslate.ts
Normal file
109
frontend/src/hooks/useTranslate.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useLanguage } from '@/contexts/LanguageContext';
|
||||
|
||||
// Cache local no cliente
|
||||
const clientCache = new Map<string, string>();
|
||||
|
||||
export function useTranslate() {
|
||||
const { language } = useLanguage();
|
||||
const [isTranslating, setIsTranslating] = useState(false);
|
||||
|
||||
const translate = useCallback(async (text: string): Promise<string> => {
|
||||
if (!text || language === 'PT') return text;
|
||||
|
||||
const targetLang = language.toLowerCase(); // PT -> pt, EN -> en, ES -> es
|
||||
const cacheKey = `pt:${targetLang}:${text}`;
|
||||
|
||||
// Verificar cache local
|
||||
if (clientCache.has(cacheKey)) {
|
||||
return clientCache.get(cacheKey)!;
|
||||
}
|
||||
|
||||
try {
|
||||
setIsTranslating(true);
|
||||
const response = await fetch('/api/translate', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ text, source: 'pt', target: targetLang }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
clientCache.set(cacheKey, data.translatedText);
|
||||
return data.translatedText;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Translation error:', error);
|
||||
} finally {
|
||||
setIsTranslating(false);
|
||||
}
|
||||
|
||||
return text;
|
||||
}, [language]);
|
||||
|
||||
const translateBatch = useCallback(async (texts: string[]): Promise<string[]> => {
|
||||
if (language === 'PT') return texts;
|
||||
|
||||
const targetLang = language.toLowerCase();
|
||||
|
||||
// Separar textos em cache e não em cache
|
||||
const results: string[] = new Array(texts.length);
|
||||
const toTranslate: { index: number; text: string }[] = [];
|
||||
|
||||
texts.forEach((text, index) => {
|
||||
if (!text) {
|
||||
results[index] = text;
|
||||
return;
|
||||
}
|
||||
|
||||
const cacheKey = `pt:${targetLang}:${text}`;
|
||||
if (clientCache.has(cacheKey)) {
|
||||
results[index] = clientCache.get(cacheKey)!;
|
||||
} else {
|
||||
toTranslate.push({ index, text });
|
||||
}
|
||||
});
|
||||
|
||||
if (toTranslate.length === 0) return results;
|
||||
|
||||
try {
|
||||
setIsTranslating(true);
|
||||
const response = await fetch('/api/translate', {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
texts: toTranslate.map(t => t.text),
|
||||
source: 'pt',
|
||||
target: targetLang,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
toTranslate.forEach((item, i) => {
|
||||
const translated = data.translations[i];
|
||||
results[item.index] = translated;
|
||||
clientCache.set(`pt:${targetLang}:${item.text}`, translated);
|
||||
});
|
||||
} else {
|
||||
// Fallback: usar texto original
|
||||
toTranslate.forEach(item => {
|
||||
results[item.index] = item.text;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Batch translation error:', error);
|
||||
toTranslate.forEach(item => {
|
||||
results[item.index] = item.text;
|
||||
});
|
||||
} finally {
|
||||
setIsTranslating(false);
|
||||
}
|
||||
|
||||
return results;
|
||||
}, [language]);
|
||||
|
||||
return { translate, translateBatch, isTranslating, language };
|
||||
}
|
||||
Reference in New Issue
Block a user