import { useEffect, useRef, useState } from "react"; async function translateText(text: string, target: string, apiKey: string) { let url = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`; let body = JSON.stringify({ q: text, target, }); let options = { body, method: "POST", }; let result = await fetch(url, options); let json = await result.json(); let { data } = json; if (data?.translations) { let [translation] = data.translations; return { from: translation.detectedSourceLanguage, translation: translation.translatedText, }; } return false; } export function useTranslation(text: string, targetLanguage: string, apiKey: string) { let [translation, setTranslation] = useState(""); let [error, setError] = useState(null); let [from, setSourceLang] = useState(null); let [isTranslating, setIsTranslating] = useState(false); let textRef = useRef(text); // oxlint-disable-next-line react-hooks/exhaustive-deps -- this is a way of resetting the state so we don't show outdated translations when the text changes useEffect(() => { textRef.current = text; return () => { setTranslation(""); setError(null); setSourceLang(null); setIsTranslating(false); }; }, [apiKey, targetLanguage, text]); async function translate() { setIsTranslating(true); try { let result = await translateText(text, targetLanguage, apiKey); if (result && textRef.current === text) { let { from, translation } = result; setSourceLang(from); setTranslation(translation); setIsTranslating(false); } } catch (error) { if (textRef.current === text) { setError((error as Error).message); setIsTranslating(false); } } } return { error, from, isTranslating, translation, translate, }; }