Refactored EPG refresh logic
This commit is contained in:
@@ -122,11 +122,83 @@ class EpgGuide {
|
||||
getRefreshInterval() {
|
||||
// Read from server-side player settings (synced via Settings page)
|
||||
if (window.app?.player?.settings?.epgRefreshInterval) {
|
||||
return parseInt(window.app.player.settings.epgRefreshInterval);
|
||||
return parseFloat(window.app.player.settings.epgRefreshInterval);
|
||||
}
|
||||
return 24; // Default 24 hours
|
||||
}
|
||||
|
||||
/**
|
||||
* Start background EPG refresh timer
|
||||
* Automatically fetches fresh EPG data at the configured interval
|
||||
*/
|
||||
startBackgroundRefresh() {
|
||||
// Clear any existing timer
|
||||
this.stopBackgroundRefresh();
|
||||
|
||||
const intervalHours = this.getRefreshInterval();
|
||||
|
||||
// If interval is 0 or invalid, don't start timer (manual refresh only)
|
||||
if (!intervalHours || intervalHours <= 0) {
|
||||
console.log('[EPG] Background refresh disabled (manual only mode)');
|
||||
this._currentRefreshInterval = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const intervalMs = intervalHours * 60 * 60 * 1000; // Convert hours to milliseconds
|
||||
|
||||
console.log(`[EPG] Starting background refresh timer: every ${intervalHours} hours (${Math.round(intervalMs / 1000)}s)`);
|
||||
|
||||
this._backgroundRefreshTimer = setInterval(async () => {
|
||||
console.log('[EPG] Background refresh triggered');
|
||||
try {
|
||||
await this.fetchEpgData(true); // Force refresh
|
||||
this.lastRefreshTime = new Date();
|
||||
console.log('[EPG] Background refresh complete');
|
||||
|
||||
// Update channel list program info if visible
|
||||
if (window.app?.channelList) {
|
||||
window.app.channelList.clearProgramInfoCache();
|
||||
window.app.channelList.updateVisibleEpgInfo?.();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[EPG] Background refresh failed:', err);
|
||||
}
|
||||
}, intervalMs);
|
||||
|
||||
// Store current interval so we can detect changes
|
||||
this._currentRefreshInterval = intervalHours;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop background EPG refresh timer
|
||||
*/
|
||||
stopBackgroundRefresh() {
|
||||
if (this._backgroundRefreshTimer) {
|
||||
clearInterval(this._backgroundRefreshTimer);
|
||||
this._backgroundRefreshTimer = null;
|
||||
console.log('[EPG] Background refresh timer stopped');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart background refresh if interval has changed
|
||||
* Called when settings change
|
||||
*/
|
||||
restartBackgroundRefreshIfNeeded() {
|
||||
const newInterval = this.getRefreshInterval();
|
||||
if (this._currentRefreshInterval !== newInterval) {
|
||||
console.log(`[EPG] Refresh interval changed: ${this._currentRefreshInterval}h -> ${newInterval}h`);
|
||||
this.startBackgroundRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last refresh time for display
|
||||
*/
|
||||
getLastRefreshTime() {
|
||||
return this.lastRefreshTime || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load EPG data (server-side caching)
|
||||
*/
|
||||
@@ -134,7 +206,12 @@ class EpgGuide {
|
||||
try {
|
||||
this.container.innerHTML = '<div class="loading"></div>';
|
||||
await this.fetchEpgData(forceRefresh);
|
||||
this.lastRefreshTime = new Date();
|
||||
this.render();
|
||||
|
||||
// Start background refresh timer after initial load
|
||||
// This ensures EPG data stays fresh while the app is open
|
||||
this.startBackgroundRefresh();
|
||||
} catch (err) {
|
||||
console.error('Error loading EPG:', err);
|
||||
this.container.innerHTML = `
|
||||
|
||||
+19
-14
@@ -19,7 +19,7 @@ class SettingsPage {
|
||||
|
||||
// Player settings
|
||||
this.initPlayerSettings();
|
||||
|
||||
|
||||
// User management (admin only)
|
||||
this.initUserManagement();
|
||||
}
|
||||
@@ -112,10 +112,15 @@ class SettingsPage {
|
||||
// Load saved value from player settings
|
||||
epgRefreshSelect.value = this.app.player.settings.epgRefreshInterval || '24';
|
||||
|
||||
// Save on change
|
||||
// Save on change and restart background timer
|
||||
epgRefreshSelect.addEventListener('change', () => {
|
||||
this.app.player.settings.epgRefreshInterval = epgRefreshSelect.value;
|
||||
this.app.player.saveSettings();
|
||||
|
||||
// Restart EPG background refresh with new interval
|
||||
if (window.app?.epgGuide) {
|
||||
window.app.epgGuide.restartBackgroundRefreshIfNeeded();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -136,17 +141,17 @@ class SettingsPage {
|
||||
initUserManagement() {
|
||||
// User tab visibility is handled in show() method
|
||||
// when currentUser is available
|
||||
|
||||
|
||||
// Handle add user form
|
||||
const addUserForm = document.getElementById('add-user-form');
|
||||
if (addUserForm) {
|
||||
addUserForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
const username = document.getElementById('new-username').value;
|
||||
const password = document.getElementById('new-password').value;
|
||||
const role = document.getElementById('new-role').value;
|
||||
|
||||
|
||||
try {
|
||||
await API.users.create({ username, password, role });
|
||||
alert('User created successfully!');
|
||||
@@ -162,15 +167,15 @@ class SettingsPage {
|
||||
async loadUsers() {
|
||||
const userList = document.getElementById('user-list');
|
||||
if (!userList) return;
|
||||
|
||||
|
||||
try {
|
||||
const users = await API.users.getAll();
|
||||
|
||||
|
||||
if (users.length === 0) {
|
||||
userList.innerHTML = '<tr><td colspan="4" class="hint">No users found</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
userList.innerHTML = users.map(user => `
|
||||
<tr>
|
||||
<td>${user.username}</td>
|
||||
@@ -192,17 +197,17 @@ class SettingsPage {
|
||||
const username = prompt('Enter new username (leave blank to keep current):');
|
||||
const password = prompt('Enter new password (leave blank to keep current):');
|
||||
const role = prompt('Enter role (admin or viewer, leave blank to keep current):');
|
||||
|
||||
|
||||
const updates = {};
|
||||
if (username) updates.username = username;
|
||||
if (password) updates.password = password;
|
||||
if (role) updates.role = role;
|
||||
|
||||
|
||||
if (Object.keys(updates).length === 0) {
|
||||
alert('No changes made');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await API.users.update(userId, updates);
|
||||
alert('User updated successfully!');
|
||||
@@ -216,7 +221,7 @@ class SettingsPage {
|
||||
if (!confirm(`Are you sure you want to delete user "${username}"?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await API.users.delete(userId);
|
||||
alert('User deleted successfully!');
|
||||
@@ -234,7 +239,7 @@ class SettingsPage {
|
||||
if (tabName === 'content') {
|
||||
this.app.sourceManager.loadContentSources();
|
||||
}
|
||||
|
||||
|
||||
// Load users when switching to users tab
|
||||
if (tabName === 'users') {
|
||||
this.loadUsers();
|
||||
@@ -249,7 +254,7 @@ class SettingsPage {
|
||||
usersTab.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load sources when page is shown
|
||||
await this.app.sourceManager.loadSources();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user