From d59cc1a29cd35f11e6e7ec4e21cd23296bbcc878 Mon Sep 17 00:00:00 2001 From: Bo26fhmC5M <88071760+Bo26fhmC5M@users.noreply.github.com> Date: Wed, 15 Jan 2025 19:56:07 +0900 Subject: [PATCH] refactor: update UI management to index-based approach --- src/lib/Others/HypaV3Modal.svelte | 312 ++++++++++++++---------------- 1 file changed, 148 insertions(+), 164 deletions(-) diff --git a/src/lib/Others/HypaV3Modal.svelte b/src/lib/Others/HypaV3Modal.svelte index 89faa2df..582236c9 100644 --- a/src/lib/Others/HypaV3Modal.svelte +++ b/src/lib/Others/HypaV3Modal.svelte @@ -10,78 +10,94 @@ import TextAreaInput from "../UI/GUI/TextAreaInput.svelte"; import { alertConfirm } from "../../ts/alert"; import { DBState, alertStore, selectedCharID } from "src/ts/stores.svelte"; - import { - type SerializableHypaV3Data, - summarize, - } from "src/ts/process/memory/hypav3"; + import { summarize } from "src/ts/process/memory/hypav3"; import { translateHTML } from "src/ts/translator/translator"; - import PersonaSettings from "../Setting/Pages/PersonaSettings.svelte"; - type Summary = SerializableHypaV3Data["summaries"][number]; - - interface ExtendedSummary extends Summary { - state: { - isTranslating: boolean; - translation?: string | null; - isRerolling: boolean; - rerolledText?: string | null; - isRerolledTranslating: boolean; - rerolledTranslation?: string | null; - }; + interface SummaryUI { + isTranslating: boolean; + translation: string | null; + isRerolling: boolean; + rerolledText: string | null; + isRerolledTranslating: boolean; + rerolledTranslation: string | null; } - interface HypaV3ModalState { - summaries: ExtendedSummary[]; - expandedMessage: { - summaryChatMemos: string[]; - selectedChatMemo: string; - isTranslating: boolean; - translation?: string | null; - } | null; + interface ExpandedMessageUI { + summaryIndex: number; + selectedChatMemo: string; + isTranslating: boolean; + translation?: string | null; } - // Initialize modal state - let modalState = $state({ - summaries: DBState.db.characters[$selectedCharID].chats[ + const hypaV3DataState = $state( + DBState.db.characters[$selectedCharID].chats[ DBState.db.characters[$selectedCharID].chatPage - ].hypaV3Data.summaries.map((s) => { - const summary = s as ExtendedSummary; + ].hypaV3Data + ); + const summaryUIStates = $state( + hypaV3DataState.summaries.map(() => ({ + isTranslating: false, + translation: null, + isRerolling: false, + rerolledText: null, + isRerolledTranslating: false, + rerolledTranslation: null, + })) + ); + let expandedMessageUIState = $state(null); - summary.state = { - isTranslating: false, - translation: null, - isRerolling: false, - rerolledText: null, - isRerolledTranslating: false, - rerolledTranslation: null, - }; - - return summary; - }), - expandedMessage: null, + $effect(() => { + // Detects changes in all nested properties including summaries + hypaV3DataState.summaries; + expandedMessageUIState = null; }); + function getMessageFromChatMemo( + chatMemo: string | null + ): { role: string; data: string } | null { + const char = DBState.db.characters[$selectedCharID]; + const chat = char.chats[DBState.db.characters[$selectedCharID].chatPage]; + const firstMessage = + chat.fmIndex === -1 + ? char.firstMessage + : char.alternateGreetings?.[chat.fmIndex ?? 0]; + + const targetMessage = + chatMemo == null + ? { role: "char", data: firstMessage } + : chat.message.find((m) => m.chatId === chatMemo); + + return targetMessage; + } + async function toggleTranslate( - summary: ExtendedSummary, + summaryIndex: number, regenerate?: boolean ): Promise { - if (summary.state.isTranslating) return; + const summaryUIState = summaryUIStates[summaryIndex]; - if (summary.state.translation) { - summary.state.translation = null; + if (summaryUIState.isTranslating) return; + + if (summaryUIState.translation) { + summaryUIState.translation = null; return; } - summary.state.isTranslating = true; - summary.state.translation = "Loading..."; + summaryUIState.isTranslating = true; + summaryUIState.translation = "Loading..."; - const result = await translate(summary.text, regenerate); + const result = await translate( + hypaV3DataState.summaries[summaryIndex].text, + regenerate + ); - summary.state.translation = result; - summary.state.isTranslating = false; + summaryUIState.translation = result; + summaryUIState.isTranslating = false; } - function isRerollable(summary: ExtendedSummary): boolean { + function isRerollable(summaryIndex: number): boolean { + const summary = hypaV3DataState.summaries[summaryIndex]; + for (const chatMemo of summary.chatMemos) { if (typeof chatMemo === "string") { const char = DBState.db.characters[$selectedCharID]; @@ -93,154 +109,121 @@ } } } - return true; } - async function toggleReroll(summary: ExtendedSummary): Promise { - if (summary.state.isRerolling) return; - if (!isRerollable(summary)) return; + async function toggleReroll(summaryIndex: number): Promise { + const summaryUIState = summaryUIStates[summaryIndex]; - summary.state.isRerolling = true; - summary.state.rerolledText = "Loading..."; + if (summaryUIState.isRerolling) return; + if (!isRerollable(summaryIndex)) return; + + summaryUIState.isRerolling = true; + summaryUIState.rerolledText = "Loading..."; try { - const char = DBState.db.characters[$selectedCharID]; - const chat = char.chats[DBState.db.characters[$selectedCharID].chatPage]; - const firstMessage = - chat.fmIndex === -1 - ? char.firstMessage - : char.alternateGreetings?.[chat.fmIndex ?? 0]; - + const summary = hypaV3DataState.summaries[summaryIndex]; const toSummarize = summary.chatMemos.map((chatMemo) => { - if (chatMemo == null) { - return { - role: "assistant", - data: firstMessage, - }; - } + const message = getMessageFromChatMemo(chatMemo); - const msg = chat.message.find((m) => m.chatId === chatMemo); - - return msg - ? { - role: msg.role === "char" ? "assistant" : msg.role, - data: msg.data, - } - : null; + return { + ...message, + role: message.role === "char" ? "assistant" : message.role, + }; }); const stringifiedChats = toSummarize .map((m) => `${m.role}: ${m.data}`) .join("\n"); - const summarizeResult = await summarize(stringifiedChats); if (summarizeResult.success) { - summary.state.rerolledText = summarizeResult.data; + summaryUIState.rerolledText = summarizeResult.data; } } catch (error) { - summary.state.rerolledText = "Reroll failed"; + summaryUIState.rerolledText = "Reroll failed"; } finally { - summary.state.isRerolling = false; + summaryUIState.isRerolling = false; } } async function toggleTranslateRerolled( - summary: ExtendedSummary, + summaryIndex: number, regenerate?: boolean ): Promise { - if (summary.state.isRerolledTranslating) return; + const summaryUIState = summaryUIStates[summaryIndex]; - if (summary.state.rerolledTranslation) { - summary.state.rerolledTranslation = null; + if (summaryUIState.isRerolledTranslating) return; + + if (summaryUIState.rerolledTranslation) { + summaryUIState.rerolledTranslation = null; return; } - if (!summary.state.rerolledText) return; + if (!summaryUIState.rerolledText) return; - summary.state.isRerolledTranslating = true; - summary.state.rerolledTranslation = "Loading..."; + summaryUIState.isRerolledTranslating = true; + summaryUIState.rerolledTranslation = "Loading..."; - const result = await translate(summary.state.rerolledText, regenerate); + const result = await translate(summaryUIState.rerolledText, regenerate); - summary.state.rerolledTranslation = result; - summary.state.isRerolledTranslating = false; + summaryUIState.rerolledTranslation = result; + summaryUIState.isRerolledTranslating = false; } async function toggleTranslateExpandedMessage( regenerate?: boolean ): Promise { - if (!modalState.expandedMessage || modalState.expandedMessage.isTranslating) - return; + if (!expandedMessageUIState || expandedMessageUIState.isTranslating) return; - if (modalState.expandedMessage.translation) { - modalState.expandedMessage.translation = null; + if (expandedMessageUIState.translation) { + expandedMessageUIState.translation = null; return; } - const messageData = getMessageData(); + const message = getMessageFromChatMemo( + expandedMessageUIState.selectedChatMemo + ); - if (!messageData) return; + if (!message) return; - modalState.expandedMessage.isTranslating = true; - modalState.expandedMessage.translation = "Loading..."; + expandedMessageUIState.isTranslating = true; + expandedMessageUIState.translation = "Loading..."; - const result = await translate(messageData.data, regenerate); + const result = await translate(message.data, regenerate); - modalState.expandedMessage.translation = result; - modalState.expandedMessage.isTranslating = false; + expandedMessageUIState.translation = result; + expandedMessageUIState.isTranslating = false; } function isMessageExpanded( - summary: ExtendedSummary, + summaryIndex: number, chatMemo: string | null ): boolean { + if (!expandedMessageUIState) return false; + + const summary = hypaV3DataState.summaries[summaryIndex]; + return ( - modalState.expandedMessage?.summaryChatMemos === summary.chatMemos && - modalState.expandedMessage?.selectedChatMemo === chatMemo + expandedMessageUIState.summaryIndex === summaryIndex && + expandedMessageUIState.selectedChatMemo === chatMemo ); } function toggleExpandMessage( - summary: ExtendedSummary, + summaryIndex: number, chatMemo: string | null ): void { - modalState.expandedMessage = isMessageExpanded(summary, chatMemo) + expandedMessageUIState = isMessageExpanded(summaryIndex, chatMemo) ? null : { - summaryChatMemos: summary.chatMemos, + summaryIndex, selectedChatMemo: chatMemo, isTranslating: false, translation: null, }; } - function getMessageData(): { role: string; data: string } | null { - const char = DBState.db.characters[$selectedCharID]; - const chat = char.chats[DBState.db.characters[$selectedCharID].chatPage]; - const firstMessage = - chat.fmIndex === -1 - ? char.firstMessage - : char.alternateGreetings?.[chat.fmIndex ?? 0]; - - const targetMessage = - modalState.expandedMessage?.selectedChatMemo == null - ? { role: "char", data: firstMessage } - : chat.message.find( - (m) => m.chatId === modalState.expandedMessage!.selectedChatMemo - ); - - if (!targetMessage) { - return null; - } - - return { - ...targetMessage, - role: targetMessage.role === "char" ? char.name : targetMessage.role, - }; - } - async function translate( text: string, regenerate?: boolean @@ -318,7 +301,7 @@
- {#each modalState.summaries as summary, i} + {#each hypaV3DataState.summaries as summary, i}
@@ -382,8 +365,8 @@ @@ -419,7 +402,7 @@ /> - {#if summary.state.translation} + {#if summaryUIStates[i].translation}
Translation - {summary.state.translation} + {summaryUIStates[i].translation}
{/if} - {#if summary.state.rerolledText} + {#if summaryUIStates[i].rerolledText}
Rerolled Summary @@ -442,10 +425,9 @@
- {#if summary.state.rerolledTranslation} + {#if summaryUIStates[i].rerolledTranslation}
Rerolled Translation - {summary.state.rerolledTranslation} + {summaryUIStates[i].rerolledTranslation}
{/if} @@ -520,12 +502,12 @@ {#each summary.chatMemos as chatMemo} @@ -533,26 +515,28 @@
- {#if modalState.expandedMessage?.summaryChatMemos === summary.chatMemos} - {@const messageData = getMessageData()} + {#if expandedMessageUIState?.summaryIndex === i} + {@const message = getMessageFromChatMemo( + expandedMessageUIState.selectedChatMemo + )}
- {#if messageData} + {#if message}
- {messageData.role}: + {message.role}'s Message
- {messageData.data} + {message.data}
{:else}
Message not found
{/if} - {#if modalState.expandedMessage.translation} + {#if expandedMessageUIState.translation}
Translation - {modalState.expandedMessage.translation} + {expandedMessageUIState.translation}
{/if} @@ -570,7 +554,7 @@
{/each} - {#if modalState.summaries.length === 0} + {#if hypaV3DataState.summaries.length === 0} No summaries yet {/if}