diff --git a/src/renderer/component/overlay/index.js b/src/renderer/component/overlay/index.js new file mode 100644 index 000000000..4e1ed7e64 --- /dev/null +++ b/src/renderer/component/overlay/index.js @@ -0,0 +1,14 @@ +import { connect } from 'react-redux'; +import { selectShowOverlay } from 'redux/selectors/media'; +import { doHideOverlay } from 'redux/actions/media'; +import Overlay from './view'; + +const select = state => ({ + showOverlay: selectShowOverlay(state), +}); + +const perform = dispatch => ({ + doCloseOverlay: dispatch(doHideOverlay()), +}); + +export default connect(select, perform)(Overlay); diff --git a/src/renderer/component/overlay/view.jsx b/src/renderer/component/overlay/view.jsx new file mode 100644 index 000000000..30e4c3f2d --- /dev/null +++ b/src/renderer/component/overlay/view.jsx @@ -0,0 +1,16 @@ +// @flow +import React from 'react'; + +type Props = { + showOverlay: ?boolean, + children: ?React.node, +}; + +class Overlay extends React.PureComponent { + render() { + const { showOverlay, children } = this.props; + return
{showOverlay ? children : ''}
; + } +} + +export default Overlay; diff --git a/src/renderer/component/video/index.js b/src/renderer/component/video/index.js index 9ce5f62e0..608333a98 100644 --- a/src/renderer/component/video/index.js +++ b/src/renderer/component/video/index.js @@ -3,7 +3,7 @@ import * as settings from 'constants/settings'; import { doChangeVolume } from 'redux/actions/app'; import { selectVolume } from 'redux/selectors/app'; import { doPlayUri, doSetPlayingUri, doLoadVideo } from 'redux/actions/content'; -import { doPlay, doPause, savePosition } from 'redux/actions/media'; +import { doPlay, doPause, savePosition, doHideOverlay, doShowOverlay } from 'redux/actions/media'; import { makeSelectMetadataForUri, makeSelectContentTypeForUri, @@ -15,7 +15,11 @@ import { selectSearchBarFocused, } from 'lbry-redux'; import { makeSelectClientSetting, selectShowNsfw } from 'redux/selectors/settings'; -import { selectMediaPaused, makeSelectMediaPositionForUri } from 'redux/selectors/media'; +import { + selectMediaPaused, + makeSelectMediaPositionForUri, + selectShowOverlay, +} from 'redux/selectors/media'; import { selectPlayingUri } from 'redux/selectors/content'; import Video from './view'; @@ -34,15 +38,18 @@ const select = (state, props) => ({ mediaPosition: makeSelectMediaPositionForUri(props.uri)(state), autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), searchBarFocused: selectSearchBarFocused(state), + showOverlay: selectShowOverlay(state), + overlayed: props.overlayed, }); const perform = dispatch => ({ play: uri => dispatch(doPlayUri(uri)), load: uri => dispatch(doLoadVideo(uri)), - cancelPlay: () => dispatch(doSetPlayingUri(null)), changeVolume: volume => dispatch(doChangeVolume(volume)), doPlay: () => dispatch(doPlay()), doPause: () => dispatch(doPause()), + doShowOverlay: () => dispatch(doShowOverlay()), + doHideOverlay: () => dispatch(doHideOverlay()), savePosition: (claimId, position) => dispatch(savePosition(claimId, position)), }); diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index 064f2105a..fad4afb40 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -10,7 +10,6 @@ import LoadingScreen from './internal/loading-screen'; const SPACE_BAR_KEYCODE = 32; type Props = { - cancelPlay: () => void, fileInfo: { outpoint: string, file_name: string, @@ -34,12 +33,16 @@ type Props = { doPlay: () => void, doPause: () => void, savePosition: (string, number) => void, + doShowOverlay: () => void, + doHideOverlay: () => void, mediaPaused: boolean, mediaPosition: ?number, className: ?string, obscureNsfw: boolean, play: string => void, searchBarFocused: boolean, + showOverlay: boolean, + overlayed: boolean, }; class Video extends React.PureComponent { @@ -53,6 +56,11 @@ class Video extends React.PureComponent { componentDidMount() { this.handleAutoplay(this.props); window.addEventListener('keydown', this.handleKeyDown); + + const { showOverlay, doHideOverlay, uri, playingUri, overlayed } = this.props; + if (showOverlay && uri === playingUri && !overlayed) { + doHideOverlay(); + } } componentWillReceiveProps(nextProps: Props) { @@ -67,7 +75,10 @@ class Video extends React.PureComponent { } componentWillUnmount() { - this.props.cancelPlay(); + const { overlayed, doShowOverlay } = this.props; + if (!overlayed) { + doShowOverlay(); + } window.removeEventListener('keydown', this.handleKeyDown); } @@ -111,7 +122,10 @@ class Video extends React.PureComponent { } playContent() { - const { play, uri } = this.props; + const { play, uri, showOverlay, playingUri, doHideOverlay } = this.props; + if (playingUri && showOverlay) { + doHideOverlay(); + } play(uri); } diff --git a/src/renderer/component/videoOverlay/index.js b/src/renderer/component/videoOverlay/index.js new file mode 100644 index 000000000..75a249ad7 --- /dev/null +++ b/src/renderer/component/videoOverlay/index.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; +import { selectPlayingUri } from 'redux/selectors/content'; +import VideoOverlay from './view'; + +const select = state => ({ + playingUri: selectPlayingUri(state), +}); + +export default connect(select, null)(VideoOverlay); diff --git a/src/renderer/component/videoOverlay/view.jsx b/src/renderer/component/videoOverlay/view.jsx new file mode 100644 index 000000000..13119e9f2 --- /dev/null +++ b/src/renderer/component/videoOverlay/view.jsx @@ -0,0 +1,25 @@ +// @flow +import React from 'react'; +import Video from 'component/video'; +import FileActions from 'component/fileActions'; +import Overlay from 'component/overlay'; + +type Props = { + playingUri: ?string, +}; + +class VideoOverlay extends React.Component { + render() { + const { playingUri } = this.props; + return ( + +
+ +
+ {playingUri ?
+ ); + } +} + +export default VideoOverlay; diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index 3ffe23e6e..9105af981 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -187,6 +187,9 @@ export const SET_VIDEO_PAUSE = 'SET_VIDEO_PAUSE'; export const MEDIA_PLAY = 'MEDIA_PLAY'; export const MEDIA_PAUSE = 'MEDIA_PAUSE'; export const MEDIA_POSITION = 'MEDIA_POSITION'; +// Overlay Media +export const SHOW_OVERLAY_MEDIA = 'SHOW_OVERLAY_MEDIA'; +export const HIDE_OVERLAY_MEDIA = 'HIDE_OVERLAY_MEDIA'; // Publishing export const CLEAR_PUBLISH = 'CLEAR_PUBLISH'; diff --git a/src/renderer/index.js b/src/renderer/index.js index c82db3287..5e777d41e 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -16,6 +16,7 @@ import 'scss/all.scss'; import store from 'store'; import app from './app'; import analytics from './analytics'; +import VideoOverlay from './component/videoOverlay/'; const { autoUpdater } = remote.require('electron-updater'); @@ -131,6 +132,7 @@ const init = () => {
+
, document.getElementById('app') diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js index 1b7d0b85f..fca62b7ad 100644 --- a/src/renderer/redux/actions/media.js +++ b/src/renderer/redux/actions/media.js @@ -26,3 +26,13 @@ export function savePosition(claimId: String, position: Number) { }); }; } + +export const doShowOverlay = () => (dispatch: Dispatch) => + dispatch({ + type: actions.SHOW_OVERLAY_MEDIA, + }); + +export const doHideOverlay = () => (dispatch: Dispatch) => + dispatch({ + type: actions.HIDE_OVERLAY_MEDIA, + }); diff --git a/src/renderer/redux/reducers/content.js b/src/renderer/redux/reducers/content.js index e9cbdff99..9b84e85dd 100644 --- a/src/renderer/redux/reducers/content.js +++ b/src/renderer/redux/reducers/content.js @@ -2,6 +2,7 @@ import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = { + showOverlay: false, playingUri: null, currentlyIsPlaying: false, rewardedContentClaimIds: [], diff --git a/src/renderer/redux/reducers/media.js b/src/renderer/redux/reducers/media.js index 44447fe4f..cb762ac28 100644 --- a/src/renderer/redux/reducers/media.js +++ b/src/renderer/redux/reducers/media.js @@ -3,6 +3,7 @@ import * as actions from 'constants/action_types'; import { handleActions } from 'util/redux-utils'; export type MediaState = { + showOverlay: Boolean, paused: Boolean, positions: { [string]: number, @@ -12,21 +13,22 @@ export type MediaState = { export type Action = any; export type Dispatch = (action: Action) => any; -const defaultState = { paused: true, positions: {} }; +const defaultState = { paused: true, positions: {}, showOverlay: false }; export default handleActions( { - [actions.MEDIA_PLAY]: (state: MediaState, action: Action) => ({ + // if parameters: state: MediaState, action: Action + [actions.MEDIA_PLAY]: (state: MediaState) => ({ ...state, paused: false, }), - [actions.MEDIA_PAUSE]: (state: MediaState, action: Action) => ({ + [actions.MEDIA_PAUSE]: (state: MediaState) => ({ ...state, paused: true, }), - [actions.MEDIA_POSITION]: (state: MediaState, action: Action) => { + [actions.MEDIA_POSITION]: (state: MediaState) => { const { outpoint, position } = action.data; return { ...state, @@ -36,6 +38,16 @@ export default handleActions( }, }; }, + + [actions.SHOW_OVERLAY_MEDIA]: (state: MediaState) => ({ + ...state, + showOverlay: true, + }), + + [actions.HIDE_OVERLAY_MEDIA]: (state: MediaState) => ({ + ...state, + showOverlay: false, + }), }, defaultState ); diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js index 40a6725e1..4381a9c2a 100644 --- a/src/renderer/redux/selectors/media.js +++ b/src/renderer/redux/selectors/media.js @@ -10,3 +10,5 @@ export const makeSelectMediaPositionForUri = uri => const outpoint = `${claim.txid}:${claim.nout}`; return state.positions[outpoint] || null; }); + +export const selectShowOverlay = createSelector(selectState, state => state.showOverlay); diff --git a/src/renderer/scss/all.scss b/src/renderer/scss/all.scss index 0055ca6d0..54b3981f5 100644 --- a/src/renderer/scss/all.scss +++ b/src/renderer/scss/all.scss @@ -24,3 +24,4 @@ @import 'component/_nav.scss'; @import 'component/_file-list.scss'; @import 'component/_search.scss'; +@import 'component/_overlay.scss'; diff --git a/src/renderer/scss/component/_overlay.scss b/src/renderer/scss/component/_overlay.scss new file mode 100644 index 000000000..3592b1105 --- /dev/null +++ b/src/renderer/scss/component/_overlay.scss @@ -0,0 +1,28 @@ +.overlay { + position: fixed; + max-height: 50%; + max-width: 50%; + width: 20%; + height: inherit; + bottom: 1%; + right: 1%; + z-index: 3; + box-shadow: var(--box-shadow-layer); + + &:hover .button-close { + display: inline-block; + background: rgba(0, 0, 0, 0.5); + position: absolute; + height: 22px; + width: 22px; + top: 0px; + right: 0px; + color: #000; + text-align: center; + cursor: pointer; + z-index: 4; + } +} +.overlay .button-close { + display: none; +}