Adds a translate buttons for character messages in the chat for beta.character.ai
目前為
// ==UserScript==
// @name Translate Buttons for beta.character.ai
// @namespace TranslateButtonsForBetaCharacterAI
// @description Adds a translate buttons for character messages in the chat for beta.character.ai
// @version 2.0.1
// @author CriDos
// @icon https://www.google.com/s2/favicons?sz=64&domain=beta.character.ai
// @match https://beta.character.ai/chat?char=*
// @grant GM_xmlhttpRequest
// @run-at document-end
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js
// @license MIT
// ==/UserScript==
'use strict';
console.log(`Translate Buttons initializing...`);
let debug = false;
setInterval(addTranslateButtons, 1000);
function addTranslateButtons() {
var charMessages = document.getElementsByClassName("char-msg");
for (var i = 0; i < charMessages.length; i++) {
const msgNode = charMessages[i];
const parentMsgMarkdown = msgNode.parentElement;
if (parentMsgMarkdown.isAutoTranslate) {
continue;
}
parentMsgMarkdown.isAutoTranslate = true;
setInterval(async () => {
await translateNode(msgNode);
}, 500);
}
}
async function translateNode(node) {
const translateClassName = "translate-markdown";
const parentMsgMarkdown = node.parentElement;
const msgMarkdownContent = $(node).html();
if (node.storeContent == msgMarkdownContent) {
return;
}
node.storeContent = msgMarkdownContent;
var translateNode = parentMsgMarkdown.querySelector(`.${translateClassName}`);
if (translateNode == null) {
translateNode = node.cloneNode(true);
translateNode.classList.add(translateClassName);
parentMsgMarkdown.insertBefore(translateNode, parentMsgMarkdown.firstChild);
}
var msgMarkdownClone = node.cloneNode(true);
msgMarkdownClone.classList.add(translateClassName);
const msgMarkdownCloneContent = $(msgMarkdownClone).html();
msgMarkdownClone = null;
$(translateNode).html(await translateText(msgMarkdownCloneContent, "en", navigator.language));
}
async function translateText(text, sLang, tLang) {
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&format=text&sl=${sLang}&tl=${tLang}&dt=t&q=${encodeURIComponent(text)}`;
try {
if (debug) {
console.log(`preTranslate: ${text}`);
}
const response = await doXHR(url);
const responseText = JSON.parse(response.responseText);
let postTranslate = "";
responseText[0].forEach(part => {
postTranslate += part[0];
});
if (debug) {
console.log(`postTranslate: ${postTranslate}`);
}
return postTranslate;
} catch (error) {
console.error(error);
}
}
async function doXHR(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}