diff --git a/src/renderer/component/fileViewer/index.js b/src/renderer/component/fileViewer/index.js index c21e5f5c1..e34786474 100644 --- a/src/renderer/component/fileViewer/index.js +++ b/src/renderer/component/fileViewer/index.js @@ -2,9 +2,8 @@ import { connect } from 'react-redux'; import * as settings from 'constants/settings'; 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 { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards'; +import { doPlayUri, doSetPlayingUri, savePosition } from 'redux/actions/content'; +import { doPlay, doPause } from 'redux/actions/media'; import { makeSelectMetadataForUri, makeSelectContentTypeForUri, @@ -16,8 +15,8 @@ import { selectSearchBarFocused, } from 'lbry-redux'; import { makeSelectClientSetting, selectShowNsfw } from 'redux/selectors/settings'; -import { selectMediaPaused, makeSelectMediaPositionForUri } from 'redux/selectors/media'; -import { selectPlayingUri } from 'redux/selectors/content'; +import { selectMediaPaused } from 'redux/selectors/media'; +import { selectPlayingUri, makeSelectContentPositionForUri } from 'redux/selectors/content'; import { selectFileInfoErrors } from 'redux/selectors/file_info'; import FileViewer from './view'; @@ -33,7 +32,7 @@ const select = (state, props) => ({ contentType: makeSelectContentTypeForUri(props.uri)(state), volume: selectVolume(state), mediaPaused: selectMediaPaused(state), - mediaPosition: makeSelectMediaPositionForUri(props.uri)(state), + playbackPosition: makeSelectContentPositionForUri(props.uri)(state), autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), searchBarFocused: selectSearchBarFocused(state), fileInfoErrors: selectFileInfoErrors(state), @@ -45,8 +44,8 @@ const perform = dispatch => ({ changeVolume: volume => dispatch(doChangeVolume(volume)), doPlay: () => dispatch(doPlay()), doPause: () => dispatch(doPause()), - savePosition: (claimId, position) => dispatch(savePosition(claimId, position)), - claimRewards: () => dispatch(doClaimEligiblePurchaseRewards()), + savePosition: (claimId, outpoint, position) => + dispatch(savePosition(claimId, outpoint, position)), }); export default connect( diff --git a/src/renderer/component/fileViewer/internal/player.jsx b/src/renderer/component/fileViewer/internal/player.jsx index d76d0bcaf..6f7782c5f 100644 --- a/src/renderer/component/fileViewer/internal/player.jsx +++ b/src/renderer/component/fileViewer/internal/player.jsx @@ -90,7 +90,11 @@ class MediaPlayer extends React.PureComponent { mediaElement.addEventListener('play', () => this.props.doPlay()); mediaElement.addEventListener('pause', () => this.props.doPause()); mediaElement.addEventListener('timeupdate', () => - this.props.savePosition(claim.claim_id, mediaElement.currentTime) + this.props.savePosition( + claim.claim_id, + `${claim.txid}:${claim.nout}`, + mediaElement.currentTime + ) ); mediaElement.addEventListener('click', this.togglePlayListener); mediaElement.addEventListener('loadedmetadata', loadedMetadata.bind(this), { diff --git a/src/renderer/component/fileViewer/view.jsx b/src/renderer/component/fileViewer/view.jsx index 3e51bab10..e213092dd 100644 --- a/src/renderer/component/fileViewer/view.jsx +++ b/src/renderer/component/fileViewer/view.jsx @@ -36,9 +36,9 @@ type Props = { uri: string, doPlay: () => void, doPause: () => void, - savePosition: (string, number) => void, + savePosition: (string, string, number) => void, mediaPaused: boolean, - mediaPosition: ?number, + playbackPosition: ?number, className: ?string, obscureNsfw: boolean, play: string => void, @@ -206,7 +206,7 @@ class FileViewer extends React.PureComponent { doPause, savePosition, mediaPaused, - mediaPosition, + playbackPosition, className, obscureNsfw, mediaType, @@ -257,8 +257,7 @@ class FileViewer extends React.PureComponent { claim={claim} uri={uri} paused={mediaPaused} - position={mediaPosition} - startedPlayingCb={this.startedPlayingCb} + position={playbackPosition} /> )} diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index 4a2d31e0d..9596eed3e 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -74,6 +74,7 @@ export const PUBLISH_STARTED = 'PUBLISH_STARTED'; export const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; export const PUBLISH_FAILED = 'PUBLISH_FAILED'; export const SET_PLAYING_URI = 'PLAY_URI'; +export const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; @@ -187,7 +188,6 @@ 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'; // Publishing export const CLEAR_PUBLISH = 'CLEAR_PUBLISH'; diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index 0a4e96130..2fd51a748 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -1,3 +1,4 @@ +// @flow import * as NOTIFICATION_TYPES from 'constants/notification_types'; import { ipcRenderer } from 'electron'; import Lbryio from 'lbryio'; @@ -494,3 +495,12 @@ export function doPublish(params) { Lbry.publishDeprecated(params, null, success, failure); }); } + +export function savePosition(claimId: string, outpoint: string, position: number) { + return dispatch => { + dispatch({ + type: ACTIONS.SET_CONTENT_POSITION, + data: { claimId, outpoint, position }, + }); + }; +} diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js index 1b7d0b85f..99f297c5d 100644 --- a/src/renderer/redux/actions/media.js +++ b/src/renderer/redux/actions/media.js @@ -11,18 +11,3 @@ export const doPause = () => (dispatch: Dispatch) => dispatch({ type: actions.MEDIA_PAUSE, }); - -export function savePosition(claimId: String, position: Number) { - 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/content.js b/src/renderer/redux/reducers/content.js index e5242b599..3a760515a 100644 --- a/src/renderer/redux/reducers/content.js +++ b/src/renderer/redux/reducers/content.js @@ -5,6 +5,7 @@ const defaultState = { playingUri: null, rewardedContentClaimIds: [], channelClaimCounts: {}, + positions: {}, }; reducers[ACTIONS.FETCH_FEATURED_CONTENT_STARTED] = state => @@ -79,6 +80,20 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = (state, action) => { }); }; +reducers[ACTIONS.SET_CONTENT_POSITION] = (state, action) => { + const { claimId, outpoint, position } = action.data; + return { + ...state, + positions: { + ...state.positions, + [claimId]: { + ...state.positions[claimId], + [outpoint]: position, + }, + }, + }; +}; + export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/renderer/redux/reducers/media.js b/src/renderer/redux/reducers/media.js index 44447fe4f..981820a27 100644 --- a/src/renderer/redux/reducers/media.js +++ b/src/renderer/redux/reducers/media.js @@ -4,9 +4,6 @@ import { handleActions } from 'util/redux-utils'; export type MediaState = { paused: Boolean, - positions: { - [string]: number, - }, }; export type Action = any; @@ -25,17 +22,6 @@ export default handleActions( ...state, paused: true, }), - - [actions.MEDIA_POSITION]: (state: MediaState, action: Action) => { - const { outpoint, position } = action.data; - return { - ...state, - positions: { - ...state.positions, - [outpoint]: position, - }, - }; - }, }, defaultState ); diff --git a/src/renderer/redux/selectors/content.js b/src/renderer/redux/selectors/content.js index 346f044c1..ed73e59fe 100644 --- a/src/renderer/redux/selectors/content.js +++ b/src/renderer/redux/selectors/content.js @@ -1,4 +1,5 @@ import { createSelector } from 'reselect'; +import { makeSelectClaimForUri } from 'lbry-redux'; export const selectState = state => state.content || {}; @@ -29,3 +30,10 @@ export const selectRewardContentClaimIds = createSelector( selectState, state => state.rewardedContentClaimIds ); + +export const makeSelectContentPositionForUri = uri => + createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { + const outpoint = `${claim.txid}:${claim.nout}`; + const id = claim.claim_id; + return state.positions[id] ? state.positions[id][outpoint] : null; + }); diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js index 40a6725e1..a0518307f 100644 --- a/src/renderer/redux/selectors/media.js +++ b/src/renderer/redux/selectors/media.js @@ -1,12 +1,5 @@ import { createSelector } from 'reselect'; -import { makeSelectClaimForUri } from 'lbry-redux'; const selectState = state => state.media || {}; export const selectMediaPaused = createSelector(selectState, state => state.paused); - -export const makeSelectMediaPositionForUri = uri => - createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { - const outpoint = `${claim.txid}:${claim.nout}`; - return state.positions[outpoint] || null; - });