diff --git a/public/css/main.css b/public/css/main.css index 9f7b784..64b31c3 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -4544,4 +4544,87 @@ kbd { background: rgba(255, 255, 255, 0.02); border-radius: var(--radius-lg); border: 1px dashed rgba(255, 255, 255, 0.1); +} + +/* ===================================================== + Channel Tile Styles (Favorite Channels) + ===================================================== */ + +.channel-tiles { + gap: 16px; +} + +.channel-tile { + flex: 0 0 100px; + display: flex; + flex-direction: column; + align-items: center; + cursor: pointer; + padding: 12px 8px; + border-radius: var(--radius-md); + transition: transform var(--transition-fast), background var(--transition-fast); + scroll-snap-align: start; +} + +.channel-tile:hover { + transform: translateY(-4px); + background: rgba(255, 255, 255, 0.05); +} + +.tile-logo { + width: 64px; + height: 64px; + border-radius: 50%; + overflow: hidden; + background: var(--color-surface); + border: 2px solid rgba(255, 255, 255, 0.1); + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 8px; + transition: border-color var(--transition-fast), box-shadow var(--transition-fast); +} + +.channel-tile:hover .tile-logo { + border-color: var(--color-accent); + box-shadow: 0 0 16px rgba(var(--color-accent-rgb), 0.3); +} + +.tile-logo img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.tile-name { + font-size: 0.75rem; + font-weight: 500; + color: var(--color-text-secondary); + text-align: center; + max-width: 90px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.channel-tile:hover .tile-name { + color: var(--color-text-bright); +} + +/* Responsive: smaller tiles on mobile */ +@media (max-width: 480px) { + .channel-tile { + flex: 0 0 80px; + padding: 8px 4px; + } + + .tile-logo { + width: 52px; + height: 52px; + } + + .tile-name { + font-size: 0.7rem; + max-width: 70px; + } } \ No newline at end of file diff --git a/public/js/pages/Guide.js b/public/js/pages/Guide.js index adcf37e..2b0e5af 100644 --- a/public/js/pages/Guide.js +++ b/public/js/pages/Guide.js @@ -12,6 +12,15 @@ class GuidePage { } async show() { + // Ensure channel data is loaded before rendering EPG + // This fixes a race condition where navigating directly to the Guide page + // before visiting Live TV would result in an empty EPG. + const channelList = this.app.channelList; + if (!channelList.channels || channelList.channels.length === 0) { + await channelList.loadSources(); + await channelList.loadChannels(); + } + // Only load EPG data if not already loaded if (!this.app.epgGuide.programmes || this.app.epgGuide.programmes.length === 0) { await this.app.epgGuide.loadEpg(); diff --git a/public/js/pages/HomePage.js b/public/js/pages/HomePage.js index b599351..814b280 100644 --- a/public/js/pages/HomePage.js +++ b/public/js/pages/HomePage.js @@ -31,6 +31,15 @@ class HomePage { pageHome.innerHTML = `