diff --git a/src/lib/Others/HypaV3Modal.svelte b/src/lib/Others/HypaV3Modal.svelte index 4aebdf7d..89faa2df 100644 --- a/src/lib/Others/HypaV3Modal.svelte +++ b/src/lib/Others/HypaV3Modal.svelte @@ -61,7 +61,10 @@ expandedMessage: null, }); - async function toggleTranslate(summary: ExtendedSummary): Promise { + async function toggleTranslate( + summary: ExtendedSummary, + regenerate?: boolean + ): Promise { if (summary.state.isTranslating) return; if (summary.state.translation) { @@ -72,7 +75,7 @@ summary.state.isTranslating = true; summary.state.translation = "Loading..."; - const result = await translate(summary.text); + const result = await translate(summary.text, regenerate); summary.state.translation = result; summary.state.isTranslating = false; @@ -144,7 +147,8 @@ } async function toggleTranslateRerolled( - summary: ExtendedSummary + summary: ExtendedSummary, + regenerate?: boolean ): Promise { if (summary.state.isRerolledTranslating) return; @@ -158,13 +162,15 @@ summary.state.isRerolledTranslating = true; summary.state.rerolledTranslation = "Loading..."; - const result = await translate(summary.state.rerolledText); + const result = await translate(summary.state.rerolledText, regenerate); summary.state.rerolledTranslation = result; summary.state.isRerolledTranslating = false; } - async function toggleTranslateExpandedMessage(): Promise { + async function toggleTranslateExpandedMessage( + regenerate?: boolean + ): Promise { if (!modalState.expandedMessage || modalState.expandedMessage.isTranslating) return; @@ -180,7 +186,7 @@ modalState.expandedMessage.isTranslating = true; modalState.expandedMessage.translation = "Loading..."; - const result = await translate(messageData.data); + const result = await translate(messageData.data, regenerate); modalState.expandedMessage.translation = result; modalState.expandedMessage.isTranslating = false; @@ -235,13 +241,78 @@ }; } - async function translate(text) { + async function translate( + text: string, + regenerate?: boolean + ): Promise { try { - return await translateHTML(text, false, "", -1); + return await translateHTML(text, false, "", -1, regenerate); } catch (error) { return `Translation failed: ${error}`; } } + + type DualActionParams = { + onMainAction?: () => void; + onAlternativeAction?: () => void; + }; + + function handleDualAction(node: HTMLElement, params: DualActionParams = {}) { + const state = { + lastTap: 0, + tapTimeout: null as any, + }; + + const DOUBLE_TAP_DELAY = 300; + + function handleInteraction(event: Event) { + if ("ontouchend" in window) { + // Mobile environment + const currentTime = new Date().getTime(); + const tapLength = currentTime - state.lastTap; + + if (tapLength < DOUBLE_TAP_DELAY && tapLength > 0) { + // Double tap detected + event.preventDefault(); + clearTimeout(state.tapTimeout); // Cancel the first tap timeout + params.onAlternativeAction?.(); + state.lastTap = 0; // Reset state + } else { + // First tap + state.lastTap = currentTime; + + // Delayed single tap execution + state.tapTimeout = setTimeout(() => { + if (state.lastTap === currentTime) { + // If no double tap occurred + params.onMainAction?.(); + } + }, DOUBLE_TAP_DELAY); + } + } else { + // Desktop environment + if ((event as MouseEvent).shiftKey) { + params.onAlternativeAction?.(); + } else { + params.onMainAction?.(); + } + } + } + + node.addEventListener("click", handleInteraction); + node.addEventListener("touchend", handleInteraction); + + return { + destroy() { + node.removeEventListener("click", handleInteraction); + node.removeEventListener("touchend", handleInteraction); + clearTimeout(state.tapTimeout); // Cleanup timeout + }, + update(newParams: DualActionParams) { + params = newParams; + }, + }; + }
@@ -310,7 +381,10 @@ @@ -367,8 +441,12 @@ @@ -427,7 +505,11 @@ diff --git a/src/ts/process/memory/hypav3.ts b/src/ts/process/memory/hypav3.ts index 4786c1bf..25d7d83f 100644 --- a/src/ts/process/memory/hypav3.ts +++ b/src/ts/process/memory/hypav3.ts @@ -854,7 +854,7 @@ class HypaProcesserEx extends HypaProcesser { summaryChunkVectors: SummaryChunkVector[] = []; // Calculate dot product similarity between two vectors - similarity(a: VectorArray, b: VectorArray) { + similarity(a: VectorArray, b: VectorArray): number { let dot = 0; for (let i = 0; i < a.length; i++) { @@ -864,7 +864,7 @@ class HypaProcesserEx extends HypaProcesser { return dot; } - async addSummaryChunks(chunks: SummaryChunk[]) { + async addSummaryChunks(chunks: SummaryChunk[]): Promise { // Maintain the superclass's caching structure by adding texts const texts = chunks.map((chunk) => chunk.text);