From 772cde815edf39a248e3357e8b71725112ebc6b0 Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 19 Jun 2021 11:11:46 +0200 Subject: [PATCH 1/6] refactor(Player): allow to download a m3u playlist in case of a playback error --- src/routes/Player/Player.js | 16 +++++++++++++-- src/routes/Player/styles.less | 37 ++++++++++++++++++++++++++++++++-- src/routes/Player/usePlayer.js | 14 ++++++++++++- 3 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index d54124e02..d8c91af99 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -6,7 +6,8 @@ const classnames = require('classnames'); const debounce = require('lodash.debounce'); const { useRouteFocused } = require('stremio-router'); const { useServices } = require('stremio/services'); -const { HorizontalNavBar, useDeepEqualEffect, useFullscreen, useBinaryState, useToast, useStreamingServer } = require('stremio/common'); +const { HorizontalNavBar, Button, useDeepEqualEffect, useFullscreen, useBinaryState, useToast, useStreamingServer } = require('stremio/common'); +const Icon = require('@stremio/stremio-icons/dom'); const BufferingLoader = require('./BufferingLoader'); const ControlBar = require('./ControlBar'); const InfoMenu = require('./InfoMenu'); @@ -21,7 +22,7 @@ const Player = ({ urlParams, queryParams }) => { const forceTranscoding = React.useMemo(() => { return queryParams.has('forceTranscoding'); }, [queryParams]); - const [player, updateLibraryItemState, pushToLibrary] = usePlayer(urlParams); + const [player, playlist, updateLibraryItemState, pushToLibrary] = usePlayer(urlParams); const [settings, updateSettings] = useSettings(); const streamingServer = useStreamingServer(); const routeFocused = useRouteFocused(); @@ -418,6 +419,17 @@ const Player = ({ urlParams, queryParams }) => { error !== null ?
{error.message}
+ { + playlist ? +
+ +
+ : + null + }
: null diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index 8c84da749..a77874539 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -36,13 +36,14 @@ html:not(.active-slider-within) { left: 0; right: 0; bottom: 0; - z-index: 0; &.error-layer { + z-index: 1; display: flex; - flex-direction: row; + flex-direction: column; align-items: center; justify-content: center; + gap: 1.5rem; background-color: @color-background-dark5; .error-label { @@ -53,9 +54,39 @@ html:not(.active-slider-within) { color: @color-surface-light5-90; text-align: center; } + + .error-details { + gap: 0.8rem; + font-size: 1.5rem; + color: @color-surface-light5-90; + + .error-details-button { + flex: none; + display: flex; + flex-direction: row; + align-items: center; + gap: 1rem; + height: 3.5rem; + padding: 0.5rem 1rem; + font-weight: 500; + color: @color-surface-light5-90; + background-color: @color-surface-light5-20; + + &:hover, &:focus { + background-color: @color-accent3; + } + + .icon { + width: 1.5rem; + height: 1.5rem; + fill: @color-surface-light5-90; + } + } + } } &.nav-bar-layer { + z-index: 2; bottom: initial; background: transparent; overflow: visible; @@ -86,6 +117,7 @@ html:not(.active-slider-within) { } &.control-bar-layer { + z-index: 2; top: initial; overflow: visible; @@ -101,6 +133,7 @@ html:not(.active-slider-within) { } &.menu-layer { + z-index: 2; top: initial; left: initial; right: 2rem; diff --git a/src/routes/Player/usePlayer.js b/src/routes/Player/usePlayer.js index 54b6ded23..3db53fd1b 100644 --- a/src/routes/Player/usePlayer.js +++ b/src/routes/Player/usePlayer.js @@ -110,7 +110,19 @@ const usePlayer = (urlParams) => { }, 'player'); }, []); const player = useModelState({ model: 'player', action, init, map }); - return [player, updateLibraryItemState, pushToLibrary]; + const playlist = React.useMemo(() => { + if (player.selected === null || typeof player.selected.stream.url !== 'string') { + return null; + } + + const playlist = `#EXTM3U\n\n#EXTINF:0,${player.title}\n${player.selected.stream.url}`; + const base64File = `data:application/octet-stream;charset=utf-8;base64,${window.btoa(playlist)}`; + return { + name: `${player.title}.m3u`, + file: base64File + }; + }, [player]); + return [player, playlist, updateLibraryItemState, pushToLibrary]; }; module.exports = usePlayer; From 89832951ec6e2df38ddced1eb71cab9a7ed7b47b Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 12 Jul 2021 19:48:47 +0200 Subject: [PATCH 2/6] refactor(Player): move playlist to Player.js, fix less --- src/routes/Player/Player.js | 14 +++++++++++++- src/routes/Player/styles.less | 3 ++- src/routes/Player/usePlayer.js | 14 +------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index d8c91af99..d96048ed5 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -22,7 +22,7 @@ const Player = ({ urlParams, queryParams }) => { const forceTranscoding = React.useMemo(() => { return queryParams.has('forceTranscoding'); }, [queryParams]); - const [player, playlist, updateLibraryItemState, pushToLibrary] = usePlayer(urlParams); + const [player, updateLibraryItemState, pushToLibrary] = usePlayer(urlParams); const [settings, updateSettings] = useSettings(); const streamingServer = useStreamingServer(); const routeFocused = useRouteFocused(); @@ -64,6 +64,18 @@ const Player = ({ urlParams, queryParams }) => { videoRef.current.dispatch(args); } }, []); + const playlist = React.useMemo(() => { + if (player.selected === null || typeof player.selected.stream.url !== 'string') { + return null; + } + + const m3u = `#EXTM3U\n\n#EXTINF:0,${encodeURIComponent(player.title)}\n${encodeURI(player.selected.stream.url)}`; + const base64File = `data:application/octet-stream;charset=utf-8;base64,${window.btoa(m3u)}`; + return { + name: `${player.title}.m3u`, + file: base64File + }; + }, [player]); const onImplementationChanged = React.useCallback((manifest) => { manifest.props.forEach((propName) => { dispatch({ type: 'observeProp', propName }); diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index a77874539..07ba94378 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -43,7 +43,6 @@ html:not(.active-slider-within) { flex-direction: column; align-items: center; justify-content: center; - gap: 1.5rem; background-color: @color-background-dark5; .error-label { @@ -56,8 +55,10 @@ html:not(.active-slider-within) { } .error-details { + display: flex; gap: 0.8rem; font-size: 1.5rem; + margin-top: 1.5rem; color: @color-surface-light5-90; .error-details-button { diff --git a/src/routes/Player/usePlayer.js b/src/routes/Player/usePlayer.js index 3db53fd1b..54b6ded23 100644 --- a/src/routes/Player/usePlayer.js +++ b/src/routes/Player/usePlayer.js @@ -110,19 +110,7 @@ const usePlayer = (urlParams) => { }, 'player'); }, []); const player = useModelState({ model: 'player', action, init, map }); - const playlist = React.useMemo(() => { - if (player.selected === null || typeof player.selected.stream.url !== 'string') { - return null; - } - - const playlist = `#EXTM3U\n\n#EXTINF:0,${player.title}\n${player.selected.stream.url}`; - const base64File = `data:application/octet-stream;charset=utf-8;base64,${window.btoa(playlist)}`; - return { - name: `${player.title}.m3u`, - file: base64File - }; - }, [player]); - return [player, playlist, updateLibraryItemState, pushToLibrary]; + return [player, updateLibraryItemState, pushToLibrary]; }; module.exports = usePlayer; From 3ce8a57bc3e90224ee711bad012ec2474d90cf85 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 15 Jul 2021 10:46:50 +0200 Subject: [PATCH 3/6] refactor(Player): fix markup hierarchy, remove gap and declare flex props in style --- src/routes/Player/Player.js | 37 +++++++++++++++++++---------------- src/routes/Player/styles.less | 6 ++---- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index d96048ed5..10e896ce9 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -428,29 +428,32 @@ const Player = ({ urlParams, queryParams }) => { videoState.buffering ? : - error !== null ? -
-
{error.message}
- { - playlist ? -
- -
- : - null - } -
- : - null + null }
+ { + error !== null ? +
+
{error.message}
+ { + playlist ? +
+ +
+ : + null + } +
+ : + null + } { subtitlesMenuOpen || infoMenuOpen ?
diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index 07ba94378..6ada11277 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -38,7 +38,6 @@ html:not(.active-slider-within) { bottom: 0; &.error-layer { - z-index: 1; display: flex; flex-direction: column; align-items: center; @@ -55,8 +54,7 @@ html:not(.active-slider-within) { } .error-details { - display: flex; - gap: 0.8rem; + flex: 0 1 auto; font-size: 1.5rem; margin-top: 1.5rem; color: @color-surface-light5-90; @@ -66,7 +64,6 @@ html:not(.active-slider-within) { display: flex; flex-direction: row; align-items: center; - gap: 1rem; height: 3.5rem; padding: 0.5rem 1rem; font-weight: 500; @@ -80,6 +77,7 @@ html:not(.active-slider-within) { .icon { width: 1.5rem; height: 1.5rem; + margin-right: 1rem; fill: @color-surface-light5-90; } } From 25322171716b522ce5a75c506732bcb7d4237b0a Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 16 Jul 2021 03:02:38 +0200 Subject: [PATCH 4/6] refactor(Player): revert z-index changes --- src/routes/Player/styles.less | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index 6ada11277..45889141b 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -36,6 +36,7 @@ html:not(.active-slider-within) { left: 0; right: 0; bottom: 0; + z-index: 0; &.error-layer { display: flex; @@ -85,7 +86,6 @@ html:not(.active-slider-within) { } &.nav-bar-layer { - z-index: 2; bottom: initial; background: transparent; overflow: visible; @@ -116,7 +116,6 @@ html:not(.active-slider-within) { } &.control-bar-layer { - z-index: 2; top: initial; overflow: visible; @@ -132,7 +131,6 @@ html:not(.active-slider-within) { } &.menu-layer { - z-index: 2; top: initial; left: initial; right: 2rem; From 335fc5ccca73948b7c61cb12655aef9bc2a1dd60 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 16 Jul 2021 11:38:19 +0200 Subject: [PATCH 5/6] style(Player): fix flex, add missing class --- src/routes/Player/styles.less | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index 45889141b..9be841e46 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -46,7 +46,7 @@ html:not(.active-slider-within) { background-color: @color-background-dark5; .error-label { - flex: 0 1 auto; + flex: none; padding: 0 8rem; max-height: 4.8em; font-size: 2rem; @@ -55,32 +55,40 @@ html:not(.active-slider-within) { } .error-details { - flex: 0 1 auto; + display: flex; + flex: none; font-size: 1.5rem; margin-top: 1.5rem; color: @color-surface-light5-90; .error-details-button { - flex: none; display: flex; + flex: none; flex-direction: row; align-items: center; height: 3.5rem; padding: 0.5rem 1rem; font-weight: 500; - color: @color-surface-light5-90; - background-color: @color-surface-light5-20; + background-color: @color-accent3; &:hover, &:focus { - background-color: @color-accent3; + background-color: @color-accent3-light1; } .icon { + flex: none; width: 1.5rem; height: 1.5rem; margin-right: 1rem; fill: @color-surface-light5-90; } + + .label { + flex: auto; + max-height: 2.4em; + font-size: 1.1rem; + color: @color-surface-light5-90; + } } } } From e190f43ef171efb6164dd9841d2d1a94e32e1343 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 16 Jul 2021 20:03:28 +0200 Subject: [PATCH 6/6] style(Player): fix flex --- src/routes/Player/styles.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/Player/styles.less b/src/routes/Player/styles.less index 9be841e46..10c1921c5 100644 --- a/src/routes/Player/styles.less +++ b/src/routes/Player/styles.less @@ -46,7 +46,7 @@ html:not(.active-slider-within) { background-color: @color-background-dark5; .error-label { - flex: none; + flex: auto; padding: 0 8rem; max-height: 4.8em; font-size: 2rem; @@ -56,7 +56,7 @@ html:not(.active-slider-within) { .error-details { display: flex; - flex: none; + flex: auto; font-size: 1.5rem; margin-top: 1.5rem; color: @color-surface-light5-90;