From 03c9a14c71c564604bc66687c4e4176009f8fd7f Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Tue, 14 Nov 2017 22:50:21 -0300 Subject: [PATCH] Add timer for checking for app upgrades --- ui/js/actions/app.js | 90 +++++++++++++++++++++++---------- ui/js/component/app/index.js | 8 ++- ui/js/component/app/view.jsx | 5 ++ ui/js/constants/action_types.js | 5 ++ ui/js/reducers/app.js | 15 +++++- ui/js/selectors/app.js | 18 ++++--- 6 files changed, 106 insertions(+), 35 deletions(-) diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index 0ccc6a977..8679000ca 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -5,12 +5,15 @@ import { selectUpgradeDownloadPath, selectUpgradeDownloadItem, selectUpgradeFilename, + selectIsUpgradeSkipped, + selectRemoteVersion, } from "selectors/app"; import { doFetchDaemonSettings } from "actions/settings"; import { doBalanceSubscribe } from "actions/wallet"; import { doAuthenticate } from "actions/user"; import { doFetchFileInfosAndPublishedClaims } from "actions/file_info"; import * as modals from "constants/modal_types"; +import { selectBalance } from "../selectors/wallet"; const { remote, ipcRenderer, shell } = require("electron"); const path = require("path"); @@ -63,33 +66,31 @@ export function doDownloadUpgrade() { const state = getState(); // Make a new directory within temp directory so the filename is guaranteed to be available const dir = fs.mkdtempSync( - remote.app.getPath("temp") + require("path").sep - ), + remote.app.getPath("temp") + require("path").sep + ), upgradeFilename = selectUpgradeFilename(state); let options = { onProgress: p => dispatch(doUpdateDownloadProgress(Math.round(p * 100))), directory: dir, }; - download( - remote.getCurrentWindow(), - selectUpdateUrl(state), - options - ).then(downloadItem => { - /** + download(remote.getCurrentWindow(), selectUpdateUrl(state), options).then( + downloadItem => { + /** * TODO: get the download path directly from the download object. It should just be * downloadItem.getSavePath(), but the copy on the main process is being garbage collected * too soon. */ - dispatch({ - type: types.UPGRADE_DOWNLOAD_COMPLETED, - data: { - downloadItem, - path: path.join(dir, upgradeFilename), - }, - }); - }); + dispatch({ + type: types.UPGRADE_DOWNLOAD_COMPLETED, + data: { + downloadItem, + path: path.join(dir, upgradeFilename), + }, + }); + } + ); dispatch({ type: types.UPGRADE_DOWNLOAD_STARTED, @@ -129,15 +130,25 @@ export function doCancelUpgrade() { export function doCheckUpgradeAvailable() { return function(dispatch, getState) { const state = getState(); + dispatch({ + type: types.CHECK_UPGRADE_STARTED, + }); - lbry.getAppVersionInfo().then(({ remoteVersion, upgradeAvailable }) => { - if (upgradeAvailable) { - dispatch({ - type: types.UPDATE_VERSION, - data: { - version: remoteVersion, - }, - }); + const success = ({ remoteVersion, upgradeAvailable }) => { + dispatch({ + type: types.CHECK_UPGRADE_COMPLETED, + data: { + upgradeAvailable, + remoteVersion, + }, + }); + + // If there's an available upgrade and the user hasn't skipped it or if there's a newer one, show un upgrade modal + if ( + upgradeAvailable && + (!selectIsUpgradeSkipped(state) || + remoteVersion !== selectRemoteVersion(state)) + ) { dispatch({ type: types.OPEN_MODAL, data: { @@ -145,6 +156,30 @@ export function doCheckUpgradeAvailable() { }, }); } + }; + + const failure = () => { + dispatch({ + type: types.CHECK_UPGRADE_FAILED, + }); + }; + + lbry.getAppVersionInfo().then(success, failure); + }; +} + +/* + Initiate a timer that will check for an app upgrade every 10 minutes. + */ +export function doInitCheckUpgradeTimer() { + return function(dispatch) { + const checkUpgradeTimer = setInterval( + () => dispatch(doCheckUpgradeAvailable()), + 600000 + ); + dispatch({ + type: types.CHECK_UPGRADE_TIMER_INITIATED, + data: { checkUpgradeTimer }, }); }; } @@ -153,9 +188,10 @@ export function doCheckDaemonVersion() { return function(dispatch, getState) { lbry.version().then(({ lbrynet_version }) => { dispatch({ - type: config.lbrynetDaemonVersion == lbrynet_version - ? types.DAEMON_VERSION_MATCH - : types.DAEMON_VERSION_MISMATCH, + type: + config.lbrynetDaemonVersion == lbrynet_version + ? types.DAEMON_VERSION_MATCH + : types.DAEMON_VERSION_MISMATCH, }); }); }; diff --git a/ui/js/component/app/index.js b/ui/js/component/app/index.js index 06ff45f18..f4d8c451b 100644 --- a/ui/js/component/app/index.js +++ b/ui/js/component/app/index.js @@ -2,10 +2,15 @@ import React from "react"; import { connect } from "react-redux"; import { selectPageTitle } from "selectors/navigation"; import { selectUser } from "selectors/user"; -import { doCheckUpgradeAvailable, doAlertError } from "actions/app"; +import { + doCheckUpgradeAvailable, + doStartUpgradeCheckTimer, + doAlertError, +} from "actions/app"; import { doRecordScroll } from "actions/navigation"; import { doFetchRewardedContent } from "actions/content"; import App from "./view"; +import { doInitCheckUpgradeTimer } from "../../actions/app"; const select = (state, props) => ({ pageTitle: selectPageTitle(state), @@ -15,6 +20,7 @@ const select = (state, props) => ({ const perform = dispatch => ({ alertError: errorList => dispatch(doAlertError(errorList)), checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()), + initCheckUpgradeTimer: () => dispatch(doInitCheckUpgradeTimer()), fetchRewardedContent: () => dispatch(doFetchRewardedContent()), recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)), }); diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx index 17e0ec030..c23e5d0c8 100644 --- a/ui/js/component/app/view.jsx +++ b/ui/js/component/app/view.jsx @@ -10,6 +10,7 @@ class App extends React.PureComponent { const { alertError, checkUpgradeAvailable, + initCheckUpgradeTimer, fetchRewardedContent, } = this.props; @@ -21,6 +22,8 @@ class App extends React.PureComponent { checkUpgradeAvailable(); } + initCheckUpgradeTimer(); + fetchRewardedContent(); this.scrollListener = () => this.props.recordScroll(window.scrollY); @@ -30,6 +33,8 @@ class App extends React.PureComponent { this.setTitleFromProps(this.props); } + componentDidMount() {} + componentWillUnmount() { window.removeEventListener("scroll", this.scrollListener); } diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 9a9143070..47c653524 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -20,7 +20,12 @@ export const UPGRADE_DOWNLOAD_STARTED = "UPGRADE_DOWNLOAD_STARTED"; export const UPGRADE_DOWNLOAD_COMPLETED = "UPGRADE_DOWNLOAD_COMPLETED"; export const UPGRADE_DOWNLOAD_PROGRESSED = "UPGRADE_DOWNLOAD_PROGRESSED"; export const CHECK_UPGRADE_AVAILABLE = "CHECK_UPGRADE_AVAILABLE"; +export const CHECK_UPGRADE_STARTED = "CHECK_UPGRADE_STARTED"; +export const CHECK_UPGRADE_COMPLETED = "CHECK_UPGRADE_COMPLETED"; +export const CHECK_UPGRADE_FAILED = "CHECK_UPGRADE_FAILED"; +export const CHECK_UPGRADE_TIMER_INITIATED = "CHECK_UPGRADE_TIMER_INITIATED"; export const UPDATE_VERSION = "UPDATE_VERSION"; +export const UPDATE_REMOTE_VERSION = "UPDATE_REMOTE_VERSION"; export const SKIP_UPGRADE = "SKIP_UPGRADE"; export const START_UPGRADE = "START_UPGRADE"; diff --git a/ui/js/reducers/app.js b/ui/js/reducers/app.js index d7bc2cd6b..6155ea4c0 100644 --- a/ui/js/reducers/app.js +++ b/ui/js/reducers/app.js @@ -64,7 +64,7 @@ reducers[types.SKIP_UPGRADE] = function(state, action) { sessionStorage.setItem("upgradeSkipped", true); return Object.assign({}, state, { - upgradeSkipped: true, + isUpgradeSkipped: true, modal: null, }); }; @@ -75,6 +75,19 @@ reducers[types.UPDATE_VERSION] = function(state, action) { }); }; +reducers[types.CHECK_UPGRADE_COMPLETED] = function(state, action) { + return Object.assign({}, state, { + isUpgradeAvailable: action.data.upgradeAvailable, + remoteVersion: action.data.remoteVersion, + }); +}; + +reducers[types.CHECK_UPGRADE_TIMER_INITIATED] = function(state, action) { + return Object.assign({}, state, { + checkUpgradeTimer: action.data.checkUpgradeTimer, + }); +}; + reducers[types.OPEN_MODAL] = function(state, action) { return Object.assign({}, state, { modal: action.data.modal, diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index c721916c0..24c2f2b95 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -20,13 +20,19 @@ export const selectUpdateUrl = createSelector(selectPlatform, platform => { } }); -export const selectVersion = createSelector(_selectState, state => { - return state.version; -}); +export const selectRemoteVersion = createSelector( + _selectState, + state => state.remoteVersion +); + +export const selectIsUpgradeAvailable = createSelector( + _selectState, + state => state.isUpgradeAvailable +); export const selectUpgradeFilename = createSelector( selectPlatform, - selectVersion, + selectRemoteVersion, (platform, version) => { switch (platform) { case "darwin": @@ -56,9 +62,9 @@ export const selectDownloadComplete = createSelector( state => state.upgradeDownloadCompleted ); -export const selectUpgradeSkipped = createSelector( +export const selectIsUpgradeSkipped = createSelector( _selectState, - state => state.upgradeSkipped + state => state.isUpgradeSkipped ); export const selectUpgradeDownloadPath = createSelector(