From f74ebfe6f40e7cf8bd7b52cbbfe123bb6e6ea9a3 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:37:02 -0500 Subject: [PATCH 1/3] Use modal video for source switching --- js/app.js | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/js/app.js b/js/app.js index cde193d9..aaed7860 100644 --- a/js/app.js +++ b/js/app.js @@ -400,18 +400,41 @@ class Application { if (!source) { return; } - if (this.currentVideo) { - this.playVideoWithFallback({ - url: this.currentVideo.url, - magnet: this.currentVideo.magnet, - forcedSource: source, - }).catch((error) => { - devLogger.warn( - "[app] Failed to switch playback source:", - error, - ); - }); + const modalVideo = detail?.video || null; + const fallbackVideo = this.currentVideo || null; + const video = { + ...(fallbackVideo || {}), + ...(modalVideo || {}), + }; + + if (!modalVideo && !fallbackVideo) { + devLogger.warn("[app] Playback source switch missing video data."); + return; } + + const magnetAvailable = + typeof video.magnet === "string" && video.magnet.trim(); + + if (source === "torrent" && !magnetAvailable) { + userLogger.warn( + "[app] Unable to switch to torrent playback: missing magnet.", + ); + this.showError( + "Torrent playback is unavailable for this video. No magnet was provided.", + ); + return; + } + + this.playVideoWithFallback({ + url: video.url, + magnet: video.magnet, + forcedSource: source, + }).catch((error) => { + devLogger.warn( + "[app] Failed to switch playback source:", + error, + ); + }); }); } }); From 72ee5b9f2b50936ec8e7ed7e30357395faceb15e Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 15 Jan 2026 11:49:01 -0500 Subject: [PATCH 2/3] Guard source toggle with CDN/peer availability --- js/app.js | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/js/app.js b/js/app.js index aaed7860..66d20224 100644 --- a/js/app.js +++ b/js/app.js @@ -406,14 +406,33 @@ class Application { ...(fallbackVideo || {}), ...(modalVideo || {}), }; + const urlCandidate = + typeof video.url === "string" ? video.url.trim() : ""; + const magnetCandidate = + typeof video.magnet === "string" ? video.magnet.trim() : ""; if (!modalVideo && !fallbackVideo) { devLogger.warn("[app] Playback source switch missing video data."); return; } - const magnetAvailable = - typeof video.magnet === "string" && video.magnet.trim(); + const magnetAvailable = Boolean(magnetCandidate); + const cachedStreamHealth = + video?.id && this.streamHealthSnapshots instanceof Map + ? this.streamHealthSnapshots.get(video.id) + : null; + const cachedPeers = Number.isFinite(cachedStreamHealth?.peers) + ? cachedStreamHealth.peers + : null; + const hasActivePeers = + cachedPeers === null ? null : cachedPeers > 0; + const cachedUrlHealth = + video?.id && urlCandidate + ? this.getCachedUrlHealth(video.id, urlCandidate) + : null; + const cdnUnavailable = + !urlCandidate || + ["offline", "timeout"].includes(cachedUrlHealth?.status); if (source === "torrent" && !magnetAvailable) { userLogger.warn( @@ -425,9 +444,29 @@ class Application { return; } + if (source === "torrent" && hasActivePeers === false) { + userLogger.warn( + "[app] Unable to switch to torrent playback: no active peers.", + ); + this.showError( + "Torrent playback is unavailable right now because there are no active peers.", + ); + return; + } + + if (source === "url" && cdnUnavailable) { + userLogger.warn( + "[app] Unable to switch to CDN playback: URL unavailable.", + ); + this.showError( + "CDN playback is unavailable right now, staying on the torrent stream.", + ); + return; + } + this.playVideoWithFallback({ - url: video.url, - magnet: video.magnet, + url: urlCandidate, + magnet: magnetCandidate, forcedSource: source, }).catch((error) => { devLogger.warn( From 815664ee3c9f5008521db1126a38eecb3a8b9c9e Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 15 Jan 2026 12:13:01 -0500 Subject: [PATCH 3/3] Avoid resetting playback on same source toggle --- js/app.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/app.js b/js/app.js index 66d20224..60c85c48 100644 --- a/js/app.js +++ b/js/app.js @@ -464,6 +464,10 @@ class Application { return; } + if (this.playSource && source === this.playSource) { + return; + } + this.playVideoWithFallback({ url: urlCandidate, magnet: magnetCandidate,