From 386e9271ffc8c8e5706fcdd5f9ddec9f3538d407 Mon Sep 17 00:00:00 2001 From: Travis Eden Date: Fri, 10 Aug 2018 10:51:51 -0400 Subject: [PATCH] when file download completes, notify through snackbar if on subscriptions page; formatting --- src/renderer/constants/settings.js | 1 + src/renderer/page/settings/index.js | 1 + src/renderer/page/settings/view.jsx | 14 ++++ src/renderer/redux/actions/app.js | 4 +- src/renderer/redux/actions/content.js | 16 +++- src/renderer/redux/actions/subscriptions.js | 77 ++++++++++--------- src/renderer/redux/reducers/settings.js | 1 + src/renderer/redux/selectors/subscriptions.js | 18 +++-- 8 files changed, 84 insertions(+), 48 deletions(-) diff --git a/src/renderer/constants/settings.js b/src/renderer/constants/settings.js index d5ab15a83..f63368105 100644 --- a/src/renderer/constants/settings.js +++ b/src/renderer/constants/settings.js @@ -15,3 +15,4 @@ export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; export const AUTOPLAY = 'autoplay'; export const RESULT_COUNT = 'resultCount'; export const OS_NOTIFICATIONS_ENABLED = 'osNotificationsEnabled'; +export const AUTO_DOWNLOAD = 'autoDownload'; diff --git a/src/renderer/page/settings/index.js b/src/renderer/page/settings/index.js index 2eeb42c25..6d178b368 100644 --- a/src/renderer/page/settings/index.js +++ b/src/renderer/page/settings/index.js @@ -30,6 +30,7 @@ const select = state => ({ autoplay: makeSelectClientSetting(settings.AUTOPLAY)(state), walletEncrypted: selectWalletIsEncrypted(state), osNotificationsEnabled: selectosNotificationsEnabled(state), + autoDownload: makeSelectClientSetting(settings.AUTO_DOWNLOAD)(state), }); const perform = dispatch => ({ diff --git a/src/renderer/page/settings/view.jsx b/src/renderer/page/settings/view.jsx index 1a79f1ece..8f0fb0556 100644 --- a/src/renderer/page/settings/view.jsx +++ b/src/renderer/page/settings/view.jsx @@ -31,6 +31,7 @@ type Props = { themes: Array, automaticDarkModeEnabled: boolean, autoplay: boolean, + autoDownload: boolean, encryptWallet: () => void, decryptWallet: () => void, walletEncrypted: boolean, @@ -59,6 +60,7 @@ class SettingsPage extends React.PureComponent { (this: any).onAutoplayChange = this.onAutoplayChange.bind(this); (this: any).clearCache = this.clearCache.bind(this); (this: any).onDesktopNotificationsChange = this.onDesktopNotificationsChange.bind(this); + (this: any).onAutoDownloadChange = this.onAutoDownloadChange.bind(this); // (this: any).onLanguageChange = this.onLanguageChange.bind(this) } @@ -119,6 +121,10 @@ class SettingsPage extends React.PureComponent { this.props.setClientSetting(settings.SHOW_NSFW, event.target.checked); } + onAutoDownloadChange(event: SyntheticInputEvent<*>) { + this.props.setClientSetting(settings.AUTO_DOWNLOAD, event.target.checked); + } + onChangeEncryptWallet() { const { props } = this; props.walletEncrypted ? props.decryptWallet() : props.encryptWallet(); @@ -157,6 +163,7 @@ class SettingsPage extends React.PureComponent { autoplay, walletEncrypted, osNotificationsEnabled, + autoDownload, } = this.props; const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0; @@ -265,6 +272,13 @@ class SettingsPage extends React.PureComponent { checked={autoplay} postfix={__('Autoplay media files')} /> + @@ -138,7 +139,14 @@ export function doUpdateLoadStatus(uri, outpoint) { 0 ); - if (selectosNotificationsEnabled(getState())) { + if (state.navigation.currentPath === '/subscriptions') { + dispatch( + doNotify({ + message: `'${fileInfo.metadata.title}' has been downloaded`, + displayType: ['snackbar'], + }) + ); + } else if (selectosNotificationsEnabled(state)) { const notif = new window.Notification(notifications[uri].subscription.channelName, { body: `Posted ${fileInfo.metadata.title}${ count > 1 && count < 10 ? ` and ${count - 1} other new items` : '' diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index b2e751e26..02fd76df6 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -1,14 +1,12 @@ // @flow import * as ACTIONS from 'constants/action_types'; import * as NOTIFICATION_TYPES from 'constants/notification_types'; +import * as SETTINGS from 'constants/settings'; import rewards from 'rewards'; -import type { - Dispatch, - SubscriptionState, - SubscriptionNotifications, -} from 'redux/reducers/subscriptions'; +import type { Dispatch, SubscriptionNotifications } from 'redux/reducers/subscriptions'; import type { Subscription } from 'types/subscription'; -import { selectSubscriptions } from 'redux/selectors/subscriptions'; +import { selectSubscriptions, selectDownloadingCount } from 'redux/selectors/subscriptions'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import { Lbry, buildURI, parseURI } from 'lbry-redux'; import { doPurchaseUri } from 'redux/actions/content'; import { doClaimRewardType } from 'redux/actions/rewards'; @@ -16,7 +14,7 @@ import Promise from 'bluebird'; import Lbryio from 'lbryio'; const CHECK_SUBSCRIPTIONS_INTERVAL = 15 * 60 * 1000; -const SUBSCRIPTION_DOWNLOAD_LIMIT = 1; +const SUBSCRIPTION_DOWNLOAD_LIMIT = 3; export const doFetchMySubscriptions = () => (dispatch: Dispatch, getState: () => any) => { const { @@ -127,29 +125,28 @@ export const setSubscriptionNotification = ( }); export const doCheckSubscription = (subscription: Subscription, notify?: boolean) => ( - dispatch: Dispatch + dispatch: Dispatch, + getState: () => {} ) => { - // this action is not implemented - dispatch({ - type: ACTIONS.CHECK_SUBSCRIPTION_STARTED, - data: subscription, - }); + // no dispatching FETCH_CHANNEL_CLAIMS_STARTED; causes loading issues on Lbry.claim_list_by_channel({ uri: subscription.uri, page: 1 }).then(result => { const claimResult = result[subscription.uri] || {}; const { claims_in_channel: claimsInChannel } = claimResult; - const autodownload = true; // temp - const latestIndex = claimsInChannel.findIndex( claim => `${claim.name}#${claim.claim_id}` === subscription.latest ); if (claimsInChannel.length && latestIndex !== 0) { - claimsInChannel.slice(0, latestIndex === -1 ? 10 : latestIndex).forEach((claim, index) => { + claimsInChannel.slice(0, latestIndex === -1 ? 10 : latestIndex).forEach(claim => { const uri = buildURI({ contentName: claim.name, claimId: claim.claim_id }, false); + const state = getState(); + const downloadCount = selectDownloadingCount(state); const shouldDownload = Boolean( - index < SUBSCRIPTION_DOWNLOAD_LIMIT && !claim.value.stream.metadata.fee + downloadCount < SUBSCRIPTION_DOWNLOAD_LIMIT && + !claim.value.stream.metadata.fee && + makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state) ); if (notify) { dispatch( @@ -160,10 +157,11 @@ export const doCheckSubscription = (subscription: Subscription, notify?: boolean ) ); } - if (autodownload && shouldDownload) { + if (shouldDownload) { dispatch(doPurchaseUri(uri, { cost: 0 })); } }); + dispatch( setSubscriptionLatest( { @@ -182,13 +180,18 @@ export const doCheckSubscription = (subscription: Subscription, notify?: boolean ) ) ); - } - }); - // this action is not implemented - dispatch({ - type: ACTIONS.CHECK_SUBSCRIPTION_COMPLETED, - data: subscription, + // calling FETCH_CHANNEL_CLAIMS_COMPLETED after not calling STARTED + // means it will delete a non-existant fetchingChannelClaims[uri] + dispatch({ + type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, + data: { + uri: subscription.uri, + claims: claimsInChannel || [], + page: 1, + }, + }); + } }); }; @@ -253,18 +256,20 @@ export const doChannelUnsubscribe = (subscription: Subscription) => ( } }; -export const doCheckSubscriptions = () => ( - dispatch: Dispatch, - getState: () => SubscriptionState -) => { - function doCheck() { - const subscriptions = selectSubscriptions(getState()); - subscriptions.forEach((sub: Subscription) => { - dispatch(doCheckSubscription(sub, true)); - }); - } - setTimeout(doCheck, 2000); // bad fix for not getting subs on load - const checkSubscriptionsTimer = setInterval(doCheck, 1000 * 20); // temporary; 20 seconds for testing +export const doCheckSubscriptions = () => (dispatch: Dispatch, getState: () => any) => { + const state = getState(); + const subscriptions = selectSubscriptions(state); + subscriptions.forEach((sub: Subscription) => { + dispatch(doCheckSubscription(sub, true)); + }); +}; + +export const doCheckSubscriptionsInit = () => (dispatch: Dispatch) => { + setTimeout(() => dispatch(doCheckSubscriptions()), 5000); // bad fix for not getting subs on load + const checkSubscriptionsTimer = setInterval( + () => dispatch(doCheckSubscriptions()), + CHECK_SUBSCRIPTIONS_INTERVAL + ); dispatch({ type: ACTIONS.CHECK_SUBSCRIPTIONS_SUBSCRIBE, data: { checkSubscriptionsTimer }, diff --git a/src/renderer/redux/reducers/settings.js b/src/renderer/redux/reducers/settings.js index 215032c8b..43336c9b9 100644 --- a/src/renderer/redux/reducers/settings.js +++ b/src/renderer/redux/reducers/settings.js @@ -26,6 +26,7 @@ const defaultState = { automaticDarkModeEnabled: getLocalStorageSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, false), autoplay: getLocalStorageSetting(SETTINGS.AUTOPLAY, false), resultCount: Number(getLocalStorageSetting(SETTINGS.RESULT_COUNT, 50)), + autoDownload: getLocalStorageSetting(SETTINGS.AUTO_DOWNLOAD, false), osNotificationsEnabled: Boolean( getLocalStorageSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED, true) ), diff --git a/src/renderer/redux/selectors/subscriptions.js b/src/renderer/redux/selectors/subscriptions.js index 1e9ca71cd..7b95604d0 100644 --- a/src/renderer/redux/selectors/subscriptions.js +++ b/src/renderer/redux/selectors/subscriptions.js @@ -1,3 +1,4 @@ +import * as NOTIFICATION_TYPES from 'constants/notification_types'; import { createSelector } from 'reselect'; import { selectAllClaimsByChannel, @@ -25,7 +26,7 @@ export const selectSubscriptionClaims = createSelector( return []; } - const fetchedSubscriptions = []; + let fetchedSubscriptions = []; savedSubscriptions.forEach(subscription => { let channelClaims = []; @@ -39,18 +40,18 @@ export const selectSubscriptionClaims = createSelector( // loop over the list of ids and grab the claim pageOneChannelIds.forEach(id => { const grabbedClaim = allClaims[id]; - channelClaims.push(grabbedClaim); + channelClaims = channelClaims.concat([grabbedClaim]); }); } - fetchedSubscriptions.push({ - claims: channelClaims, + fetchedSubscriptions = fetchedSubscriptions.concat([{ + claims: [...channelClaims], channelName: subscription.channelName, uri: subscription.uri, - }); + }]); }); - return fetchedSubscriptions; + return [...fetchedSubscriptions]; } ); @@ -69,3 +70,8 @@ export const selectSubscriptionsBeingFetched = createSelector( return fetchingSubscriptionMap; } ); + +export const selectDownloadingCount = createSelector( + selectNotifications, + notifs => Object.values(notifs).reduce((acc, notif) => notif.type === NOTIFICATION_TYPES.DOWNLOADING ? acc + 1 : acc, 0) +);