diff --git a/src/lib/Others/HypaV3Modal.svelte b/src/lib/Others/HypaV3Modal.svelte index a1e1b6f8..83d39cba 100644 --- a/src/lib/Others/HypaV3Modal.svelte +++ b/src/lib/Others/HypaV3Modal.svelte @@ -7,6 +7,7 @@ RefreshCw, CheckIcon, } from "lucide-svelte"; + import { tick } from "svelte"; import TextAreaInput from "../UI/GUI/TextAreaInput.svelte"; import { alertConfirm, showHypaV3Alert } from "../../ts/alert"; import { DBState, alertStore, selectedCharID } from "src/ts/stores.svelte"; @@ -18,17 +19,20 @@ interface SummaryUI { isTranslating: boolean; translation: string | null; + translationRef: HTMLDivElement; isRerolling: boolean; rerolledText: string | null; isRerolledTranslating: boolean; rerolledTranslation: string | null; + rerolledTranslationRef: HTMLDivElement; } interface ExpandedMessageUI { summaryIndex: number; selectedChatMemo: string; isTranslating: boolean; - translation?: string | null; + translation: string | null; + translationRef: HTMLDivElement; } const hypaV3DataState = $derived( @@ -44,10 +48,12 @@ summaryUIStates = hypaV3DataState.summaries.map(() => ({ isTranslating: false, translation: null, + translationRef: null, isRerolling: false, rerolledText: null, isRerolledTranslating: false, rerolledTranslation: null, + rerolledTranslationRef: null, })); expandedMessageUIState = null; @@ -105,6 +111,18 @@ summaryUIState.isTranslating = true; summaryUIState.translation = "Loading..."; + // Focus on translation element after it's rendered + await tick(); + + if (summaryUIState.translationRef) { + summaryUIState.translationRef.focus(); + summaryUIState.translationRef.scrollIntoView({ + behavior: "smooth", + block: "nearest", + }); + } + + // Translate const result = await translate( hypaV3DataState.summaries[summaryIndex].text, regenerate @@ -178,37 +196,24 @@ summaryUIState.isRerolledTranslating = true; summaryUIState.rerolledTranslation = "Loading..."; + // Focus on rerolled translation element after it's rendered + await tick(); + + if (summaryUIState.rerolledTranslationRef) { + summaryUIState.rerolledTranslationRef.focus(); + summaryUIState.rerolledTranslationRef.scrollIntoView({ + behavior: "smooth", + block: "nearest", + }); + } + + // Translate const result = await translate(summaryUIState.rerolledText, regenerate); summaryUIState.rerolledTranslation = result; summaryUIState.isRerolledTranslating = false; } - async function toggleTranslateExpandedMessage( - regenerate?: boolean - ): Promise { - if (!expandedMessageUIState || expandedMessageUIState.isTranslating) return; - - if (expandedMessageUIState.translation) { - expandedMessageUIState.translation = null; - return; - } - - const message = getMessageFromChatMemo( - expandedMessageUIState.selectedChatMemo - ); - - if (!message) return; - - expandedMessageUIState.isTranslating = true; - expandedMessageUIState.translation = "Loading..."; - - const result = await translate(message.data, regenerate); - - expandedMessageUIState.translation = result; - expandedMessageUIState.isTranslating = false; - } - function isMessageExpanded( summaryIndex: number, chatMemo: string | null @@ -234,9 +239,47 @@ selectedChatMemo: chatMemo, isTranslating: false, translation: null, + translationRef: null, }; } + async function toggleTranslateExpandedMessage( + regenerate?: boolean + ): Promise { + if (!expandedMessageUIState || expandedMessageUIState.isTranslating) return; + + if (expandedMessageUIState.translation) { + expandedMessageUIState.translation = null; + return; + } + + const message = getMessageFromChatMemo( + expandedMessageUIState.selectedChatMemo + ); + + if (!message) return; + + expandedMessageUIState.isTranslating = true; + expandedMessageUIState.translation = "Loading..."; + + // Focus on translation element after it's rendered + await tick(); + + if (expandedMessageUIState.translationRef) { + expandedMessageUIState.translationRef.focus(); + expandedMessageUIState.translationRef.scrollIntoView({ + behavior: "smooth", + block: "nearest", + }); + } + + // Translate + const result = await translate(message.data, regenerate); + + expandedMessageUIState.translation = result; + expandedMessageUIState.isTranslating = false; + } + function getNextMessageToSummarize(): Message | null { const char = DBState.db.characters[$selectedCharID]; const chat = char.chats[DBState.db.characters[$selectedCharID].chatPage]; @@ -326,7 +369,7 @@ params.onAlternativeAction?.(); } else { params.onMainAction?.(); -`` } + } }; if ("ontouchend" in window) { @@ -354,17 +397,21 @@ } +
+
+

HypaV3 Data

+
- +
{#if hypaV3DataState.summaries.length === 0} No summaries yet {/if} + {#each hypaV3DataState.summaries as summary, i} {#if summaryUIStates[i]} +
@@ -468,6 +517,8 @@ >
{summaryUIStates[i].translation}
@@ -531,6 +582,8 @@ >
{summaryUIStates[i].rerolledTranslation}
@@ -575,7 +628,7 @@ {/each}
- + {#if expandedMessageUIState?.summaryIndex === i} {@const message = getMessageFromChatMemo( expandedMessageUIState.selectedChatMemo @@ -604,6 +657,8 @@ >
{expandedMessageUIState.translation}
@@ -616,13 +671,15 @@ {/if} {/each} + {#if true} - {@const nextMessage = getNextMessageToSummarize()} {#if nextMessage}
- HypaV3 will summarize [{nextMessage.chatId}] + HypaV3 will summarize [{nextMessage.chatId + ? nextMessage.chatId + : "no message id"}]