From 5ce348d61ec99db74c754d88feffd88e8034e17a Mon Sep 17 00:00:00 2001 From: MasterDraco Date: Mon, 10 Mar 2025 18:24:29 +0000 Subject: [PATCH] Implement floating notification for update alerts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Created an entirely new floating notification system independent of the main UI - Positioned notification as fixed element attached directly to the body - Used bright red styling with high contrast to ensure visibility - Added redundant notification alongside original update alert - Implemented try/catch blocks for robust error handling - Added event listeners for update button in floating notification - Enhanced force show function to handle both notification types - Applied fixed position and high z-index to ensure visibility - Added console logging for better debugging 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- public/index.html | 38 +++++++ public/js/system-status.js | 198 ++++++++++++++++++++++++++----------- 2 files changed, 178 insertions(+), 58 deletions(-) diff --git a/public/index.html b/public/index.html index d14ae56..3a46ab1 100644 --- a/public/index.html +++ b/public/index.html @@ -687,8 +687,46 @@ color: #004085 !important; font-weight: bold !important; } + + /* Floating update notification that's impossible to miss */ + #floating-update-notification { + display: none; + position: fixed; + top: 20px; + right: 20px; + width: 300px; + padding: 15px; + background-color: #ff5555; + color: white; + border: 3px solid #cc0000; + border-radius: 5px; + box-shadow: 0 0 20px rgba(0,0,0,0.5); + z-index: 10000; + font-weight: bold; + text-align: center; + } + #floating-update-notification button { + margin-top: 10px; + padding: 5px 10px; + background-color: white; + color: #cc0000; + border: none; + border-radius: 3px; + font-weight: bold; + cursor: pointer; + } + #floating-update-notification button:hover { + background-color: #eeeeee; + } + +
+
Update Available!
+
New version available
+ +
+ diff --git a/public/js/system-status.js b/public/js/system-status.js index d9b6c67..f8a1aaa 100644 --- a/public/js/system-status.js +++ b/public/js/system-status.js @@ -62,40 +62,71 @@ function initSystemStatus() { // Function to show update alert function showUpdateAlert(currentVersion, remoteVersion) { - // Set status text + // Set status text in the system status panel updateStatusElement.innerHTML = ' Update available'; - // Show alert box with extreme prejudice - const alertBox = updateAvailableDiv.querySelector('.alert'); - if (alertBox) { - // Add important inline styles to override any CSS - alertBox.setAttribute('style', - 'display: block !important; ' + - 'visibility: visible !important; ' + - 'opacity: 1 !important; ' + - 'margin-top: 10px !important; ' + - 'border: 3px solid red !important; ' + - 'background-color: #ffeeee !important; ' + - 'color: #990000 !important; ' + - 'font-weight: bold !important; ' + - 'box-shadow: 0 4px 8px rgba(0,0,0,0.3) !important; ' + - 'position: relative !important; ' + - 'z-index: 9999 !important;' - ); - - // Update message with important style - const spanElement = alertBox.querySelector('span'); - if (spanElement) { - spanElement.textContent = `A new version is available: ${currentVersion} → ${remoteVersion}`; - spanElement.setAttribute('style', 'color: #990000 !important; font-weight: bold !important;'); + // Try to show the original alert box, but don't rely on it + try { + const alertBox = updateAvailableDiv.querySelector('.alert'); + if (alertBox) { + alertBox.style.display = 'block'; + const spanElement = alertBox.querySelector('span'); + if (spanElement) { + spanElement.textContent = `A new version is available: ${currentVersion} → ${remoteVersion}`; + } } - - // Also ensure the parent div is visible - updateAvailableDiv.style.display = 'block'; - updateAvailableDiv.style.visibility = 'visible'; - - // Log that we've shown the update button - console.log('Update alert shown:', currentVersion, '->', remoteVersion); + } catch (e) { + console.error('Error showing original alert box:', e); + } + + // Show the floating notification (our new approach) + try { + const floatingNotification = document.getElementById('floating-update-notification'); + if (floatingNotification) { + // Set text + const versionElement = document.getElementById('floating-update-version'); + if (versionElement) { + versionElement.textContent = `Version ${currentVersion} → ${remoteVersion}`; + } + + // Show with inline styles to force display + floatingNotification.style.display = 'block'; + + // Make absolutely sure it's visible + floatingNotification.setAttribute('style', + 'display: block !important; ' + + 'visibility: visible !important; ' + + 'opacity: 1 !important; ' + + 'position: fixed !important; ' + + 'top: 20px !important; ' + + 'right: 20px !important; ' + + 'width: 300px !important; ' + + 'padding: 15px !important; ' + + 'background-color: #ff5555 !important; ' + + 'color: white !important; ' + + 'border: 3px solid #cc0000 !important; ' + + 'border-radius: 5px !important; ' + + 'box-shadow: 0 0 20px rgba(0,0,0,0.5) !important; ' + + 'z-index: 10000 !important; ' + + 'font-weight: bold !important; ' + + 'text-align: center !important;' + ); + + // Set up update button click handler + const updateButton = document.getElementById('floating-update-button'); + if (updateButton) { + // Remove any existing listeners + updateButton.removeEventListener('click', applyUpdate); + // Add new listener + updateButton.addEventListener('click', applyUpdate); + } + + console.log('Floating update notification shown:', currentVersion, '->', remoteVersion); + } else { + console.error('Floating notification element not found!'); + } + } catch (e) { + console.error('Error showing floating notification:', e); } // Store in localStorage @@ -106,9 +137,24 @@ function initSystemStatus() { // Function to hide update alert function hideUpdateAlert() { - const alertBox = updateAvailableDiv.querySelector('.alert'); - if (alertBox) { - alertBox.style.display = 'none'; + // Hide original alert + try { + const alertBox = updateAvailableDiv.querySelector('.alert'); + if (alertBox) { + alertBox.style.display = 'none'; + } + } catch (e) { + console.error('Error hiding original alert:', e); + } + + // Hide floating notification + try { + const floatingNotification = document.getElementById('floating-update-notification'); + if (floatingNotification) { + floatingNotification.style.display = 'none'; + } + } catch (e) { + console.error('Error hiding floating notification:', e); } // Clear localStorage @@ -401,31 +447,67 @@ function initSystemStatus() { const isUpdateAvailable = localStorage.getItem(UPDATE_KEY) === 'true'; if (isUpdateAvailable) { - const alertBox = updateAvailableDiv.querySelector('.alert'); - if (alertBox && alertBox.style.display !== 'block') { - console.log('Forcing update button display'); - alertBox.style.display = 'block'; - alertBox.style.visibility = 'visible'; - alertBox.style.opacity = '1'; + const currentVersion = localStorage.getItem(CURRENT_VERSION_KEY); + const remoteVersion = localStorage.getItem(REMOTE_VERSION_KEY); + + if (currentVersion && remoteVersion) { + // Check floating notification + const floatingNotification = document.getElementById('floating-update-notification'); + if (floatingNotification && floatingNotification.style.display !== 'block') { + console.log('Forcing floating update notification display'); + + // Set the version text + const versionElement = document.getElementById('floating-update-version'); + if (versionElement) { + versionElement.textContent = `Version ${currentVersion} → ${remoteVersion}`; + } + + // Apply strong styling + floatingNotification.setAttribute('style', + 'display: block !important; ' + + 'visibility: visible !important; ' + + 'opacity: 1 !important; ' + + 'position: fixed !important; ' + + 'top: 20px !important; ' + + 'right: 20px !important; ' + + 'width: 300px !important; ' + + 'padding: 15px !important; ' + + 'background-color: #ff5555 !important; ' + + 'color: white !important; ' + + 'border: 3px solid #cc0000 !important; ' + + 'border-radius: 5px !important; ' + + 'box-shadow: 0 0 20px rgba(0,0,0,0.5) !important; ' + + 'z-index: 10000 !important; ' + + 'font-weight: bold !important; ' + + 'text-align: center !important;' + ); + + // Ensure button has correct event handler + const updateButton = document.getElementById('floating-update-button'); + if (updateButton) { + // Remove any existing listeners + updateButton.removeEventListener('click', applyUpdate); + // Add new listener + updateButton.addEventListener('click', applyUpdate); + } + } - // Add important inline styles to override any CSS - alertBox.setAttribute('style', - 'display: block !important; ' + - 'visibility: visible !important; ' + - 'opacity: 1 !important; ' + - 'margin-top: 10px !important; ' + - 'border: 3px solid red !important; ' + - 'background-color: #ffeeee !important; ' + - 'color: #990000 !important; ' + - 'font-weight: bold !important; ' + - 'box-shadow: 0 4px 8px rgba(0,0,0,0.3) !important; ' + - 'position: relative !important; ' + - 'z-index: 9999 !important;' - ); - - // Also ensure the parent div is visible - updateAvailableDiv.style.display = 'block'; - updateAvailableDiv.style.visibility = 'visible'; + // Still try the original alert as a fallback + try { + const alertBox = updateAvailableDiv.querySelector('.alert'); + if (alertBox && alertBox.style.display !== 'block') { + alertBox.style.display = 'block'; + updateAvailableDiv.style.display = 'block'; + + // Update message + const spanElement = alertBox.querySelector('span'); + if (spanElement) { + spanElement.textContent = `A new version is available: ${currentVersion} → ${remoteVersion}`; + } + } + } catch (e) { + console.error('Error forcing original update button:', e); + } } } }