feat: add translations for chat message button tooltips

- Add deleteMessage, copyRawMarkdown, copyHTML translation keys to all 19 language files
- Update all chat bubble button tooltips to use translation functions
- Provides proper localization for Delete message, Copy raw (Markdown), and Copy HTML buttons
This commit is contained in:
Russell Ballestrini 2025-07-10 22:01:43 -04:00
parent 48c5146e65
commit 4f4993b605
20 changed files with 68 additions and 11 deletions

View file

@ -108,5 +108,8 @@ export const ar = {
pausedClickToResume: "متوقف. انقر للمتابعة",
downloadPageAudio: "تنزيل ملف MP3 الخاص بتحويل النص إلى كلام لهذه الصفحة.",
downloadChatAudio: "تنزيل هذه الرسالة كملف .mp3.",
deleteMessage: "حذف الرسالة",
copyRawMarkdown: "نسخ النص الخام (Markdown)",
copyHTML: "نسخ HTML",
aiModalNotAvailable: "نافذة الذكاء الاصطناعي غير متاحة في هذا السياق",
};

View file

@ -108,5 +108,8 @@ export const bn = {
pausedClickToResume: "বিরতি। পুনরায় শুরুর জন্য ক্লিক করুন",
downloadPageAudio: "এই পৃষ্ঠার জন্য টেক্সট-টু-স্পিচ .mp3 ফাইলটি ডাউনলোড করুন।",
downloadChatAudio: "এই বার্তাটি একটি .mp3 ফাইল হিসাবে ডাউনলোড করুন।",
deleteMessage: "বার্তা মুছুন",
copyRawMarkdown: "কাঁচা টেক্সট কপি করুন (Markdown)",
copyHTML: "HTML কপি করুন",
aiModalNotAvailable: "AI মডেল এই প্রসঙ্গে উপলব্ধ নয়",
};

View file

@ -108,5 +108,8 @@ export const de = {
pausedClickToResume: "Pausiert. Klicken zum Fortsetzen",
downloadPageAudio: "Laden Sie die Text-to-Speech-MP3-Datei für diese Seite herunter.",
downloadChatAudio: "Diese Nachricht als .mp3-Datei herunterladen.",
deleteMessage: "Nachricht löschen",
copyRawMarkdown: "Rohen Text kopieren (Markdown)",
copyHTML: "HTML kopieren",
aiModalNotAvailable: "KI-Modal ist in diesem Kontext nicht verfügbar",
};

View file

