sample InfoMenu component added

This commit is contained in:
nklhrstv 2020-03-31 12:13:58 +03:00
parent 11ebfae747
commit 5c89856765
8 changed files with 66 additions and 37 deletions

View file

@ -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;

View file

@ -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;

View file

@ -0,0 +1,3 @@
const InfoMenuButton = require('./InfoMenuButton');
module.exports = InfoMenuButton;

View file

@ -1,3 +0,0 @@
const MetaPreviewButton = require('./MetaPreviewButton');
module.exports = MetaPreviewButton;

View 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;

View file

@ -0,0 +1,3 @@
const InfoMenu = require('./InfoMenu');
module.exports = InfoMenu;

View file

@ -0,0 +1,3 @@
.info-menu-container {
}

View file

@ -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>
); );
}; };