From 7296800ce0683adb94ad8584903e25b8b20321fc Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Mon, 5 Mar 2018 16:28:11 -0800 Subject: [PATCH 1/8] Add most recent latest video to subscription state --- src/renderer/constants/action_types.js | 1 + src/renderer/redux/actions/content.js | 9 +++++++++ src/renderer/redux/actions/subscriptions.js | 11 +++++++++++ src/renderer/redux/reducers/subscriptions.js | 18 +++++++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index df8cf1407..ffc20b6bb 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -164,6 +164,7 @@ export const CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; export const HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS'; +export const SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST'; // Video controls export const SET_VIDEO_PAUSE = 'SET_VIDEO_PAUSE'; diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index 2ca2c4dbb..263470103 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -7,6 +7,7 @@ import Lbryio from 'lbryio'; import { normalizeURI, buildURI } from 'lbryURI'; import { doAlertError, doOpenModal } from 'redux/actions/app'; import { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards'; +import { setSubscriptionLatest } from 'redux/actions/subscriptions'; import { selectBadgeNumber } from 'redux/selectors/app'; import { selectMyClaimsRaw } from 'redux/selectors/claims'; import { selectResolvingUris } from 'redux/selectors/content'; @@ -358,6 +359,14 @@ export function doFetchClaimsByChannel(uri, page) { const claimResult = result[uri] || {}; const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; + if(claimResult && claimResult.claims_in_channel && claimResult.claims_in_channel.length) { + let latest = claimResult.claims_in_channel[0]; + dispatch(setSubscriptionLatest({ + channelName: latest.channel_name, + uri: `${latest.channel_name}#${latest.value.publisherSignature.certificateId}` + }, `${latest.name}#${latest.claim_id}`)); + } + dispatch({ type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, data: { diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index e3eb939ed..55632c785 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -14,5 +14,16 @@ export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: D data: subscription, }); +export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (dispatch: Dispatch) => +{ + return dispatch({ + type: ACTIONS.SET_SUBSCRIPTION_LATEST, + data: { + subscription, + uri + } + }) +}; + export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) => dispatch({ type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS }); diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js index f7a846ffc..e821b5854 100644 --- a/src/renderer/redux/reducers/subscriptions.js +++ b/src/renderer/redux/reducers/subscriptions.js @@ -5,6 +5,7 @@ import { handleActions } from 'util/redux-utils'; export type Subscription = { channelName: string, uri: string, + latest: ?string }; // Subscription redux types @@ -28,7 +29,15 @@ type HasFetchedSubscriptions = { type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS, }; -export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions; +type setSubscriptionLatest = { + type: ACTIONS.SET_SUBSCRIPTION_LATEST, + data: { + subscription: Subscription, + uri: string + } +} + +export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions | setSubscriptionLatest; export type Dispatch = (action: Action) => any; const defaultState = { @@ -70,6 +79,13 @@ export default handleActions( ...state, hasFetchedSubscriptions: true, }), + [ACTIONS.SET_SUBSCRIPTION_LATEST]: ( + state: SubscriptionState, + action: setSubscriptionLatest + ): SubscriptionState => ({ + ...state, + subscriptions: state.subscriptions.map(subscription => subscription.channelName === action.data.subscription.channelName ? {...subscription, latest: action.data.uri} : subscription) + }) }, defaultState ); -- 2.45.3 From c3dd7f34496dd0cf7c9ad352edecee853d9ff00f Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Mon, 5 Mar 2018 23:44:36 -0800 Subject: [PATCH 2/8] Added notifications and downloading upon detecting to subscription items --- src/renderer/constants/action_types.js | 3 ++ src/renderer/redux/actions/app.js | 2 + src/renderer/redux/actions/content.js | 8 +-- src/renderer/redux/actions/subscriptions.js | 52 +++++++++++++++++++- src/renderer/redux/reducers/subscriptions.js | 10 +++- 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index ffc20b6bb..584fa7a47 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -165,6 +165,9 @@ export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; export const HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS'; export const SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST'; +export const CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED'; +export const CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED'; +export const CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE'; // Video controls export const SET_VIDEO_PAUSE = 'SET_VIDEO_PAUSE'; diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 08009c896..f8f6cecdc 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -11,6 +11,7 @@ import { doFetchDaemonSettings } from 'redux/actions/settings'; import { doAuthenticate } from 'redux/actions/user'; import { doBalanceSubscribe } from 'redux/actions/wallet'; import { doPause } from 'redux/actions/media'; +import { doCheckSubscriptions } from 'redux/actions/subscriptions'; import { selectCurrentModal, @@ -298,6 +299,7 @@ export function doDaemonReady() { dispatch(doCheckUpgradeAvailable()); } dispatch(doCheckUpgradeSubscribe()); + dispatch(doCheckSubscriptions()); }; } diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index 263470103..d665828d6 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -289,7 +289,7 @@ export function doLoadVideo(uri) { }; } -export function doPurchaseUri(uri) { +export function doPurchaseUri(uri, specificCostInfo) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); @@ -322,7 +322,7 @@ export function doPurchaseUri(uri) { return; } - const costInfo = makeSelectCostInfoForUri(uri)(state); + const costInfo = makeSelectCostInfoForUri(uri)(state) || specificCostInfo; const { cost } = costInfo; if (cost > balance) { @@ -359,8 +359,8 @@ export function doFetchClaimsByChannel(uri, page) { const claimResult = result[uri] || {}; const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; - if(claimResult && claimResult.claims_in_channel && claimResult.claims_in_channel.length) { - let latest = claimResult.claims_in_channel[0]; + if(claimsInChannel && claimsInChannel.length) { + let latest = claimsInChannel[0]; dispatch(setSubscriptionLatest({ channelName: latest.channel_name, uri: `${latest.channel_name}#${latest.value.publisherSignature.certificateId}` diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 55632c785..5121648e0 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -1,6 +1,12 @@ // @flow import * as ACTIONS from 'constants/action_types'; -import type { Subscription, Dispatch } from 'redux/reducers/subscriptions'; +import type { Subscription, Dispatch, SubscriptionState } from 'redux/reducers/subscriptions'; +import { selectSubscriptions } from 'redux/selectors/subscriptions'; +import Lbry from 'lbry'; +import { doPurchaseUri } from 'redux/actions/content'; +import { doNavigate } from 'redux/actions/navigation'; + +const CHECK_SUBSCRIPTIONS_INTERVAL = 10 * 60 * 1000; export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch) => dispatch({ @@ -14,6 +20,50 @@ export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: D data: subscription, }); +export const doCheckSubscriptions = () => (dispatch: Dispatch, getState: () => SubscriptionState) => { + const checkSubscriptionsTimer = setInterval( + () => selectSubscriptions(getState()).map((subscription: Subscription) => dispatch(doCheckSubscription(subscription))), + CHECK_SUBSCRIPTIONS_INTERVAL + ); + dispatch({ + type: ACTIONS.CHECK_SUBSCRIPTIONS_SUBSCRIBE, + data: { checkSubscriptionsTimer }, + }); +}; + +export const doCheckSubscription = (subscription: Subscription) => (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.CHECK_SUBSCRIPTION_STARTED, + data: subscription, + }); + + Lbry.claim_list_by_channel({ uri: subscription.uri, page: 1 }).then(result => { + const claimResult = result[subscription.uri] || {}; + const { claims_in_channel: claimsInChannel } = claimResult; + + let count = claimsInChannel.reduce((prev, cur, index) => `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, -1) + + if(count !== 0) { + if(!claimsInChannel[0].value.stream.metadata.fee) { + dispatch(doPurchaseUri(`${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, {cost: 0})); + } + + const notif = new window.Notification(subscription.channelName, { + body: `Posted ${claimsInChannel[0].value.stream.metadata.title}${count > 1 ? ` and ${count-1} other new items` : '' }${count < 0 ? ' and 9+ other new items' : ''}`, + silent: false, + }); + notif.onclick = () => { + dispatch(doNavigate('/show', { uri: `lbry://${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` })) + }; + } + + dispatch({ + type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED, + data: subscription + }); + }); +} + export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (dispatch: Dispatch) => { return dispatch({ diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js index e821b5854..2ef3b17cc 100644 --- a/src/renderer/redux/reducers/subscriptions.js +++ b/src/renderer/redux/reducers/subscriptions.js @@ -37,7 +37,15 @@ type setSubscriptionLatest = { } } -export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions | setSubscriptionLatest; +type CheckSubscriptionStarted = { + type: ACTIONS.CHECK_SUBSCRIPTION_STARTED +} + +type CheckSubscriptionCompleted = { + type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED +} + +export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions | setSubscriptionLatest | CheckSubscriptionStarted | CheckSubscriptionCompleted | Function; export type Dispatch = (action: Action) => any; const defaultState = { -- 2.45.3 From 2c6f2d52bfd6f84d94444fd8ccf558b5d48746d9 Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Tue, 6 Mar 2018 00:32:58 -0800 Subject: [PATCH 3/8] Fix issues with viewing most recent and uninitiated latest videos --- src/renderer/page/file/index.js | 2 ++ src/renderer/page/file/view.jsx | 8 ++++++++ src/renderer/redux/actions/subscriptions.js | 19 ++++++++++++++----- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/renderer/page/file/index.js b/src/renderer/page/file/index.js index 4984ed812..a4a86f131 100644 --- a/src/renderer/page/file/index.js +++ b/src/renderer/page/file/index.js @@ -4,6 +4,7 @@ import { doFetchFileInfo } from 'redux/actions/file_info'; import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; import { selectRewardContentClaimIds } from 'redux/selectors/content'; import { doFetchCostInfoForUri } from 'redux/actions/cost_info'; +import { checkSubscriptionLatest } from 'redux/actions/subscriptions'; import { makeSelectClaimForUri, makeSelectContentTypeForUri, @@ -29,6 +30,7 @@ const perform = dispatch => ({ navigate: (path, params) => dispatch(doNavigate(path, params)), fetchFileInfo: uri => dispatch(doFetchFileInfo(uri)), fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)), + checkSubscriptionLatest: (subscription, uri) => dispatch(checkSubscriptionLatest(subscription, uri)), }); export default connect(select, perform)(FilePage); diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index e248ee5d6..77d422d1c 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -17,6 +17,7 @@ class FilePage extends React.PureComponent { componentDidMount() { this.fetchFileInfo(this.props); this.fetchCostInfo(this.props); + this.checkSubscriptionLatest(this.props); } componentWillReceiveProps(nextProps) { @@ -35,6 +36,13 @@ class FilePage extends React.PureComponent { } } + checkSubscriptionLatest(props) { + props.checkSubscriptionLatest({ + channelName: props.claim.channel_name, + uri: `${props.claim.channel_name}#${props.claim.value.publisherSignature.certificateId}`, + }, `${props.claim.name}#${props.claim.claim_id}`); + } + render() { const { claim, diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 5121648e0..5ae3885ea 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -41,7 +41,7 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di const claimResult = result[subscription.uri] || {}; const { claims_in_channel: claimsInChannel } = claimResult; - let count = claimsInChannel.reduce((prev, cur, index) => `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, -1) + let count = subscription.latest ? claimsInChannel.reduce((prev, cur, index) => `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, -1) : 1; if(count !== 0) { if(!claimsInChannel[0].value.stream.metadata.fee) { @@ -64,16 +64,25 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di }); } +export const checkSubscriptionLatest = (channel: Subscription, uri: string) => (dispatch: Dispatch) => { + Lbry.claim_list_by_channel({ uri: channel.uri, page: 1 }).then(result => { + const claimResult = result[channel.uri] || {}; + const { claims_in_channel: claimsInChannel } = claimResult; + + if(claimsInChannel && claimsInChannel.length && `${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` === uri) { + dispatch(setSubscriptionLatest(channel, uri)); + } + }); +} + export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (dispatch: Dispatch) => -{ - return dispatch({ + dispatch({ type: ACTIONS.SET_SUBSCRIPTION_LATEST, data: { subscription, uri } - }) -}; + }); export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) => dispatch({ type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS }); -- 2.45.3 From 98c9dfb68e444e62d02b306ed832970abb4557fc Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Tue, 6 Mar 2018 00:36:04 -0800 Subject: [PATCH 4/8] Formatted code with prettier --- src/main/index.js | 4 +- src/renderer/component/fileList/view.jsx | 12 ++-- src/renderer/component/rewardSummary/view.jsx | 6 +- src/renderer/index.js | 2 +- src/renderer/page/file/index.js | 3 +- src/renderer/page/file/view.jsx | 11 ++-- src/renderer/redux/actions/content.js | 15 +++-- src/renderer/redux/actions/settings.js | 3 +- src/renderer/redux/actions/subscriptions.js | 62 ++++++++++++++----- src/renderer/redux/reducers/subscriptions.js | 34 ++++++---- 10 files changed, 101 insertions(+), 51 deletions(-) diff --git a/src/main/index.js b/src/main/index.js index d068e87e0..ec468ae70 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -64,8 +64,8 @@ app.on('ready', async () => { dialog.showErrorBox( 'Daemon has Exited', 'The daemon may have encountered an unexpected error, or another daemon instance is already running. \n\n' + - 'For more information please visit: \n' + - 'https://lbry.io/faq/startup-troubleshooting' + 'For more information please visit: \n' + + 'https://lbry.io/faq/startup-troubleshooting' ); app.quit(); } diff --git a/src/renderer/component/fileList/view.jsx b/src/renderer/component/fileList/view.jsx index afb446323..eef0993c6 100644 --- a/src/renderer/component/fileList/view.jsx +++ b/src/renderer/component/fileList/view.jsx @@ -15,27 +15,27 @@ class FileList extends React.PureComponent { this._sortFunctions = { dateNew(fileInfos) { return fileInfos.slice().sort((fileInfo1, fileInfo2) => { - const height1 = fileInfo1.height - const height2 = fileInfo2.height + const height1 = fileInfo1.height; + const height2 = fileInfo2.height; if (height1 > height2) { return -1; } else if (height1 < height2) { return 1; } return 0; - }); + }); }, dateOld(fileInfos) { return fileInfos.slice().sort((fileInfo1, fileInfo2) => { - const height1 = fileInfo1.height - const height2 = fileInfo2.height + const height1 = fileInfo1.height; + const height2 = fileInfo2.height; if (height1 < height2) { return -1; } else if (height1 > height2) { return 1; } return 0; - }); + }); }, title(fileInfos) { return fileInfos.slice().sort((fileInfo1, fileInfo2) => { diff --git a/src/renderer/component/rewardSummary/view.jsx b/src/renderer/component/rewardSummary/view.jsx index 36507d535..9fa611902 100644 --- a/src/renderer/component/rewardSummary/view.jsx +++ b/src/renderer/component/rewardSummary/view.jsx @@ -15,9 +15,9 @@ const RewardSummary = (props: Props) => {

