Compare commits
4 commits
Author | SHA1 | Date | |
---|---|---|---|
|
b8e25d7945 | ||
|
4b922d47f6 | ||
|
0ea5d01062 | ||
|
6e97fbf5f8 |
14 changed files with 1166 additions and 977 deletions
0
.yarn/versions/362c0c03.yml
vendored
Normal file
0
.yarn/versions/362c0c03.yml
vendored
Normal file
|
@ -29,6 +29,10 @@
|
|||
"from": "./static/font",
|
||||
"to": "static/font",
|
||||
"filter": ["**/*"]
|
||||
},
|
||||
{
|
||||
"from": "./static/app-update.yml",
|
||||
"to": "app-update.yml"
|
||||
}
|
||||
],
|
||||
"publish": [
|
||||
|
|
|
@ -22,6 +22,7 @@ import { diskSpaceLinux, diskSpaceWindows, diskSpaceMac } from '../ui/util/disks
|
|||
const { download } = require('electron-dl');
|
||||
const remote = require('@electron/remote/main');
|
||||
const os = require('os');
|
||||
const sudo = require('sudo-prompt');
|
||||
|
||||
remote.initialize();
|
||||
const filePath = path.join(process.resourcesPath, 'static', 'upgradeDisabled');
|
||||
|
@ -50,11 +51,9 @@ let showingAutoUpdateCloseAlert = false;
|
|||
// https://www.electronjs.org/docs/latest/api/auto-updater#autoupdatercheckforupdates
|
||||
let keepCheckingForUpdates = true;
|
||||
|
||||
// Auto updater doesn't support Linux installations (only trough AppImages)
|
||||
// this is why, for that case, we download a full executable (.deb package)
|
||||
// as a fallback support. This variable will be used to prevent
|
||||
// multiple downloads when auto updater isn't supported.
|
||||
let downloadUpgradeInProgress = false;
|
||||
let downloadUpgradeInitiated = false;
|
||||
|
||||
let downloadUpgradeItem;
|
||||
|
||||
// Keep a global reference, if you don't, they will be closed automatically when the JavaScript
|
||||
// object is garbage collected.
|
||||
|
@ -327,37 +326,74 @@ ipcMain.on('get-disk-space', async (event) => {
|
|||
}
|
||||
});
|
||||
|
||||
ipcMain.on('cancel-download-upgrade', () => {
|
||||
if (downloadUpgradeItem) {
|
||||
// Cancel the download and execute the onCancel
|
||||
// callback set in the options.
|
||||
downloadUpgradeItem.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('download-upgrade', async (event, params) => {
|
||||
if (downloadUpgradeInProgress) {
|
||||
// Prevent downloading multiple times.
|
||||
if (downloadUpgradeInitiated || downloadUpgradeItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { url, options } = params;
|
||||
const dir = fs.mkdtempSync(app.getPath('temp') + path.sep);
|
||||
|
||||
downloadUpgradeInitiated = true;
|
||||
|
||||
// Grab the download item's handler to allow
|
||||
// cancelling the operation if required.
|
||||
options.onStarted = function(downloadItem) {
|
||||
downloadUpgradeItem = downloadItem;
|
||||
};
|
||||
options.onCancel = function() {
|
||||
downloadUpgradeItem = undefined;
|
||||
downloadUpgradeInitiated = false;
|
||||
};
|
||||
options.onProgress = function(p) {
|
||||
rendererWindow.webContents.send('download-progress-update', p);
|
||||
};
|
||||
options.directory = dir;
|
||||
options.onCompleted = function(c) {
|
||||
downloadUpgradeInProgress = false;
|
||||
downloadUpgradeInitiated = false;
|
||||
downloadUpgradeItem = undefined;
|
||||
rendererWindow.webContents.send('download-update-complete', c);
|
||||
};
|
||||
const win = BrowserWindow.getFocusedWindow();
|
||||
downloadUpgradeInProgress = true;
|
||||
await download(win, url, options).catch(e => console.log('e', e));
|
||||
});
|
||||
|
||||
ipcMain.on('upgrade', (event, installerPath) => {
|
||||
// what to do if no shutdown in a long time?
|
||||
console.log('Update downloaded to', installerPath);
|
||||
console.log('The app will close and you will be prompted to install the latest version of LBRY.');
|
||||
console.log('After the install is complete, please reopen the app.');
|
||||
|
||||
// Prevent .deb package from opening with archive manager (Ubuntu >= 20)
|
||||
if (process.platform === 'linux' && !process.env.APPIMAGE) {
|
||||
sudo.exec(`dpkg -i ${installerPath}`, { name: app.name }, (err, stdout, stderr) => {
|
||||
if (err || stderr) {
|
||||
rendererWindow.webContents.send('upgrade-installing-error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-launch the application when the installation finishes.
|
||||
app.relaunch();
|
||||
app.quit();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
app.on('quit', () => {
|
||||
console.log('Launching upgrade installer at', installerPath);
|
||||
// This gets triggered called after *all* other quit-related events, so
|
||||
// we'll only get here if we're fully prepared and quitting for real.
|
||||
shell.openPath(installerPath);
|
||||
});
|
||||
// what to do if no shutdown in a long time?
|
||||
console.log('Update downloaded to', installerPath);
|
||||
console.log('The app will close and you will be prompted to install the latest version of LBRY.');
|
||||
console.log('After the install is complete, please reopen the app.');
|
||||
app.quit();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lbry",
|
||||
"version": "0.53.4",
|
||||
"version": "0.53.5-alpha.test7495a",
|
||||
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
||||
"keywords": [
|
||||
"lbry"
|
||||
|
@ -67,6 +67,7 @@
|
|||
"remove-markdown": "^0.3.0",
|
||||
"rss": "^1.2.2",
|
||||
"source-map-explorer": "^2.5.2",
|
||||
"sudo-prompt": "^9.2.1",
|
||||
"tempy": "^0.6.0",
|
||||
"videojs-logo": "^2.1.4"
|
||||
},
|
||||
|
@ -243,5 +244,6 @@
|
|||
"lbrynetDaemonDir": "static/daemon",
|
||||
"lbrynetDaemonFileName": "lbrynet"
|
||||
},
|
||||
"packageManager": "yarn@3.2.0"
|
||||
"packageManager": "yarn@3.2.0",
|
||||
"stableVersion": "0.53.4"
|
||||
}
|
||||
|
|
|
@ -2312,5 +2312,7 @@
|
|||
"Free --[legend, unused disk space]--": "Free",
|
||||
"Top content in %language%": "Top content in %language%",
|
||||
"Apply": "Apply",
|
||||
"Installing, please wait...": "Installing, please wait...",
|
||||
"There was an error during installation. Please, try again.": "There was an error during installation. Please, try again.",
|
||||
"--end--": "--end--"
|
||||
}
|
||||
|
|
3
static/app-update.yml
Normal file
3
static/app-update.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
owner: lbryio
|
||||
repo: lbry-desktop
|
||||
provider: github
|
|
@ -45,6 +45,8 @@ export const DOWNLOAD_UPGRADE = 'DOWNLOAD_UPGRADE';
|
|||
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 UPGRADE_INIT_INSTALL = 'UPGRADE_INIT_INSTALL';
|
||||
export const UPGRADE_INSTALL_ERROR = 'UPGRADE_INSTALL_ERROR';
|
||||
export const CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE';
|
||||
export const CHECK_UPGRADE_START = 'CHECK_UPGRADE_START';
|
||||
export const CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS';
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
doToggle3PAnalytics,
|
||||
doUpdateDownloadProgress,
|
||||
doNotifyUpdateAvailable,
|
||||
doShowUpgradeInstallationError,
|
||||
} from 'redux/actions/app';
|
||||
import { isURIValid } from 'util/lbryURI';
|
||||
import { setSearchApi } from 'redux/actions/search';
|
||||
|
@ -132,6 +133,10 @@ autoUpdater.on('update-available', (e) => {
|
|||
app.store.dispatch(doNotifyUpdateAvailable(e));
|
||||
});
|
||||
|
||||
ipcRenderer.on('upgrade-installing-error', () => {
|
||||
app.store.dispatch(doShowUpgradeInstallationError());
|
||||
});
|
||||
|
||||
ipcRenderer.on('download-progress-update', (e, p) => {
|
||||
app.store.dispatch(doUpdateDownloadProgress(Math.round(p.percent * 100)));
|
||||
});
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doStartUpgrade, doCancelUpgrade, doHideModal } from 'redux/actions/app';
|
||||
import { selectDownloadProgress, selectDownloadComplete, selectUpgradeDownloadPath } from 'redux/selectors/app';
|
||||
import {
|
||||
selectDownloadProgress,
|
||||
selectDownloadComplete,
|
||||
selectUpgradeDownloadPath,
|
||||
selectUpgradeInitialized,
|
||||
selectUpgradeFailedInstallation,
|
||||
} from 'redux/selectors/app';
|
||||
import ModalDownloading from './view';
|
||||
|
||||
const select = state => ({
|
||||
const select = (state) => ({
|
||||
downloadProgress: selectDownloadProgress(state),
|
||||
downloadComplete: selectDownloadComplete(state),
|
||||
downloadItem: selectUpgradeDownloadPath(state),
|
||||
upgradeInitialized: selectUpgradeInitialized(state),
|
||||
failedInstallation: selectUpgradeFailedInstallation(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
const perform = (dispatch) => ({
|
||||
startUpgrade: () => dispatch(doStartUpgrade()),
|
||||
cancelUpgrade: () => {
|
||||
dispatch(doHideModal());
|
||||
|
@ -17,7 +25,4 @@ const perform = dispatch => ({
|
|||
},
|
||||
});
|
||||
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(ModalDownloading);
|
||||
export default connect(select, perform)(ModalDownloading);
|
||||
|
|
|
@ -10,11 +10,21 @@ type Props = {
|
|||
downloadItem: string,
|
||||
startUpgrade: () => void,
|
||||
cancelUpgrade: () => void,
|
||||
upgradeInitialized: boolean,
|
||||
failedInstallation: boolean,
|
||||
};
|
||||
|
||||
class ModalDownloading extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { downloadProgress, downloadComplete, downloadItem, startUpgrade, cancelUpgrade } = this.props;
|
||||
const {
|
||||
downloadProgress,
|
||||
downloadComplete,
|
||||
downloadItem,
|
||||
startUpgrade,
|
||||
cancelUpgrade,
|
||||
upgradeInitialized,
|
||||
failedInstallation,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<Modal title={__('Downloading update')} isOpen contentLabel={__('Downloading update')} type="custom">
|
||||
|
@ -40,9 +50,18 @@ class ModalDownloading extends React.PureComponent<Props> {
|
|||
</React.Fragment>
|
||||
) : null}
|
||||
|
||||
{failedInstallation && <p>{__('There was an error during installation. Please, try again.')}</p>}
|
||||
|
||||
<div className="card__actions">
|
||||
{downloadComplete ? <Button button="primary" label={__('Begin Upgrade')} onClick={startUpgrade} /> : null}
|
||||
<Button button="link" label={__('Cancel')} onClick={cancelUpgrade} />
|
||||
{downloadComplete ? (
|
||||
<Button
|
||||
disabled={upgradeInitialized}
|
||||
button="primary"
|
||||
label={__(upgradeInitialized ? 'Installing, please wait...' : 'Begin Upgrade')}
|
||||
onClick={startUpgrade}
|
||||
/>
|
||||
) : null}
|
||||
<Button disabled={upgradeInitialized} button="link" label={__('Cancel')} onClick={cancelUpgrade} />
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -28,7 +28,6 @@ import {
|
|||
import {
|
||||
selectIsUpgradeSkipped,
|
||||
selectUpdateUrl,
|
||||
selectUpgradeDownloadItem,
|
||||
selectUpgradeDownloadPath,
|
||||
selectAutoUpdateDeclined,
|
||||
selectRemoteVersion,
|
||||
|
@ -85,6 +84,15 @@ export function doStartUpgrade() {
|
|||
const upgradeDownloadPath = selectUpgradeDownloadPath(state);
|
||||
|
||||
ipcRenderer.send('upgrade', upgradeDownloadPath);
|
||||
dispatch({
|
||||
type: ACTIONS.UPGRADE_INIT_INSTALL,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function doShowUpgradeInstallationError() {
|
||||
return {
|
||||
type: ACTIONS.UPGRADE_INSTALL_ERROR,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -154,25 +162,8 @@ export function doAutoUpdateDeclined() {
|
|||
}
|
||||
|
||||
export function doCancelUpgrade() {
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
const upgradeDownloadItem = selectUpgradeDownloadItem(state);
|
||||
|
||||
if (upgradeDownloadItem) {
|
||||
/*
|
||||
* Right now the remote reference to the download item gets garbage collected as soon as the
|
||||
* the download is over (maybe even earlier), so trying to cancel a finished download may
|
||||
* throw an error.
|
||||
*/
|
||||
try {
|
||||
upgradeDownloadItem.cancel();
|
||||
} catch (err) {
|
||||
console.error(err); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({ type: ACTIONS.UPGRADE_CANCELLED });
|
||||
};
|
||||
ipcRenderer.send('cancel-download-upgrade');
|
||||
return { type: ACTIONS.UPGRADE_CANCELLED };
|
||||
}
|
||||
|
||||
export function doCheckUpgradeAvailable() {
|
||||
|
|
|
@ -67,6 +67,8 @@ const defaultState: AppState = {
|
|||
modalsAllowed: true,
|
||||
hasClickedComment: false,
|
||||
downloadProgress: undefined,
|
||||
upgradeInitialized: false,
|
||||
upgradeFailedInstallation: false,
|
||||
upgradeDownloading: undefined,
|
||||
upgradeDownloadComplete: undefined,
|
||||
checkUpgradeTimer: undefined,
|
||||
|
@ -162,6 +164,18 @@ reducers[ACTIONS.UPGRADE_DOWNLOAD_STARTED] = (state) =>
|
|||
upgradeDownloading: true,
|
||||
});
|
||||
|
||||
reducers[ACTIONS.UPGRADE_INIT_INSTALL] = (state) =>
|
||||
Object.assign({}, state, {
|
||||
upgradeInitialized: true,
|
||||
upgradeFailedInstallation: false,
|
||||
});
|
||||
|
||||
reducers[ACTIONS.UPGRADE_INSTALL_ERROR] = (state) =>
|
||||
Object.assign({}, state, {
|
||||
upgradeInitialized: false,
|
||||
upgradeFailedInstallation: true,
|
||||
});
|
||||
|
||||
reducers[ACTIONS.CHANGE_MODALS_ALLOWED] = (state, action) =>
|
||||
Object.assign({}, state, {
|
||||
modalsAllowed: action.data.modalsAllowed,
|
||||
|
|
|
@ -25,6 +25,10 @@ export const selectRemoteVersion = createSelector(selectState, (state) => state.
|
|||
|
||||
export const selectIsUpgradeAvailable = createSelector(selectState, (state) => state.isUpgradeAvailable);
|
||||
|
||||
export const selectUpgradeInitialized = createSelector(selectState, (state) => state.upgradeInitialized);
|
||||
|
||||
export const selectUpgradeFailedInstallation = createSelector(selectState, (state) => state.upgradeFailedInstallation);
|
||||
|
||||
export const selectUpgradeFilename = createSelector(selectPlatform, selectRemoteVersion, (platform, version) => {
|
||||
switch (platform) {
|
||||
case 'darwin':
|
||||
|
@ -46,8 +50,6 @@ export const selectIsUpgradeSkipped = createSelector(selectState, (state) => sta
|
|||
|
||||
export const selectUpgradeDownloadPath = createSelector(selectState, (state) => state.downloadPath);
|
||||
|
||||
export const selectUpgradeDownloadItem = createSelector(selectState, (state) => state.downloadItem);
|
||||
|
||||
export const selectAutoUpdateDownloaded = createSelector(selectState, (state) => state.autoUpdateDownloaded);
|
||||
|
||||
export const selectAutoUpdateDeclined = createSelector(selectState, (state) => state.autoUpdateDeclined);
|
||||
|
|
Loading…
Reference in a new issue