Add videos to be played across all pages. #1523

Closed
dan1d wants to merge 13 commits from video-overlay-new into master
14 changed files with 154 additions and 10 deletions
Showing only changes of commit 3287d3616e - Show all commits

View file

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

View file

@ -0,0 +1,16 @@
// @flow
import React from 'react';
type Props = {
showOverlay: ?boolean,
children: ?React.node,
};
class Overlay extends React.PureComponent<Props> {
render() {
const { showOverlay, children } = this.props;
return <div className="overlay">{showOverlay ? children : ''}</div>;
}
}
export default Overlay;

View file

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

View file

@ -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<Props> {
@ -53,6 +56,11 @@ class Video extends React.PureComponent<Props> {
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<Props> {
}
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<Props> {
}
playContent() {
const { play, uri } = this.props;
const { play, uri, showOverlay, playingUri, doHideOverlay } = this.props;
if (playingUri && showOverlay) {
doHideOverlay();
}
play(uri);
}

View file

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

View file

@ -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<Props> {
render() {
const { playingUri } = this.props;
return (
<Overlay>
<div className="card-media__internal-links">
<FileActions uri={playingUri} vertical />
</div>
{playingUri ? <Video className="content__embedded" uri={playingUri} overlayed /> : ''}
</Overlay>
);
}
}
export default VideoOverlay;

View file

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

View file

@ -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 = () => {
<div>
<App />
<SnackBar />
<VideoOverlay />
</div>
</Provider>,
document.getElementById('app')

View file

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

View file

@ -2,6 +2,7 @@ import * as ACTIONS from 'constants/action_types';
const reducers = {};
const defaultState = {
showOverlay: false,
playingUri: null,
currentlyIsPlaying: false,
rewardedContentClaimIds: [],

View file

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

View file

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

View file

@ -24,3 +24,4 @@
@import 'component/_nav.scss';
@import 'component/_file-list.scss';
@import 'component/_search.scss';
@import 'component/_overlay.scss';

View file

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