Fix browser compatibility and update button persistence

- Replaced AbortSignal.timeout() with AbortController for broader browser support
- Fixed promise chaining for proper cleanup of timeout handlers
- Added localStorage persistence for update information
- Made update button display more reliable with forced display styles
- Added ID to version elements for easier targeting
- Improved version number synchronization across UI elements

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MasterDraco 2025-03-10 17:35:58 +00:00
parent 3ff0a50553
commit b8818a9bec
2 changed files with 56 additions and 8 deletions

View File

@ -658,7 +658,7 @@
</div> </div>
<div class="text-center mt-4"> <div class="text-center mt-4">
<p><strong>Transmission RSS Manager v2.0.10</strong></p> <p><strong id="about-version">Transmission RSS Manager v2.0.10</strong></p>
<p>© 2025 PowerData.dk - All Rights Reserved</p> <p>© 2025 PowerData.dk - All Rights Reserved</p>
<p><a href="https://powerdata.dk" target="_blank">Visit PowerData.dk</a></p> <p><a href="https://powerdata.dk" target="_blank">Visit PowerData.dk</a></p>
</div> </div>

View File

@ -33,8 +33,8 @@ function initSystemStatus() {
} }
// Update version in about modal too if it exists // Update version in about modal too if it exists
const aboutVersionElement = document.querySelector('.text-center.mt-4 strong'); const aboutVersionElement = document.getElementById('about-version');
if (aboutVersionElement && aboutVersionElement.textContent.includes('Transmission RSS Manager v')) { if (aboutVersionElement) {
aboutVersionElement.textContent = 'Transmission RSS Manager v' + data.data.version; aboutVersionElement.textContent = 'Transmission RSS Manager v' + data.data.version;
} }
@ -55,9 +55,23 @@ function initSystemStatus() {
} }
// Track update check status // Track update check status
let updateAvailable = false; let updateAvailable = localStorage.getItem('updateAvailable') === 'true';
let updateCheckInProgress = false; let updateCheckInProgress = false;
// If we have stored update info, restore it
if (updateAvailable) {
const currentVersion = localStorage.getItem('currentVersion');
const remoteVersion = localStorage.getItem('remoteVersion');
if (currentVersion && remoteVersion) {
updateStatusElement.innerHTML = '<i class="fas fa-exclamation-circle text-warning"></i> Update available';
updateAvailableDiv.classList.remove('d-none');
updateAvailableDiv.style.display = 'block'; // Force display
updateAvailableDiv.querySelector('span').textContent =
`A new version is available: ${currentVersion}${remoteVersion}`;
}
}
// Check for updates // Check for updates
function checkForUpdates() { function checkForUpdates() {
// Don't hide update button if an update is available and we're just refreshing // Don't hide update button if an update is available and we're just refreshing
@ -79,13 +93,26 @@ function initSystemStatus() {
showNotification('Update check timed out. Please try again later.', 'warning'); showNotification('Update check timed out. Please try again later.', 'warning');
}, 10000); // 10 second timeout }, 10000); // 10 second timeout
// Create a timeout controller
const controller = new AbortController();
const timeoutId2 = setTimeout(() => controller.abort(), 15000);
fetch(url, { fetch(url, {
headers: authHeaders(), headers: authHeaders(),
// Add a fetch timeout as well // Add a fetch timeout using abort controller
signal: AbortSignal.timeout(15000) // 15 second timeout (available in modern browsers) signal: controller.signal // 15 second timeout
}) })
.then(response => { .then(response => {
clearTimeout(timeoutId2);
clearTimeout(timeoutId); clearTimeout(timeoutId);
return response;
})
.catch(error => {
clearTimeout(timeoutId2);
clearTimeout(timeoutId);
throw error;
})
.then(response => {
// Better error checking // Better error checking
if (!response.ok) { if (!response.ok) {
return response.json().then(data => { return response.json().then(data => {
@ -101,18 +128,27 @@ function initSystemStatus() {
}) })
.then(data => { .then(data => {
updateCheckInProgress = false; updateCheckInProgress = false;
clearTimeout(timeoutId);
if (data.status === 'success') { if (data.status === 'success') {
if (data.data && data.data.updateAvailable) { if (data.data && data.data.updateAvailable) {
updateAvailable = true; updateAvailable = true;
updateStatusElement.innerHTML = '<i class="fas fa-exclamation-circle text-warning"></i> Update available'; updateStatusElement.innerHTML = '<i class="fas fa-exclamation-circle text-warning"></i> Update available';
// Make update button visible immediately
updateAvailableDiv.classList.remove('d-none'); updateAvailableDiv.classList.remove('d-none');
updateAvailableDiv.style.display = 'block'; // Force display
updateAvailableDiv.querySelector('span').textContent = updateAvailableDiv.querySelector('span').textContent =
`A new version is available: ${data.data.currentVersion}${data.data.remoteVersion}`; `A new version is available: ${data.data.currentVersion}${data.data.remoteVersion}`;
// Store update info in localStorage to persist across refreshes
localStorage.setItem('updateAvailable', 'true');
localStorage.setItem('currentVersion', data.data.currentVersion);
localStorage.setItem('remoteVersion', data.data.remoteVersion);
} else { } else {
updateAvailable = false; updateAvailable = false;
updateStatusElement.innerHTML = '<i class="fas fa-check-circle text-success"></i> Up to date'; updateStatusElement.innerHTML = '<i class="fas fa-check-circle text-success"></i> Up to date';
localStorage.removeItem('updateAvailable');
} }
} else { } else {
// Error status but with a response // Error status but with a response
@ -157,13 +193,25 @@ function initSystemStatus() {
showNotification('Update process timed out. Please try again or check server logs.', 'warning'); showNotification('Update process timed out. Please try again or check server logs.', 'warning');
}, 60000); // 60 second timeout for the entire update process }, 60000); // 60 second timeout for the entire update process
// Create a timeout controller
const updateController = new AbortController();
const updateTimeoutId2 = setTimeout(() => updateController.abort(), 45000);
fetch('/api/system/update', { fetch('/api/system/update', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...authHeaders() ...authHeaders()
}, },
signal: AbortSignal.timeout(45000) // 45 second timeout signal: updateController.signal // 45 second timeout
})
.then(response => {
clearTimeout(updateTimeoutId2);
return response;
})
.catch(error => {
clearTimeout(updateTimeoutId2);
throw error;
}) })
.then(response => { .then(response => {
// Better error checking // Better error checking