{__('Rewards')}

- {__('Read our')}{' '} - {__('FAQ')}{' '}{__('to learn more about LBRY Rewards')}. -

+ {__('Read our')} {__('FAQ')}{' '} + {__('to learn more about LBRY Rewards')}. +

{unclaimedRewardAmount > 0 ? ( diff --git a/src/renderer/index.js b/src/renderer/index.js index 822f0b153..c1edc1271 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -69,7 +69,7 @@ ipcRenderer.on('window-is-focused', () => { document.addEventListener('dragover', event => { event.preventDefault(); -}) +}); document.addEventListener('drop', event => { event.preventDefault(); }); diff --git a/src/renderer/page/file/index.js b/src/renderer/page/file/index.js index a4a86f131..eb5dd0fd4 100644 --- a/src/renderer/page/file/index.js +++ b/src/renderer/page/file/index.js @@ -30,7 +30,8 @@ const perform = dispatch => ({ navigate: (path, params) => dispatch(doNavigate(path, params)), fetchFileInfo: uri => dispatch(doFetchFileInfo(uri)), fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)), - checkSubscriptionLatest: (subscription, uri) => dispatch(checkSubscriptionLatest(subscription, uri)), + checkSubscriptionLatest: (subscription, uri) => + dispatch(checkSubscriptionLatest(subscription, uri)), }); export default connect(select, perform)(FilePage); diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index 77d422d1c..1de94e32a 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -37,10 +37,13 @@ class FilePage extends React.PureComponent { } checkSubscriptionLatest(props) { - props.checkSubscriptionLatest({ - channelName: props.claim.channel_name, - uri: `${props.claim.channel_name}#${props.claim.value.publisherSignature.certificateId}`, - }, `${props.claim.name}#${props.claim.claim_id}`); + props.checkSubscriptionLatest( + { + channelName: props.claim.channel_name, + uri: `${props.claim.channel_name}#${props.claim.value.publisherSignature.certificateId}`, + }, + `${props.claim.name}#${props.claim.claim_id}` + ); } render() { diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index d665828d6..c369ceb1a 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -359,12 +359,17 @@ export function doFetchClaimsByChannel(uri, page) { const claimResult = result[uri] || {}; const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; - if(claimsInChannel && claimsInChannel.length) { + if (claimsInChannel && claimsInChannel.length) { let latest = claimsInChannel[0]; - dispatch(setSubscriptionLatest({ - channelName: latest.channel_name, - uri: `${latest.channel_name}#${latest.value.publisherSignature.certificateId}` - }, `${latest.name}#${latest.claim_id}`)); + dispatch( + setSubscriptionLatest( + { + channelName: latest.channel_name, + uri: `${latest.channel_name}#${latest.value.publisherSignature.certificateId}`, + }, + `${latest.name}#${latest.claim_id}` + ) + ); } dispatch({ diff --git a/src/renderer/redux/actions/settings.js b/src/renderer/redux/actions/settings.js index da4ed52a0..db3fa5020 100644 --- a/src/renderer/redux/actions/settings.js +++ b/src/renderer/redux/actions/settings.js @@ -70,7 +70,8 @@ export function doUpdateIsNight() { const momentNow = moment(); return { type: ACTIONS.UPDATE_IS_NIGHT, - data: { isNight: (() => { + data: { + isNight: (() => { const startNightMoment = moment('21:00', 'HH:mm'); const endNightMoment = moment('8:00', 'HH:mm'); return !(momentNow.isAfter(endNightMoment) && momentNow.isBefore(startNightMoment)); diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 5ae3885ea..5e8fddb8c 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -20,9 +20,15 @@ export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: D data: subscription, }); -export const doCheckSubscriptions = () => (dispatch: Dispatch, getState: () => SubscriptionState) => { +export const doCheckSubscriptions = () => ( + dispatch: Dispatch, + getState: () => SubscriptionState +) => { const checkSubscriptionsTimer = setInterval( - () => selectSubscriptions(getState()).map((subscription: Subscription) => dispatch(doCheckSubscription(subscription))), + () => + selectSubscriptions(getState()).map((subscription: Subscription) => + dispatch(doCheckSubscription(subscription)) + ), CHECK_SUBSCRIPTIONS_INTERVAL ); dispatch({ @@ -41,47 +47,69 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di const claimResult = result[subscription.uri] || {}; const { claims_in_channel: claimsInChannel } = claimResult; - let count = subscription.latest ? claimsInChannel.reduce((prev, cur, index) => `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, -1) : 1; + let count = subscription.latest + ? claimsInChannel.reduce( + (prev, cur, index) => + `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, + -1 + ) + : 1; - if(count !== 0) { - if(!claimsInChannel[0].value.stream.metadata.fee) { - dispatch(doPurchaseUri(`${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, {cost: 0})); + if (count !== 0) { + if (!claimsInChannel[0].value.stream.metadata.fee) { + dispatch( + doPurchaseUri(`${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, { cost: 0 }) + ); } const notif = new window.Notification(subscription.channelName, { - body: `Posted ${claimsInChannel[0].value.stream.metadata.title}${count > 1 ? ` and ${count-1} other new items` : '' }${count < 0 ? ' and 9+ other new items' : ''}`, + body: `Posted ${claimsInChannel[0].value.stream.metadata.title}${ + count > 1 ? ` and ${count - 1} other new items` : '' + }${count < 0 ? ' and 9+ other new items' : ''}`, silent: false, }); notif.onclick = () => { - dispatch(doNavigate('/show', { uri: `lbry://${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` })) + dispatch( + doNavigate('/show', { + uri: `lbry://${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, + }) + ); }; } dispatch({ type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED, - data: subscription + data: subscription, }); }); -} +}; -export const checkSubscriptionLatest = (channel: Subscription, uri: string) => (dispatch: Dispatch) => { +export const checkSubscriptionLatest = (channel: Subscription, uri: string) => ( + dispatch: Dispatch +) => { Lbry.claim_list_by_channel({ uri: channel.uri, page: 1 }).then(result => { const claimResult = result[channel.uri] || {}; const { claims_in_channel: claimsInChannel } = claimResult; - if(claimsInChannel && claimsInChannel.length && `${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` === uri) { + if ( + claimsInChannel && + claimsInChannel.length && + `${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` === uri + ) { dispatch(setSubscriptionLatest(channel, uri)); } }); -} +}; -export const setSubscriptionLatest = (subscription: Subscription, uri: string) => (dispatch: Dispatch) => - dispatch({ +export const setSubscriptionLatest = (subscription: Subscription, uri: string) => ( + dispatch: Dispatch +) => + dispatch({ type: ACTIONS.SET_SUBSCRIPTION_LATEST, data: { subscription, - uri - } + uri, + }, }); export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) => diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js index 2ef3b17cc..a8f40746f 100644 --- a/src/renderer/redux/reducers/subscriptions.js +++ b/src/renderer/redux/reducers/subscriptions.js @@ -5,7 +5,7 @@ import { handleActions } from 'util/redux-utils'; export type Subscription = { channelName: string, uri: string, - latest: ?string + latest: ?string, }; // Subscription redux types @@ -33,19 +33,26 @@ type setSubscriptionLatest = { type: ACTIONS.SET_SUBSCRIPTION_LATEST, data: { subscription: Subscription, - uri: string - } -} + uri: string, + }, +}; type CheckSubscriptionStarted = { - type: ACTIONS.CHECK_SUBSCRIPTION_STARTED -} + type: ACTIONS.CHECK_SUBSCRIPTION_STARTED, +}; type CheckSubscriptionCompleted = { - type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED -} + type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED, +}; -export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions | setSubscriptionLatest | CheckSubscriptionStarted | CheckSubscriptionCompleted | Function; +export type Action = + | doChannelSubscribe + | doChannelUnsubscribe + | HasFetchedSubscriptions + | setSubscriptionLatest + | CheckSubscriptionStarted + | CheckSubscriptionCompleted + | Function; export type Dispatch = (action: Action) => any; const defaultState = { @@ -92,8 +99,13 @@ export default handleActions( action: setSubscriptionLatest ): SubscriptionState => ({ ...state, - subscriptions: state.subscriptions.map(subscription => subscription.channelName === action.data.subscription.channelName ? {...subscription, latest: action.data.uri} : subscription) - }) + subscriptions: state.subscriptions.map( + subscription => + subscription.channelName === action.data.subscription.channelName + ? { ...subscription, latest: action.data.uri } + : subscription + ), + }), }, defaultState ); -- 2.45.3 From 6e293fd04b6efbb3b9ec9d2a5faaa8ab8ba09e08 Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Tue, 6 Mar 2018 01:37:53 -0800 Subject: [PATCH 5/8] Fixed weird issue with flow throwing fallacious error --- src/renderer/page/file/view.jsx | 4 ++-- src/renderer/redux/actions/content.js | 4 ++-- src/renderer/redux/actions/subscriptions.js | 10 ++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index 1de94e32a..670fd8e10 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -40,9 +40,9 @@ class FilePage extends React.PureComponent { props.checkSubscriptionLatest( { channelName: props.claim.channel_name, - uri: `${props.claim.channel_name}#${props.claim.value.publisherSignature.certificateId}`, + uri: buildURI({ contentName: props.claim.channel_name, claimId: props.claim.value.publisherSignature.certificateId }, false), }, - `${props.claim.name}#${props.claim.claim_id}` + buildURI({ contentName: props.claim.name, claimId: props.claim.claim_id }, false) ); } diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index c369ceb1a..cc81b1ed1 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -365,9 +365,9 @@ export function doFetchClaimsByChannel(uri, page) { setSubscriptionLatest( { channelName: latest.channel_name, - uri: `${latest.channel_name}#${latest.value.publisherSignature.certificateId}`, + uri: buildURI({ contentName: latest.channel_name, claimId: latest.value.publisherSignature.certificateId }, false), }, - `${latest.name}#${latest.claim_id}` + buildURI({ contentName: latest.name, claimId: latest.claim_id }, false) ) ); } diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 5e8fddb8c..c75ba1408 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -5,6 +5,7 @@ import { selectSubscriptions } from 'redux/selectors/subscriptions'; import Lbry from 'lbry'; import { doPurchaseUri } from 'redux/actions/content'; import { doNavigate } from 'redux/actions/navigation'; +import { buildURI } from 'lbryURI'; const CHECK_SUBSCRIPTIONS_INTERVAL = 10 * 60 * 1000; @@ -50,7 +51,7 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di let count = subscription.latest ? claimsInChannel.reduce( (prev, cur, index) => - `${cur.name}#${cur.claim_id}` === subscription.latest ? index : prev, + buildURI({ contentName: cur.name, claimId: cur.claim_id}, false) === subscription.latest ? index : prev, -1 ) : 1; @@ -58,7 +59,7 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di if (count !== 0) { if (!claimsInChannel[0].value.stream.metadata.fee) { dispatch( - doPurchaseUri(`${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, { cost: 0 }) + doPurchaseUri(buildURI({ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, false), { cost: 0 }) ); } @@ -71,12 +72,13 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di notif.onclick = () => { dispatch( doNavigate('/show', { - uri: `lbry://${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}`, + uri: buildURI({ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, true), }) ); }; } + //$FlowIssue dispatch({ type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED, data: subscription, @@ -94,7 +96,7 @@ export const checkSubscriptionLatest = (channel: Subscription, uri: string) => ( if ( claimsInChannel && claimsInChannel.length && - `${claimsInChannel[0].name}#${claimsInChannel[0].claim_id}` === uri + buildURI({ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, false) === uri ) { dispatch(setSubscriptionLatest(channel, uri)); } -- 2.45.3 From 1e1c49436726a72d12196ad773750aadd0fbb708 Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Wed, 7 Mar 2018 11:19:45 -0800 Subject: [PATCH 6/8] Re-ran prettier --- src/renderer/page/file/view.jsx | 8 ++++++- src/renderer/redux/actions/content.js | 8 ++++++- src/renderer/redux/actions/subscriptions.js | 23 +++++++++++++++++---- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index 670fd8e10..9742c9848 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -40,7 +40,13 @@ class FilePage extends React.PureComponent { props.checkSubscriptionLatest( { channelName: props.claim.channel_name, - uri: buildURI({ contentName: props.claim.channel_name, claimId: props.claim.value.publisherSignature.certificateId }, false), + uri: buildURI( + { + contentName: props.claim.channel_name, + claimId: props.claim.value.publisherSignature.certificateId, + }, + false + ), }, buildURI({ contentName: props.claim.name, claimId: props.claim.claim_id }, false) ); diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index cc81b1ed1..9962d7e69 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -365,7 +365,13 @@ export function doFetchClaimsByChannel(uri, page) { setSubscriptionLatest( { channelName: latest.channel_name, - uri: buildURI({ contentName: latest.channel_name, claimId: latest.value.publisherSignature.certificateId }, false), + uri: buildURI( + { + contentName: latest.channel_name, + claimId: latest.value.publisherSignature.certificateId, + }, + false + ), }, buildURI({ contentName: latest.name, claimId: latest.claim_id }, false) ) diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index c75ba1408..5dca7d859 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -51,7 +51,10 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di let count = subscription.latest ? claimsInChannel.reduce( (prev, cur, index) => - buildURI({ contentName: cur.name, claimId: cur.claim_id}, false) === subscription.latest ? index : prev, + buildURI({ contentName: cur.name, claimId: cur.claim_id }, false) === + subscription.latest + ? index + : prev, -1 ) : 1; @@ -59,7 +62,13 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di if (count !== 0) { if (!claimsInChannel[0].value.stream.metadata.fee) { dispatch( - doPurchaseUri(buildURI({ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, false), { cost: 0 }) + doPurchaseUri( + buildURI( + { contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, + false + ), + { cost: 0 } + ) ); } @@ -72,7 +81,10 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di notif.onclick = () => { dispatch( doNavigate('/show', { - uri: buildURI({ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, true), + uri: buildURI( + { contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, + true + ), }) ); }; @@ -96,7 +108,10 @@ export const checkSubscriptionLatest = (channel: Subscription, uri: string) => ( if ( claimsInChannel && claimsInChannel.length && - buildURI({ contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, false) === uri + buildURI( + { contentName: claimsInChannel[0].name, claimId: claimsInChannel[0].claim_id }, + false + ) === uri ) { dispatch(setSubscriptionLatest(channel, uri)); } -- 2.45.3 From 3f8f25dc431adf131c2006419af463b53bab1455 Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Wed, 7 Mar 2018 11:41:14 -0800 Subject: [PATCH 7/8] let --> const --- src/renderer/redux/actions/content.js | 2 +- src/renderer/redux/actions/subscriptions.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index 9962d7e69..bdf831a03 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -360,7 +360,7 @@ export function doFetchClaimsByChannel(uri, page) { const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; if (claimsInChannel && claimsInChannel.length) { - let latest = claimsInChannel[0]; + const latest = claimsInChannel[0]; dispatch( setSubscriptionLatest( { diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 5dca7d859..650f98a9b 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -48,7 +48,7 @@ export const doCheckSubscription = (subscription: Subscription) => (dispatch: Di const claimResult = result[subscription.uri] || {}; const { claims_in_channel: claimsInChannel } = claimResult; - let count = subscription.latest + const count = subscription.latest ? claimsInChannel.reduce( (prev, cur, index) => buildURI({ contentName: cur.name, claimId: cur.claim_id }, false) === -- 2.45.3 From 174285aea8703726bd46bcec0bea863aff145ff3 Mon Sep 17 00:00:00 2001 From: liamcardenas Date: Wed, 7 Mar 2018 12:02:53 -0800 Subject: [PATCH 8/8] Reduce unnecessary api calls --- src/renderer/page/file/index.js | 2 ++ src/renderer/page/file/view.jsx | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/renderer/page/file/index.js b/src/renderer/page/file/index.js index eb5dd0fd4..37fb13c7f 100644 --- a/src/renderer/page/file/index.js +++ b/src/renderer/page/file/index.js @@ -14,6 +14,7 @@ import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info'; import { selectShowNsfw } from 'redux/selectors/settings'; import FilePage from './view'; import { makeSelectCurrentParam } from 'redux/selectors/navigation'; +import { selectSubscriptions } from 'redux/selectors/subscriptions'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), @@ -24,6 +25,7 @@ const select = (state, props) => ({ tab: makeSelectCurrentParam('tab')(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state), rewardedContentClaimIds: selectRewardContentClaimIds(state, props), + subscriptions: selectSubscriptions(state), }); const perform = dispatch => ({ diff --git a/src/renderer/page/file/view.jsx b/src/renderer/page/file/view.jsx index 9742c9848..069a0dfdc 100644 --- a/src/renderer/page/file/view.jsx +++ b/src/renderer/page/file/view.jsx @@ -37,19 +37,25 @@ class FilePage extends React.PureComponent { } checkSubscriptionLatest(props) { - props.checkSubscriptionLatest( - { - channelName: props.claim.channel_name, - uri: buildURI( - { - contentName: props.claim.channel_name, - claimId: props.claim.value.publisherSignature.certificateId, - }, - false - ), - }, - buildURI({ contentName: props.claim.name, claimId: props.claim.claim_id }, false) - ); + if ( + props.subscriptions + .map(subscription => subscription.channelName) + .indexOf(props.claim.channel_name) !== -1 + ) { + props.checkSubscriptionLatest( + { + channelName: props.claim.channel_name, + uri: buildURI( + { + contentName: props.claim.channel_name, + claimId: props.claim.value.publisherSignature.certificateId, + }, + false + ), + }, + buildURI({ contentName: props.claim.name, claimId: props.claim.claim_id }, false) + ); + } } render() { -- 2.45.3