From 503bc76ef14da1e664d9b7c9e0f760836b2f7499 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Sat, 28 Jul 2018 18:30:02 -0400 Subject: [PATCH 01/16] remove unused state.content.currentlyIsPlaying --- src/renderer/redux/reducers/content.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderer/redux/reducers/content.js b/src/renderer/redux/reducers/content.js index e9cbdff99..e5242b599 100644 --- a/src/renderer/redux/reducers/content.js +++ b/src/renderer/redux/reducers/content.js @@ -3,7 +3,6 @@ import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = { playingUri: null, - currentlyIsPlaying: false, rewardedContentClaimIds: [], channelClaimCounts: {}, }; From f1a799374a8920d548ee235ccfce66e04ab400e4 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Tue, 31 Jul 2018 08:36:20 -0400 Subject: [PATCH 02/16] media.positions[outpoint] |> content.positions[claimId][outpoint] --- src/renderer/component/fileViewer/index.js | 15 +++++++-------- .../component/fileViewer/internal/player.jsx | 6 +++++- src/renderer/component/fileViewer/view.jsx | 9 ++++----- src/renderer/constants/action_types.js | 2 +- src/renderer/redux/actions/content.js | 10 ++++++++++ src/renderer/redux/actions/media.js | 15 --------------- src/renderer/redux/reducers/content.js | 15 +++++++++++++++ src/renderer/redux/reducers/media.js | 14 -------------- src/renderer/redux/selectors/content.js | 8 ++++++++ src/renderer/redux/selectors/media.js | 7 ------- 10 files changed, 50 insertions(+), 51 deletions(-) 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; - }); From 82252e69853266edf8eeedd6fb0a349621bf2429 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Tue, 31 Jul 2018 09:29:28 -0400 Subject: [PATCH 03/16] remove media.paused; catch file open pause from change of content.playingUri --- .../component/fileDownloadLink/index.js | 5 ++-- .../component/fileDownloadLink/view.jsx | 7 +++-- src/renderer/component/fileViewer/index.js | 5 ---- .../component/fileViewer/internal/player.jsx | 9 +++---- src/renderer/component/fileViewer/view.jsx | 11 ++------ src/renderer/constants/action_types.js | 7 ----- src/renderer/page/file/index.js | 7 ++--- src/renderer/redux/actions/app.js | 7 ++--- src/renderer/redux/actions/media.js | 13 --------- src/renderer/redux/reducers/media.js | 27 ------------------- src/renderer/redux/selectors/media.js | 5 ---- src/renderer/store.js | 2 -- 12 files changed, 17 insertions(+), 88 deletions(-) delete mode 100644 src/renderer/redux/actions/media.js delete mode 100644 src/renderer/redux/reducers/media.js delete 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 23ed6b3f7..6d4334e01 100644 --- a/src/renderer/component/fileDownloadLink/index.js +++ b/src/renderer/component/fileDownloadLink/index.js @@ -7,8 +7,7 @@ import { makeSelectClaimForUri, } from 'lbry-redux'; import { doOpenFileInShell } from 'redux/actions/file'; -import { doPurchaseUri, doStartDownload } from 'redux/actions/content'; -import { doPause } from 'redux/actions/media'; +import { doPurchaseUri, doStartDownload, doSetPlayingUri } from 'redux/actions/content'; import FileDownloadLink from './view'; const select = (state, props) => ({ @@ -24,7 +23,7 @@ const perform = dispatch => ({ openInShell: path => dispatch(doOpenFileInShell(path)), purchaseUri: uri => dispatch(doPurchaseUri(uri)), restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)), - doPause: () => dispatch(doPause()), + pause: () => dispatch(doSetPlayingUri(null)), }); export default connect( diff --git a/src/renderer/component/fileDownloadLink/view.jsx b/src/renderer/component/fileDownloadLink/view.jsx index bcb352eb2..1ffe15690 100644 --- a/src/renderer/component/fileDownloadLink/view.jsx +++ b/src/renderer/component/fileDownloadLink/view.jsx @@ -22,7 +22,7 @@ type Props = { restartDownload: (string, number) => void, openInShell: string => void, purchaseUri: string => void, - doPause: () => void, + pause: () => void, }; class FileDownloadLink extends React.PureComponent { @@ -50,14 +50,13 @@ class FileDownloadLink extends React.PureComponent { purchaseUri, costInfo, loading, - doPause, - claim, + pause, } = this.props; const openFile = () => { if (fileInfo) { openInShell(fileInfo.download_path); - doPause(); + pause(); } }; diff --git a/src/renderer/component/fileViewer/index.js b/src/renderer/component/fileViewer/index.js index e34786474..005dc45f5 100644 --- a/src/renderer/component/fileViewer/index.js +++ b/src/renderer/component/fileViewer/index.js @@ -3,7 +3,6 @@ import * as settings from 'constants/settings'; import { doChangeVolume } from 'redux/actions/app'; import { selectVolume } from 'redux/selectors/app'; import { doPlayUri, doSetPlayingUri, savePosition } from 'redux/actions/content'; -import { doPlay, doPause } from 'redux/actions/media'; import { makeSelectMetadataForUri, makeSelectContentTypeForUri, @@ -15,7 +14,6 @@ import { selectSearchBarFocused, } from 'lbry-redux'; import { makeSelectClientSetting, selectShowNsfw } from 'redux/selectors/settings'; -import { selectMediaPaused } from 'redux/selectors/media'; import { selectPlayingUri, makeSelectContentPositionForUri } from 'redux/selectors/content'; import { selectFileInfoErrors } from 'redux/selectors/file_info'; import FileViewer from './view'; @@ -31,7 +29,6 @@ const select = (state, props) => ({ playingUri: selectPlayingUri(state), contentType: makeSelectContentTypeForUri(props.uri)(state), volume: selectVolume(state), - mediaPaused: selectMediaPaused(state), playbackPosition: makeSelectContentPositionForUri(props.uri)(state), autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), searchBarFocused: selectSearchBarFocused(state), @@ -42,8 +39,6 @@ const perform = dispatch => ({ play: uri => dispatch(doPlayUri(uri)), cancelPlay: () => dispatch(doSetPlayingUri(null)), changeVolume: volume => dispatch(doChangeVolume(volume)), - doPlay: () => dispatch(doPlay()), - doPause: () => dispatch(doPause()), savePosition: (claimId, outpoint, position) => dispatch(savePosition(claimId, outpoint, position)), }); diff --git a/src/renderer/component/fileViewer/internal/player.jsx b/src/renderer/component/fileViewer/internal/player.jsx index 6f7782c5f..50ba340aa 100644 --- a/src/renderer/component/fileViewer/internal/player.jsx +++ b/src/renderer/component/fileViewer/internal/player.jsx @@ -27,9 +27,11 @@ class MediaPlayer extends React.PureComponent { this.toggleFullScreenVideo = this.toggleFullScreen.bind(this); } - componentWillReceiveProps(nextProps) { + componentDidUpdate(nextProps) { const el = this.refs.media.children[0]; - if (!this.props.paused && nextProps.paused && !el.paused) el.pause(); + if (this.props.playingUri && !nextProps.playingUri && !el.paused) { + el.pause(); + } } componentDidMount() { @@ -87,8 +89,6 @@ class MediaPlayer extends React.PureComponent { const mediaElement = this.media.children[0]; if (mediaElement) { mediaElement.currentTime = position || 0; - mediaElement.addEventListener('play', () => this.props.doPlay()); - mediaElement.addEventListener('pause', () => this.props.doPause()); mediaElement.addEventListener('timeupdate', () => this.props.savePosition( claim.claim_id, @@ -140,7 +140,6 @@ class MediaPlayer extends React.PureComponent { if (mediaElement) { mediaElement.removeEventListener('click', this.togglePlayListener); } - this.props.doPause(); } toggleFullScreen(event) { diff --git a/src/renderer/component/fileViewer/view.jsx b/src/renderer/component/fileViewer/view.jsx index e213092dd..7fa36ffee 100644 --- a/src/renderer/component/fileViewer/view.jsx +++ b/src/renderer/component/fileViewer/view.jsx @@ -34,10 +34,7 @@ type Props = { volume: number, claim: Claim, uri: string, - doPlay: () => void, - doPause: () => void, savePosition: (string, string, number) => void, - mediaPaused: boolean, playbackPosition: ?number, className: ?string, obscureNsfw: boolean, @@ -202,10 +199,7 @@ class FileViewer extends React.PureComponent { volume, claim, uri, - doPlay, - doPause, savePosition, - mediaPaused, playbackPosition, className, obscureNsfw, @@ -237,6 +231,7 @@ class FileViewer extends React.PureComponent {
{isPlaying && (
+

hai

{!isReadyToPlay ? (
@@ -251,13 +246,11 @@ class FileViewer extends React.PureComponent { downloadCompleted={fileInfo.completed} changeVolume={changeVolume} volume={volume} - doPlay={doPlay} - doPause={doPause} savePosition={savePosition} claim={claim} uri={uri} - paused={mediaPaused} position={playbackPosition} + playingUri={playingUri} /> )}
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index 9596eed3e..7cace66ca 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -182,13 +182,6 @@ export const FETCH_SUBSCRIPTIONS_START = 'FETCH_SUBSCRIPTIONS_START'; export const FETCH_SUBSCRIPTIONS_FAIL = 'FETCH_SUBSCRIPTIONS_FAIL'; export const FETCH_SUBSCRIPTIONS_SUCCESS = 'FETCH_SUBSCRIPTIONS_SUCCESS'; -// Video controls -export const SET_VIDEO_PAUSE = 'SET_VIDEO_PAUSE'; - -// Media controls -export const MEDIA_PLAY = 'MEDIA_PLAY'; -export const MEDIA_PAUSE = 'MEDIA_PAUSE'; - // Publishing export const CLEAR_PUBLISH = 'CLEAR_PUBLISH'; export const UPDATE_PUBLISH_FORM = 'UPDATE_PUBLISH_FORM'; diff --git a/src/renderer/page/file/index.js b/src/renderer/page/file/index.js index 99a89e4fd..9799fa4b5 100644 --- a/src/renderer/page/file/index.js +++ b/src/renderer/page/file/index.js @@ -17,7 +17,6 @@ import { } from 'lbry-redux'; import { selectShowNsfw, makeSelectClientSetting } from 'redux/selectors/settings'; import { selectSubscriptions } from 'redux/selectors/subscriptions'; -import { selectMediaPaused } from 'redux/selectors/media'; import { doPrepareEdit } from 'redux/actions/publish'; import FilePage from './view'; @@ -31,7 +30,6 @@ const select = (state, props) => ({ rewardedContentClaimIds: selectRewardContentClaimIds(state, props), subscriptions: selectSubscriptions(state), playingUri: selectPlayingUri(state), - isPaused: selectMediaPaused(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state), autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), }); @@ -46,4 +44,7 @@ const perform = dispatch => ({ setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), }); -export default connect(select, perform)(FilePage); +export default connect( + select, + perform +)(FilePage); diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 7b6e2cc31..1c8337d01 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -16,8 +16,8 @@ import Native from 'native'; import { doFetchRewardedContent } from 'redux/actions/content'; import { doFetchDaemonSettings } from 'redux/actions/settings'; import { doAuthNavigate } from 'redux/actions/navigation'; -import { doPause } from 'redux/actions/media'; -import { doCheckSubscriptionsInit } from 'redux/actions/subscriptions'; +import { doAuthenticate } from 'redux/actions/user'; +import { doCheckSubscriptions } from 'redux/actions/subscriptions'; import { selectIsUpgradeSkipped, selectUpdateUrl, @@ -109,9 +109,6 @@ export function doDownloadUpgradeRequested() { return (dispatch, getState) => { const state = getState(); - // Pause video if needed - dispatch(doPause()); - const autoUpdateDeclined = selectAutoUpdateDeclined(state); if (['win32', 'darwin'].includes(process.platform)) { diff --git a/src/renderer/redux/actions/media.js b/src/renderer/redux/actions/media.js deleted file mode 100644 index 99f297c5d..000000000 --- a/src/renderer/redux/actions/media.js +++ /dev/null @@ -1,13 +0,0 @@ -// @flow -import * as actions from 'constants/action_types'; -import type { Dispatch } from 'redux/reducers/media'; - -export const doPlay = () => (dispatch: Dispatch) => - dispatch({ - type: actions.MEDIA_PLAY, - }); - -export const doPause = () => (dispatch: Dispatch) => - dispatch({ - type: actions.MEDIA_PAUSE, - }); diff --git a/src/renderer/redux/reducers/media.js b/src/renderer/redux/reducers/media.js deleted file mode 100644 index 981820a27..000000000 --- a/src/renderer/redux/reducers/media.js +++ /dev/null @@ -1,27 +0,0 @@ -// @flow -import * as actions from 'constants/action_types'; -import { handleActions } from 'util/redux-utils'; - -export type MediaState = { - paused: Boolean, -}; - -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, - }), - }, - defaultState -); diff --git a/src/renderer/redux/selectors/media.js b/src/renderer/redux/selectors/media.js deleted file mode 100644 index a0518307f..000000000 --- a/src/renderer/redux/selectors/media.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createSelector } from 'reselect'; - -const selectState = state => state.media || {}; - -export const selectMediaPaused = createSelector(selectState, state => state.paused); diff --git a/src/renderer/store.js b/src/renderer/store.js index 690387ffe..ba2f25b86 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -17,7 +17,6 @@ import settingsReducer from 'redux/reducers/settings'; import userReducer from 'redux/reducers/user'; import shapeShiftReducer from 'redux/reducers/shape_shift'; import subscriptionsReducer from 'redux/reducers/subscriptions'; -import mediaReducer from 'redux/reducers/media'; import publishReducer from 'redux/reducers/publish'; import { persistStore, autoRehydrate } from 'redux-persist'; import createCompressor from 'redux-persist-transform-compress'; @@ -69,7 +68,6 @@ const reducers = combineReducers({ user: userReducer, shapeShift: shapeShiftReducer, subscriptions: subscriptionsReducer, - media: mediaReducer, publish: publishReducer, notifications: notificationsReducer, blacklist: blacklistReducer, From 287f1ac6567128708c4efe059f077f635df5d73a Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Tue, 31 Jul 2018 09:56:54 -0400 Subject: [PATCH 04/16] add refresh icon to when playback position exists --- src/renderer/component/fileCard/index.js | 6 +++++- src/renderer/component/fileCard/view.jsx | 3 +++ src/renderer/redux/selectors/content.js | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/renderer/component/fileCard/index.js b/src/renderer/component/fileCard/index.js index 3754e3ffa..d210993d4 100644 --- a/src/renderer/component/fileCard/index.js +++ b/src/renderer/component/fileCard/index.js @@ -8,7 +8,10 @@ import { makeSelectClaimIsMine, } from 'lbry-redux'; import { doNavigate } from 'redux/actions/navigation'; -import { selectRewardContentClaimIds } from 'redux/selectors/content'; +import { + selectRewardContentClaimIds, + makeSelectContentPositionForUri, +} from 'redux/selectors/content'; import { selectShowNsfw } from 'redux/selectors/settings'; import { selectPendingPublish } from 'redux/selectors/publish'; import FileCard from './view'; @@ -32,6 +35,7 @@ const select = (state, props) => { rewardedContentClaimIds: selectRewardContentClaimIds(state, props), ...fileCardInfo, pending: !!pendingPublish, + position: makeSelectContentPositionForUri(props.uri)(state), }; }; diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index f8dd8582c..ad95f0053 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -23,6 +23,7 @@ type Props = { claimIsMine: boolean, showPrice: boolean, pending?: boolean, + position: ?number, /* eslint-disable react/no-unused-prop-types */ resolveUri: string => void, isResolvingUri: boolean, @@ -61,6 +62,7 @@ class FileCard extends React.PureComponent { claimIsMine, showPrice, pending, + position, } = this.props; const shouldHide = !claimIsMine && !pending && obscureNsfw && metadata && metadata.nsfw; @@ -103,6 +105,7 @@ class FileCard extends React.PureComponent { {showPrice && } {isRewardContent && } {fileInfo && } + {position && }
diff --git a/src/renderer/redux/selectors/content.js b/src/renderer/redux/selectors/content.js index ed73e59fe..0811f8e42 100644 --- a/src/renderer/redux/selectors/content.js +++ b/src/renderer/redux/selectors/content.js @@ -33,6 +33,9 @@ export const selectRewardContentClaimIds = createSelector( export const makeSelectContentPositionForUri = uri => createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { + if (!claim) { + return null; + } const outpoint = `${claim.txid}:${claim.nout}`; const id = claim.claim_id; return state.positions[id] ? state.positions[id][outpoint] : null; From 58ed68d8c3f78c7e5a867d74f9b56a2f8ad97b21 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Tue, 31 Jul 2018 14:06:50 -0400 Subject: [PATCH 05/16] position tracking clean up --- src/renderer/component/fileViewer/index.js | 2 +- src/renderer/component/fileViewer/internal/player.jsx | 4 +++- src/renderer/component/fileViewer/view.jsx | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/renderer/component/fileViewer/index.js b/src/renderer/component/fileViewer/index.js index 005dc45f5..1ee003ee7 100644 --- a/src/renderer/component/fileViewer/index.js +++ b/src/renderer/component/fileViewer/index.js @@ -29,7 +29,7 @@ const select = (state, props) => ({ playingUri: selectPlayingUri(state), contentType: makeSelectContentTypeForUri(props.uri)(state), volume: selectVolume(state), - playbackPosition: makeSelectContentPositionForUri(props.uri)(state), + position: makeSelectContentPositionForUri(props.uri)(state), autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), searchBarFocused: selectSearchBarFocused(state), fileInfoErrors: selectFileInfoErrors(state), diff --git a/src/renderer/component/fileViewer/internal/player.jsx b/src/renderer/component/fileViewer/internal/player.jsx index 50ba340aa..10b47fd0e 100644 --- a/src/renderer/component/fileViewer/internal/player.jsx +++ b/src/renderer/component/fileViewer/internal/player.jsx @@ -88,7 +88,9 @@ class MediaPlayer extends React.PureComponent { document.addEventListener('keydown', this.togglePlayListener); const mediaElement = this.media.children[0]; if (mediaElement) { - mediaElement.currentTime = position || 0; + if (position) { + mediaElement.currentTime = position; + } mediaElement.addEventListener('timeupdate', () => this.props.savePosition( claim.claim_id, diff --git a/src/renderer/component/fileViewer/view.jsx b/src/renderer/component/fileViewer/view.jsx index 7fa36ffee..1e226ef5e 100644 --- a/src/renderer/component/fileViewer/view.jsx +++ b/src/renderer/component/fileViewer/view.jsx @@ -35,7 +35,7 @@ type Props = { claim: Claim, uri: string, savePosition: (string, string, number) => void, - playbackPosition: ?number, + position: ?number, className: ?string, obscureNsfw: boolean, play: string => void, @@ -200,7 +200,7 @@ class FileViewer extends React.PureComponent { claim, uri, savePosition, - playbackPosition, + position, className, obscureNsfw, mediaType, @@ -249,7 +249,7 @@ class FileViewer extends React.PureComponent { savePosition={savePosition} claim={claim} uri={uri} - position={playbackPosition} + position={position} playingUri={playingUri} /> )} From 5cd7794fa03ba3f792ee8eeccb2c24166253d434 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Tue, 31 Jul 2018 14:07:45 -0400 Subject: [PATCH 06/16] record browsing history, persist content --- src/renderer/component/fileViewer/view.jsx | 1 - src/renderer/constants/action_types.js | 5 +++- src/renderer/constants/content.js | 1 + src/renderer/page/file/index.js | 2 ++ src/renderer/page/file/view.jsx | 9 ++++---- src/renderer/redux/actions/content.js | 24 +++++++++++++++++++ src/renderer/redux/reducers/content.js | 27 ++++++++++++++++++++++ src/renderer/redux/selectors/content.js | 9 ++++++++ src/renderer/store.js | 5 ++-- 9 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 src/renderer/constants/content.js diff --git a/src/renderer/component/fileViewer/view.jsx b/src/renderer/component/fileViewer/view.jsx index 1e226ef5e..2062fd7df 100644 --- a/src/renderer/component/fileViewer/view.jsx +++ b/src/renderer/component/fileViewer/view.jsx @@ -231,7 +231,6 @@ class FileViewer extends React.PureComponent {
{isPlaying && (
-

hai

{!isReadyToPlay ? (
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index 7cace66ca..d97032bc6 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -73,8 +73,11 @@ export const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; 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_PLAYING_URI = 'SET_PLAYING_URI'; export const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; +export const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED'; +export const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI'; +export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; diff --git a/src/renderer/constants/content.js b/src/renderer/constants/content.js new file mode 100644 index 000000000..31a776af2 --- /dev/null +++ b/src/renderer/constants/content.js @@ -0,0 +1 @@ +export const HISTORY_ITEMS_PER_PAGE = 30; diff --git a/src/renderer/page/file/index.js b/src/renderer/page/file/index.js index 9799fa4b5..1870c9f9f 100644 --- a/src/renderer/page/file/index.js +++ b/src/renderer/page/file/index.js @@ -4,6 +4,7 @@ import { doNavigate } from 'redux/actions/navigation'; import { selectRewardContentClaimIds, selectPlayingUri } from 'redux/selectors/content'; import { doCheckSubscription } from 'redux/actions/subscriptions'; import { doSetClientSetting } from 'redux/actions/settings'; +import { doSetContentHistoryItem } from 'redux/actions/content'; import { doFetchFileInfo, doFetchCostInfoForUri, @@ -42,6 +43,7 @@ const perform = dispatch => ({ openModal: (modal, props) => dispatch(doNotify(modal, props)), prepareEdit: (publishData, uri) => dispatch(doPrepareEdit(publishData, uri)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), + setViewed: uri => dispatch(doSetContentHistoryItem(uri)), }); export default connect( diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index da35a01d1..ad3a133e7 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -46,8 +46,7 @@ type Props = { prepareEdit: ({}, string) => void, checkSubscription: (uri: string) => void, subscriptions: Array, - setClientSetting: (string, boolean | string) => void, - autoplay: boolean, + setViewed: string => void, }; class FilePage extends React.Component { @@ -71,7 +70,7 @@ class FilePage extends React.Component { } componentDidMount() { - const { uri, fileInfo, fetchFileInfo, fetchCostInfo } = this.props; + const { uri, fileInfo, fetchFileInfo, fetchCostInfo, setViewed } = this.props; if (fileInfo === undefined) { fetchFileInfo(uri); @@ -81,6 +80,8 @@ class FilePage extends React.Component { fetchCostInfo(uri); this.checkSubscription(this.props); + + setViewed(uri); } componentWillReceiveProps(nextProps: Props) { @@ -129,7 +130,7 @@ class FilePage extends React.Component { const { title, thumbnail } = metadata; const { height, channel_name: channelName, value } = claim; const { PLAYABLE_MEDIA_TYPES, PREVIEW_MEDIA_TYPES } = FilePage; - const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); + const isRewardContent = (rewardedContentClaimIds || []).includes(claim.claim_id); const shouldObscureThumbnail = obscureNsfw && metadata.nsfw; const fileName = fileInfo ? fileInfo.file_name : null; const mediaType = getMediaType(contentType, fileName); diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index 2fd51a748..e9d98817f 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -504,3 +504,27 @@ export function savePosition(claimId: string, outpoint: string, position: number }); }; } + +export function doSetContentHistoryItem(uri: string) { + return dispatch => { + dispatch({ + type: ACTIONS.SET_CONTENT_LAST_VIEWED, + data: { uri, lastViewed: Date.now() }, + }); + }; +} + +export function doClearContentHistoryUri(uri: string) { + return dispatch => { + dispatch({ + type: ACTIONS.CLEAR_CONTENT_HISTORY_URI, + data: { uri }, + }); + }; +} + +export function doSetContentHistoryAll() { + return dispatch => { + dispatch({ type: ACTIONS.CLEAR_CONTENT_HISTORY_ALL }); + }; +} diff --git a/src/renderer/redux/reducers/content.js b/src/renderer/redux/reducers/content.js index 3a760515a..0b96be940 100644 --- a/src/renderer/redux/reducers/content.js +++ b/src/renderer/redux/reducers/content.js @@ -6,6 +6,7 @@ const defaultState = { rewardedContentClaimIds: [], channelClaimCounts: {}, positions: {}, + history: [], }; reducers[ACTIONS.FETCH_FEATURED_CONTENT_STARTED] = state => @@ -94,6 +95,32 @@ reducers[ACTIONS.SET_CONTENT_POSITION] = (state, action) => { }; }; +reducers[ACTIONS.SET_CONTENT_LAST_VIEWED] = (state, action) => { + const { uri, lastViewed } = action.data; + const { history } = state; + const historyObj = { uri, lastViewed }; + const index = history.findIndex(i => i.uri === uri); + const newHistory = + index === -1 + ? [historyObj].concat(history) + : [historyObj].concat(history.slice(0, index), history.slice(index + 1)); + return { ...state, history: [...newHistory] }; +}; + +reducers[ACTIONS.CLEAR_CONTENT_HISTORY_URI] = (state, action) => { + const { uri } = action.data; + const { history } = state; + const index = history.findIndex(i => i.uri === uri); + return index === -1 + ? state + : { + ...state, + history: history.slice(0, index).concat(history.slice(index + 1)), + }; +}; + +reducers[ACTIONS.CLEAR_CONTENT_HISTORY_ALL] = state => ({ ...state, history: [] }); + export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/renderer/redux/selectors/content.js b/src/renderer/redux/selectors/content.js index 0811f8e42..0f77fc811 100644 --- a/src/renderer/redux/selectors/content.js +++ b/src/renderer/redux/selectors/content.js @@ -1,5 +1,6 @@ import { createSelector } from 'reselect'; import { makeSelectClaimForUri } from 'lbry-redux'; +import { HISTORY_ITEMS_PER_PAGE } from 'constants/content'; export const selectState = state => state.content || {}; @@ -40,3 +41,11 @@ export const makeSelectContentPositionForUri = uri => const id = claim.claim_id; return state.positions[id] ? state.positions[id][outpoint] : null; }); + +export const makeSelectHistoryForPage = (page = 1) => + createSelector(selectState, state => + state.history.slice((page - 1) * HISTORY_ITEMS_PER_PAGE, HISTORY_ITEMS_PER_PAGE) + ); + +export const makeSelectHistoryForUri = uri => + createSelector(selectState, state => state.history.find(i => i.uri === uri)); diff --git a/src/renderer/store.js b/src/renderer/store.js index ba2f25b86..37cbd6cf0 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -100,15 +100,16 @@ const store = createStore( const compressor = createCompressor(); const saveClaimsFilter = createFilter('claims', ['byId', 'claimsByUri']); const subscriptionsFilter = createFilter('subscriptions', ['subscriptions']); +const contentFilter = createFilter('content', ['positions', 'history']); // We only need to persist the receiveAddress for the wallet const walletFilter = createFilter('wallet', ['receiveAddress']); const persistOptions = { - whitelist: ['claims', 'subscriptions', 'publish', 'wallet'], + whitelist: ['claims', 'subscriptions', 'publish', 'wallet', 'content'], // Order is important. Needs to be compressed last or other transforms can't // read the data - transforms: [saveClaimsFilter, subscriptionsFilter, walletFilter, compressor], + transforms: [saveClaimsFilter, subscriptionsFilter, walletFilter, contentFilter, compressor], debounce: 10000, storage: localForage, }; From 86a40eacbcc71f3e640a5fab3e3b1c1ce32809cf Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Wed, 1 Aug 2018 10:06:43 -0400 Subject: [PATCH 07/16] add UserHistoryPage --- src/renderer/component/router/view.jsx | 2 + src/renderer/page/userHistory/index.js | 24 +++++++ src/renderer/page/userHistory/view.jsx | 91 +++++++++++++++++++++++++ src/renderer/redux/actions/content.js | 11 ++- src/renderer/redux/selectors/content.js | 13 ++-- 5 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 src/renderer/page/userHistory/index.js create mode 100644 src/renderer/page/userHistory/view.jsx diff --git a/src/renderer/component/router/view.jsx b/src/renderer/component/router/view.jsx index fa1a0fea3..c6cb09026 100644 --- a/src/renderer/component/router/view.jsx +++ b/src/renderer/component/router/view.jsx @@ -18,6 +18,7 @@ import InvitePage from 'page/invite'; import BackupPage from 'page/backup'; import SubscriptionsPage from 'page/subscriptions'; import SearchPage from 'page/search'; +import UserHistoryPage from 'page/userHistory'; const route = (props, page, routesMap) => { const component = routesMap[page]; @@ -53,6 +54,7 @@ const Router = props => { wallet: , subscriptions: , search: , + user_history: , }); }; diff --git a/src/renderer/page/userHistory/index.js b/src/renderer/page/userHistory/index.js new file mode 100644 index 000000000..a922bb58c --- /dev/null +++ b/src/renderer/page/userHistory/index.js @@ -0,0 +1,24 @@ +import { connect } from 'react-redux'; +import { selectHistoryPageCount, makeSelectHistoryForPage } from 'redux/selectors/content'; +import { doNavigate } from 'redux/actions/navigation'; +import { selectCurrentParams, makeSelectCurrentParam } from 'lbry-redux'; +import UserHistoryPage from './view'; + +const select = state => { + const paramPage = makeSelectCurrentParam('page')(state) || 0; + return { + pageCount: selectHistoryPageCount(state), + page: paramPage, + params: selectCurrentParams(state), + history: makeSelectHistoryForPage(paramPage)(state), + }; +}; + +const perform = dispatch => ({ + navigate: (path, params) => dispatch(doNavigate(path, params)), +}); + +export default connect( + select, + perform +)(UserHistoryPage); diff --git a/src/renderer/page/userHistory/view.jsx b/src/renderer/page/userHistory/view.jsx new file mode 100644 index 000000000..13b9efc50 --- /dev/null +++ b/src/renderer/page/userHistory/view.jsx @@ -0,0 +1,91 @@ +// @flow +import React from 'react'; +import FileCard from 'component/fileCard'; +import Page from 'component/page'; +import Button from 'component/button'; +import { FormField, FormRow } from 'component/common/form'; +import ReactPaginate from 'react-paginate'; + +type HistoryItem = { + uri: string, + lastViewed: number, +}; + +type Props = { + history: Array, + page: number, + pageCount: number, + navigate: string => void, + params: { page: number }, +}; + +class UserHistoryPage extends React.PureComponent { + changePage(pageNumber: number) { + const { params } = this.props; + const newParams = { ...params, page: pageNumber }; + this.props.navigate('/user_history', newParams); + } + + paginate(e: SyntheticKeyboardEvent<*>) { + const pageFromInput = Number(e.currentTarget.value); + if ( + pageFromInput && + e.keyCode === 13 && + !Number.isNaN(pageFromInput) && + pageFromInput > 0 && + pageFromInput <= this.props.pageCount + ) { + this.changePage(pageFromInput); + } + } + + render() { + const { history, page, pageCount, navigate } = this.props; + + return ( + +
+ {history && history.length ? ( + + {history.map(item => )} + {pageCount > 1 && ( + + this.changePage(e.selected)} + forcePage={page} + initialPage={page} + containerClassName="pagination" + /> + + this.paginate(e)} + prefix={__('Go to page:')} + type="text" + /> + + )} + + ) : ( +

+ {__('You have no saved history. Go')}{' '} +

+
+ ); + } +} +export default UserHistoryPage; diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index e9d98817f..b8073d820 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -523,8 +523,17 @@ export function doClearContentHistoryUri(uri: string) { }; } -export function doSetContentHistoryAll() { +export function doClearContentHistoryAll() { return dispatch => { dispatch({ type: ACTIONS.CLEAR_CONTENT_HISTORY_ALL }); }; } + +export function doSetHistoryPage(page) { + return dispatch => { + dispatch({ + type: ACTIONS.SET_CONTENT_HISTORY_PAGE, + data: { page }, + }); + }; +} diff --git a/src/renderer/redux/selectors/content.js b/src/renderer/redux/selectors/content.js index 0f77fc811..8c8c11fbe 100644 --- a/src/renderer/redux/selectors/content.js +++ b/src/renderer/redux/selectors/content.js @@ -42,10 +42,15 @@ export const makeSelectContentPositionForUri = uri => return state.positions[id] ? state.positions[id][outpoint] : null; }); -export const makeSelectHistoryForPage = (page = 1) => - createSelector(selectState, state => - state.history.slice((page - 1) * HISTORY_ITEMS_PER_PAGE, HISTORY_ITEMS_PER_PAGE) - ); +export const selectHistoryPageCount = createSelector(selectState, state => + Math.ceil(state.history.length / HISTORY_ITEMS_PER_PAGE) +); + +export const makeSelectHistoryForPage = page => + createSelector(selectState, state => { + const left = page * HISTORY_ITEMS_PER_PAGE; + return state.history.slice(left, left + HISTORY_ITEMS_PER_PAGE); + }); export const makeSelectHistoryForUri = uri => createSelector(selectState, state => state.history.find(i => i.uri === uri)); From 9bd0a32b99226cacd4f2e92d1a7edf07a7bc40ec Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Wed, 1 Aug 2018 10:45:13 -0400 Subject: [PATCH 08/16] add lastViewed prop to --- src/renderer/component/fileCard/view.jsx | 6 ++++++ src/renderer/page/userHistory/view.jsx | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index ad95f0053..7d235d19f 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -1,5 +1,6 @@ // @flow import * as React from 'react'; +import moment from 'moment'; import { normalizeURI, convertToShareLink } from 'lbry-redux'; import type { Claim, Metadata } from 'types/claim'; import CardMedia from 'component/cardMedia'; @@ -24,6 +25,7 @@ type Props = { showPrice: boolean, pending?: boolean, position: ?number, + lastViewed: ?number, /* eslint-disable react/no-unused-prop-types */ resolveUri: string => void, isResolvingUri: boolean, @@ -63,6 +65,7 @@ class FileCard extends React.PureComponent { showPrice, pending, position, + lastViewed, } = this.props; const shouldHide = !claimIsMine && !pending && obscureNsfw && metadata && metadata.nsfw; @@ -107,6 +110,9 @@ class FileCard extends React.PureComponent { {fileInfo && } {position && }
+ {lastViewed && ( +
{moment(lastViewed).from(moment())}
+ )}
); diff --git a/src/renderer/page/userHistory/view.jsx b/src/renderer/page/userHistory/view.jsx index 13b9efc50..ed5a32a11 100644 --- a/src/renderer/page/userHistory/view.jsx +++ b/src/renderer/page/userHistory/view.jsx @@ -47,7 +47,9 @@ class UserHistoryPage extends React.PureComponent {
{history && history.length ? ( - {history.map(item => )} + {history.map(item => ( + + ))} {pageCount > 1 && ( Date: Wed, 1 Aug 2018 12:25:13 -0400 Subject: [PATCH 09/16] fix type error --- src/renderer/page/userHistory/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/page/userHistory/index.js b/src/renderer/page/userHistory/index.js index a922bb58c..d58148b7f 100644 --- a/src/renderer/page/userHistory/index.js +++ b/src/renderer/page/userHistory/index.js @@ -5,7 +5,7 @@ import { selectCurrentParams, makeSelectCurrentParam } from 'lbry-redux'; import UserHistoryPage from './view'; const select = state => { - const paramPage = makeSelectCurrentParam('page')(state) || 0; + const paramPage = Number(makeSelectCurrentParam('page')(state) || 0); return { pageCount: selectHistoryPageCount(state), page: paramPage, From 00c488799f0b873471ac1ba00d285ab15b139cc7 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Wed, 1 Aug 2018 15:33:22 -0400 Subject: [PATCH 10/16] add delete icons to --- src/renderer/component/fileCard/index.js | 2 ++ src/renderer/component/fileCard/view.jsx | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/renderer/component/fileCard/index.js b/src/renderer/component/fileCard/index.js index d210993d4..74017f40e 100644 --- a/src/renderer/component/fileCard/index.js +++ b/src/renderer/component/fileCard/index.js @@ -12,6 +12,7 @@ import { selectRewardContentClaimIds, makeSelectContentPositionForUri, } from 'redux/selectors/content'; +import { doClearContentHistoryUri } from 'redux/actions/content'; import { selectShowNsfw } from 'redux/selectors/settings'; import { selectPendingPublish } from 'redux/selectors/publish'; import FileCard from './view'; @@ -42,6 +43,7 @@ const select = (state, props) => { const perform = dispatch => ({ navigate: (path, params) => dispatch(doNavigate(path, params)), resolveUri: uri => dispatch(doResolveUri(uri)), + clearHistoryUri: uri => dispatch(doClearContentHistoryUri(uri)), }); export default connect( diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index 7d235d19f..16f2c3127 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -6,7 +6,6 @@ import type { Claim, Metadata } from 'types/claim'; import CardMedia from 'component/cardMedia'; import TruncatedText from 'component/common/truncated-text'; import Icon from 'component/common/icon'; -import FilePrice from 'component/filePrice'; import UriIndicator from 'component/uriIndicator'; import * as icons from 'constants/icons'; import classnames from 'classnames'; @@ -22,10 +21,10 @@ type Props = { rewardedContentClaimIds: Array, obscureNsfw: boolean, claimIsMine: boolean, - showPrice: boolean, pending?: boolean, position: ?number, lastViewed: ?number, + clearHistoryUri: string => void, /* eslint-disable react/no-unused-prop-types */ resolveUri: string => void, isResolvingUri: boolean, @@ -62,10 +61,10 @@ class FileCard extends React.PureComponent { rewardedContentClaimIds, obscureNsfw, claimIsMine, - showPrice, pending, position, lastViewed, + clearHistoryUri, } = this.props; const shouldHide = !claimIsMine && !pending && obscureNsfw && metadata && metadata.nsfw; @@ -111,7 +110,18 @@ class FileCard extends React.PureComponent { {position && }
{lastViewed && ( -
{moment(lastViewed).from(moment())}
+
+ {moment(lastViewed).from(moment())} + {position && } + { + e.stopPropagation(); + clearHistoryUri(uri); + }} + > + + +
)}
From fab8e478016efe0acb4a9ac1fb4ceb852a2aed17 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 29 Aug 2018 23:28:53 -0400 Subject: [PATCH 11/16] rebase --- package.json | 2 +- src/renderer/component/fileCard/view.jsx | 4 +++- src/renderer/redux/actions/app.js | 3 +-- yarn.lock | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f34b0e865..261c816c2 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "formik": "^0.10.4", "hast-util-sanitize": "^1.1.2", "keytar": "^4.2.1", - "lbry-redux": "lbryio/lbry-redux#421321a78397251589e5a890f4caa95e79975e2b", + "lbry-redux": "lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c", "localforage": "^1.7.1", "mammoth": "^1.4.6", "mime": "^2.3.1", diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index 16f2c3127..126ba83bf 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -9,7 +9,8 @@ import Icon from 'component/common/icon'; import UriIndicator from 'component/uriIndicator'; import * as icons from 'constants/icons'; import classnames from 'classnames'; -import { openCopyLinkMenu } from '../../util/contextMenu'; +import FilePrice from 'component/filePrice'; +import { openCopyLinkMenu } from 'util/contextMenu'; // TODO: iron these out type Props = { @@ -65,6 +66,7 @@ class FileCard extends React.PureComponent { position, lastViewed, clearHistoryUri, + showPrice, } = this.props; const shouldHide = !claimIsMine && !pending && obscureNsfw && metadata && metadata.nsfw; diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 1c8337d01..afb7bf13e 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -17,7 +17,7 @@ import { doFetchRewardedContent } from 'redux/actions/content'; import { doFetchDaemonSettings } from 'redux/actions/settings'; import { doAuthNavigate } from 'redux/actions/navigation'; import { doAuthenticate } from 'redux/actions/user'; -import { doCheckSubscriptions } from 'redux/actions/subscriptions'; +import { doCheckSubscriptionsInit } from 'redux/actions/subscriptions'; import { selectIsUpgradeSkipped, selectUpdateUrl, @@ -28,7 +28,6 @@ import { selectRemoteVersion, selectUpgradeTimer, } from 'redux/selectors/app'; -import { doAuthenticate } from 'redux/actions/user'; import { lbrySettings as config } from 'package.json'; const { autoUpdater } = remote.require('electron-updater'); diff --git a/yarn.lock b/yarn.lock index db1f53c7d..149175414 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5655,9 +5655,9 @@ lazy-val@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc" -lbry-redux@lbryio/lbry-redux#eae0d134d92d83f733b85a8ecebf529a6e9799cf: +lbry-redux@lbryio/lbry-redux#d1cee82af119c0c5f98ec27f94b2e7f61e34b54c: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/eae0d134d92d83f733b85a8ecebf529a6e9799cf" + resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/d1cee82af119c0c5f98ec27f94b2e7f61e34b54c" dependencies: proxy-polyfill "0.1.6" reselect "^3.0.0" From 625a9177ee95a401f4acf9755a0fad2195fbbe41 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 29 Aug 2018 23:35:49 -0400 Subject: [PATCH 12/16] add back stuff I shouldn't have deleted --- src/renderer/component/fileViewer/index.js | 2 ++ src/renderer/component/fileViewer/view.jsx | 1 + 2 files changed, 3 insertions(+) diff --git a/src/renderer/component/fileViewer/index.js b/src/renderer/component/fileViewer/index.js index 1ee003ee7..3dca7eb02 100644 --- a/src/renderer/component/fileViewer/index.js +++ b/src/renderer/component/fileViewer/index.js @@ -13,6 +13,7 @@ import { makeSelectDownloadingForUri, selectSearchBarFocused, } from 'lbry-redux'; +import { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards'; import { makeSelectClientSetting, selectShowNsfw } from 'redux/selectors/settings'; import { selectPlayingUri, makeSelectContentPositionForUri } from 'redux/selectors/content'; import { selectFileInfoErrors } from 'redux/selectors/file_info'; @@ -39,6 +40,7 @@ const perform = dispatch => ({ play: uri => dispatch(doPlayUri(uri)), cancelPlay: () => dispatch(doSetPlayingUri(null)), changeVolume: volume => dispatch(doChangeVolume(volume)), + claimRewards: () => dispatch(doClaimEligiblePurchaseRewards()), savePosition: (claimId, outpoint, position) => dispatch(savePosition(claimId, outpoint, position)), }); diff --git a/src/renderer/component/fileViewer/view.jsx b/src/renderer/component/fileViewer/view.jsx index 2062fd7df..21451e123 100644 --- a/src/renderer/component/fileViewer/view.jsx +++ b/src/renderer/component/fileViewer/view.jsx @@ -249,6 +249,7 @@ class FileViewer extends React.PureComponent { claim={claim} uri={uri} position={position} + startedPlayingCb={this.startedPlayingCb} playingUri={playingUri} /> )} From d01b893a68e757e29c6d97802fc9f817f7689137 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 30 Aug 2018 01:11:05 -0400 Subject: [PATCH 13/16] add UserHistory component --- .../common/form-components/form-field.jsx | 4 +- src/renderer/component/fileCard/index.js | 1 - src/renderer/component/fileCard/view.jsx | 15 -- src/renderer/component/userHistory/index.js | 27 ++++ src/renderer/component/userHistory/view.jsx | 149 ++++++++++++++++++ .../component/userHistoryItem/index.js | 9 ++ .../component/userHistoryItem/view.jsx | 53 +++++++ src/renderer/page/file/view.jsx | 4 + src/renderer/page/userHistory/index.js | 22 +-- src/renderer/page/userHistory/view.jsx | 84 +--------- src/renderer/redux/reducers/navigation.js | 2 +- src/renderer/redux/selectors/content.js | 20 ++- src/renderer/scss/component/_table.scss | 31 +++- 13 files changed, 295 insertions(+), 126 deletions(-) create mode 100644 src/renderer/component/userHistory/index.js create mode 100644 src/renderer/component/userHistory/view.jsx create mode 100644 src/renderer/component/userHistoryItem/index.js create mode 100644 src/renderer/component/userHistoryItem/view.jsx diff --git a/src/renderer/component/common/form-components/form-field.jsx b/src/renderer/component/common/form-components/form-field.jsx index a38722d94..52c1003dc 100644 --- a/src/renderer/component/common/form-components/form-field.jsx +++ b/src/renderer/component/common/form-components/form-field.jsx @@ -76,8 +76,8 @@ export class FormField extends React.PureComponent { ); } else if (type === 'textarea') { input =