mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-21 03:22:11 +00:00
sample InfoMenu component added
This commit is contained in:
parent
11ebfae747
commit
5c89856765
8 changed files with 66 additions and 37 deletions
|
|
@ -3,7 +3,7 @@ const PropTypes = require('prop-types');
|
||||||
const classnames = require('classnames');
|
const classnames = require('classnames');
|
||||||
const Icon = require('stremio-icons/dom');
|
const Icon = require('stremio-icons/dom');
|
||||||
const { Button } = require('stremio/common');
|
const { Button } = require('stremio/common');
|
||||||
const MetaPreviewButton = require('./MetaPreviewButton');
|
const InfoMenuButton = require('./InfoMenuButton');
|
||||||
const MuteButton = require('./MuteButton');
|
const MuteButton = require('./MuteButton');
|
||||||
const PlayPauseButton = require('./PlayPauseButton');
|
const PlayPauseButton = require('./PlayPauseButton');
|
||||||
const SeekBar = require('./SeekBar');
|
const SeekBar = require('./SeekBar');
|
||||||
|
|
@ -27,7 +27,7 @@ const ControlBar = ({
|
||||||
onVolumeChangeRequested,
|
onVolumeChangeRequested,
|
||||||
onSeekRequested,
|
onSeekRequested,
|
||||||
onToggleSubtitlesPicker,
|
onToggleSubtitlesPicker,
|
||||||
onToggleMetaPreview,
|
onToggleInfoMenu,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -61,10 +61,10 @@ const ControlBar = ({
|
||||||
<Button className={classnames(styles['control-bar-button'], 'disabled')} tabIndex={-1}>
|
<Button className={classnames(styles['control-bar-button'], 'disabled')} tabIndex={-1}>
|
||||||
<Icon className={'icon'} icon={'ic_network'} />
|
<Icon className={'icon'} icon={'ic_network'} />
|
||||||
</Button>
|
</Button>
|
||||||
<MetaPreviewButton
|
<InfoMenuButton
|
||||||
className={styles['control-bar-button']}
|
className={styles['control-bar-button']}
|
||||||
metaResource={metaResource}
|
metaResource={metaResource}
|
||||||
onToggleMetaPreview={onToggleMetaPreview}
|
onToggleInfoMenu={onToggleInfoMenu}
|
||||||
/>
|
/>
|
||||||
<Button className={classnames(styles['control-bar-button'], 'disabled')} tabIndex={-1}>
|
<Button className={classnames(styles['control-bar-button'], 'disabled')} tabIndex={-1}>
|
||||||
<Icon className={'icon'} icon={'ic_cast'} />
|
<Icon className={'icon'} icon={'ic_cast'} />
|
||||||
|
|
@ -98,7 +98,7 @@ ControlBar.propTypes = {
|
||||||
onVolumeChangeRequested: PropTypes.any,
|
onVolumeChangeRequested: PropTypes.any,
|
||||||
onSeekRequested: PropTypes.any,
|
onSeekRequested: PropTypes.any,
|
||||||
onToggleSubtitlesPicker: PropTypes.any,
|
onToggleSubtitlesPicker: PropTypes.any,
|
||||||
onToggleMetaPreview: PropTypes.any
|
onToggleInfoMenu: PropTypes.any
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = ControlBar;
|
module.exports = ControlBar;
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,15 @@ const classnames = require('classnames');
|
||||||
const Icon = require('stremio-icons/dom');
|
const Icon = require('stremio-icons/dom');
|
||||||
const { Button } = require('stremio/common');
|
const { Button } = require('stremio/common');
|
||||||
|
|
||||||
const MetaPreviewButton = ({ className, metaResource, onToggleMetaPreview }) => {
|
const InfoMenuButton = ({ className, metaResource, onToggleInfoMenu }) => {
|
||||||
const onMouseDown = React.useCallback((event) => {
|
const onMouseDown = React.useCallback((event) => {
|
||||||
event.nativeEvent.metaPreviewClosePrevented = true;
|
event.nativeEvent.infoMenuClosePrevented = true;
|
||||||
}, []);
|
}, []);
|
||||||
const onClick = React.useCallback(() => {
|
const onClick = React.useCallback(() => {
|
||||||
if (typeof onToggleMetaPreview === 'function') {
|
if (typeof onToggleInfoMenu === 'function') {
|
||||||
onToggleMetaPreview();
|
onToggleInfoMenu();
|
||||||
}
|
}
|
||||||
}, [onToggleMetaPreview]);
|
}, [onToggleInfoMenu]);
|
||||||
return (
|
return (
|
||||||
<Button className={classnames(className, { 'disabled': metaResource === null || metaResource.content.type !== 'Ready' })} tabIndex={-1} onMouseDown={onMouseDown} onClick={onClick}>
|
<Button className={classnames(className, { 'disabled': metaResource === null || metaResource.content.type !== 'Ready' })} tabIndex={-1} onMouseDown={onMouseDown} onClick={onClick}>
|
||||||
<Icon className={'icon'} icon={'ic_info'} />
|
<Icon className={'icon'} icon={'ic_info'} />
|
||||||
|
|
@ -20,10 +20,10 @@ const MetaPreviewButton = ({ className, metaResource, onToggleMetaPreview }) =>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
MetaPreviewButton.propTypes = {
|
InfoMenuButton.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
metaResource: PropTypes.object,
|
metaResource: PropTypes.object,
|
||||||
onToggleMetaPreview: PropTypes.func
|
onToggleInfoMenu: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = MetaPreviewButton;
|
module.exports = InfoMenuButton;
|
||||||
3
src/routes/Player/ControlBar/InfoMenuButton/index.js
Normal file
3
src/routes/Player/ControlBar/InfoMenuButton/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
const InfoMenuButton = require('./InfoMenuButton');
|
||||||
|
|
||||||
|
module.exports = InfoMenuButton;
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
const MetaPreviewButton = require('./MetaPreviewButton');
|
|
||||||
|
|
||||||
module.exports = MetaPreviewButton;
|
|
||||||
22
src/routes/Player/InfoMenu/InfoMenu.js
Normal file
22
src/routes/Player/InfoMenu/InfoMenu.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
const React = require('react');
|
||||||
|
const PropTypes = require('prop-types');
|
||||||
|
const classnames = require('classnames');
|
||||||
|
const MetaPreview = require('stremio/common/MetaPreview');
|
||||||
|
const styles = require('./styles');
|
||||||
|
|
||||||
|
const InfoMenu = ({ className }) => {
|
||||||
|
const onMouseDown = React.useCallback((event) => {
|
||||||
|
event.nativeEvent.infoMenuClosePrevented = true;
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div className={classnames(className, styles['info-menu-container'])} onMouseDown={onMouseDown}>
|
||||||
|
<MetaPreview name={'Info menu name'} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
InfoMenu.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = InfoMenu;
|
||||||
3
src/routes/Player/InfoMenu/index.js
Normal file
3
src/routes/Player/InfoMenu/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
const InfoMenu = require('./InfoMenu');
|
||||||
|
|
||||||
|
module.exports = InfoMenu;
|
||||||
3
src/routes/Player/InfoMenu/styles.less
Normal file
3
src/routes/Player/InfoMenu/styles.less
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
.info-menu-container {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ const { useServices } = require('stremio/services');
|
||||||
const { HorizontalNavBar, useDeepEqualEffect, useDeepEqualMemo, useFullscreen, useBinaryState, useToast } = require('stremio/common');
|
const { HorizontalNavBar, useDeepEqualEffect, useDeepEqualMemo, useFullscreen, useBinaryState, useToast } = require('stremio/common');
|
||||||
const BufferingLoader = require('./BufferingLoader');
|
const BufferingLoader = require('./BufferingLoader');
|
||||||
const ControlBar = require('./ControlBar');
|
const ControlBar = require('./ControlBar');
|
||||||
|
const InfoMenu = require('./InfoMenu');
|
||||||
const SubtitlesPicker = require('./SubtitlesPicker');
|
const SubtitlesPicker = require('./SubtitlesPicker');
|
||||||
const Video = require('./Video');
|
const Video = require('./Video');
|
||||||
const usePlayer = require('./usePlayer');
|
const usePlayer = require('./usePlayer');
|
||||||
|
|
@ -23,7 +24,7 @@ const Player = ({ urlParams }) => {
|
||||||
const [immersed, setImmersed] = React.useState(true);
|
const [immersed, setImmersed] = React.useState(true);
|
||||||
const setImmersedDebounced = React.useCallback(debounce(setImmersed, 3000), []);
|
const setImmersedDebounced = React.useCallback(debounce(setImmersed, 3000), []);
|
||||||
const [subtitlesPickerOpen, , closeSubtitlesPicker, toggleSubtitlesPicker] = useBinaryState(false);
|
const [subtitlesPickerOpen, , closeSubtitlesPicker, toggleSubtitlesPicker] = useBinaryState(false);
|
||||||
const [metaPreviewOpen, , closeMetaPreview, toggleMetaPreview] = useBinaryState(false);
|
const [infoMenuOpen, , closeInfoMenu, toggleInfoMenu] = useBinaryState(false);
|
||||||
const [error, setError] = React.useState(null);
|
const [error, setError] = React.useState(null);
|
||||||
const [videoState, setVideoState] = React.useReducer(
|
const [videoState, setVideoState] = React.useReducer(
|
||||||
(videoState, nextVideoState) => ({ ...videoState, ...nextVideoState }),
|
(videoState, nextVideoState) => ({ ...videoState, ...nextVideoState }),
|
||||||
|
|
@ -142,8 +143,8 @@ const Player = ({ urlParams }) => {
|
||||||
if (!event.nativeEvent.subtitlesPickerClosePrevented) {
|
if (!event.nativeEvent.subtitlesPickerClosePrevented) {
|
||||||
closeSubtitlesPicker();
|
closeSubtitlesPicker();
|
||||||
}
|
}
|
||||||
if (!event.nativeEvent.metaPreviewClosePrevented) {
|
if (!event.nativeEvent.infoMenuClosePrevented) {
|
||||||
closeMetaPreview();
|
closeInfoMenu();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
const onContainerMouseMove = React.useCallback((event) => {
|
const onContainerMouseMove = React.useCallback((event) => {
|
||||||
|
|
@ -244,7 +245,7 @@ const Player = ({ urlParams }) => {
|
||||||
const onKeyDown = (event) => {
|
const onKeyDown = (event) => {
|
||||||
switch (event.code) {
|
switch (event.code) {
|
||||||
case 'Space': {
|
case 'Space': {
|
||||||
if (!subtitlesPickerOpen && !metaPreviewOpen && videoState.paused !== null) {
|
if (!subtitlesPickerOpen && !infoMenuOpen && videoState.paused !== null) {
|
||||||
if (videoState.paused) {
|
if (videoState.paused) {
|
||||||
onPlayRequested();
|
onPlayRequested();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -255,46 +256,46 @@ const Player = ({ urlParams }) => {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'ArrowRight': {
|
case 'ArrowRight': {
|
||||||
if (!subtitlesPickerOpen && !metaPreviewOpen && videoState.time !== null) {
|
if (!subtitlesPickerOpen && !infoMenuOpen && videoState.time !== null) {
|
||||||
onSeekRequested(videoState.time + 15000);
|
onSeekRequested(videoState.time + 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'ArrowLeft': {
|
case 'ArrowLeft': {
|
||||||
if (!subtitlesPickerOpen && !metaPreviewOpen && videoState.time !== null) {
|
if (!subtitlesPickerOpen && !infoMenuOpen && videoState.time !== null) {
|
||||||
onSeekRequested(videoState.time - 15000);
|
onSeekRequested(videoState.time - 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'ArrowUp': {
|
case 'ArrowUp': {
|
||||||
if (!subtitlesPickerOpen && !metaPreviewOpen && videoState.volume !== null) {
|
if (!subtitlesPickerOpen && !infoMenuOpen && videoState.volume !== null) {
|
||||||
onVolumeChangeRequested(videoState.volume + 5);
|
onVolumeChangeRequested(videoState.volume + 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'ArrowDown': {
|
case 'ArrowDown': {
|
||||||
if (!subtitlesPickerOpen && !metaPreviewOpen && videoState.volume !== null) {
|
if (!subtitlesPickerOpen && !infoMenuOpen && videoState.volume !== null) {
|
||||||
onVolumeChangeRequested(videoState.volume - 5);
|
onVolumeChangeRequested(videoState.volume - 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'KeyS': {
|
case 'KeyS': {
|
||||||
closeMetaPreview();
|
closeInfoMenu();
|
||||||
toggleSubtitlesPicker();
|
toggleSubtitlesPicker();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'KeyM': {
|
case 'KeyM': {
|
||||||
closeSubtitlesPicker();
|
closeSubtitlesPicker();
|
||||||
toggleMetaPreview();
|
toggleInfoMenu();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'Escape': {
|
case 'Escape': {
|
||||||
closeSubtitlesPicker();
|
closeSubtitlesPicker();
|
||||||
closeMetaPreview();
|
closeInfoMenu();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -305,14 +306,14 @@ const Player = ({ urlParams }) => {
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('keydown', onKeyDown);
|
window.removeEventListener('keydown', onKeyDown);
|
||||||
};
|
};
|
||||||
}, [routeFocused, subtitlesPickerOpen, metaPreviewOpen, videoState.paused, videoState.time, videoState.volume, toggleSubtitlesPicker, toggleMetaPreview]);
|
}, [routeFocused, subtitlesPickerOpen, infoMenuOpen, videoState.paused, videoState.time, videoState.volume, toggleSubtitlesPicker, toggleInfoMenu]);
|
||||||
React.useLayoutEffect(() => {
|
React.useLayoutEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
setImmersedDebounced.cancel();
|
setImmersedDebounced.cancel();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<div className={classnames(styles['player-container'], { [styles['immersed']]: immersed && videoState.paused !== null && !videoState.paused && !subtitlesPickerOpen && !metaPreviewOpen })}
|
<div className={classnames(styles['player-container'], { [styles['immersed']]: immersed && videoState.paused !== null && !videoState.paused && !subtitlesPickerOpen && !infoMenuOpen })}
|
||||||
onMouseDown={onContainerMouseDown}
|
onMouseDown={onContainerMouseDown}
|
||||||
onMouseMove={onContainerMouseMove}
|
onMouseMove={onContainerMouseMove}
|
||||||
onMouseOver={onContainerMouseMove}
|
onMouseOver={onContainerMouseMove}
|
||||||
|
|
@ -365,7 +366,7 @@ const Player = ({ urlParams }) => {
|
||||||
volume={videoState.volume}
|
volume={videoState.volume}
|
||||||
muted={videoState.muted}
|
muted={videoState.muted}
|
||||||
subtitlesTracks={videoState.subtitlesTracks}
|
subtitlesTracks={videoState.subtitlesTracks}
|
||||||
metaResource={null}
|
metaResource={player.meta_resource}
|
||||||
onPlayRequested={onPlayRequested}
|
onPlayRequested={onPlayRequested}
|
||||||
onPauseRequested={onPauseRequested}
|
onPauseRequested={onPauseRequested}
|
||||||
onMuteRequested={onMuteRequested}
|
onMuteRequested={onMuteRequested}
|
||||||
|
|
@ -373,7 +374,7 @@ const Player = ({ urlParams }) => {
|
||||||
onVolumeChangeRequested={onVolumeChangeRequested}
|
onVolumeChangeRequested={onVolumeChangeRequested}
|
||||||
onSeekRequested={onSeekRequested}
|
onSeekRequested={onSeekRequested}
|
||||||
onToggleSubtitlesPicker={toggleSubtitlesPicker}
|
onToggleSubtitlesPicker={toggleSubtitlesPicker}
|
||||||
onToggleMetaPreview={toggleMetaPreview}
|
onToggleInfoMenu={toggleInfoMenu}
|
||||||
onMouseMove={onBarMouseMove}
|
onMouseMove={onBarMouseMove}
|
||||||
onMouseOver={onBarMouseMove}
|
onMouseOver={onBarMouseMove}
|
||||||
/>
|
/>
|
||||||
|
|
@ -397,14 +398,14 @@ const Player = ({ urlParams }) => {
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
{/* {
|
{
|
||||||
metaPreviewOpen ?
|
infoMenuOpen ?
|
||||||
<div className={classnames(styles['layer'], styles['menu-layer'])} onMouseDown={(event) => event.nativeEvent.metaPreviewClosePrevented = true}>
|
<InfoMenu
|
||||||
<div style={{ width: 300, height: 800, background: 'red' }} />
|
className={classnames(styles['layer'], styles['menu-layer'])}
|
||||||
</div>
|
/>
|
||||||
:
|
:
|
||||||
null
|
null
|
||||||
} */}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue