Multiple fixes in auto updates.
- Add "disable auto updates" setting (prevents downloading updates in the background but will still notify if there are newer versions) - Prevent downloading multiple times the same update - Hide nag when auto update modal is displayed
This commit is contained in:
parent
aa40a44ce3
commit
48c5f58a8e
10 changed files with 115 additions and 2 deletions
|
@ -39,6 +39,12 @@ let autoUpdateDownloaded = false;
|
|||
// that we show on Windows after you decline an upgrade and close the app later.
|
||||
let showingAutoUpdateCloseAlert = false;
|
||||
|
||||
// This is used to prevent downloading updates multiple times.
|
||||
// As read in the documentation:
|
||||
// "Calling autoUpdater.checkForUpdates() twice will download the update two times."
|
||||
// https://www.electronjs.org/docs/latest/api/auto-updater#autoupdatercheckforupdates
|
||||
let keepCheckingForUpdates = true;
|
||||
|
||||
// Keep a global reference, if you don't, they will be closed automatically when the JavaScript
|
||||
// object is garbage collected.
|
||||
let rendererWindow;
|
||||
|
@ -315,16 +321,49 @@ ipcMain.on('upgrade', (event, installerPath) => {
|
|||
});
|
||||
|
||||
ipcMain.on('check-for-updates', () => {
|
||||
// Prevent downloading the same update multiple times.
|
||||
if (!keepCheckingForUpdates) {
|
||||
return;
|
||||
}
|
||||
|
||||
keepCheckingForUpdates = false;
|
||||
autoUpdater.checkForUpdates();
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
autoUpdateDownloaded = true;
|
||||
|
||||
// If this download was trigger by
|
||||
// autoUpdateAccepted it means, the user
|
||||
// wants to install the new update but
|
||||
// needed to downloaded the files first.
|
||||
if (appState.autoUpdateAccepted) {
|
||||
autoUpdater.quitAndInstall();
|
||||
}
|
||||
});
|
||||
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
keepCheckingForUpdates = true;
|
||||
});
|
||||
|
||||
ipcMain.on('autoUpdateAccepted', () => {
|
||||
appState.autoUpdateAccepted = true;
|
||||
|
||||
// quitAndInstall can only be called if the
|
||||
// update has been downloaded. Since the user
|
||||
// can disable auto updates, we have to make
|
||||
// sure it has been downloaded first.
|
||||
if (autoUpdateDownloaded) {
|
||||
autoUpdater.quitAndInstall();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the update hasn't been downloaded,
|
||||
// start downloading it. After it's done, the
|
||||
// event 'update-downloaded' will be triggered,
|
||||
// where we will be able to resume the
|
||||
// update installation.
|
||||
autoUpdater.downloadUpdate();
|
||||
});
|
||||
|
||||
ipcMain.on('version-info-requested', () => {
|
||||
|
|
|
@ -2285,5 +2285,7 @@
|
|||
"Enable Automatic Hosting": "Enable Automatic Hosting",
|
||||
"Download and serve arbitrary data on the network.": "Download and serve arbitrary data on the network.",
|
||||
"View History Hosting": "View History Hosting",
|
||||
"Disable automatic updates": "Disable automatic updates",
|
||||
"Preven't new updates to be downloaded automatically in the background (we will keep notifying you if there is an update)": "Preven't new updates to be downloaded automatically in the background (we will keep notifying you if there is an update)",
|
||||
"--end--": "--end--"
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
selectAutoUpdateDownloaded,
|
||||
selectModal,
|
||||
selectActiveChannelClaim,
|
||||
selectIsUpdateModelDisplayed,
|
||||
} from 'redux/selectors/app';
|
||||
import { doGetWalletSyncPreference, doSetLanguage } from 'redux/actions/settings';
|
||||
import { doSyncLoop } from 'redux/actions/sync';
|
||||
|
@ -50,6 +51,7 @@ const select = (state) => ({
|
|||
myChannelUrls: selectMyChannelUrls(state),
|
||||
myChannelClaimIds: selectMyChannelClaimIds(state),
|
||||
subscriptions: selectSubscriptions(state),
|
||||
isUpdateModalDisplayed: selectIsUpdateModelDisplayed(state),
|
||||
});
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
|
|
|
@ -76,6 +76,7 @@ type Props = {
|
|||
fetchModBlockedList: () => void,
|
||||
resolveUris: (Array<string>) => void,
|
||||
fetchModAmIList: () => void,
|
||||
isUpdateModalDisplayed: boolean,
|
||||
};
|
||||
|
||||
function App(props: Props) {
|
||||
|
@ -111,6 +112,7 @@ function App(props: Props) {
|
|||
resolveUris,
|
||||
subscriptions,
|
||||
fetchModAmIList,
|
||||
isUpdateModalDisplayed,
|
||||
} = props;
|
||||
|
||||
const appRef = useRef();
|
||||
|
@ -345,7 +347,7 @@ function App(props: Props) {
|
|||
<FileRenderFloating />
|
||||
{isEnhancedLayout && <Yrbl className="yrbl--enhanced" />}
|
||||
|
||||
{showUpgradeButton && (
|
||||
{showUpgradeButton && !isUpdateModalDisplayed && (
|
||||
<Nag
|
||||
message={__('An upgrade is available.')}
|
||||
actionText={__('Install Now')}
|
||||
|
|
17
ui/component/settingDisableAutoUpdates/index.js
Normal file
17
ui/component/settingDisableAutoUpdates/index.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import SettingDisableAutoUpdates from './view';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import { connect } from 'react-redux';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import { doSetClientSetting } from 'redux/actions/settings';
|
||||
|
||||
const select = (state) => {
|
||||
return {
|
||||
disableAutoUpdates: makeSelectClientSetting(SETTINGS.DISABLE_AUTO_UPDATES)(state),
|
||||
};
|
||||
};
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
setClientSetting: (value) => dispatch(doSetClientSetting(SETTINGS.DISABLE_AUTO_UPDATES, value)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(SettingDisableAutoUpdates);
|
30
ui/component/settingDisableAutoUpdates/view.jsx
Normal file
30
ui/component/settingDisableAutoUpdates/view.jsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import * as remote from '@electron/remote';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
||||
const { autoUpdater } = remote.require('electron-updater');
|
||||
|
||||
type Props = {
|
||||
setClientSetting: (boolean) => void,
|
||||
disableAutoUpdates: boolean,
|
||||
};
|
||||
function SettingDisableAutoUpdates(props: Props) {
|
||||
const { setClientSetting, disableAutoUpdates } = props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="autoupdates"
|
||||
onChange={() => {
|
||||
const newDisableAutoUpdates = !disableAutoUpdates;
|
||||
autoUpdater.autoDownload = !newDisableAutoUpdates;
|
||||
setClientSetting(newDisableAutoUpdates);
|
||||
}}
|
||||
checked={disableAutoUpdates}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default SettingDisableAutoUpdates;
|
|
@ -18,6 +18,7 @@ import Spinner from 'component/spinner';
|
|||
import { getPasswordFromCookie } from 'util/saved-passwords';
|
||||
import * as DAEMON_SETTINGS from 'constants/daemon_settings';
|
||||
import SettingEnablePrereleases from 'component/settingEnablePrereleases';
|
||||
import SettingDisableAutoUpdates from 'component/settingDisableAutoUpdates';
|
||||
|
||||
const IS_MAC = process.platform === 'darwin';
|
||||
|
||||
|
@ -222,6 +223,14 @@ export default function SettingSystem(props: Props) {
|
|||
>
|
||||
<SettingEnablePrereleases />
|
||||
</SettingsRow>
|
||||
<SettingsRow
|
||||
title={__('Disable automatic updates')}
|
||||
subtitle={__(
|
||||
"Preven't new updates to be downloaded automatically in the background (we will keep notifying you if there is an update)"
|
||||
)}
|
||||
>
|
||||
<SettingDisableAutoUpdates />
|
||||
</SettingsRow>
|
||||
<SettingsRow
|
||||
title={
|
||||
<span>
|
||||
|
|
|
@ -45,6 +45,7 @@ export const CUSTOM_COMMENTS_SERVERS = 'custom_comments_servers';
|
|||
export const CUSTOM_SHARE_URL_ENABLED = 'custom_share_url_enabled';
|
||||
export const CUSTOM_SHARE_URL = 'custom_share_url';
|
||||
export const ENABLE_PRERELEASE_UPDATES = 'enable_prerelease_updates';
|
||||
export const DISABLE_AUTO_UPDATES = 'disable_auto_updates';
|
||||
|
||||
export const SETTINGS_GRP = {
|
||||
APPEARANCE: 'appearance',
|
||||
|
|
|
@ -200,6 +200,12 @@ function AppWrapper() {
|
|||
|
||||
useEffect(() => {
|
||||
// @if TARGET='app'
|
||||
|
||||
// Enable/disable automatic updates download based on user's settings.
|
||||
const state = store.getState();
|
||||
const autoUpdatesDisabled = makeSelectClientSetting(SETTINGS.DISABLE_AUTO_UPDATES)(state);
|
||||
autoUpdater.autoDownload = !autoUpdatesDisabled;
|
||||
|
||||
moment.locale(remote.app.getLocale());
|
||||
|
||||
autoUpdater.on('error', (error) => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { createSelector } from 'reselect';
|
||||
import { selectClaimsById, selectMyChannelClaims, selectTotalStakedAmountForChannelUri } from 'redux/selectors/claims';
|
||||
import { AUTO_UPDATE_DOWNLOADED } from 'constants/modal_types';
|
||||
|
||||
export const selectState = (state) => state.app || {};
|
||||
|
||||
|
@ -51,6 +52,10 @@ export const selectAutoUpdateDownloaded = createSelector(selectState, (state) =>
|
|||
|
||||
export const selectAutoUpdateDeclined = createSelector(selectState, (state) => state.autoUpdateDeclined);
|
||||
|
||||
export const selectIsUpdateModelDisplayed = createSelector(selectState, (state) => {
|
||||
return state.modal === AUTO_UPDATE_DOWNLOADED;
|
||||
});
|
||||
|
||||
export const selectDaemonVersionMatched = createSelector(selectState, (state) => state.daemonVersionMatched);
|
||||
|
||||
export const selectVolume = createSelector(selectState, (state) => state.volume);
|
||||
|
|
Loading…
Reference in a new issue