// Translator frontend (() => { const $ = (id) => document.getElementById(id); // ── Populate language pickers ── async function loadLanguages() { try { const r = await fetch("/api/languages"); const data = await r.json(); const srcSel = $("source-lang"); const tgtSel = $("target-lang"); for (const lang of data.languages) { const o1 = document.createElement("option"); o1.value = lang.code; o1.textContent = lang.cs; srcSel.appendChild(o1); if (lang.code === "auto") continue; const o2 = document.createElement("option"); o2.value = lang.code; o2.textContent = lang.cs; tgtSel.appendChild(o2); } // Persisted prefs srcSel.value = localStorage.getItem("trans_source") || "auto"; tgtSel.value = localStorage.getItem("trans_target") || "en"; $("tone").value = localStorage.getItem("trans_tone") || "formal"; updateSwapEnabled(); } catch (err) { console.error("Failed to load languages", err); } } function updateSwapEnabled() { // Can only swap when source is a specific language (not auto) $("swap-btn").disabled = $("source-lang").value === "auto"; } // Persist on change $("source-lang").addEventListener("change", () => { localStorage.setItem("trans_source", $("source-lang").value); updateSwapEnabled(); }); $("target-lang").addEventListener("change", () => localStorage.setItem("trans_target", $("target-lang").value)); $("tone").addEventListener("change", () => localStorage.setItem("trans_tone", $("tone").value)); $("swap-btn").addEventListener("click", () => { const src = $("source-lang").value; const tgt = $("target-lang").value; if (src === "auto") return; $("source-lang").value = tgt; $("target-lang").value = src; // Also swap text content if both panels have content const sourceText = $("source-text").value; const outputText = $("output-text").value; if (outputText.trim()) { $("source-text").value = outputText; $("output-text").value = sourceText; updateCount(); } localStorage.setItem("trans_source", $("source-lang").value); localStorage.setItem("trans_target", $("target-lang").value); }); // ── Source text handling ── const sourceTextEl = $("source-text"); const outputTextEl = $("output-text"); function updateCount() { const n = sourceTextEl.value.length; $("source-count").textContent = `${n.toLocaleString("cs-CZ")} znaků`; updateRunButton(); } function updateRunButton() { const hasText = sourceTextEl.value.trim().length > 0; $("translate-btn").disabled = !hasText; $("translate-hint").textContent = hasText ? "Připraveno k překladu." : "Vložte text výše."; } sourceTextEl.addEventListener("input", updateCount); updateCount(); $("clear-btn").addEventListener("click", () => { sourceTextEl.value = ""; outputTextEl.value = ""; $("copy-btn").disabled = true; updateCount(); }); // ── Translate ── $("translate-btn").addEventListener("click", async () => { const text = sourceTextEl.value.trim(); if (!text) return; $("translate-btn").disabled = true; $("translate-loading").classList.remove("hidden"); outputTextEl.value = ""; try { const r = await fetch("/api/translate", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({ text, source_lang: $("source-lang").value, target_lang: $("target-lang").value, tone: $("tone").value, }), }); if (!r.ok) { const errBody = await r.json().catch(() => ({detail: r.statusText})); throw new Error(errBody.detail || r.statusText); } const data = await r.json(); outputTextEl.value = data.translated || ""; $("copy-btn").disabled = !data.translated; } catch (err) { alert("Chyba: " + err.message); } finally { $("translate-loading").classList.add("hidden"); $("translate-btn").disabled = false; } }); // ── Copy ── $("copy-btn").addEventListener("click", (e) => { const btn = e.target; navigator.clipboard.writeText(outputTextEl.value).then(() => { const original = btn.textContent; btn.textContent = "Zkopírováno"; btn.classList.add("copied"); setTimeout(() => { btn.textContent = original; btn.classList.remove("copied"); }, 1500); }).catch(() => alert("Kopírování selhalo.")); }); // Keyboard shortcut: Ctrl/Cmd+Enter in source area to translate sourceTextEl.addEventListener("keydown", (e) => { if ((e.ctrlKey || e.metaKey) && e.key === "Enter") { e.preventDefault(); if (!$("translate-btn").disabled) $("translate-btn").click(); } }); loadLanguages(); })();