[feat] new html translation

This commit is contained in:
kwaroran
2023-11-12 23:59:21 +09:00
parent dd3fa358dd
commit 54a9170041
2 changed files with 65 additions and 36 deletions

View File

@@ -4,10 +4,11 @@
import AutoresizeArea from "../UI/GUI/TextAreaResizable.svelte"; import AutoresizeArea from "../UI/GUI/TextAreaResizable.svelte";
import { alertConfirm } from "../../ts/alert"; import { alertConfirm } from "../../ts/alert";
import { language } from "../../lang"; import { language } from "../../lang";
import { DataBase, type character, type groupChat } from "../../ts/storage/database"; import { DataBase, type groupChat } from "../../ts/storage/database";
import { CurrentChat, selectedCharID } from "../../ts/stores"; import { CurrentChat, selectedCharID } from "../../ts/stores";
import { translate } from "../../ts/translator/translator"; import { translate, translateHTML } from "../../ts/translator/translator";
import { risuChatParser } from "src/ts/process/scripts"; import { risuChatParser } from "src/ts/process/scripts";
import { get } from "svelte/store";
export let message = '' export let message = ''
export let name = '' export let name = ''
export let largePortrait = false export let largePortrait = false
@@ -24,8 +25,7 @@
export let altGreeting = false export let altGreeting = false
let msgDisplay = '' let msgDisplay = ''
let msgTranslated = '' let translated = get(DataBase).autoTranslate
let translated = false;
async function rm(){ async function rm(){
const rm = $DataBase.askRemoval ? await alertConfirm(language.removeChat) : true const rm = $DataBase.askRemoval ? await alertConfirm(language.removeChat) : true
if(rm){ if(rm){
@@ -55,14 +55,7 @@
} }
async function displaya(message:string){ async function displaya(message:string){
if($DataBase.autoTranslate && $DataBase.translator !== ''){ msgDisplay = risuChatParser(message, {chara: name, chatID: idx, rmVar: true})
msgDisplay = risuChatParser(message, {chara: name, chatID: idx, rmVar: true})
msgDisplay = await translate(risuChatParser(message, {chara: name, chatID: idx, rmVar: true}), false)
}
else{
msgDisplay = risuChatParser(message, {chara: name, chatID: idx, rmVar: true})
}
} }
const setStatusMessage = (message:string, timeout:number = 0)=>{ const setStatusMessage = (message:string, timeout:number = 0)=>{
@@ -73,6 +66,20 @@
}, timeout) }, timeout)
} }
let lastParsed = ''
const markParsing = async (data: string, charArg?: string | groupChat | simpleCharacterArgument, mode?: "normal" | "back", chatID?: number, translateText?:boolean) => {
const marked = await ParseMarkdown(data, charArg, mode, chatID)
lastParsed = marked
if(translateText){
translating = true
const translated = await translateHTML(marked, false)
translating = false
return translated
}
return marked
}
$: displaya(message) $: displaya(message)
</script> </script>
<div class="flex max-w-full justify-center risu-chat" class:bgc={isLastMemory}> <div class="flex max-w-full justify-center risu-chat" class:bgc={isLastMemory}>
@@ -107,11 +114,9 @@
<button class={"ml-2 hover:text-green-500 transition-colors "+(editMode?'text-green-400':'')} on:click={() => { <button class={"ml-2 hover:text-green-500 transition-colors "+(editMode?'text-green-400':'')} on:click={() => {
if(!editMode){ if(!editMode){
editMode = true editMode = true
msgTranslated = ""
} }
else{ else{
editMode = false editMode = false
msgTranslated = ""
edit() edit()
} }
}}> }}>
@@ -123,17 +128,7 @@
{/if} {/if}
{#if $DataBase.translator !== ''} {#if $DataBase.translator !== ''}
<button class={"ml-2 cursor-pointer hover:text-green-500 transition-colors " + (translated ? 'text-green-400':'')} class:translating={translating} on:click={async () => { <button class={"ml-2 cursor-pointer hover:text-green-500 transition-colors " + (translated ? 'text-green-400':'')} class:translating={translating} on:click={async () => {
if(translating){ translated = !translated
return
}
if(msgDisplay === risuChatParser(message, {chara: name, chatID: idx, rmVar: true})){
translating = true
msgDisplay = risuChatParser(await translate(message, false), {chara: name, chatID: idx, rmVar: true}), false
translating = false
}
else{
msgDisplay = risuChatParser(message, {chara: name, chatID: idx, rmVar: true})
}
}}> }}>
<LanguagesIcon /> <LanguagesIcon />
</button> </button>
@@ -157,18 +152,21 @@
{#if editMode} {#if editMode}
<AutoresizeArea bind:value={message} /> <AutoresizeArea bind:value={message} />
{:else} {:else}
{#await ParseMarkdown(msgDisplay, character, 'normal', idx) then md} <!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-click-events-have-key-events --> <span class="text chat chattext prose prose-invert minw-0" on:click={() => {
<span class="text chat chattext prose prose-invert minw-0" on:click={() => { if($DataBase.clickToEdit && idx > -1){
if($DataBase.clickToEdit && idx > -1){ editMode = true
editMode = true }
msgTranslated = "" }}
} style:font-size="{0.875 * ($DataBase.zoomsize / 100)}rem"
}} style:line-height="{1.25 * ($DataBase.zoomsize / 100)}rem"
style:font-size="{0.875 * ($DataBase.zoomsize / 100)}rem" >
style:line-height="{1.25 * ($DataBase.zoomsize / 100)}rem" {#await markParsing(msgDisplay, character, 'normal', idx, translated)}
>{@html md}</span> {@html lastParsed}
{:then md}
{@html md}
{/await} {/await}
</span>
{/if} {/if}
</span> </span>

View File

@@ -157,3 +157,34 @@ export async function translateVox(text:string) {
async function jaTrans(text:string) { async function jaTrans(text:string) {
return await runTranslator(text, true, 'en','ja') return await runTranslator(text, true, 'en','ja')
} }
export async function translateHTML(html: string, reverse:boolean): Promise<string> {
const dom = new DOMParser().parseFromString(html, 'text/html');
// Recursive function to translate all text nodes
async function translateNode(node: Node): Promise<void> {
if (node.nodeType === Node.TEXT_NODE) {
// Translate the text content of the node
if(node.textContent){
node.textContent = await translate(node.textContent || '', reverse);
}
} else {
// Translate child nodes
for (const child of Array.from(node.childNodes)) {
await translateNode(child);
}
}
}
// Start translation from the body element
await translateNode(dom.body);
// Serialize the DOM back to HTML
const serializer = new XMLSerializer();
const translatedHTML = serializer.serializeToString(dom.body);
// Return the translated HTML, excluding the outer <body> tags if needed
return translatedHTML
}