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);