From 6c4a4e593c26ed7eae9356cf9b8a03933b90542c Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Wed, 20 Dec 2017 18:38:11 -0500 Subject: [PATCH 01/13] track and manage video state --- .../component/fileDownloadLink/index.js | 4 +- .../component/fileDownloadLink/view.jsx | 4 +- src/renderer/component/video/index.js | 17 ++++++-- .../component/video/internal/player.jsx | 24 +++++++++--- src/renderer/component/video/view.jsx | 16 ++++++-- src/renderer/constants/action_types.js | 5 +++ src/renderer/redux/actions/media.js | 31 +++++++++++++++ src/renderer/redux/reducers/media.js | 39 +++++++++++++++++++ src/renderer/redux/selectors/media.js | 15 +++++++ src/renderer/store.js | 2 + 10 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 src/renderer/redux/actions/media.js create mode 100644 src/renderer/redux/reducers/media.js create mode 100644 src/renderer/redux/selectors/media.js diff --git a/src/renderer/component/fileDownloadLink/index.js b/src/renderer/component/fileDownloadLink/index.js index e35dc5b94..edc52cffc 100644 --- a/src/renderer/component/fileDownloadLink/index.js +++ b/src/renderer/component/fileDownloadLink/index.js @@ -9,7 +9,7 @@ import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; import { doFetchAvailability } from "redux/actions/availability"; import { doOpenFileInShell } from "redux/actions/file_info"; import { doPurchaseUri, doStartDownload } from "redux/actions/content"; -import { setVideoPause } from "redux/actions/video"; +import { doPause } from "redux/actions/media"; import FileDownloadLink from "./view"; const select = (state, props) => ({ @@ -25,7 +25,7 @@ const perform = dispatch => ({ openInShell: path => dispatch(doOpenFileInShell(path)), purchaseUri: uri => dispatch(doPurchaseUri(uri)), restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)), - setVideoPause: val => dispatch(setVideoPause(val)), + doPause: () => dispatch(doPause()), }); export default connect(select, perform)(FileDownloadLink); diff --git a/src/renderer/component/fileDownloadLink/view.jsx b/src/renderer/component/fileDownloadLink/view.jsx index 0619460dd..d2349059b 100644 --- a/src/renderer/component/fileDownloadLink/view.jsx +++ b/src/renderer/component/fileDownloadLink/view.jsx @@ -42,12 +42,12 @@ class FileDownloadLink extends React.PureComponent { purchaseUri, costInfo, loading, - setVideoPause, + doPause, } = this.props; const openFile = () => { openInShell(fileInfo.download_path); - setVideoPause(true); + doPause(); }; if (loading || downloading) { diff --git a/src/renderer/component/video/index.js b/src/renderer/component/video/index.js index f0a1a43f1..bec9e46b6 100644 --- a/src/renderer/component/video/index.js +++ b/src/renderer/component/video/index.js @@ -3,7 +3,8 @@ import { connect } from "react-redux"; import { doChangeVolume } from "redux/actions/app"; import { selectVolume } from "redux/selectors/app"; import { doPlayUri, doSetPlayingUri } from "redux/actions/content"; -import { setVideoPause } from "redux/actions/video"; +import { doPlay, doPause, savePosition } from "redux/actions/media"; +// import { setVideoPause } from "redux/actions/video"; import { makeSelectMetadataForUri, makeSelectContentTypeForUri, @@ -15,7 +16,11 @@ import { } from "redux/selectors/file_info"; import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; import { selectShowNsfw } from "redux/selectors/settings"; -import { selectVideoPause } from "redux/selectors/video"; +// import { selectVideoPause } from "redux/selectors/video"; +import { + selectMediaPaused, + makeSelectMediaPositionForUri, +} from "redux/selectors/media"; import Video from "./view"; import { selectPlayingUri } from "redux/selectors/content"; @@ -29,14 +34,18 @@ const select = (state, props) => ({ playingUri: selectPlayingUri(state), contentType: makeSelectContentTypeForUri(props.uri)(state), volume: selectVolume(state), - videoPause: selectVideoPause(state), + // videoPause: selectVideoPause(state), + mediaPaused: selectMediaPaused(state), + mediaPosition: makeSelectMediaPositionForUri(props.uri)(state), }); const perform = dispatch => ({ play: uri => dispatch(doPlayUri(uri)), cancelPlay: () => dispatch(doSetPlayingUri(null)), changeVolume: volume => dispatch(doChangeVolume(volume)), - setVideoPause: val => dispatch(setVideoPause(val)), + // setVideoPause: val => dispatch(setVideoPause(val)), + doPlay: () => dispatch(doPlay()), + doPause: (id, position) => dispatch(doPause(id, position)), }); export default connect(select, perform)(Video); diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index e993dac36..c0e13acab 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -20,11 +20,10 @@ class VideoPlayer extends React.PureComponent { this.togglePlayListener = this.togglePlay.bind(this); } - componentWillReceiveProps(nextProps) { - if (nextProps.videoPause) { - this.refs.media.children[0].pause(); - this.props.setVideoPause(false); - } + componentWillReceiveProps(next) { + const el = this.refs.media.children[0]; + if (!this.props.paused && next.paused && !el.paused) el.pause(); + // if (this.props.paused && !next.paused && el.paused) el.play(); } componentDidMount() { @@ -35,7 +34,15 @@ class VideoPlayer extends React.PureComponent { mediaType, changeVolume, volume, + mediaId, + position, } = this.props; + + // I'm using a Timeout because I'm not sure where this should happen + if (position > 0) { + setTimeout(() => (mediaElement.currentTime = position), 900); + } + const loadedMetadata = e => { this.setState({ hasMetadata: true, startedPlaying: true }); this.refs.media.children[0].play(); @@ -68,6 +75,11 @@ class VideoPlayer extends React.PureComponent { document.addEventListener("keydown", this.togglePlayListener); const mediaElement = this.refs.media.children[0]; if (mediaElement) { + mediaElement.addEventListener("play", () => this.props.doPlay()); + mediaElement.addEventListener("pause", () => { + console.log("CURRENT TIME:", mediaElement.currentTime); + this.props.doPause(this.props.mediaId, mediaElement.currentTime); + }); mediaElement.addEventListener("click", this.togglePlayListener); mediaElement.addEventListener( "loadedmetadata", @@ -92,7 +104,9 @@ class VideoPlayer extends React.PureComponent { const mediaElement = this.refs.media.children[0]; if (mediaElement) { mediaElement.removeEventListener("click", this.togglePlayListener); + //mediaElement.removeEventListener("play"); ?? } + this.props.doPause(this.props.mediaId, mediaElement.currentTime); } renderAudio(container, autoplay) { diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index c5c4d8d88..9f793b783 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -56,8 +56,10 @@ class Video extends React.PureComponent { changeVolume, volume, uri, - videoPause, - setVideoPause, + doPlay, + doPause, + mediaPaused, + mediaPosition, } = this.props; const isPlaying = playingUri === uri; @@ -93,6 +95,9 @@ class Video extends React.PureComponent { } const poster = metadata.thumbnail; + const mediaId = uri.split("#")[1]; + console.log("mediaId:", mediaId); + return (
))} {!isPlaying && ( diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index bbf6c520b..774a48559 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -167,3 +167,8 @@ export const HAS_FETCHED_SUBSCRIPTIONS = "HAS_FETCHED_SUBSCRIPTIONS"; // Video controls export const SET_VIDEO_PAUSE = "SET_VIDEO_PAUSE"; + +// Media controls +export const MEDIA_PLAY = "MEDIA_PLAY"; +export const MEDIA_PAUSE = "MEDIA_PAUSE"; +export const MEDIA_POSITION = "MEDIA_POSITION"; diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js new file mode 100644 index 000000000..2ee20e3fa --- /dev/null +++ b/src/renderer/redux/actions/media.js @@ -0,0 +1,31 @@ +// @flow +import * as actions from "constants/action_types"; +import type { Action, Dispatch } from "redux/reducers/media"; +import lbry from "lbry"; + +export const doPlay = () => (dispatch: Dispatch) => + dispatch({ + type: actions.MEDIA_PLAY, + }); + +export const doPause = (id: String, position: String) => ( + dispatch: Dispatch +) => { + if (id && position) { + dispatch({ + type: actions.MEDIA_POSITION, + id, + position, + }); + } + dispatch({ type: actions.MEDIA_PAUSE }); +}; + +export const savePosition = (id: String, position: String) => ( + dispatch: Dispatch +) => + dispatch({ + type: actions.MEDIA_POSITION, + id, + position, + }); diff --git a/src/renderer/redux/reducers/media.js b/src/renderer/redux/reducers/media.js new file mode 100644 index 000000000..242f65be7 --- /dev/null +++ b/src/renderer/redux/reducers/media.js @@ -0,0 +1,39 @@ +// @flow +import * as actions from "constants/action_types"; +import { handleActions } from "util/redux-utils"; + +export type MediaState = { + paused: Boolean, + positions: Object, +}; + +export type Action = any; +export type Dispatch = (action: Action) => any; + +const defaultState = { paused: true, positions: {} }; + +export default handleActions( + { + [actions.MEDIA_PLAY]: (state: MediaState, action: Action) => ({ + ...state, + paused: false, + }), + + [actions.MEDIA_PAUSE]: (state: MediaState, action: Action) => ({ + ...state, + paused: true, + }), + + [actions.MEDIA_POSITION]: (state: MediaState, action: Action) => { + const { id, position } = action; + return { + ...state, + positions: { + ...state.positions, + [id]: position, + }, + }; + }, + }, + defaultState +); diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js new file mode 100644 index 000000000..070604c2b --- /dev/null +++ b/src/renderer/redux/selectors/media.js @@ -0,0 +1,15 @@ +import * as settings from "constants/settings"; +import { createSelector } from "reselect"; + +const _selectState = state => state.media || {}; + +export const selectMediaPaused = createSelector( + _selectState, + state => state.paused +); + +export const makeSelectMediaPositionForUri = uri => + createSelector(_selectState, state => { + const id = uri.split("#")[1]; + return state.positions[id] || null; + }); diff --git a/src/renderer/store.js b/src/renderer/store.js index f4a61f779..8c6e89277 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -14,6 +14,7 @@ import walletReducer from "redux/reducers/wallet"; import shapeShiftReducer from "redux/reducers/shape_shift"; import subscriptionsReducer from "redux/reducers/subscriptions"; import videoReducer from "redux/reducers/video"; +import mediaReducer from "redux/reducers/media"; import { persistStore, autoRehydrate } from "redux-persist"; import createCompressor from "redux-persist-transform-compress"; import createFilter from "redux-persist-transform-filter"; @@ -71,6 +72,7 @@ const reducers = combineReducers({ shapeShift: shapeShiftReducer, subscriptions: subscriptionsReducer, video: videoReducer, + media: mediaReducer, }); const bulkThunk = createBulkThunkMiddleware(); From 7d29c4b91d01c1c5bc8e42ea78466bb40ae314a6 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Thu, 21 Dec 2017 20:22:40 -0500 Subject: [PATCH 02/13] apply starting position directly (no setTimeout) --- src/renderer/component/video/internal/player.jsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index c0e13acab..7e436f566 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -38,11 +38,6 @@ class VideoPlayer extends React.PureComponent { position, } = this.props; - // I'm using a Timeout because I'm not sure where this should happen - if (position > 0) { - setTimeout(() => (mediaElement.currentTime = position), 900); - } - const loadedMetadata = e => { this.setState({ hasMetadata: true, startedPlaying: true }); this.refs.media.children[0].play(); @@ -75,6 +70,7 @@ class VideoPlayer extends React.PureComponent { document.addEventListener("keydown", this.togglePlayListener); const mediaElement = this.refs.media.children[0]; if (mediaElement) { + mediaElement.currentTime = position; mediaElement.addEventListener("play", () => this.props.doPlay()); mediaElement.addEventListener("pause", () => { console.log("CURRENT TIME:", mediaElement.currentTime); From 11a5f9d1d5bc391d7c82f4a60aebc7e0632de24b Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 22 Dec 2017 18:14:54 -0500 Subject: [PATCH 03/13] use timeupdate instead of pause to update video state --- src/renderer/component/video/index.js | 3 ++- src/renderer/component/video/internal/player.jsx | 8 ++++---- src/renderer/component/video/view.jsx | 2 ++ src/renderer/redux/actions/media.js | 16 ++++------------ 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/renderer/component/video/index.js b/src/renderer/component/video/index.js index bec9e46b6..36c92eab9 100644 --- a/src/renderer/component/video/index.js +++ b/src/renderer/component/video/index.js @@ -45,7 +45,8 @@ const perform = dispatch => ({ changeVolume: volume => dispatch(doChangeVolume(volume)), // setVideoPause: val => dispatch(setVideoPause(val)), doPlay: () => dispatch(doPlay()), - doPause: (id, position) => dispatch(doPause(id, position)), + doPause: () => dispatch(doPause()), + savePosition: (id, position) => dispatch(savePosition(id, position)), }); export default connect(select, perform)(Video); diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index 7e436f566..be2497032 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -72,10 +72,10 @@ class VideoPlayer extends React.PureComponent { if (mediaElement) { mediaElement.currentTime = position; mediaElement.addEventListener("play", () => this.props.doPlay()); - mediaElement.addEventListener("pause", () => { - console.log("CURRENT TIME:", mediaElement.currentTime); - this.props.doPause(this.props.mediaId, mediaElement.currentTime); - }); + mediaElement.addEventListener("pause", () => this.props.doPause()); + mediaElement.addEventListener("timeupdate", () => + this.props.savePosition(mediaId, mediaElement.currentTime) + ); mediaElement.addEventListener("click", this.togglePlayListener); mediaElement.addEventListener( "loadedmetadata", diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index 9f793b783..96715c990 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -58,6 +58,7 @@ class Video extends React.PureComponent { uri, doPlay, doPause, + savePosition, mediaPaused, mediaPosition, } = this.props; @@ -119,6 +120,7 @@ class Video extends React.PureComponent { volume={volume} doPlay={doPlay} doPause={doPause} + savePosition={savePosition} mediaId={mediaId} paused={mediaPaused} position={mediaPosition} diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js index 2ee20e3fa..6cdc6815e 100644 --- a/src/renderer/redux/actions/media.js +++ b/src/renderer/redux/actions/media.js @@ -8,18 +8,10 @@ export const doPlay = () => (dispatch: Dispatch) => type: actions.MEDIA_PLAY, }); -export const doPause = (id: String, position: String) => ( - dispatch: Dispatch -) => { - if (id && position) { - dispatch({ - type: actions.MEDIA_POSITION, - id, - position, - }); - } - dispatch({ type: actions.MEDIA_PAUSE }); -}; +export const doPause = () => (dispatch: Dispatch) => + dispatch({ + type: actions.MEDIA_PAUSE, + }); export const savePosition = (id: String, position: String) => ( dispatch: Dispatch From 61b8e8ee717e19beb9226c5be5ff62ab2dd39196 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 22 Dec 2017 18:18:00 -0500 Subject: [PATCH 04/13] remove arguments from doPause call in Unmount --- src/renderer/component/video/internal/player.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index be2497032..3d675c723 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -100,9 +100,8 @@ class VideoPlayer extends React.PureComponent { const mediaElement = this.refs.media.children[0]; if (mediaElement) { mediaElement.removeEventListener("click", this.togglePlayListener); - //mediaElement.removeEventListener("play"); ?? } - this.props.doPause(this.props.mediaId, mediaElement.currentTime); + this.props.doPause(); } renderAudio(container, autoplay) { From a8988d9e0504a1ddc2a8c1aa835f5bae017e9aea Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 29 Dec 2017 11:07:03 -0500 Subject: [PATCH 05/13] remove video files; save video claimId rather than URI --- src/renderer/component/video/index.js | 6 ++--- .../component/video/internal/player.jsx | 6 +++-- src/renderer/component/video/view.jsx | 8 +++--- src/renderer/redux/actions/video.js | 10 -------- src/renderer/redux/reducers/media.js | 4 ++- src/renderer/redux/reducers/video.js | 25 ------------------- src/renderer/redux/selectors/media.js | 12 +++++++-- src/renderer/redux/selectors/video.js | 9 ------- src/renderer/store.js | 2 -- 9 files changed, 23 insertions(+), 59 deletions(-) delete mode 100644 src/renderer/redux/actions/video.js delete mode 100644 src/renderer/redux/reducers/video.js delete mode 100644 src/renderer/redux/selectors/video.js diff --git a/src/renderer/component/video/index.js b/src/renderer/component/video/index.js index 36c92eab9..cc01f032a 100644 --- a/src/renderer/component/video/index.js +++ b/src/renderer/component/video/index.js @@ -4,7 +4,6 @@ import { doChangeVolume } from "redux/actions/app"; import { selectVolume } from "redux/selectors/app"; import { doPlayUri, doSetPlayingUri } from "redux/actions/content"; import { doPlay, doPause, savePosition } from "redux/actions/media"; -// import { setVideoPause } from "redux/actions/video"; import { makeSelectMetadataForUri, makeSelectContentTypeForUri, @@ -16,15 +15,16 @@ import { } from "redux/selectors/file_info"; import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; import { selectShowNsfw } from "redux/selectors/settings"; -// import { selectVideoPause } from "redux/selectors/video"; import { selectMediaPaused, makeSelectMediaPositionForUri, } from "redux/selectors/media"; import Video from "./view"; import { selectPlayingUri } from "redux/selectors/content"; +import { makeSelectClaimForUri } from "redux/selectors/claims"; const select = (state, props) => ({ + claim: makeSelectClaimForUri(props.uri)(state), costInfo: makeSelectCostInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state), @@ -34,7 +34,6 @@ const select = (state, props) => ({ playingUri: selectPlayingUri(state), contentType: makeSelectContentTypeForUri(props.uri)(state), volume: selectVolume(state), - // videoPause: selectVideoPause(state), mediaPaused: selectMediaPaused(state), mediaPosition: makeSelectMediaPositionForUri(props.uri)(state), }); @@ -43,7 +42,6 @@ const perform = dispatch => ({ play: uri => dispatch(doPlayUri(uri)), cancelPlay: () => dispatch(doSetPlayingUri(null)), changeVolume: volume => dispatch(doChangeVolume(volume)), - // setVideoPause: val => dispatch(setVideoPause(val)), doPlay: () => dispatch(doPlay()), doPause: () => dispatch(doPause()), savePosition: (id, position) => dispatch(savePosition(id, position)), diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index 3d675c723..2e9a9a0b1 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -34,10 +34,12 @@ class VideoPlayer extends React.PureComponent { mediaType, changeVolume, volume, - mediaId, position, + id, } = this.props; + console.log("position:", position); + const loadedMetadata = e => { this.setState({ hasMetadata: true, startedPlaying: true }); this.refs.media.children[0].play(); @@ -74,7 +76,7 @@ class VideoPlayer extends React.PureComponent { mediaElement.addEventListener("play", () => this.props.doPlay()); mediaElement.addEventListener("pause", () => this.props.doPause()); mediaElement.addEventListener("timeupdate", () => - this.props.savePosition(mediaId, mediaElement.currentTime) + this.props.savePosition(id, mediaElement.currentTime) ); mediaElement.addEventListener("click", this.togglePlayListener); mediaElement.addEventListener( diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index 96715c990..77b7463ab 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -55,6 +55,7 @@ class Video extends React.PureComponent { contentType, changeVolume, volume, + claim, uri, doPlay, doPause, @@ -63,6 +64,8 @@ class Video extends React.PureComponent { mediaPosition, } = this.props; + console.log("mediaPosition:", mediaPosition); + const isPlaying = playingUri === uri; const isReadyToPlay = fileInfo && fileInfo.written_bytes > 0; const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; @@ -96,9 +99,6 @@ class Video extends React.PureComponent { } const poster = metadata.thumbnail; - const mediaId = uri.split("#")[1]; - console.log("mediaId:", mediaId); - return (
diff --git a/src/renderer/redux/actions/video.js b/src/renderer/redux/actions/video.js deleted file mode 100644 index bf88d2d26..000000000 --- a/src/renderer/redux/actions/video.js +++ /dev/null @@ -1,10 +0,0 @@ -// @flow -import * as actions from "constants/action_types"; -import type { Action, Dispatch } from "redux/reducers/video"; -import lbry from "lbry"; - -export const setVideoPause = (data: boolean) => (dispatch: Dispatch) => - dispatch({ - type: actions.SET_VIDEO_PAUSE, - data, - }); diff --git a/src/renderer/redux/reducers/media.js b/src/renderer/redux/reducers/media.js index 242f65be7..92d5f4115 100644 --- a/src/renderer/redux/reducers/media.js +++ b/src/renderer/redux/reducers/media.js @@ -4,7 +4,9 @@ import { handleActions } from "util/redux-utils"; export type MediaState = { paused: Boolean, - positions: Object, + positions: { + [string]: number, + }, }; export type Action = any; diff --git a/src/renderer/redux/reducers/video.js b/src/renderer/redux/reducers/video.js deleted file mode 100644 index 0f18844dd..000000000 --- a/src/renderer/redux/reducers/video.js +++ /dev/null @@ -1,25 +0,0 @@ -// @flow -import * as actions from "constants/action_types"; -import { handleActions } from "util/redux-utils"; - -export type VideoState = { videoPause: boolean }; - -type setVideoPause = { - type: actions.SET_VIDEO_PAUSE, - data: boolean, -}; - -export type Action = setVideoPause; -export type Dispatch = (action: Action) => any; - -const defaultState = { videoPause: false }; - -export default handleActions( - { - [actions.SET_VIDEO_PAUSE]: ( - state: VideoState, - action: setVideoPause - ): VideoState => ({ ...state, videoPause: action.data }), - }, - defaultState -); diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js index 070604c2b..f0cf17886 100644 --- a/src/renderer/redux/selectors/media.js +++ b/src/renderer/redux/selectors/media.js @@ -1,5 +1,6 @@ import * as settings from "constants/settings"; import { createSelector } from "reselect"; +import lbryuri from "lbryuri"; const _selectState = state => state.media || {}; @@ -10,6 +11,13 @@ export const selectMediaPaused = createSelector( export const makeSelectMediaPositionForUri = uri => createSelector(_selectState, state => { - const id = uri.split("#")[1]; - return state.positions[id] || null; + // console.log("select positions:", state.positions); + // const videoId = lbryuri.parse(uri).claimId; + // console.log("videoId:", videoId); + // const position = state.positions[videoId]; + // console.log("position:", position); + // console.log("positions:", state.positions); + const obj = lbryuri.parse(uri); + console.log("state.positions:\n", state.positions); + return state.positions[obj.claimId] || null; }); diff --git a/src/renderer/redux/selectors/video.js b/src/renderer/redux/selectors/video.js deleted file mode 100644 index a41c95803..000000000 --- a/src/renderer/redux/selectors/video.js +++ /dev/null @@ -1,9 +0,0 @@ -import * as settings from "constants/settings"; -import { createSelector } from "reselect"; - -const _selectState = state => state.video || {}; - -export const selectVideoPause = createSelector( - _selectState, - state => state.videoPause -); diff --git a/src/renderer/store.js b/src/renderer/store.js index 8c6e89277..836412983 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -13,7 +13,6 @@ import userReducer from "redux/reducers/user"; import walletReducer from "redux/reducers/wallet"; import shapeShiftReducer from "redux/reducers/shape_shift"; import subscriptionsReducer from "redux/reducers/subscriptions"; -import videoReducer from "redux/reducers/video"; import mediaReducer from "redux/reducers/media"; import { persistStore, autoRehydrate } from "redux-persist"; import createCompressor from "redux-persist-transform-compress"; @@ -71,7 +70,6 @@ const reducers = combineReducers({ user: userReducer, shapeShift: shapeShiftReducer, subscriptions: subscriptionsReducer, - video: videoReducer, media: mediaReducer, }); From bfe5fe851aa972a73f0faa38f8ab5ae17e5bff5c Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 29 Dec 2017 15:45:32 -0500 Subject: [PATCH 06/13] remove logging --- src/renderer/component/video/internal/player.jsx | 2 -- src/renderer/redux/selectors/media.js | 7 ------- 2 files changed, 9 deletions(-) diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index 2e9a9a0b1..fdb5dccc3 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -38,8 +38,6 @@ class VideoPlayer extends React.PureComponent { id, } = this.props; - console.log("position:", position); - const loadedMetadata = e => { this.setState({ hasMetadata: true, startedPlaying: true }); this.refs.media.children[0].play(); diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js index f0cf17886..a3418775d 100644 --- a/src/renderer/redux/selectors/media.js +++ b/src/renderer/redux/selectors/media.js @@ -11,13 +11,6 @@ export const selectMediaPaused = createSelector( export const makeSelectMediaPositionForUri = uri => createSelector(_selectState, state => { - // console.log("select positions:", state.positions); - // const videoId = lbryuri.parse(uri).claimId; - // console.log("videoId:", videoId); - // const position = state.positions[videoId]; - // console.log("position:", position); - // console.log("positions:", state.positions); const obj = lbryuri.parse(uri); - console.log("state.positions:\n", state.positions); return state.positions[obj.claimId] || null; }); From ecd2207314d6067b3f08fbcfad8fd96c3d6d4c05 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 29 Dec 2017 15:47:11 -0500 Subject: [PATCH 07/13] remove log in video view --- src/renderer/component/video/view.jsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index 77b7463ab..1daf4e00e 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -64,8 +64,6 @@ class Video extends React.PureComponent { mediaPosition, } = this.props; - console.log("mediaPosition:", mediaPosition); - const isPlaying = playingUri === uri; const isReadyToPlay = fileInfo && fileInfo.written_bytes > 0; const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; From 345badb0497fc687b8bbcf8d3adf6119e3ef72aa Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 5 Jan 2018 14:27:58 -0500 Subject: [PATCH 08/13] store position by outpoint --- .../component/video/internal/player.jsx | 7 +++--- src/renderer/component/video/view.jsx | 4 +++- src/renderer/redux/actions/media.js | 23 ++++++++++++------- src/renderer/redux/reducers/media.js | 4 ++-- src/renderer/redux/selectors/media.js | 7 +++--- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index fdb5dccc3..521de6470 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -35,7 +35,8 @@ class VideoPlayer extends React.PureComponent { changeVolume, volume, position, - id, + claim, + uri, } = this.props; const loadedMetadata = e => { @@ -70,11 +71,11 @@ class VideoPlayer extends React.PureComponent { document.addEventListener("keydown", this.togglePlayListener); const mediaElement = this.refs.media.children[0]; if (mediaElement) { - mediaElement.currentTime = position; + mediaElement.currentTime = position || 0; mediaElement.addEventListener("play", () => this.props.doPlay()); mediaElement.addEventListener("pause", () => this.props.doPause()); mediaElement.addEventListener("timeupdate", () => - this.props.savePosition(id, mediaElement.currentTime) + this.props.savePosition(claim.claim_id, mediaElement.currentTime) ); mediaElement.addEventListener("click", this.togglePlayListener); mediaElement.addEventListener( diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index 1daf4e00e..74f896bc1 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -62,6 +62,7 @@ class Video extends React.PureComponent { savePosition, mediaPaused, mediaPosition, + positions, } = this.props; const isPlaying = playingUri === uri; @@ -119,7 +120,8 @@ class Video extends React.PureComponent { doPlay={doPlay} doPause={doPause} savePosition={savePosition} - id={claim.claim_id} + claim={claim} + uri={uri} paused={mediaPaused} position={mediaPosition} /> diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js index 6cdc6815e..9971c4a45 100644 --- a/src/renderer/redux/actions/media.js +++ b/src/renderer/redux/actions/media.js @@ -2,6 +2,7 @@ import * as actions from "constants/action_types"; import type { Action, Dispatch } from "redux/reducers/media"; import lbry from "lbry"; +import { makeSelectClaimForUri } from "redux/selectors/claims"; export const doPlay = () => (dispatch: Dispatch) => dispatch({ @@ -13,11 +14,17 @@ export const doPause = () => (dispatch: Dispatch) => type: actions.MEDIA_PAUSE, }); -export const savePosition = (id: String, position: String) => ( - dispatch: Dispatch -) => - dispatch({ - type: actions.MEDIA_POSITION, - id, - position, - }); +export function savePosition(claimId, position) { + return function(dispatch: Dispatch, getState: Function) { + const state = getState(); + const claim = state.claims.byId[claimId]; + const outpoint = `${claim.txid}:${claim.nout}`; + dispatch({ + type: actions.MEDIA_POSITION, + data: { + outpoint, + position, + }, + }); + }; +} diff --git a/src/renderer/redux/reducers/media.js b/src/renderer/redux/reducers/media.js index 92d5f4115..7e3bb9591 100644 --- a/src/renderer/redux/reducers/media.js +++ b/src/renderer/redux/reducers/media.js @@ -27,12 +27,12 @@ export default handleActions( }), [actions.MEDIA_POSITION]: (state: MediaState, action: Action) => { - const { id, position } = action; + const { outpoint, position } = action.data; return { ...state, positions: { ...state.positions, - [id]: position, + [outpoint]: position, }, }; }, diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js index a3418775d..9ef16abaf 100644 --- a/src/renderer/redux/selectors/media.js +++ b/src/renderer/redux/selectors/media.js @@ -1,6 +1,7 @@ import * as settings from "constants/settings"; import { createSelector } from "reselect"; import lbryuri from "lbryuri"; +import { makeSelectClaimForUri } from "redux/selectors/claims"; const _selectState = state => state.media || {}; @@ -10,7 +11,7 @@ export const selectMediaPaused = createSelector( ); export const makeSelectMediaPositionForUri = uri => - createSelector(_selectState, state => { - const obj = lbryuri.parse(uri); - return state.positions[obj.claimId] || null; + createSelector(_selectState, makeSelectClaimForUri(uri), (state, claim) => { + const outpoint = `${claim.txid}:${claim.nout}`; + return state.positions[outpoint] || null; }); From 504c5469e398221a6f2ba7f3df7cfefc1b215a6e Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 5 Jan 2018 14:29:25 -0500 Subject: [PATCH 09/13] safely type params in position selector --- src/renderer/redux/actions/media.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js index 9971c4a45..d3076ed75 100644 --- a/src/renderer/redux/actions/media.js +++ b/src/renderer/redux/actions/media.js @@ -14,7 +14,7 @@ export const doPause = () => (dispatch: Dispatch) => type: actions.MEDIA_PAUSE, }); -export function savePosition(claimId, position) { +export function savePosition(claimId: String, position: Number) { return function(dispatch: Dispatch, getState: Function) { const state = getState(); const claim = state.claims.byId[claimId]; From 0cfc9ab32c7a11a3c16f06a83050163e86655bb9 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 5 Jan 2018 14:31:58 -0500 Subject: [PATCH 10/13] remove old positions variable --- src/renderer/component/video/view.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/component/video/view.jsx b/src/renderer/component/video/view.jsx index 74f896bc1..a924cf262 100644 --- a/src/renderer/component/video/view.jsx +++ b/src/renderer/component/video/view.jsx @@ -62,7 +62,6 @@ class Video extends React.PureComponent { savePosition, mediaPaused, mediaPosition, - positions, } = this.props; const isPlaying = playingUri === uri; From 566fb2e0b56e80a80b5909b07ea106e80731d424 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 5 Jan 2018 15:14:12 -0500 Subject: [PATCH 11/13] rename id param to claimId --- src/renderer/component/video/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/renderer/component/video/index.js b/src/renderer/component/video/index.js index cc01f032a..8c0a91289 100644 --- a/src/renderer/component/video/index.js +++ b/src/renderer/component/video/index.js @@ -44,7 +44,8 @@ const perform = dispatch => ({ changeVolume: volume => dispatch(doChangeVolume(volume)), doPlay: () => dispatch(doPlay()), doPause: () => dispatch(doPause()), - savePosition: (id, position) => dispatch(savePosition(id, position)), + savePosition: (claimId, position) => + dispatch(savePosition(claimId, position)), }); export default connect(select, perform)(Video); From 5765c6c1ee05acf016c3001ab89aefbbcd20d1e5 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 5 Jan 2018 18:36:03 -0500 Subject: [PATCH 12/13] remove comment --- src/renderer/component/video/internal/player.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/component/video/internal/player.jsx b/src/renderer/component/video/internal/player.jsx index 521de6470..6740c5d2f 100644 --- a/src/renderer/component/video/internal/player.jsx +++ b/src/renderer/component/video/internal/player.jsx @@ -23,7 +23,6 @@ class VideoPlayer extends React.PureComponent { componentWillReceiveProps(next) { const el = this.refs.media.children[0]; if (!this.props.paused && next.paused && !el.paused) el.pause(); - // if (this.props.paused && !next.paused && el.paused) el.play(); } componentDidMount() { From d3047a741a7556ccd29e19c29bece05e78c2e4a8 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 5 Jan 2018 19:04:12 -0500 Subject: [PATCH 13/13] remove ENV statement --- src/renderer/store.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/renderer/store.js b/src/renderer/store.js index 7af0ce7ea..ca6db3afd 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -21,8 +21,6 @@ import localForage from 'localforage'; import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; import thunk from 'redux-thunk'; -const env = process.env.NODE_ENV || 'production'; - function isFunction(object) { return typeof object === 'function'; }