diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js
index 1b00b5903..7d11ba108 100644
--- a/src/routes/Player/ControlBar/ControlBar.js
+++ b/src/routes/Player/ControlBar/ControlBar.js
@@ -3,33 +3,68 @@ const PropTypes = require('prop-types');
const classnames = require('classnames');
const Icon = require('stremio-icons/dom');
const { Button } = require('stremio/common');
-const InfoMenuButton = require('./InfoMenuButton');
-const MuteButton = require('./MuteButton');
-const PlayPauseButton = require('./PlayPauseButton');
const SeekBar = require('./SeekBar');
-const SubtitlesButton = require('./SubtitlesButton');
const VolumeSlider = require('./VolumeSlider');
const styles = require('./styles');
const ControlBar = ({
className,
- infoAvailable,
paused,
time,
duration,
volume,
muted,
subtitlesTracks,
+ metaItem,
+ stream,
onPlayRequested,
onPauseRequested,
onMuteRequested,
onUnmuteRequested,
onVolumeChangeRequested,
onSeekRequested,
- onToggleSubtitlesPicker,
+ onToggleSubtitlesMenu,
onToggleInfoMenu,
...props
}) => {
+ const onSubtitlesButtonMouseDown = React.useCallback((event) => {
+ event.nativeEvent.subtitlesMenuClosePrevented = true;
+ }, []);
+ const onInfoButtonMouseDown = React.useCallback((event) => {
+ event.nativeEvent.infoMenuClosePrevented = true;
+ }, []);
+ const onPlayPauseButtonClick = React.useCallback(() => {
+ if (paused) {
+ if (typeof onPlayRequested === 'function') {
+ onPlayRequested();
+ }
+ } else {
+ if (typeof onPauseRequested === 'function') {
+ onPauseRequested();
+ }
+ }
+ }, [paused, onPlayRequested, onPauseRequested]);
+ const onMuteButtonClick = React.useCallback(() => {
+ if (muted) {
+ if (typeof onUnmuteRequested === 'function') {
+ onUnmuteRequested();
+ }
+ } else {
+ if (typeof onMuteRequested === 'function') {
+ onMuteRequested();
+ }
+ }
+ }, [muted, onMuteRequested, onUnmuteRequested]);
+ const onSubtitlesButtonClick = React.useCallback(() => {
+ if (typeof onToggleSubtitlesMenu === 'function') {
+ onToggleSubtitlesMenu();
+ }
+ }, [onToggleSubtitlesMenu]);
+ const onInfoButtonClick = React.useCallback(() => {
+ if (typeof onToggleInfoMenu === 'function') {
+ onToggleInfoMenu();
+ }
+ }, [onToggleInfoMenu]);
return (
-
-
+
+
-
-
@@ -83,21 +117,22 @@ const ControlBar = ({
ControlBar.propTypes = {
className: PropTypes.string,
- infoAvailable: PropTypes.bool,
- paused: PropTypes.any,
- time: PropTypes.any,
- duration: PropTypes.any,
- volume: PropTypes.any,
- muted: PropTypes.any,
- subtitlesTracks: PropTypes.any,
- onPlayRequested: PropTypes.any,
- onPauseRequested: PropTypes.any,
- onMuteRequested: PropTypes.any,
- onUnmuteRequested: PropTypes.any,
- onVolumeChangeRequested: PropTypes.any,
- onSeekRequested: PropTypes.any,
- onToggleSubtitlesPicker: PropTypes.any,
- onToggleInfoMenu: PropTypes.any
+ paused: PropTypes.bool,
+ time: PropTypes.number,
+ duration: PropTypes.number,
+ volume: PropTypes.number,
+ muted: PropTypes.bool,
+ subtitlesTracks: PropTypes.array,
+ metaItem: PropTypes.object,
+ stream: PropTypes.object,
+ onPlayRequested: PropTypes.func,
+ onPauseRequested: PropTypes.func,
+ onMuteRequested: PropTypes.func,
+ onUnmuteRequested: PropTypes.func,
+ onVolumeChangeRequested: PropTypes.func,
+ onSeekRequested: PropTypes.func,
+ onToggleSubtitlesMenu: PropTypes.func,
+ onToggleInfoMenu: PropTypes.func
};
module.exports = ControlBar;
diff --git a/src/routes/Player/ControlBar/InfoMenuButton/InfoMenuButton.js b/src/routes/Player/ControlBar/InfoMenuButton/InfoMenuButton.js
deleted file mode 100644
index 2062a2bdd..000000000
--- a/src/routes/Player/ControlBar/InfoMenuButton/InfoMenuButton.js
+++ /dev/null
@@ -1,27 +0,0 @@
-const React = require('react');
-const PropTypes = require('prop-types');
-const Icon = require('stremio-icons/dom');
-const { Button } = require('stremio/common');
-
-const InfoMenuButton = ({ className, onToggleInfoMenu }) => {
- const onMouseDown = React.useCallback((event) => {
- event.nativeEvent.infoMenuClosePrevented = true;
- }, []);
- const onClick = React.useCallback(() => {
- if (typeof onToggleInfoMenu === 'function') {
- onToggleInfoMenu();
- }
- }, [onToggleInfoMenu]);
- return (
-
-
-
- );
-};
-
-InfoMenuButton.propTypes = {
- className: PropTypes.string,
- onToggleInfoMenu: PropTypes.func
-};
-
-module.exports = InfoMenuButton;
diff --git a/src/routes/Player/ControlBar/InfoMenuButton/index.js b/src/routes/Player/ControlBar/InfoMenuButton/index.js
deleted file mode 100644
index 6dfeff76d..000000000
--- a/src/routes/Player/ControlBar/InfoMenuButton/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const InfoMenuButton = require('./InfoMenuButton');
-
-module.exports = InfoMenuButton;
diff --git a/src/routes/Player/ControlBar/MuteButton/MuteButton.js b/src/routes/Player/ControlBar/MuteButton/MuteButton.js
deleted file mode 100644
index 7e3c2b0b5..000000000
--- a/src/routes/Player/ControlBar/MuteButton/MuteButton.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const React = require('react');
-const PropTypes = require('prop-types');
-const classnames = require('classnames');
-const Icon = require('stremio-icons/dom');
-const { Button } = require('stremio/common');
-
-const MuteButton = ({ className, muted, volume, onMuteRequested, onUnmuteRequested }) => {
- const toggleMuted = React.useCallback(() => {
- if (muted) {
- if (typeof onUnmuteRequested === 'function') {
- onUnmuteRequested();
- }
- } else {
- if (typeof onMuteRequested === 'function') {
- onMuteRequested();
- }
- }
- }, [muted, onMuteRequested, onUnmuteRequested]);
- const icon = (typeof muted === 'boolean' && muted) ? 'ic_volume0' :
- (volume === null || isNaN(volume)) ? 'ic_volume3' :
- volume < 30 ? 'ic_volume1' :
- volume < 70 ? 'ic_volume2' :
- 'ic_volume3';
- return (
-
-
-
- );
-};
-
-MuteButton.propTypes = {
- className: PropTypes.string,
- muted: PropTypes.bool,
- volume: PropTypes.number,
- onMuteRequested: PropTypes.func,
- onUnmuteRequested: PropTypes.func
-};
-
-module.exports = MuteButton;
diff --git a/src/routes/Player/ControlBar/MuteButton/index.js b/src/routes/Player/ControlBar/MuteButton/index.js
deleted file mode 100644
index 3bc5c743b..000000000
--- a/src/routes/Player/ControlBar/MuteButton/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const MuteButton = require('./MuteButton');
-
-module.exports = MuteButton;
diff --git a/src/routes/Player/ControlBar/PlayPauseButton/PlayPauseButton.js b/src/routes/Player/ControlBar/PlayPauseButton/PlayPauseButton.js
deleted file mode 100644
index 34d9bbd7f..000000000
--- a/src/routes/Player/ControlBar/PlayPauseButton/PlayPauseButton.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const React = require('react');
-const PropTypes = require('prop-types');
-const classnames = require('classnames');
-const Icon = require('stremio-icons/dom');
-const { Button } = require('stremio/common');
-
-const PlayPauseButton = ({ className, paused, onPlayRequested, onPauseRequested }) => {
- const togglePaused = React.useCallback(() => {
- if (paused) {
- if (typeof onPlayRequested === 'function') {
- onPlayRequested();
- }
- } else {
- if (typeof onPauseRequested === 'function') {
- onPauseRequested();
- }
- }
- }, [paused, onPlayRequested, onPauseRequested]);
- return (
-
-
-
- );
-};
-
-PlayPauseButton.propTypes = {
- className: PropTypes.string,
- paused: PropTypes.bool,
- onPlayRequested: PropTypes.func,
- onPauseRequested: PropTypes.func
-};
-
-module.exports = PlayPauseButton;
diff --git a/src/routes/Player/ControlBar/PlayPauseButton/index.js b/src/routes/Player/ControlBar/PlayPauseButton/index.js
deleted file mode 100644
index cdaf43c88..000000000
--- a/src/routes/Player/ControlBar/PlayPauseButton/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const PlayPauseButton = require('./PlayPauseButton');
-
-module.exports = PlayPauseButton;
diff --git a/src/routes/Player/ControlBar/SubtitlesButton/SubtitlesButton.js b/src/routes/Player/ControlBar/SubtitlesButton/SubtitlesButton.js
deleted file mode 100644
index 891247025..000000000
--- a/src/routes/Player/ControlBar/SubtitlesButton/SubtitlesButton.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const React = require('react');
-const PropTypes = require('prop-types');
-const classnames = require('classnames');
-const Icon = require('stremio-icons/dom');
-const { Button } = require('stremio/common');
-
-const SubtitlesButton = ({ className, subtitlesTracks, onToggleSubtitlesPicker }) => {
- const onMouseDown = React.useCallback((event) => {
- event.nativeEvent.subtitlesPickerClosePrevented = true;
- }, []);
- const onClick = React.useCallback(() => {
- if (typeof onToggleSubtitlesPicker === 'function') {
- onToggleSubtitlesPicker();
- }
- }, [onToggleSubtitlesPicker]);
- return (
-
-
-
- );
-};
-
-SubtitlesButton.propTypes = {
- className: PropTypes.string,
- subtitlesTracks: PropTypes.array,
- onToggleSubtitlesPicker: PropTypes.func
-};
-
-module.exports = SubtitlesButton;
diff --git a/src/routes/Player/ControlBar/SubtitlesButton/index.js b/src/routes/Player/ControlBar/SubtitlesButton/index.js
deleted file mode 100644
index 53fd48771..000000000
--- a/src/routes/Player/ControlBar/SubtitlesButton/index.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const SubtitlesButton = require('./SubtitlesButton');
-
-module.exports = SubtitlesButton;
diff --git a/src/routes/Player/ControlBar/styles.less b/src/routes/Player/ControlBar/styles.less
index 5fa5ae688..8dd80785f 100644
--- a/src/routes/Player/ControlBar/styles.less
+++ b/src/routes/Player/ControlBar/styles.less
@@ -21,12 +21,12 @@
align-items: center;
&:global(.disabled) {
- :global(.icon) {
+ .icon {
fill: @color-surface;
}
}
- :global(.icon) {
+ .icon {
flex: none;
width: 3rem;
height: 2rem;
diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js
index fcc1d0f73..4bd2f9390 100644
--- a/src/routes/Player/Player.js
+++ b/src/routes/Player/Player.js
@@ -18,17 +18,26 @@ const Player = ({ urlParams }) => {
const { core } = useServices();
const [player, updateLibraryItemState, pushToLibrary] = usePlayer(urlParams);
const [settings, updateSettings] = useSettings();
+ const stream = React.useMemo(() => {
+ return player.selected !== null ?
+ player.selected.stream
+ :
+ null;
+ }, [player]);
+ const metaItem = React.useMemo(() => {
+ return player.meta_resource !== null && player.meta_resource.content.type === 'Ready' ?
+ player.meta_resource.content.content
+ :
+ null;
+ }, [player]);
const routeFocused = useRouteFocused();
const toast = useToast();
const [, , , toggleFullscreen] = useFullscreen();
const [immersed, setImmersed] = React.useState(true);
const setImmersedDebounced = React.useCallback(debounce(setImmersed, 3000), []);
- const [subtitlesPickerOpen, , closeSubtitlesPicker, toggleSubtitlesPicker] = useBinaryState(false);
+ const [subtitlesMenuOpen, , closeSubtitlesMenu, toggleSubtitlesMenu] = useBinaryState(false);
const [infoMenuOpen, , closeInfoMenu, toggleInfoMenu] = useBinaryState(false);
const [error, setError] = React.useState(null);
- const infoAvailable = React.useMemo(() => {
- return player.meta_resource !== null && player.meta_resource.content.type === 'Ready';
- }, [player]);
const [videoState, setVideoState] = React.useReducer(
(videoState, nextVideoState) => ({ ...videoState, ...nextVideoState }),
{
@@ -150,8 +159,8 @@ const Player = ({ urlParams }) => {
toggleFullscreen();
}, [toggleFullscreen]);
const onContainerMouseDown = React.useCallback((event) => {
- if (!event.nativeEvent.subtitlesPickerClosePrevented) {
- closeSubtitlesPicker();
+ if (!event.nativeEvent.subtitlesMenuClosePrevented) {
+ closeSubtitlesMenu();
}
if (!event.nativeEvent.infoMenuClosePrevented) {
closeInfoMenu();
@@ -239,7 +248,7 @@ const Player = ({ urlParams }) => {
const onKeyDown = (event) => {
switch (event.code) {
case 'Space': {
- if (!subtitlesPickerOpen && !infoMenuOpen && videoState.paused !== null) {
+ if (!subtitlesMenuOpen && !infoMenuOpen && videoState.paused !== null) {
if (videoState.paused) {
onPlayRequested();
} else {
@@ -250,28 +259,28 @@ const Player = ({ urlParams }) => {
break;
}
case 'ArrowRight': {
- if (!subtitlesPickerOpen && !infoMenuOpen && videoState.time !== null) {
+ if (!subtitlesMenuOpen && !infoMenuOpen && videoState.time !== null) {
onSeekRequested(videoState.time + 15000);
}
break;
}
case 'ArrowLeft': {
- if (!subtitlesPickerOpen && !infoMenuOpen && videoState.time !== null) {
+ if (!subtitlesMenuOpen && !infoMenuOpen && videoState.time !== null) {
onSeekRequested(videoState.time - 15000);
}
break;
}
case 'ArrowUp': {
- if (!subtitlesPickerOpen && !infoMenuOpen && videoState.volume !== null) {
+ if (!subtitlesMenuOpen && !infoMenuOpen && videoState.volume !== null) {
onVolumeChangeRequested(videoState.volume + 5);
}
break;
}
case 'ArrowDown': {
- if (!subtitlesPickerOpen && !infoMenuOpen && videoState.volume !== null) {
+ if (!subtitlesMenuOpen && !infoMenuOpen && videoState.volume !== null) {
onVolumeChangeRequested(videoState.volume - 5);
}
@@ -279,18 +288,22 @@ const Player = ({ urlParams }) => {
}
case 'KeyS': {
closeInfoMenu();
- toggleSubtitlesPicker();
+ if (Array.isArray(videoState.subtitlesTracks) && videoState.subtitlesTracks.length > 0) {
+ toggleSubtitlesMenu();
+ }
+
break;
}
case 'KeyM': {
- closeSubtitlesPicker();
- if (infoAvailable) {
+ closeSubtitlesMenu();
+ if (typeof metaItem === 'object' && metaItem !== null && typeof stream === 'object' && stream !== null) {
toggleInfoMenu();
}
+
break;
}
case 'Escape': {
- closeSubtitlesPicker();
+ closeSubtitlesMenu();
closeInfoMenu();
break;
}
@@ -302,7 +315,7 @@ const Player = ({ urlParams }) => {
return () => {
window.removeEventListener('keydown', onKeyDown);
};
- }, [routeFocused, subtitlesPickerOpen, infoAvailable, infoMenuOpen, videoState.paused, videoState.time, videoState.volume, toggleSubtitlesPicker, toggleInfoMenu]);
+ }, [routeFocused, subtitlesMenuOpen, infoMenuOpen, stream, metaItem, videoState.paused, videoState.time, videoState.volume, videoState.subtitlesTracks, toggleSubtitlesMenu, toggleInfoMenu]);
React.useLayoutEffect(() => {
return () => {
setImmersedDebounced.cancel();
@@ -311,7 +324,7 @@ const Player = ({ urlParams }) => {
};
}, []);
return (
- {
onDoubleClick={onVideoDoubleClick}
/>
{
- subtitlesPickerOpen || infoMenuOpen ?
+ subtitlesMenuOpen || infoMenuOpen ?
:
null
@@ -370,20 +383,21 @@ const Player = ({ urlParams }) => {
volume={videoState.volume}
muted={videoState.muted}
subtitlesTracks={videoState.subtitlesTracks}
- infoAvailable={infoAvailable}
+ stream={stream}
+ metaItem={metaItem}
onPlayRequested={onPlayRequested}
onPauseRequested={onPauseRequested}
onMuteRequested={onMuteRequested}
onUnmuteRequested={onUnmuteRequested}
onVolumeChangeRequested={onVolumeChangeRequested}
onSeekRequested={onSeekRequested}
- onToggleSubtitlesPicker={toggleSubtitlesPicker}
+ onToggleSubtitlesMenu={toggleSubtitlesMenu}
onToggleInfoMenu={toggleInfoMenu}
onMouseMove={onBarMouseMove}
onMouseOver={onBarMouseMove}
/>
{
- subtitlesPickerOpen ?
+ subtitlesMenuOpen ?
{
[];
}, [props.tracks, selectedLanguage]);
const onMouseDown = React.useCallback((event) => {
- event.nativeEvent.subtitlesPickerClosePrevented = true;
+ event.nativeEvent.subtitlesMenuClosePrevented = true;
}, []);
const languageOnClick = React.useCallback((event) => {
const trackId = Array.isArray(props.tracks) ?