From 5b56c58e5b0edd1133cbab2ce68439eca30cb533 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 21:56:37 +0300 Subject: [PATCH 01/19] fix(player): redirect to MetaDetails --- src/routes/Player/Player.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 5e3552dbc..638a7162b 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -219,7 +219,6 @@ const Player = ({ urlParams, queryParams }) => { const deepLinks = player.nextVideo.deepLinks; if (deepLinks.metaDetailsStreams && deepLinks.player) { - window.location.replace(deepLinks.metaDetailsStreams); window.location.href = deepLinks.player; } else { window.location.replace(deepLinks.player ?? deepLinks.metaDetailsStreams); From 6bfe079030f366e7943cf5ea08dd8c2a3d04eed0 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 22:23:14 +0300 Subject: [PATCH 02/19] test(player): use replace instead of href --- src/routes/Player/Player.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 638a7162b..f04c960f4 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -219,7 +219,7 @@ const Player = ({ urlParams, queryParams }) => { const deepLinks = player.nextVideo.deepLinks; if (deepLinks.metaDetailsStreams && deepLinks.player) { - window.location.href = deepLinks.player; + window.location.replace(deepLinks.player); } else { window.location.replace(deepLinks.player ?? deepLinks.metaDetailsStreams); } @@ -620,11 +620,7 @@ const Player = ({ urlParams, queryParams }) => { video.events.off('implementationChanged', onImplementationChanged); }; }, [ - onError, onEnded, - onSubtitlesTrackLoaded, - onExtraSubtitlesTrackLoaded, - onExtraSubtitlesTrackAdded, onImplementationChanged ]); From 0efd1453bb6697d1964ceaf172c7f5275b96abe2 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 22:41:04 +0300 Subject: [PATCH 03/19] test(player): fix binge watching (2) --- src/routes/Player/Player.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index f04c960f4..d26248452 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -216,12 +216,12 @@ const Player = ({ urlParams, queryParams }) => { const onNextVideoRequested = React.useCallback(() => { if (player.nextVideo !== null) { nextVideo(); - const deepLinks = player.nextVideo.deepLinks; - if (deepLinks.metaDetailsStreams && deepLinks.player) { + + if (deepLinks.player) { window.location.replace(deepLinks.player); - } else { - window.location.replace(deepLinks.player ?? deepLinks.metaDetailsStreams); + } else if (deepLinks.metaDetailsStreams) { + window.location.replace(deepLinks.metaDetailsStreams); } } }, [player.nextVideo]); From 980d0038ece0bf09635a84199fabc2995feb9528 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 22:52:39 +0300 Subject: [PATCH 04/19] test(player): fix binge watching (3) --- src/routes/Player/Player.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index d26248452..f7d918696 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -215,14 +215,19 @@ const Player = ({ urlParams, queryParams }) => { const onNextVideoRequested = React.useCallback(() => { if (player.nextVideo !== null) { - nextVideo(); const deepLinks = player.nextVideo.deepLinks; - - if (deepLinks.player) { - window.location.replace(deepLinks.player); - } else if (deepLinks.metaDetailsStreams) { - window.location.replace(deepLinks.metaDetailsStreams); - } + const navigateToPlayer = deepLinks.player ? deepLinks.player : null; + const navigateToDetails = deepLinks.metaDetailsStreams ? deepLinks.metaDetailsStreams : null; + + nextVideo(); + + requestAnimationFrame(() => { + if (navigateToPlayer) { + window.location.replace(navigateToPlayer); + } else if (navigateToDetails) { + window.location.replace(navigateToDetails); + } + }); } }, [player.nextVideo]); From 7924200daba892195131f2b7ad0ce43d0a7db3c1 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 23:01:02 +0300 Subject: [PATCH 05/19] chore(player): lint --- src/routes/Player/Player.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index f7d918696..251cabe1e 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -218,9 +218,9 @@ const Player = ({ urlParams, queryParams }) => { const deepLinks = player.nextVideo.deepLinks; const navigateToPlayer = deepLinks.player ? deepLinks.player : null; const navigateToDetails = deepLinks.metaDetailsStreams ? deepLinks.metaDetailsStreams : null; - + nextVideo(); - + requestAnimationFrame(() => { if (navigateToPlayer) { window.location.replace(navigateToPlayer); From 18ac3583b4e80d1cb200f54aefc7b472517f7174 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 23:07:00 +0300 Subject: [PATCH 06/19] chore(Player): lint (2) --- src/routes/Player/Player.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 251cabe1e..496c39878 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -218,9 +218,9 @@ const Player = ({ urlParams, queryParams }) => { const deepLinks = player.nextVideo.deepLinks; const navigateToPlayer = deepLinks.player ? deepLinks.player : null; const navigateToDetails = deepLinks.metaDetailsStreams ? deepLinks.metaDetailsStreams : null; - + nextVideo(); - + requestAnimationFrame(() => { if (navigateToPlayer) { window.location.replace(navigateToPlayer); From 672a0067cea64f6065f36c0871f010aa8822e9c6 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Thu, 1 May 2025 23:37:44 +0300 Subject: [PATCH 07/19] test(Player): fix binge watching --- src/routes/Player/Player.js | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 496c39878..e47a2179c 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -102,6 +102,7 @@ const Player = ({ urlParams, queryParams }) => { }, [settings.subtitlesSize, settings.subtitlesOffset, settings.subtitlesTextColor, settings.subtitlesBackgroundColor, settings.subtitlesOutlineColor]); const onEnded = React.useCallback(() => { + console.log('Player in on ended callback', player.nextVideo); // eslint-disable-line no-console ended(); if (player.nextVideo !== null) { onNextVideoRequested(); @@ -215,19 +216,26 @@ const Player = ({ urlParams, queryParams }) => { const onNextVideoRequested = React.useCallback(() => { if (player.nextVideo !== null) { - const deepLinks = player.nextVideo.deepLinks; - const navigateToPlayer = deepLinks.player ? deepLinks.player : null; - const navigateToDetails = deepLinks.metaDetailsStreams ? deepLinks.metaDetailsStreams : null; + const navigationData = { + playerLink: player.nextVideo.deepLinks.player, + metaDetailsLink: player.nextVideo.deepLinks.metaDetailsStreams + }; - nextVideo(); - - requestAnimationFrame(() => { - if (navigateToPlayer) { - window.location.replace(navigateToPlayer); - } else if (navigateToDetails) { - window.location.replace(navigateToDetails); - } - }); + if (navigationData.playerLink) { + requestAnimationFrame(() => { + window.location.replace(navigationData.playerLink); + }); + setTimeout(() => { + nextVideo(); + }, 500); + } else if (navigationData.metaDetailsLink) { + requestAnimationFrame(() => { + window.location.replace(navigationData.metaDetailsLink); + }); + setTimeout(() => { + nextVideo(); + }, 500); + } } }, [player.nextVideo]); @@ -629,6 +637,10 @@ const Player = ({ urlParams, queryParams }) => { onImplementationChanged ]); + React.useEffect(() => { + console.log('Player next video in use effect', player.nextVideo); // eslint-disable-line no-console + }, [player.nextVideo]); + React.useLayoutEffect(() => { return () => { setImmersedDebounced.cancel(); From 9aed64d998ee1163640fec5bd8de6954d0958cc1 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 00:00:15 +0300 Subject: [PATCH 08/19] test(Player): fix binge watching (4) --- src/routes/Player/Player.js | 78 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index e47a2179c..2ad9efd17 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -83,6 +83,7 @@ const Player = ({ urlParams, queryParams }) => { return immersed && !casting && video.state.paused !== null && !video.state.paused && !menusOpen && !nextVideoPopupOpen; }, [immersed, casting, video.state.paused, menusOpen, nextVideoPopupOpen]); + const nextVideoHandledRef = React.useRef(false); const nextVideoPopupDismissed = React.useRef(false); const defaultSubtitlesSelected = React.useRef(false); const defaultAudioTrackSelected = React.useRef(false); @@ -215,26 +216,22 @@ const Player = ({ urlParams, queryParams }) => { }, []); const onNextVideoRequested = React.useCallback(() => { - if (player.nextVideo !== null) { + if (player.nextVideo !== null && !nextVideoHandledRef.current) { + nextVideoHandledRef.current = true; + const navigationData = { playerLink: player.nextVideo.deepLinks.player, metaDetailsLink: player.nextVideo.deepLinks.metaDetailsStreams }; - if (navigationData.playerLink) { - requestAnimationFrame(() => { - window.location.replace(navigationData.playerLink); - }); - setTimeout(() => { - nextVideo(); - }, 500); - } else if (navigationData.metaDetailsLink) { - requestAnimationFrame(() => { - window.location.replace(navigationData.metaDetailsLink); - }); - setTimeout(() => { - nextVideo(); - }, 500); + const targetLink = navigationData.playerLink || navigationData.metaDetailsLink; + + if (targetLink) { + nextVideo(); + + window.location.replace(targetLink); + } else { + nextVideo(); } } }, [player.nextVideo]); @@ -430,6 +427,7 @@ const Player = ({ urlParams, queryParams }) => { defaultSubtitlesSelected.current = false; defaultAudioTrackSelected.current = false; nextVideoPopupDismissed.current = false; + nextVideoHandledRef.current = false; }, [video.state.stream]); React.useEffect(() => { @@ -493,6 +491,31 @@ const Player = ({ urlParams, queryParams }) => { } }, [settings.pauseOnMinimize, shell.windowClosed, shell.windowHidden]); + React.useEffect(() => { + nextVideoHandledRef.current = false; + }, [player.selected]); + + React.useEffect(() => { + video.events.on('error', onError); + video.events.on('ended', onEnded); + video.events.on('subtitlesTrackLoaded', onSubtitlesTrackLoaded); + video.events.on('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); + video.events.on('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); + video.events.on('implementationChanged', onImplementationChanged); + + return () => { + video.events.off('error', onError); + video.events.off('ended', onEnded); + video.events.off('subtitlesTrackLoaded', onSubtitlesTrackLoaded); + video.events.off('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); + video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); + video.events.off('implementationChanged', onImplementationChanged); + }; + }, [ + onEnded, + onImplementationChanged + ]); + React.useLayoutEffect(() => { const onKeyDown = (event) => { switch (event.code) { @@ -616,31 +639,6 @@ const Player = ({ urlParams, queryParams }) => { }; }, [player.metaItem, player.selected, streamingServer.statistics, settings.seekTimeDuration, settings.seekShortTimeDuration, settings.escExitFullscreen, routeFocused, menusOpen, nextVideoPopupOpen, video.state.paused, video.state.time, video.state.volume, video.state.audioTracks, video.state.subtitlesTracks, video.state.extraSubtitlesTracks, video.state.playbackSpeed, toggleSubtitlesMenu, toggleStatisticsMenu, toggleSideDrawer]); - React.useEffect(() => { - video.events.on('error', onError); - video.events.on('ended', onEnded); - video.events.on('subtitlesTrackLoaded', onSubtitlesTrackLoaded); - video.events.on('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); - video.events.on('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); - video.events.on('implementationChanged', onImplementationChanged); - - return () => { - video.events.off('error', onError); - video.events.off('ended', onEnded); - video.events.off('subtitlesTrackLoaded', onSubtitlesTrackLoaded); - video.events.off('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); - video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); - video.events.off('implementationChanged', onImplementationChanged); - }; - }, [ - onEnded, - onImplementationChanged - ]); - - React.useEffect(() => { - console.log('Player next video in use effect', player.nextVideo); // eslint-disable-line no-console - }, [player.nextVideo]); - React.useLayoutEffect(() => { return () => { setImmersedDebounced.cancel(); From 9b405c53d8fffe24616acd3bcfc2c29cd8c98e6b Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 00:22:39 +0300 Subject: [PATCH 09/19] test(player): fix binge watching (5) --- src/routes/Player/Player.js | 60 ++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 2ad9efd17..6fb5b02c8 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -103,7 +103,6 @@ const Player = ({ urlParams, queryParams }) => { }, [settings.subtitlesSize, settings.subtitlesOffset, settings.subtitlesTextColor, settings.subtitlesBackgroundColor, settings.subtitlesOutlineColor]); const onEnded = React.useCallback(() => { - console.log('Player in on ended callback', player.nextVideo); // eslint-disable-line no-console ended(); if (player.nextVideo !== null) { onNextVideoRequested(); @@ -216,22 +215,36 @@ const Player = ({ urlParams, queryParams }) => { }, []); const onNextVideoRequested = React.useCallback(() => { - if (player.nextVideo !== null && !nextVideoHandledRef.current) { - nextVideoHandledRef.current = true; + if (player.nextVideo !== null) { + // Call nextVideo only for analytics + nextVideo(); - const navigationData = { - playerLink: player.nextVideo.deepLinks.player, - metaDetailsLink: player.nextVideo.deepLinks.metaDetailsStreams - }; + // Capture navigation data + const navigationLink = player.nextVideo.deepLinks.player || + player.nextVideo.deepLinks.metaDetailsStreams; - const targetLink = navigationData.playerLink || navigationData.metaDetailsLink; + if (navigationLink) { + // Force immediate navigation with no chance of React re-renders affecting it + // This bypasses the React lifecycle entirely + const navigateImmediately = () => { + const form = document.createElement('form'); + form.style.display = 'none'; + form.method = 'GET'; + form.action = navigationLink; - if (targetLink) { - nextVideo(); + const input = document.createElement('input'); + input.type = 'hidden'; + input.name = 'navigationFromPlayer'; + input.value = 'true'; + form.appendChild(input); - window.location.replace(targetLink); - } else { - nextVideo(); + // Force immediate navigation + document.body.appendChild(form); + form.submit(); + }; + + // Execute immediately + navigateImmediately(); } } }, [player.nextVideo]); @@ -511,10 +524,7 @@ const Player = ({ urlParams, queryParams }) => { video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); video.events.off('implementationChanged', onImplementationChanged); }; - }, [ - onEnded, - onImplementationChanged - ]); + }, [onEnded]); React.useLayoutEffect(() => { const onKeyDown = (event) => { @@ -647,6 +657,22 @@ const Player = ({ urlParams, queryParams }) => { }; }, []); + React.useEffect(() => { + const urlParams = new URLSearchParams(window.location.search); + // eslint-disable-next-line + const cameFromPlayer = urlParams.get('navigationFromPlayer'); + + if (cameFromPlayer === 'true') { + // eslint-disable-next-line + urlParams.delete('navigationFromPlayer'); + const newUrl = window.location.pathname + + (urlParams.toString() ? '?' + urlParams.toString() : '') + + window.location.hash; + + window.history.replaceState({}, '', newUrl); + } + }, []); + return (
Date: Fri, 2 May 2025 00:53:42 +0300 Subject: [PATCH 10/19] test(Player): fix binge watching (6) --- src/routes/Player/Player.js | 53 +++++++------------------------------ 1 file changed, 9 insertions(+), 44 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 6fb5b02c8..285f54a28 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -85,6 +85,8 @@ const Player = ({ urlParams, queryParams }) => { const nextVideoHandledRef = React.useRef(false); const nextVideoPopupDismissed = React.useRef(false); + const nextVideoInitialData = React.useRef(player.nextVideo); + nextVideoInitialData.current = player.nextVideo; const defaultSubtitlesSelected = React.useRef(false); const defaultAudioTrackSelected = React.useRef(false); const [error, setError] = React.useState(null); @@ -103,6 +105,7 @@ const Player = ({ urlParams, queryParams }) => { }, [settings.subtitlesSize, settings.subtitlesOffset, settings.subtitlesTextColor, settings.subtitlesBackgroundColor, settings.subtitlesOutlineColor]); const onEnded = React.useCallback(() => { + player.nextVideo = nextVideoInitialData.current; ended(); if (player.nextVideo !== null) { onNextVideoRequested(); @@ -216,35 +219,13 @@ const Player = ({ urlParams, queryParams }) => { const onNextVideoRequested = React.useCallback(() => { if (player.nextVideo !== null) { - // Call nextVideo only for analytics nextVideo(); - - // Capture navigation data - const navigationLink = player.nextVideo.deepLinks.player || - player.nextVideo.deepLinks.metaDetailsStreams; - - if (navigationLink) { - // Force immediate navigation with no chance of React re-renders affecting it - // This bypasses the React lifecycle entirely - const navigateImmediately = () => { - const form = document.createElement('form'); - form.style.display = 'none'; - form.method = 'GET'; - form.action = navigationLink; - - const input = document.createElement('input'); - input.type = 'hidden'; - input.name = 'navigationFromPlayer'; - input.value = 'true'; - form.appendChild(input); - - // Force immediate navigation - document.body.appendChild(form); - form.submit(); - }; - - // Execute immediately - navigateImmediately(); + const deepLinks = player.nextVideo.deepLinks; + if (deepLinks.metaDetailsStreams && deepLinks.player) { + window.location.replace(deepLinks.metaDetailsStreams); + window.location.href = deepLinks.player; + } else { + window.location.replace(deepLinks.player ?? deepLinks.metaDetailsStreams); } } }, [player.nextVideo]); @@ -657,22 +638,6 @@ const Player = ({ urlParams, queryParams }) => { }; }, []); - React.useEffect(() => { - const urlParams = new URLSearchParams(window.location.search); - // eslint-disable-next-line - const cameFromPlayer = urlParams.get('navigationFromPlayer'); - - if (cameFromPlayer === 'true') { - // eslint-disable-next-line - urlParams.delete('navigationFromPlayer'); - const newUrl = window.location.pathname + - (urlParams.toString() ? '?' + urlParams.toString() : '') + - window.location.hash; - - window.history.replaceState({}, '', newUrl); - } - }, []); - return (
Date: Fri, 2 May 2025 01:14:48 +0300 Subject: [PATCH 11/19] Update Player.js --- src/routes/Player/Player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 285f54a28..307ae2302 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -505,7 +505,7 @@ const Player = ({ urlParams, queryParams }) => { video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); video.events.off('implementationChanged', onImplementationChanged); }; - }, [onEnded]); + }, []); React.useLayoutEffect(() => { const onKeyDown = (event) => { From d6372c4f86fb7d22ac8fcd343b97e1e583ca31b0 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 01:30:58 +0300 Subject: [PATCH 12/19] test: another test --- src/routes/Player/Player.js | 43 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 307ae2302..9ec495907 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -83,7 +83,6 @@ const Player = ({ urlParams, queryParams }) => { return immersed && !casting && video.state.paused !== null && !video.state.paused && !menusOpen && !nextVideoPopupOpen; }, [immersed, casting, video.state.paused, menusOpen, nextVideoPopupOpen]); - const nextVideoHandledRef = React.useRef(false); const nextVideoPopupDismissed = React.useRef(false); const nextVideoInitialData = React.useRef(player.nextVideo); nextVideoInitialData.current = player.nextVideo; @@ -220,6 +219,7 @@ const Player = ({ urlParams, queryParams }) => { const onNextVideoRequested = React.useCallback(() => { if (player.nextVideo !== null) { nextVideo(); + const deepLinks = player.nextVideo.deepLinks; if (deepLinks.metaDetailsStreams && deepLinks.player) { window.location.replace(deepLinks.metaDetailsStreams); @@ -421,7 +421,6 @@ const Player = ({ urlParams, queryParams }) => { defaultSubtitlesSelected.current = false; defaultAudioTrackSelected.current = false; nextVideoPopupDismissed.current = false; - nextVideoHandledRef.current = false; }, [video.state.stream]); React.useEffect(() => { @@ -485,28 +484,6 @@ const Player = ({ urlParams, queryParams }) => { } }, [settings.pauseOnMinimize, shell.windowClosed, shell.windowHidden]); - React.useEffect(() => { - nextVideoHandledRef.current = false; - }, [player.selected]); - - React.useEffect(() => { - video.events.on('error', onError); - video.events.on('ended', onEnded); - video.events.on('subtitlesTrackLoaded', onSubtitlesTrackLoaded); - video.events.on('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); - video.events.on('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); - video.events.on('implementationChanged', onImplementationChanged); - - return () => { - video.events.off('error', onError); - video.events.off('ended', onEnded); - video.events.off('subtitlesTrackLoaded', onSubtitlesTrackLoaded); - video.events.off('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); - video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); - video.events.off('implementationChanged', onImplementationChanged); - }; - }, []); - React.useLayoutEffect(() => { const onKeyDown = (event) => { switch (event.code) { @@ -630,6 +607,24 @@ const Player = ({ urlParams, queryParams }) => { }; }, [player.metaItem, player.selected, streamingServer.statistics, settings.seekTimeDuration, settings.seekShortTimeDuration, settings.escExitFullscreen, routeFocused, menusOpen, nextVideoPopupOpen, video.state.paused, video.state.time, video.state.volume, video.state.audioTracks, video.state.subtitlesTracks, video.state.extraSubtitlesTracks, video.state.playbackSpeed, toggleSubtitlesMenu, toggleStatisticsMenu, toggleSideDrawer]); + React.useEffect(() => { + video.events.on('error', onError); + video.events.on('ended', onEnded); + video.events.on('subtitlesTrackLoaded', onSubtitlesTrackLoaded); + video.events.on('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); + video.events.on('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); + video.events.on('implementationChanged', onImplementationChanged); + + return () => { + video.events.off('error', onError); + video.events.off('ended', onEnded); + video.events.off('subtitlesTrackLoaded', onSubtitlesTrackLoaded); + video.events.off('extraSubtitlesTrackLoaded', onExtraSubtitlesTrackLoaded); + video.events.off('extraSubtitlesTrackAdded', onExtraSubtitlesTrackAdded); + video.events.off('implementationChanged', onImplementationChanged); + }; + }, []); + React.useLayoutEffect(() => { return () => { setImmersedDebounced.cancel(); From ce0c5da3fd39ba7199c24d92f8beddc5d3983327 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 01:46:13 +0300 Subject: [PATCH 13/19] test: again --- src/routes/Player/Player.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 9ec495907..9c9ae5e92 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -84,8 +84,6 @@ const Player = ({ urlParams, queryParams }) => { }, [immersed, casting, video.state.paused, menusOpen, nextVideoPopupOpen]); const nextVideoPopupDismissed = React.useRef(false); - const nextVideoInitialData = React.useRef(player.nextVideo); - nextVideoInitialData.current = player.nextVideo; const defaultSubtitlesSelected = React.useRef(false); const defaultAudioTrackSelected = React.useRef(false); const [error, setError] = React.useState(null); @@ -104,7 +102,6 @@ const Player = ({ urlParams, queryParams }) => { }, [settings.subtitlesSize, settings.subtitlesOffset, settings.subtitlesTextColor, settings.subtitlesBackgroundColor, settings.subtitlesOutlineColor]); const onEnded = React.useCallback(() => { - player.nextVideo = nextVideoInitialData.current; ended(); if (player.nextVideo !== null) { onNextVideoRequested(); From f3a7ef5978455d552e1c0968a9d282ea0d82bada Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 19:42:49 +0300 Subject: [PATCH 14/19] fix(Player): binge watching in shell --- src/routes/Player/Player.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 9c9ae5e92..c9173af40 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -88,6 +88,8 @@ const Player = ({ urlParams, queryParams }) => { const defaultAudioTrackSelected = React.useRef(false); const [error, setError] = React.useState(null); + const isNavigating = React.useRef(false); + const onImplementationChanged = React.useCallback(() => { video.setProp('subtitlesSize', settings.subtitlesSize); video.setProp('subtitlesOffset', settings.subtitlesOffset); @@ -101,7 +103,24 @@ const Player = ({ urlParams, queryParams }) => { video.setProp('extraSubtitlesOutlineColor', settings.subtitlesOutlineColor); }, [settings.subtitlesSize, settings.subtitlesOffset, settings.subtitlesTextColor, settings.subtitlesBackgroundColor, settings.subtitlesOutlineColor]); + const handleNextVideoNavigation = React.useCallback((deepLinks) => { + if (deepLinks.player) { + isNavigating.current = true; + window.location.href = deepLinks.player; + return true; + } else if (deepLinks.metaDetailsStreams) { + isNavigating.current = true; + window.location.href = deepLinks.metaDetailsStreams; + return true; + } + return false; + }, []); + const onEnded = React.useCallback(() => { + if (isNavigating.current) { + return; + } + ended(); if (player.nextVideo !== null) { onNextVideoRequested(); @@ -218,14 +237,9 @@ const Player = ({ urlParams, queryParams }) => { nextVideo(); const deepLinks = player.nextVideo.deepLinks; - if (deepLinks.metaDetailsStreams && deepLinks.player) { - window.location.replace(deepLinks.metaDetailsStreams); - window.location.href = deepLinks.player; - } else { - window.location.replace(deepLinks.player ?? deepLinks.metaDetailsStreams); - } + handleNextVideoNavigation(deepLinks); } - }, [player.nextVideo]); + }, [player.nextVideo, handleNextVideoNavigation]); const onVideoClick = React.useCallback(() => { if (video.state.paused !== null) { From 3985c88346fef98d57d3e0e88a0c01493f0dcfdb Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 19:44:55 +0300 Subject: [PATCH 15/19] chore(Player): lint --- src/routes/Player/Player.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index c9173af40..24a1b249e 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -123,11 +123,13 @@ const Player = ({ urlParams, queryParams }) => { ended(); if (player.nextVideo !== null) { - onNextVideoRequested(); + nextVideo(); + const deepLinks = player.nextVideo.deepLinks; + handleNextVideoNavigation(deepLinks); } else { window.history.back(); } - }, [player.nextVideo, onNextVideoRequested]); + }, [player.nextVideo, nextVideo, handleNextVideoNavigation]); const onError = React.useCallback((error) => { console.error('Player', error); From ebb15463b48b1ee7e5866d38c83d264de5d851d0 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 19:47:04 +0300 Subject: [PATCH 16/19] chore(Player): lint (2) --- src/routes/Player/Player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 24a1b249e..8e2b2f615 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -120,7 +120,7 @@ const Player = ({ urlParams, queryParams }) => { if (isNavigating.current) { return; } - + ended(); if (player.nextVideo !== null) { nextVideo(); From 17312f64fd0b596c26e4b0c17d7f042ee64c6e49 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 19:48:04 +0300 Subject: [PATCH 17/19] revert: chore lint 1 --- src/routes/Player/Player.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 8e2b2f615..cb6371986 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -123,13 +123,11 @@ const Player = ({ urlParams, queryParams }) => { ended(); if (player.nextVideo !== null) { - nextVideo(); - const deepLinks = player.nextVideo.deepLinks; - handleNextVideoNavigation(deepLinks); + onNextVideoRequested(); } else { window.history.back(); } - }, [player.nextVideo, nextVideo, handleNextVideoNavigation]); + }, [player.nextVideo, onNextVideoRequested]); const onError = React.useCallback((error) => { console.error('Player', error); From b51791baa015077ded7109ba9c2f6588a8ae8307 Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Fri, 2 May 2025 19:55:09 +0300 Subject: [PATCH 18/19] fix(Player): replace history entry - fix for the navigation --- src/routes/Player/Player.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index cb6371986..49395e2ba 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -106,11 +106,11 @@ const Player = ({ urlParams, queryParams }) => { const handleNextVideoNavigation = React.useCallback((deepLinks) => { if (deepLinks.player) { isNavigating.current = true; - window.location.href = deepLinks.player; + window.location.replace(deepLinks.player); return true; } else if (deepLinks.metaDetailsStreams) { isNavigating.current = true; - window.location.href = deepLinks.metaDetailsStreams; + window.location.replace(deepLinks.metaDetailsStreams); return true; } return false; From 4d53952368f8cdd2eddc51b4ef33af941e1141cc Mon Sep 17 00:00:00 2001 From: "Timothy Z." Date: Mon, 5 May 2025 17:51:12 +0200 Subject: [PATCH 19/19] remove(Player): unnecessary returns --- src/routes/Player/Player.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 49395e2ba..740ed46d4 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -107,13 +107,10 @@ const Player = ({ urlParams, queryParams }) => { if (deepLinks.player) { isNavigating.current = true; window.location.replace(deepLinks.player); - return true; } else if (deepLinks.metaDetailsStreams) { isNavigating.current = true; window.location.replace(deepLinks.metaDetailsStreams); - return true; } - return false; }, []); const onEnded = React.useCallback(() => {