From caaa347b355421d27f97fb328e417cf19600054e Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Tue, 1 Jul 2025 21:10:37 -0400 Subject: [PATCH] fix(preview): separate button creation from initialization for preview windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Separate DOM creation from event handler setup in floating button - Add self-contained click handler with multiple fallback methods - Enable floating button in preview windows with UNCLOSEAI_SKIP_INIT flag - Improve modal function detection with dynamic imports - Add extensive debugging for button click issues 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/ui.js | 57 ++++++++++++++++++++++++++++++++++++++++------------ uncloseai.js | 15 +++++++++++++- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/ui.js b/src/ui.js index b4744a3..eeae065 100644 --- a/src/ui.js +++ b/src/ui.js @@ -402,7 +402,15 @@ export function createFloatingAIButton() { floatingButton.style.boxShadow = "0 4px 12px rgba(0,0,0,0.3)"; }; - // Toggle modal on click + // Set up self-contained click handler + setupFloatingButtonHandler(floatingButton); + + document.body.appendChild(floatingButton); + console.log("uncloseai.js: Appended floating button to document.body."); +} + +// Set up click handler for floating button (self-contained) +function setupFloatingButtonHandler(floatingButton) { floatingButton.onclick = async () => { console.log("Floating button clicked!"); @@ -415,13 +423,36 @@ export function createFloatingAIButton() { try { console.log("Trying to toggle Hermes modal..."); + + // Try multiple ways to access the modal function + let modalFunction = null; + if (typeof toggleHermesModal === 'function') { - await toggleHermesModal(); + console.log("Found toggleHermesModal in local scope"); + modalFunction = toggleHermesModal; } else if (typeof window.toggleHermesModal === 'function') { - await window.toggleHermesModal(); + console.log("Found toggleHermesModal on window"); + modalFunction = window.toggleHermesModal; } else { - console.error("toggleHermesModal function not available"); - alert("AI modal not available in preview window"); + console.log("toggleHermesModal not found, trying dynamic import"); + // Try to import it dynamically as a fallback + try { + const uiModule = await import('./ui.js'); + if (uiModule.toggleHermesModal) { + console.log("Successfully imported toggleHermesModal"); + modalFunction = uiModule.toggleHermesModal; + } + } catch (importError) { + console.error("Could not import toggleHermesModal:", importError); + } + } + + if (modalFunction) { + console.log("Calling modal function"); + await modalFunction(); + } else { + console.error("toggleHermesModal function not available in any form"); + alert("AI modal not available in this context"); } } catch (error) { console.error("Error opening modal:", error); @@ -434,9 +465,6 @@ export function createFloatingAIButton() { floatingButton.style.cursor = "pointer"; } }; - - document.body.appendChild(floatingButton); - console.log("uncloseai.js: Appended floating button to document.body."); } // Function to toggle Hermes modal @@ -1915,9 +1943,10 @@ export function openTranslateModal() { previewWindow.document.close(); previewWindow.document.title = `Translation Preview (${targetLanguageName}) - AI Enabled`; - // Add a notice about AI functionality (wait for body to be available) + // Add a notice about AI functionality only in preview window (wait for body to be available) const addNotice = () => { - if (previewWindow.document.body) { + if (previewWindow && previewWindow.document && previewWindow.document.body) { + console.log("Adding AI notice to preview window"); const notice = previewWindow.document.createElement("div"); notice.style.cssText = "position: fixed; top: 10px; right: 10px; background: #4CAF50; color: white; padding: 8px 12px; border-radius: 4px; font-size: 12px; z-index: 10000; box-shadow: 0 2px 8px rgba(0,0,0,0.2);"; @@ -1928,14 +1957,16 @@ export function openTranslateModal() { setTimeout(() => { if (notice.parentNode) notice.parentNode.removeChild(notice); }, 5000); - } else { + } else if (previewWindow) { // Wait a bit and try again setTimeout(addNotice, 100); } }; - // Start trying to add the notice - addNotice(); + // Only add notice if we have a valid preview window + if (previewWindow) { + addNotice(); + } } // Show raw HTML toggle in modal diff --git a/uncloseai.js b/uncloseai.js index a1f823d..a7d059c 100644 --- a/uncloseai.js +++ b/uncloseai.js @@ -19,6 +19,7 @@ import * as FileUpload from "./src/file-upload.js"; import * as Storage from "./src/storage.js"; import * as PageReader from "./src/page-reader.js"; import * as UI from "./src/ui.js"; +import * as Translation from "./src/translation.js"; // ------------------------- // Public API - Main Functions @@ -65,6 +66,11 @@ export const createCustomInterface = UI.createCustomInterface; export const toggleHermesModal = UI.toggleHermesModal; export const openHermesModal = UI.openHermesModal; export const openTTSModal = UI.openTTSModal; +export const openTranslateModal = UI.openTranslateModal; + +// Translation functionality +export const translateText = Translation.translateText; +export const translateCurrentPage = Translation.translateCurrentPage; // ------------------------- // Configuration and State @@ -114,7 +120,14 @@ window.addEventListener("load", () => { // Check skip init flag first if (window.UNCLOSEAI_SKIP_INIT === true) { - console.log("uncloseai.js: Skipping initialization as requested by flag."); + console.log("uncloseai.js: Skipping full initialization as requested by flag."); + console.log("uncloseai.js: Creating floating button only for preview windows."); + + // Still create floating button for preview windows, but skip other initialization + const SHOW_FLOATING_BUTTON = window.UNCLOSEAI_FLOATING_BUTTON !== false; + if (SHOW_FLOATING_BUTTON) { + UI.createFloatingAIButton(); + } return; }