@ -75,6 +75,9 @@ export const en = {
pausedClickToResume: "Paused. Click to resume",
downloadPageAudio: "Download the text to speech .mp3 file for this page.",
downloadChatAudio: "Download this message as an .mp3 file.",
deleteMessage: "Delete message",
copyRawMarkdown: "Copy raw (Markdown)",
copyHTML: "Copy HTML",
// Translation modal tabs
translatePageTab: "📄 Translate Page",

View file

@ -76,6 +76,9 @@ export const es = {
pausedClickToResume: "Pausado. Haz clic para reanudar",
downloadPageAudio: "Descargue el archivo .mp3 de texto a voz para esta página.",
downloadChatAudio: "Descargar este mensaje como archivo .mp3.",
deleteMessage: "Eliminar mensaje",
copyRawMarkdown: "Copiar texto sin formato (Markdown)",
copyHTML: "Copiar HTML",
// Translation modal tabs
translatePageTab: "📄 Traducir Página",

View file

@ -76,6 +76,9 @@ export const fr = {
pausedClickToResume: "En pause. Cliquez pour reprendre",
downloadPageAudio: "Téléchargez le fichier .mp3 de synthèse vocale pour cette page.",
downloadChatAudio: "Télécharger ce message en fichier .mp3.",
deleteMessage: "Supprimer le message",
copyRawMarkdown: "Copier le texte brut (Markdown)",
copyHTML: "Copier HTML",
// Translation modal tabs
translatePageTab: "📄 Traduire la Page",

View file

@ -107,5 +107,8 @@ export const hi = {
pausedClickToResume: "रुका हुआ। जारी रखने के लिए क्लिक करें",
downloadPageAudio: "इस पेज के लिए टेक्स्ट-टू-स्पीच .mp3 फ़ाइल डाउनलोड करें।",
downloadChatAudio: "इस संदेश को .mp3 फ़ाइल के रूप में डाउनलोड करें।",
deleteMessage: "संदेश हटाएं",
copyRawMarkdown: "कच्चा टेक्स्ट कॉपी करें (Markdown)",
copyHTML: "HTML कॉपी करें",
aiModalNotAvailable: "AI मॉडल इस संदर्भ में उपलब्ध नहीं है",
};

View file

@ -108,5 +108,8 @@ export const id = {
pausedClickToResume: "Dijeda. Klik untuk melanjutkan",
downloadPageAudio: "Unduh file .mp3 text-to-speech untuk halaman ini.",
downloadChatAudio: "Unduh pesan ini sebagai file .mp3.",
deleteMessage: "Hapus pesan",
copyRawMarkdown: "Salin teks mentah (Markdown)",
copyHTML: "Salin HTML",
aiModalNotAvailable: "Modal AI tidak tersedia dalam konteks ini",
};

View file

@ -108,5 +108,8 @@ export const ja = {
pausedClickToResume: "一時停止中。再開するにはクリック",
downloadPageAudio: "このページのテキスト読み上げ.mp3ファイルをダウンロードします。",
downloadChatAudio: "このメッセージを.mp3ファイルとしてダウンロード。",
deleteMessage: "メッセージを削除",
copyRawMarkdown: "生テキストをコピー (Markdown)",
copyHTML: "HTMLをコピー",
aiModalNotAvailable: "AIモーダルはこのコンテキストでは利用できません",
};

View file

@ -108,5 +108,8 @@ export const ko = {
pausedClickToResume: "일시정지됨. 재개하려면 클릭",
downloadPageAudio: "이 페이지의 텍스트 음성 변환 .mp3 파일을 다운로드하십시오.",
downloadChatAudio: "이 메시지를 .mp3 파일로 다운로드합니다.",
deleteMessage: "메시지 삭제",
copyRawMarkdown: "원시 텍스트 복사 (Markdown)",
copyHTML: "HTML 복사",
aiModalNotAvailable: "AI 모달이 이 컨텍스트에서 사용할 수 없습니다",
};

View file

@ -108,5 +108,8 @@ export const mr = {
pausedClickToResume: "थांबवले आहे. पुन्हा सुरू करण्यासाठी क्लिक करा",
downloadPageAudio: "या पृष्ठासाठी टेक्स्ट-टू-स्पीच .mp3 फाइल डाउनलोड करा.",
downloadChatAudio: "हा संदेश .mp3 फाइल म्हणून डाउनलोड करा.",
deleteMessage: "संदेश हटवा",
copyRawMarkdown: "कच्चा मजकूर कॉपी करा (Markdown)",
copyHTML: "HTML कॉपी करा",
aiModalNotAvailable: "AI मॉडल या संदर्भात उपलब्ध नाही",
};

View file

@ -108,5 +108,8 @@ export const pt = {
pausedClickToResume: "Pausado. Clique para continuar",
downloadPageAudio: "Faça o download do arquivo .mp3 de conversão de texto em fala para esta página.",
downloadChatAudio: "Baixar esta mensagem como arquivo .mp3.",
deleteMessage: "Excluir mensagem",
copyRawMarkdown: "Copiar texto bruto (Markdown)",
copyHTML: "Copiar HTML",
aiModalNotAvailable: "Modal de IA não disponível neste contexto",
};

View file

@ -108,5 +108,8 @@ export const ru = {
pausedClickToResume: "На паузе. Нажмите для продолжения",
downloadPageAudio: "Загрузите mp3-файл с преобразованием текста в речь для этой страницы.",
downloadChatAudio: "Скачать это сообщение как .mp3 файл.",
deleteMessage: "Удалить сообщение",
copyRawMarkdown: "Копировать исходный текст (Markdown)",
copyHTML: "Копировать HTML",
aiModalNotAvailable: "Модальное окно ИИ недоступно в этом контексте",
};

View file

@ -108,5 +108,8 @@ export const sw = {
pausedClickToResume: "Kusitishwa. Bonyeza kuendelea",
downloadPageAudio: "Pakua faili ya .mp3 ya maandishi-hadi-hotuba ya ukurasa huu.",
downloadChatAudio: "Pakua ujumbe huu kama faili ya .mp3.",
deleteMessage: "Futa ujumbe",
copyRawMarkdown: "Nakili maandishi ghafi (Markdown)",
copyHTML: "Nakili HTML",
aiModalNotAvailable: "Modal ya AI haipatikani katika muktadha huu",
};

View file

@ -108,5 +108,8 @@ export const te = {
pausedClickToResume: "నిలిపివేయబడింది. కొనసాగించడానికి క్లిక్ చేయండి",
downloadPageAudio: "ఈ పేజీ కోసం టెక్స్ట్-టు-స్పీచ్ .mp3 ఫైల్‌ను డౌన్‌లోడ్ చేయండి.",
downloadChatAudio: "ఈ సందేశాన్ని .mp3 ఫైల్‌గా డౌన్‌లోడ్ చేయండి.",
deleteMessage: "సందేశాన్ని తొలగించు",
copyRawMarkdown: "ముడి వచనాన్ని కాపీ చేయండి (Markdown)",
copyHTML: "HTML కాపీ చేయండి",
aiModalNotAvailable: "AI మోడల్ ఈ సందర్భంలో అందుబాటులో లేదు",
};

View file

@ -108,5 +108,8 @@ export const tr = {
pausedClickToResume: "Duraklatıldı. Devam etmek için tıklayın",
downloadPageAudio: "Bu sayfa için metin okuma .mp3 dosyasını indirin.",
downloadChatAudio: "Bu mesajı .mp3 dosyası olarak indir.",
deleteMessage: "Mesajı sil",
copyRawMarkdown: "Ham metni kopyala (Markdown)",
copyHTML: "HTML kopyala",
aiModalNotAvailable: "AI modalı bu bağlamda mevcut değil",
};

View file

@ -108,5 +108,8 @@ export const ur = {
pausedClickToResume: "رک گیا۔ جاری رکھنے کے لیے کلک کریں",
downloadPageAudio: "اس صفحے کے لیے ٹیکسٹ ٹو اسپیچ .mp3 فائل ڈاؤن لوڈ کریں۔",
downloadChatAudio: "اس پیغام کو .mp3 فائل کے طور پر ڈاؤن لوڈ کریں۔",
deleteMessage: "پیغام حذف کریں",
copyRawMarkdown: "خام متن کاپی کریں (Markdown)",
copyHTML: "HTML کاپی کریں",
aiModalNotAvailable: "AI ماڈل اس سیاق میں دستیاب نہیں ہے",
};

View file

@ -106,5 +106,8 @@ export const zhTw = {
pausedClickToResume: "已暫停。點擊繼續",
downloadPageAudio: "下載此頁面的文字轉語音 .mp3 檔案。",
downloadChatAudio: "將此訊息下載為 .mp3 檔案。",
deleteMessage: "刪除訊息",
copyRawMarkdown: "複製原始文字 (Markdown)",
copyHTML: "複製 HTML",
aiModalNotAvailable: "AI對話框在此上下文中不可用",
};

View file

@ -106,5 +106,8 @@ export const zh = {
pausedClickToResume: "已暂停。点击继续",
downloadPageAudio: "下载此页面的文本转语音 .mp3 文件。",
downloadChatAudio: "将此消息下载为 .mp3 文件。",
deleteMessage: "删除消息",
copyRawMarkdown: "复制原始文本 (Markdown)",
copyHTML: "复制 HTML",
aiModalNotAvailable: "AI模态框在此上下文中不可用",
};

View file

@ -931,7 +931,7 @@ async function openUncloseaiEmbeddedModalNew() {
const userDeleteBtn = document.createElement("button");
userDeleteBtn.textContent = "🗑️";
userDeleteBtn.title = "Delete message";
userDeleteBtn.title = getUIText("deleteMessage");
userDeleteBtn.className = "uncloseai-btn-small";
userDeleteBtn.onclick = async () => {
// Remove from chat history and localStorage
@ -1124,7 +1124,7 @@ async function openUncloseaiEmbeddedModalNew() {
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "🗑️";
deleteBtn.title = "Delete message";
deleteBtn.title = getUIText("deleteMessage");
deleteBtn.className = "uncloseai-btn-small";
deleteBtn.onclick = async () => {
// Remove both user and AI messages from history and localStorage
@ -1150,7 +1150,7 @@ async function openUncloseaiEmbeddedModalNew() {
// Copy Raw (Markdown) button
const copyRawBtn = document.createElement("button");
copyRawBtn.textContent = "📋";
copyRawBtn.title = "Copy raw (Markdown)";
copyRawBtn.title = getUIText("copyRawMarkdown");
copyRawBtn.className = "uncloseai-btn-small";
copyRawBtn.onclick = async () => {
try {
@ -1168,7 +1168,7 @@ async function openUncloseaiEmbeddedModalNew() {
// Copy HTML button
const copyHtmlBtn = document.createElement("button");
copyHtmlBtn.textContent = "📄";
copyHtmlBtn.title = "Copy HTML";
copyHtmlBtn.title = getUIText("copyHTML");
copyHtmlBtn.className = "uncloseai-btn-small";
copyHtmlBtn.onclick = async () => {
try {
@ -1455,7 +1455,7 @@ You have complete knowledge of this page content and can reference any details,
const userDeleteBtn = document.createElement("button");
userDeleteBtn.textContent = "🗑️";
userDeleteBtn.title = "Delete message";
userDeleteBtn.title = getUIText("deleteMessage");
userDeleteBtn.className = "uncloseai-btn-small";
userDeleteBtn.onclick = async () => {
// Remove from chat history by index
@ -1618,7 +1618,7 @@ You have complete knowledge of this page content and can reference any details,
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "🗑️";
deleteBtn.title = "Delete message";
deleteBtn.title = getUIText("deleteMessage");
deleteBtn.className = "uncloseai-btn-small";
deleteBtn.onclick = async () => {
// Remove from chat history and localStorage by index
@ -1640,7 +1640,7 @@ You have complete knowledge of this page content and can reference any details,
// Copy Raw (Markdown) button
const copyRawBtn = document.createElement("button");
copyRawBtn.textContent = "📋";
copyRawBtn.title = "Copy raw (Markdown)";
copyRawBtn.title = getUIText("copyRawMarkdown");
copyRawBtn.className = "uncloseai-btn-small";
copyRawBtn.onclick = async () => {
try {
@ -1658,7 +1658,7 @@ You have complete knowledge of this page content and can reference any details,
// Copy HTML button
const copyHtmlBtn = document.createElement("button");
copyHtmlBtn.textContent = "📄";
copyHtmlBtn.title = "Copy HTML";
copyHtmlBtn.title = getUIText("copyHTML");
copyHtmlBtn.className = "uncloseai-btn-small";
copyHtmlBtn.onclick = async () => {
try {
@ -1868,7 +1868,7 @@ You have complete knowledge of this page content and can reference any details,
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "🗑️";
deleteBtn.title = "Delete message";
deleteBtn.title = getUIText("deleteMessage");
deleteBtn.className = "uncloseai-btn-small";
deleteBtn.onclick = async () => {
// Remove intro message from localStorage
@ -1890,7 +1890,7 @@ You have complete knowledge of this page content and can reference any details,
// Copy Raw (Markdown) button
const copyRawBtn = document.createElement("button");
copyRawBtn.textContent = "📋";
copyRawBtn.title = "Copy raw (Markdown)";
copyRawBtn.title = getUIText("copyRawMarkdown");
copyRawBtn.className = "uncloseai-btn-small";
copyRawBtn.onclick = async () => {
try {
@ -1908,7 +1908,7 @@ You have complete knowledge of this page content and can reference any details,
// Copy HTML button
const copyHtmlBtn = document.createElement("button");
copyHtmlBtn.textContent = "📄";
copyHtmlBtn.title = "Copy HTML";
copyHtmlBtn.title = getUIText("copyHTML");
copyHtmlBtn.className = "uncloseai-btn-small";
copyHtmlBtn.onclick = async () => {
try {