fix: favorites arrow navigation stays in same group, add cross-player stop on new playback

This commit is contained in:
Trevor Mears
2026-01-18 00:58:57 -08:00
parent dc029f75e5
commit d6eda66360
3 changed files with 46 additions and 9 deletions
+40 -9
View File
@@ -497,6 +497,7 @@ class ChannelList {
const isFavorite = this.isFavorite(channel.sourceId, channel.id); const isFavorite = this.isFavorite(channel.sourceId, channel.id);
const renderId = this.renderedChannels[renderIndex]?._renderId || ''; const renderId = this.renderedChannels[renderIndex]?._renderId || '';
const renderGroup = this.renderedChannels[renderIndex]?._renderGroup || groupName;
renderIndex++; renderIndex++;
html += ` html += `
@@ -506,7 +507,8 @@ class ChannelList {
data-source-type="${channel.sourceType}" data-source-type="${channel.sourceType}"
data-stream-id="${channel.streamId || ''}" data-stream-id="${channel.streamId || ''}"
data-url="${channel.url || ''}" data-url="${channel.url || ''}"
data-render-id="${renderId}"> data-render-id="${renderId}"
data-render-group="${renderGroup}">
<img class="channel-logo" src="${this.getProxiedImageUrl(channel.tvgLogo)}" <img class="channel-logo" src="${this.getProxiedImageUrl(channel.tvgLogo)}"
alt="" onerror="this.onerror=null;this.src='/img/placeholder.png'"> alt="" onerror="this.onerror=null;this.src='/img/placeholder.png'">
<div class="channel-info"> <div class="channel-info">
@@ -604,13 +606,22 @@ class ChannelList {
const isActive = this.currentChannel?.id === channel.id; const isActive = this.currentChannel?.id === channel.id;
const isFavorite = this.isFavorite(channel.sourceId, channel.id); const isFavorite = this.isFavorite(channel.sourceId, channel.id);
// Find the matching rendered channel to get its unique IDs
const renderedChannel = this.renderedChannels.find(rc =>
rc.id === channel.id && rc.sourceId === channel.sourceId && rc._renderGroup === groupName
);
const renderId = renderedChannel?._renderId || '';
const renderGroup = renderedChannel?._renderGroup || groupName;
html += ` html += `
<div class="channel-item ${isActive ? 'active' : ''} ${channelHidden ? 'hidden' : ''}" <div class="channel-item ${isActive ? 'active' : ''} ${channelHidden ? 'hidden' : ''}"
data-channel-id="${channel.id}" data-channel-id="${channel.id}"
data-source-id="${channel.sourceId}" data-source-id="${channel.sourceId}"
data-source-type="${channel.sourceType}" data-source-type="${channel.sourceType}"
data-stream-id="${channel.streamId || ''}" data-stream-id="${channel.streamId || ''}"
data-url="${channel.url || ''}"> data-url="${channel.url || ''}"
data-render-id="${renderId}"
data-render-group="${renderGroup}">
<img class="channel-logo" src="${this.getProxiedImageUrl(channel.tvgLogo)}" <img class="channel-logo" src="${this.getProxiedImageUrl(channel.tvgLogo)}"
alt="" onerror="this.onerror=null;this.src='/img/placeholder.png'"> alt="" onerror="this.onerror=null;this.src='/img/placeholder.png'">
<div class="channel-info"> <div class="channel-info">
@@ -1079,6 +1090,7 @@ class ChannelList {
this.currentChannel = channel; this.currentChannel = channel;
this.currentRenderId = dataset.renderId; // Track which visual instance is active this.currentRenderId = dataset.renderId; // Track which visual instance is active
this.currentRenderGroup = dataset.renderGroup; // Track which group the selection came from
// Update active state in DOM // Update active state in DOM
this.container.querySelectorAll('.channel-item.active').forEach(el => { this.container.querySelectorAll('.channel-item.active').forEach(el => {
@@ -1359,11 +1371,20 @@ class ChannelList {
currentIndex = this.renderedChannels.findIndex(c => c._renderId === this.currentRenderId); currentIndex = this.renderedChannels.findIndex(c => c._renderId === this.currentRenderId);
} }
// Fallback: Find first matching channel ID (if render ID lost or invalid) // Fallback: Find matching channel ID, prioritizing same render group
if (currentIndex === -1) { if (currentIndex === -1) {
currentIndex = this.renderedChannels.findIndex(c => // First try to find in same group (for Favorites containing duplicates)
c.id === this.currentChannel.id && c.sourceId === this.currentChannel.sourceId if (this.currentRenderGroup) {
); currentIndex = this.renderedChannels.findIndex(c =>
c.id === this.currentChannel.id && c.sourceId === this.currentChannel.sourceId && c._renderGroup === this.currentRenderGroup
);
}
// Final fallback: any matching channel
if (currentIndex === -1) {
currentIndex = this.renderedChannels.findIndex(c =>
c.id === this.currentChannel.id && c.sourceId === this.currentChannel.sourceId
);
}
} }
if (currentIndex === -1) return; if (currentIndex === -1) return;
@@ -1393,10 +1414,20 @@ class ChannelList {
currentIndex = this.renderedChannels.findIndex(c => c._renderId === this.currentRenderId); currentIndex = this.renderedChannels.findIndex(c => c._renderId === this.currentRenderId);
} }
// Fallback: Find matching channel ID, prioritizing same render group
if (currentIndex === -1) { if (currentIndex === -1) {
currentIndex = this.renderedChannels.findIndex(c => // First try to find in same group (for Favorites containing duplicates)
c.id === this.currentChannel.id && c.sourceId === this.currentChannel.sourceId if (this.currentRenderGroup) {
); currentIndex = this.renderedChannels.findIndex(c =>
c.id === this.currentChannel.id && c.sourceId === this.currentChannel.sourceId && c._renderGroup === this.currentRenderGroup
);
}
// Final fallback: any matching channel
if (currentIndex === -1) {
currentIndex = this.renderedChannels.findIndex(c =>
c.id === this.currentChannel.id && c.sourceId === this.currentChannel.sourceId
);
}
} }
if (currentIndex === -1) return; if (currentIndex === -1) return;
+3
View File
@@ -752,6 +752,9 @@ class VideoPlayer {
this.currentChannel = channel; this.currentChannel = channel;
try { try {
// Stop any WatchPage playback (movies/series) before starting Live TV
window.app?.pages?.watch?.stop?.();
// Stop current playback // Stop current playback
this.stop(); this.stop();
this.updateTranscodeStatus('hidden'); this.updateTranscodeStatus('hidden');
+3
View File
@@ -200,6 +200,9 @@ class WatchPage {
this.currentEpisode = content.currentEpisode || null; this.currentEpisode = content.currentEpisode || null;
this.returnPage = content.type === 'movie' ? 'movies' : 'series'; this.returnPage = content.type === 'movie' ? 'movies' : 'series';
// Stop any Live TV playback before starting movie/series
this.app?.player?.stop?.();
// Reset state // Reset state
this.cancelNextEpisode(); this.cancelNextEpisode();