diff --git a/README.md b/README.md index 21cc252..aad0240 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A modern, web-based IPTV player featuring Live TV, EPG, Movies (VOD), and Series - **📅 TV Guide (EPG)**: Interactive grid guide with 24h timeline, search, and dynamic resizing. - **🎬 VOD Support**: Dedicated sections for Movies and TV Series with rich metadata, posters, and seasonal episode lists. - **❤️ Favorites System**: Unified favorites for channels, movies, and series with instant synchronization. -- **🔐 Authentication**: User login system with admin and viewer roles ([details](#authentication)). +- **🔐 Authentication**: User login system with admin and viewer roles ([details](https://github.com/technomancer702/nodecast-tv/pull/23)). - **⚡ High Performance**: Optimized for large playlists (7000+ channels) using virtual scrolling and batch rendering. - **⚙️ Management**: - Support for Xtream Codes and M3U playlists. diff --git a/public/js/components/ChannelList.js b/public/js/components/ChannelList.js index 207b8b3..8c2f830 100644 --- a/public/js/components/ChannelList.js +++ b/public/js/components/ChannelList.js @@ -163,6 +163,57 @@ class ChannelList { this.renderNextBatch(); } }, { rootMargin: '100px' }); + + // Start EPG refresh timer (updates visible program info every 60 seconds) + this.startEpgRefreshTimer(); + } + + /** + * Start timer to refresh EPG info in visible channel items + * Updates every 60 seconds to keep "Now Playing" program info current + */ + startEpgRefreshTimer() { + // Clear any existing timer + if (this._epgRefreshTimer) { + clearInterval(this._epgRefreshTimer); + } + + // Refresh every 60 seconds + this._epgRefreshTimer = setInterval(() => { + this.updateVisibleEpgInfo(); + }, 60000); + } + + /** + * Update EPG info for visible channel items without full re-render + * Only updates the program text, not the entire channel item + */ + updateVisibleEpgInfo() { + if (!window.app || !window.app.epgGuide) return; + + // Clear the cache so we get fresh data + this.clearProgramInfoCache(); + + // Find all visible channel items and update their program info + const channelItems = this.container.querySelectorAll('.channel-item'); + channelItems.forEach(item => { + const channelId = item.dataset.channelId; + const sourceId = item.dataset.sourceId; + + // Find the channel data + const channel = this.channels.find(c => + String(c.id) === String(channelId) && + String(c.sourceId) === String(sourceId) + ); + + if (channel) { + const programInfo = this.getProgramInfo(channel); + const programElement = item.querySelector('.channel-program'); + if (programElement) { + programElement.textContent = programInfo || ''; + } + } + }); } // ... (loadSources, loadChannels, loadAllChannels, loadXtreamChannels, loadM3uChannels, loadHiddenItems, isHidden, loadFavorites, isFavorite, toggleFavorite methods remain same)