diff --git a/src/lib/ChatScreens/Chat.svelte b/src/lib/ChatScreens/Chat.svelte index 06ae4b5c..2246153f 100644 --- a/src/lib/ChatScreens/Chat.svelte +++ b/src/lib/ChatScreens/Chat.svelte @@ -2,7 +2,7 @@ import { ArrowLeft, ArrowRight, EditIcon, LanguagesIcon, RefreshCcwIcon, TrashIcon, CopyIcon } from "lucide-svelte"; import { ParseMarkdown, type simpleCharacterArgument } from "../../ts/parser"; import AutoresizeArea from "../UI/GUI/TextAreaResizable.svelte"; - import { alertConfirm } from "../../ts/alert"; + import { alertConfirm, alertError } from "../../ts/alert"; import { language } from "../../lang"; import { DataBase, type groupChat } from "../../ts/storage/database"; import { CurrentChat, selectedCharID } from "../../ts/stores"; @@ -20,13 +20,16 @@ export let onReroll = () => {} export let unReroll = () => {} export let character:simpleCharacterArgument|string|null = null - let translating = (!!$DataBase.autoTranslate) + let translating = false + try { + translating = get(DataBase).autoTranslate + } catch (error) {} let editMode = false let statusMessage:string = '' export let altGreeting = false let msgDisplay = '' - let translated = false + let translated = get(DataBase).autoTranslate async function rm(){ const rm = $DataBase.askRemoval ? await alertConfirm(language.removeChat) : true if(rm){ @@ -55,7 +58,7 @@ $CurrentChat.message = msg } - async function displaya(message:string){ + function displaya(message:string){ msgDisplay = risuChatParser(message, {chara: name, chatID: idx, rmVar: true}) } @@ -71,14 +74,19 @@ let lastCharArg:string|simpleCharacterArgument = null let lastChatId = -10 - const markParsing = async (data: string, charArg?: string | simpleCharacterArgument, mode?: "normal" | "back", chatID?: number, translateText?:boolean) => { - if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){ + const markParsing = async (data: string, charArg?: string | simpleCharacterArgument, mode?: "normal" | "back", chatID?: number, translateText?:boolean, tries?:number) => { + try { + if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){ lastParsed = '' lastCharArg = charArg lastChatId = chatID - translating = (!!$DataBase.autoTranslate) - translateText = translating - translated = false + translateText = false + try { + translated = get(DataBase).autoTranslate + if(translated){ + translateText = true + } + } catch (error) {} } if(translateText){ const marked = await ParseMarkdown(data, charArg, mode, chatID) @@ -94,6 +102,14 @@ lastParsed = marked lastCharArg = charArg return marked + } + } catch (error) { + //retry + if(tries > 2){ + alertError(`Error while parsing chat message: ${error}`) + return data + } + return await markParsing(data, charArg, mode, chatID, translateText, (tries ?? 0) + 1) } } diff --git a/src/ts/translator/translator.ts b/src/ts/translator/translator.ts index bd0a328c..04212e87 100644 --- a/src/ts/translator/translator.ts +++ b/src/ts/translator/translator.ts @@ -162,29 +162,57 @@ async function jaTrans(text:string) { export async function translateHTML(html: string, reverse:boolean): Promise { const dom = new DOMParser().parseFromString(html, 'text/html'); + console.log(html) + + let promises: Promise[] = []; + + async function translateNodeText(node:Node) { + if(node.textContent.trim().length !== 0){ + node.textContent = await translate(node.textContent || '', reverse); + } + } // Recursive function to translate all text nodes - async function translateNode(node: Node): Promise { + async function translateNode(node: Node, parent?: Node): Promise { if (node.nodeType === Node.TEXT_NODE) { // Translate the text content of the node - if(node.textContent){ - node.textContent = await translate(node.textContent || '', reverse); + if(node.textContent && parent){ + const parentName = parent.nodeName.toLowerCase(); + if(parentName === 'script' || parentName === 'style'){ + return + } + if(promises.length > 10){ + await Promise.all(promises) + promises = [] + } + promises.push(translateNodeText(node)) } } else if(node.nodeType === Node.ELEMENT_NODE) { // Translate child nodes + //skip if it's a script or style tag + if(node.nodeName.toLowerCase() === 'script' || node.nodeName.toLowerCase() === 'style'){ + return + } + for (const child of Array.from(node.childNodes)) { - await translateNode(child); + await translateNode(child, node); } } } + // Start translation from the body element await translateNode(dom.body); + await Promise.all(promises) // Serialize the DOM back to HTML const serializer = new XMLSerializer(); - const translatedHTML = serializer.serializeToString(dom.body); + let translatedHTML = serializer.serializeToString(dom); + // Remove the outer tags + translatedHTML = translatedHTML.replace(/^]*>|<\/body>$/g, ''); + // console.log(html) + // console.log(translatedHTML) // Return the translated HTML, excluding the outer tags if needed return translatedHTML } \ No newline at end of file