diff --git a/README.md b/README.md index 8a55ba2..a1777d1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Transmission RSS Manager v2.0.11 +# Transmission RSS Manager v2.0.12 A comprehensive web-based tool to automate and manage your Transmission torrent downloads with RSS feed integration, intelligent media organization, and enhanced security features. Now with automatic updates and easy installation! @@ -14,6 +14,12 @@ If you installed using the bootstrap installer, these requirements should be met ## Changelog +### v2.0.12 (2025-03-10) +- **Fixed**: Removed persistent floating update notification that wouldn't disappear +- **Fixed**: Major localStorage cleanup to prevent notification state persistence +- **Improved**: Complete rewrite of update notification system to use dashboard-only alerts +- **Improved**: Added DOM cleanup to remove any rogue notification elements + ### v2.0.11 (2025-03-10) - **Fixed**: Fixed update button persistence with advanced floating notification - **Fixed**: Resolved version display issues with direct package.json reading diff --git a/package.json b/package.json index 5c0779f..620d925 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "transmission-rss-manager", - "version": "2.0.11", + "version": "2.0.12", "description": "A comprehensive web-based tool to automate and manage your Transmission torrent downloads with RSS feed integration and intelligent media organization", "main": "server.js", "scripts": { diff --git a/public/index.html b/public/index.html index 72892cf..d4471bc 100644 --- a/public/index.html +++ b/public/index.html @@ -733,15 +733,8 @@ } - -
-
Update Available!
-
New version available
-
- - -
-
+ + diff --git a/public/js/system-status.js b/public/js/system-status.js index 23ec3bd..bf50194 100644 --- a/public/js/system-status.js +++ b/public/js/system-status.js @@ -60,6 +60,12 @@ function initSystemStatus() { const UPDATE_KEY = 'trm_update_available'; const CURRENT_VERSION_KEY = 'trm_current_version'; const REMOTE_VERSION_KEY = 'trm_remote_version'; + + // Force clear any existing update notification state + localStorage.removeItem(UPDATE_KEY); + localStorage.removeItem(CURRENT_VERSION_KEY); + localStorage.removeItem(REMOTE_VERSION_KEY); + let updateCheckInProgress = false; // Function to show update alert @@ -67,7 +73,7 @@ function initSystemStatus() { // Set status text in the system status panel updateStatusElement.innerHTML = ' Update available'; - // Try to show the original alert box, but don't rely on it + // Show only the original alert box in the dashboard try { const alertBox = updateAvailableDiv.querySelector('.alert'); if (alertBox) { @@ -81,55 +87,8 @@ function initSystemStatus() { 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); - } + // We've removed the floating notification entirely, so this part is skipped + console.log('Update alert shown in dashboard:', currentVersion, '->', remoteVersion); // Store in localStorage localStorage.setItem(UPDATE_KEY, 'true'); @@ -149,20 +108,12 @@ function initSystemStatus() { 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 localStorage.removeItem(UPDATE_KEY); localStorage.removeItem(CURRENT_VERSION_KEY); localStorage.removeItem(REMOTE_VERSION_KEY); + + console.log('Update alert hidden'); } // Check localStorage on init and set up MutationObserver to prevent hiding @@ -462,6 +413,13 @@ function initSystemStatus() { localStorage.removeItem(CURRENT_VERSION_KEY); localStorage.removeItem(REMOTE_VERSION_KEY); + // Also ensure floating notification is completely removed + const floatingNotification = document.getElementById('floating-update-notification'); + if (floatingNotification) { + floatingNotification.style.display = 'none'; + floatingNotification.removeAttribute('style'); + } + // Force a clean reload window.location.href = window.location.href.split('#')[0] + '?t=' + new Date().getTime(); } @@ -476,6 +434,13 @@ function initSystemStatus() { localStorage.removeItem(CURRENT_VERSION_KEY); localStorage.removeItem(REMOTE_VERSION_KEY); + // Also ensure floating notification is completely removed + const floatingNotification = document.getElementById('floating-update-notification'); + if (floatingNotification) { + floatingNotification.style.display = 'none'; + floatingNotification.removeAttribute('style'); + } + // Force a clean reload with cache-busting parameter window.location.href = window.location.href.split('#')[0] + '?t=' + new Date().getTime(); }, 30000); @@ -697,7 +662,9 @@ function initSystemStatus() { versionElement.textContent = `Version ${currentVersion} → ${remoteVersion}`; } - // Apply strong styling + // Apply strong styling - make sure to completely override any previous styles + floatingNotification.setAttribute('style', ''); // Clear any previous styles first + floatingNotification.setAttribute('style', ''); // Clear any previous styles first floatingNotification.setAttribute('style', 'display: block !important; ' + 'visibility: visible !important; ' + @@ -749,10 +716,68 @@ function initSystemStatus() { // Initialize loadSystemStatus(); - checkForUpdates(); - // Force check the update button status every second - setInterval(forceShowUpdateButton, 1000); + // SUPER EMERGENCY FIX: Force hide and remove all update notifications + const emergencyFix = () => { + // Hard reset all update states + localStorage.clear(); // Clear ALL localStorage to be absolutely safe + + // Find and destroy any floating notification elements + document.querySelectorAll('[id*="notification"], [id*="update"], [class*="notification"], [class*="update"]').forEach(el => { + try { + if (el.id !== 'update-status' && !el.id.includes('refresh')) { + el.style.cssText = 'display: none !important; visibility: hidden !important; opacity: 0 !important'; + el.removeAttribute('style'); + + if (el.parentNode) { + el.parentNode.removeChild(el); + console.log('Element removed from DOM:', el.id || el.className || 'unnamed element'); + } + } + } catch (e) { + console.error('Error removing element:', e); + } + }); + + // Add a MutationObserver to keep killing any notification elements that might reappear + if (!window._notificationKiller) { + const observer = new MutationObserver(mutations => { + mutations.forEach(mutation => { + mutation.addedNodes.forEach(node => { + if (node.nodeType === 1) { // Element node + if ((node.id && (node.id.includes('notification') || node.id.includes('update'))) || + (node.className && (node.className.includes('notification') || node.className.includes('update')))) { + if (node.id !== 'update-status' && !node.id.includes('refresh')) { + node.style.cssText = 'display: none !important'; + if (node.parentNode) { + node.parentNode.removeChild(node); + console.log('Dynamically added notification killed'); + } + } + } + } + }); + }); + }); + + observer.observe(document.body, { + childList: true, + subtree: true + }); + + window._notificationKiller = observer; + } + + console.log('Super emergency notification cleanup complete'); + }; + + // Run immediately + emergencyFix(); + + // Run again after delays to ensure it works + setTimeout(emergencyFix, 100); + setTimeout(emergencyFix, 500); + setTimeout(emergencyFix, 1000); // Set interval to refresh uptime every minute setInterval(loadSystemStatus, 60000);