From 285c1ca7b611c2be2f7f2f5d96278dfdcf81d543 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sat, 18 Nov 2017 00:08:44 -0500
Subject: [PATCH 01/34] Add electron-updater requirement and import
---
package.json | 1 +
src/main/index.js | 1 +
2 files changed, 2 insertions(+)
diff --git a/package.json b/package.json
index d0dc3f9c7..f96b5740a 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"bluebird": "^3.5.1",
"classnames": "^2.2.5",
"electron-dl": "^1.6.0",
+ "electron-updater": "^2.16.1",
"formik": "^0.10.4",
"from2": "^2.3.0",
"install": "^0.10.2",
diff --git a/src/main/index.js b/src/main/index.js
index 30a78c3e6..5f85e58ec 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -9,6 +9,7 @@ import Keytar from 'keytar';
import ChildProcess from 'child_process';
import Assert from 'assert';
import { app, BrowserWindow, globalShortcut, ipcMain, Menu, Tray } from 'electron';
+import { autoUpdater } from 'electron-updater';
import mainMenu from './menu/mainMenu';
import contextMenu from './menu/contextMenu';
From 2031f36f7ccca8c974f2938362d81e76b44e2ec5 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sun, 19 Nov 2017 00:15:18 -0500
Subject: [PATCH 02/34] Upgrade to electron-builder 19.45.5
It's not clear yet if this will be needed for the new upgrade process,
but we need to get on the latest version eventually anyway.
---
build/upload_assets.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/build/upload_assets.py b/build/upload_assets.py
index 2ba8b56b5..07cae795f 100644
--- a/build/upload_assets.py
+++ b/build/upload_assets.py
@@ -19,14 +19,16 @@ def get_asset_filename():
this_dir = os.path.dirname(os.path.realpath(__file__))
system = platform.system()
if system == 'Darwin':
- return glob.glob(this_dir + '/../dist/LBRY*.dmg')[0]
+ suffix = 'dmg'
elif system == 'Linux':
- return glob.glob(this_dir + '/../dist/LBRY*.deb')[0]
+ suffix = 'deb'
elif system == 'Windows':
- return glob.glob(this_dir + '/../dist/LBRY*.exe')[0]
+ suffix = 'exe'
else:
raise Exception("I don't know about any artifact on {}".format(system))
+ return glob.glob(this_dir + '/../dist/LBRY*.' + suffix)[0]
+
def upload_to_s3(folder):
tag = subprocess.check_output(['git', 'describe', '--always', '--abbrev=8', 'HEAD']).strip()
From 43297ce41404c339ba141c2866a423d3e8fb08f5 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Mon, 27 Nov 2017 03:13:33 -0500
Subject: [PATCH 03/34] Add electron-log
The daemon and lbryum log all kinds of useful status/debug info, might
as well start doing that in the app too.
---
package.json | 1 +
src/main/index.js | 4 ++++
2 files changed, 5 insertions(+)
diff --git a/package.json b/package.json
index f96b5740a..04f50ed1b 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"bluebird": "^3.5.1",
"classnames": "^2.2.5",
"electron-dl": "^1.6.0",
+ "electron-log": "^2.2.12",
"electron-updater": "^2.16.1",
"formik": "^0.10.4",
"from2": "^2.3.0",
diff --git a/src/main/index.js b/src/main/index.js
index 5f85e58ec..a774cf8ee 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -10,6 +10,7 @@ import ChildProcess from 'child_process';
import Assert from 'assert';
import { app, BrowserWindow, globalShortcut, ipcMain, Menu, Tray } from 'electron';
import { autoUpdater } from 'electron-updater';
+import log from 'electron-log';
import mainMenu from './menu/mainMenu';
import contextMenu from './menu/contextMenu';
@@ -18,6 +19,9 @@ const localVersion = app.getVersion();
// Debug configs
const isDevelopment = process.env.NODE_ENV === 'development';
+// For now, log info messages in production for easier debugging of built apps
+log.transports.file.level = 'info';
+
// Misc constants
const LATEST_RELEASE_API_URL = 'https://api.github.com/repos/lbryio/lbry-app/releases/latest';
const DAEMON_PATH = process.env.LBRY_DAEMON || Path.join(__static, 'daemon/lbrynet-daemon');
From dade1174766a932e487bd5e7947e2d3c1e8a719a Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sun, 3 Dec 2017 18:49:26 -0500
Subject: [PATCH 04/34] Add updater settings to package.json
---
electron-builder.json | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/electron-builder.json b/electron-builder.json
index 9e0a8f86b..09c928130 100644
--- a/electron-builder.json
+++ b/electron-builder.json
@@ -1,5 +1,10 @@
{
"appId": "io.lbry.LBRY",
+ "publish": {
+ "provider": "s3",
+ "bucket": "releases.lbry.io",
+ "path": "app/latest"
+ },
"mac": {
"category": "public.app-category.entertainment"
},
From b202de449e718c5d6700454e44f296b237a731dc Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sat, 2 Dec 2017 01:37:09 -0500
Subject: [PATCH 05/34] Upload assets for latest version to S3 in a separate
directory
These are the assets that go in s3://releases.lbry.io/app/latest.
Included are the built asset used for updates (on Mac this is actually
a zip file, not the dmg), as well as the update metadata file for this
platform (latest.yml, etc.)
Also includes some refactoring in the update build script.
---
build/upload_assets.py | 73 ++++++++++++++++++++++++++++++++++--------
1 file changed, 59 insertions(+), 14 deletions(-)
diff --git a/build/upload_assets.py b/build/upload_assets.py
index 07cae795f..970de642e 100644
--- a/build/upload_assets.py
+++ b/build/upload_assets.py
@@ -9,13 +9,16 @@ import github
import uritemplate
import boto3
+S3_BUCKET = 'releases.lbry.io'
+RELEASES_S3_PATH = 'app'
+LATEST_S3_PATH = 'app/latest'
def main():
upload_to_github_if_tagged('lbryio/lbry-app')
- upload_to_s3('app')
+ upload_to_s3(RELEASES_S3_PATH)
-def get_asset_filename():
+def get_asset_path():
this_dir = os.path.dirname(os.path.realpath(__file__))
system = platform.system()
if system == 'Darwin':
@@ -27,31 +30,73 @@ def get_asset_filename():
else:
raise Exception("I don't know about any artifact on {}".format(system))
- return glob.glob(this_dir + '/../dist/LBRY*.' + suffix)[0]
+ return os.path.realpath(glob.glob(this_dir + '/../dist/LBRY*.' + suffix)[0])
+
+def get_update_asset_path():
+ # Get the asset used used for updates. On Mac, this is a .zip; on
+ # Windows it's just the installer file.
+ if platform.system() == 'Darwin':
+ this_dir = os.path.dirname(os.path.realpath(__file__))
+ return os.path.realpath(glob.glob(this_dir + '/../dist/LBRY*.zip')[0])
+ else:
+ return get_asset_path()
+
+
+def get_latest_file_path():
+ # The update metadata file is called latest.yml on Windows, latest-mac.yml on
+ # Mac, latest-linux.yml on Linux
+ this_dir = os.path.dirname(os.path.realpath(__file__))
+ return os.path.realpath(glob.glob(this_dir + '/../dist/latest*.yml')[0])
def upload_to_s3(folder):
- tag = subprocess.check_output(['git', 'describe', '--always', '--abbrev=8', 'HEAD']).strip()
- commit_date = subprocess.check_output([
- 'git', 'show', '-s', '--format=%cd', '--date=format:%Y%m%d-%H%I%S', 'HEAD']).strip()
-
- asset_path = get_asset_filename()
- bucket = 'releases.lbry.io'
- key = folder + '/' + commit_date + '-' + tag + '/' + os.path.basename(asset_path)
-
- print "Uploading " + asset_path + " to s3://" + bucket + '/' + key + ''
+ asset_path = get_asset_path()
if 'AWS_ACCESS_KEY_ID' not in os.environ or 'AWS_SECRET_ACCESS_KEY' not in os.environ:
print 'Must set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to publish assets to s3'
return 1
+ asset_filename = os.path.basename(asset_path)
+
+ tag = subprocess.check_output(['git', 'describe', '--always', '--abbrev=8', 'HEAD']).strip()
+ commit_date = subprocess.check_output([
+ 'git', 'show', '-s', '--format=%cd', '--date=format:%Y%m%d-%H%I%S', 'HEAD']).strip()
+ key = folder + '/' + commit_date + '-' + tag + '/' + asset_filename
+
+ print "Uploading asset file at " + asset_path + " to s3://" + S3_BUCKET + '/' + key
+
s3 = boto3.resource(
's3',
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
config=boto3.session.Config(signature_version='s3v4')
)
- s3.meta.client.upload_file(asset_path, bucket, key)
+
+ s3.Object(S3_BUCKET, key).upload_file(asset_path)
+
+ # Populate the update bucket (update.lbry.io)
+
+ update_asset_path = get_update_asset_path()
+ if asset_path == update_asset_path:
+ # If the update asset and the regular built file are the same, we can
+ # just copy over.
+ print "Copying asset file to s3://" + S3_BUCKET + "/" + LATEST_S3_PATH + "/" + asset_filename
+ s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + asset_filename).copy_from(CopySource={
+ 'Bucket': S3_BUCKET,
+ 'Key': key
+ })
+ else:
+ update_asset_filename = os.path.basename(update_asset_path)
+ print "Uploading update asset file at", update_asset_path, \
+ "to s3://" + S3_BUCKET + "/" + LATEST_S3_PATH + "/" + update_asset_filename
+ s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + update_asset_filename).upload_file(update_asset_path)
+
+ # Upload update metadata file to update bucket
+ metadatafilepath = get_latest_file_path()
+ metadatafilename = os.path.basename(metadatafilepath)
+
+ print "Uploading update metadata file at", metadatafilepath, "to S3"
+ s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + metadatafilename).upload_file(metadatafilepath)
def upload_to_github_if_tagged(repo_name):
@@ -77,7 +122,7 @@ def upload_to_github_if_tagged(repo_name):
# TODO: maybe this should be an error
return 1
- asset_path = get_asset_filename()
+ asset_path = get_asset_path()
print "Uploading " + asset_path + " to Github tag " + current_tag
release = get_github_release(repo, current_tag)
upload_asset_to_github(release, asset_path, gh_token)
From bd8146a86ca2b0d31b2cebde9ddfab57a6d1af10 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sun, 3 Dec 2017 21:41:42 -0500
Subject: [PATCH 06/34] Add electron-publisher-s3 requirement
Needed for update system
---
package.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/package.json b/package.json
index 04f50ed1b..8cd6c8cb0 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"classnames": "^2.2.5",
"electron-dl": "^1.6.0",
"electron-log": "^2.2.12",
+ "electron-publisher-s3": "^19.47.0",
"electron-updater": "^2.16.1",
"formik": "^0.10.4",
"from2": "^2.3.0",
From 67c3863bd665f9d200f126b5a07f6eb109499688 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Thu, 7 Dec 2017 03:08:27 -0500
Subject: [PATCH 07/34] Don't try to upload latest-linux.yml file on Linux
It's not being generated on Linux. I'm pretty sure this is a bug (or at
least undocumented behavior), but it's OK because Linux doesn't support
updates yet anyway.
---
build/upload_assets.py | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/build/upload_assets.py b/build/upload_assets.py
index 970de642e..59817cf60 100644
--- a/build/upload_assets.py
+++ b/build/upload_assets.py
@@ -46,7 +46,10 @@ def get_latest_file_path():
# The update metadata file is called latest.yml on Windows, latest-mac.yml on
# Mac, latest-linux.yml on Linux
this_dir = os.path.dirname(os.path.realpath(__file__))
- return os.path.realpath(glob.glob(this_dir + '/../dist/latest*.yml')[0])
+
+ latestfilematches = glob.glob(this_dir + '/../dist/latest*.yml')
+
+ return latestfilematches[0] if latestfilematches else None
def upload_to_s3(folder):
@@ -91,12 +94,15 @@ def upload_to_s3(folder):
"to s3://" + S3_BUCKET + "/" + LATEST_S3_PATH + "/" + update_asset_filename
s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + update_asset_filename).upload_file(update_asset_path)
- # Upload update metadata file to update bucket
metadatafilepath = get_latest_file_path()
- metadatafilename = os.path.basename(metadatafilepath)
- print "Uploading update metadata file at", metadatafilepath, "to S3"
- s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + metadatafilename).upload_file(metadatafilepath)
+ if metadatafilepath is not None:
+ # For some reason latest-linux.yml isn't being created, but it's OK because updates don't
+ # work on Linux yet anyway.
+ metadatafilename = os.path.basename(metadatafilepath)
+
+ print "Uploading update metadata file at", metadatafilepath, "to S3"
+ s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + metadatafilename).upload_file(metadatafilepath)
def upload_to_github_if_tagged(repo_name):
From e39470c3cc2dd150ae715c886cd4cf76920a72d7 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Thu, 7 Dec 2017 20:38:10 -0500
Subject: [PATCH 08/34] Copy dmg file into dist/mac for TeamCity
TeamCity expects the dmg to be in dist/mac, but in the new
electron-builder it's put directly in dist/ (in the long run the right
way to solve this is to update the TeamCity config).
---
build/build.sh | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/build/build.sh b/build/build.sh
index 2273eff00..1ace2ad48 100755
--- a/build/build.sh
+++ b/build/build.sh
@@ -79,6 +79,12 @@ if [ "$FULL_BUILD" == "true" ]; then
yarn build
+ # Workaround: TeamCity expects the dmg to be in dist/mac, but in the new electron-builder
+ # it's put directly in dist/ (the right way to solve this is to update the TeamCity config)
+ if $OSX; then
+ cp dist/*.dmg dist/mac
+ fi
+
# electron-build has a publish feature, but I had a hard time getting
# it to reliably work and it also seemed difficult to configure. Not proud of
# this, but it seemed better to write my own.
From 5fff24b0fbb7c19c617c53abbd20846079b89dd5 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Fri, 8 Dec 2017 05:08:50 -0500
Subject: [PATCH 09/34] Add "auto update downloaded" modal
---
src/renderer/constants/modal_types.js | 1 +
.../modal/modalAutoUpdateDownloaded/index.js | 5 +++
.../modal/modalAutoUpdateDownloaded/view.jsx | 31 +++++++++++++++++++
src/renderer/modal/modalRouter/view.jsx | 3 ++
4 files changed, 40 insertions(+)
create mode 100644 src/renderer/modal/modalAutoUpdateDownloaded/index.js
create mode 100644 src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
diff --git a/src/renderer/constants/modal_types.js b/src/renderer/constants/modal_types.js
index 9c6d457f9..8e56e8237 100644
--- a/src/renderer/constants/modal_types.js
+++ b/src/renderer/constants/modal_types.js
@@ -2,6 +2,7 @@ export const CONFIRM_FILE_REMOVE = 'confirmFileRemove';
export const INCOMPATIBLE_DAEMON = 'incompatibleDaemon';
export const FILE_TIMEOUT = 'file_timeout';
export const DOWNLOADING = 'downloading';
+export const AUTO_UPDATE_DOWNLOADED = "auto_update_downloaded";
export const ERROR = 'error';
export const INSUFFICIENT_CREDITS = 'insufficient_credits';
export const UPGRADE = 'upgrade';
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/index.js b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
new file mode 100644
index 000000000..921271126
--- /dev/null
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
@@ -0,0 +1,5 @@
+import React from "react";
+import { connect } from "react-redux";
+import ModalAutoUpdateDownloaded from "./view";
+
+export default connect(null, null)(ModalAutoUpdateDownloaded);
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
new file mode 100644
index 000000000..46803c645
--- /dev/null
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -0,0 +1,31 @@
+import React from "react";
+import { Modal } from "modal/modal";
+import { Line } from "rc-progress";
+import Link from "component/link/index";
+
+const { remote } = require("electron");
+const { autoUpdater } = remote.require("electron-updater");
+
+class ModalAutoUpdateDownloaded extends React.PureComponent {
+ render() {
+ return (
+
+
+
{__("LBRY Leveled Up")}
+
+ {__(
+ "A new version of LBRY has been downloaded and is ready to install."
+ )}
+
+
+
+ );
+ }
+}
+
+export default ModalAutoUpdateDownloaded;
diff --git a/src/renderer/modal/modalRouter/view.jsx b/src/renderer/modal/modalRouter/view.jsx
index b2d68fbf2..81925c966 100644
--- a/src/renderer/modal/modalRouter/view.jsx
+++ b/src/renderer/modal/modalRouter/view.jsx
@@ -2,6 +2,7 @@ import React from 'react';
import ModalError from 'modal/modalError';
import ModalAuthFailure from 'modal/modalAuthFailure';
import ModalDownloading from 'modal/modalDownloading';
+import ModalAutoUpdateDownloaded from "modal/modalAutoUpdateDownloaded";
import ModalUpgrade from 'modal/modalUpgrade';
import ModalWelcome from 'modal/modalWelcome';
import ModalFirstReward from 'modal/modalFirstReward';
@@ -102,6 +103,8 @@ class ModalRouter extends React.PureComponent {
return ;
case modals.DOWNLOADING:
return ;
+ case modals.AUTO_UPDATE_DOWNLOADED:
+ return ;
case modals.ERROR:
return ;
case modals.FILE_TIMEOUT:
From 24ced8ede7a0134b57cf47a13b1c37e8df4ace28 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Fri, 8 Dec 2017 07:14:37 -0500
Subject: [PATCH 10/34] More core UI for auto-update
We keep the old dialog flow on Linux, and on Windows and Mac we show a
single dialog when the file is downloaded.
---
src/renderer/constants/action_types.js | 1 +
src/renderer/index.js | 7 ++++++-
src/renderer/redux/actions/app.js | 17 +++++++++++++++++
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js
index 3c828f5cb..f09e13167 100644
--- a/src/renderer/constants/action_types.js
+++ b/src/renderer/constants/action_types.js
@@ -19,6 +19,7 @@ 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 AUTO_UPDATE_DOWNLOAD_COMPLETED = "AUTO_UPDATE_DOWNLOAD_COMPLETED";
export const CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE';
export const CHECK_UPGRADE_START = 'CHECK_UPGRADE_START';
export const CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS';
diff --git a/src/renderer/index.js b/src/renderer/index.js
index fd6dcc1f7..d7152880a 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -9,7 +9,7 @@ import lbry from 'lbry';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
-import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar } from 'redux/actions/app';
+import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar, doAutoUpdate } from 'redux/actions/app';
import { doNavigate } from 'redux/actions/navigation';
import { doDownloadLanguages } from 'redux/actions/settings';
import { doUserEmailVerify } from 'redux/actions/user';
@@ -17,6 +17,7 @@ import 'scss/all.scss';
import store from 'store';
import app from './app';
+const { autoUpdater } = remote.require('electron-updater');
const { contextMenu } = remote.require('./main.js');
window.addEventListener('contextmenu', event => {
@@ -97,6 +98,10 @@ document.addEventListener('click', event => {
});
const init = () => {
+ autoUpdater.on("update-downloaded", () => {
+ app.store.dispatch(doAutoUpdate());
+ });
+
app.store.dispatch(doDownloadLanguages());
function onDaemonReady() {
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index 2ecc1dcaf..26eb5bd7b 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -20,6 +20,7 @@ import {
selectUpgradeFilename,
} from 'redux/selectors/app';
+const { autoUpdater } = remote.require('electron-updater');
const { download } = remote.require('electron-dl');
const Fs = remote.require('fs');
const { lbrySettings: config } = require('package.json');
@@ -105,6 +106,16 @@ export function doDownloadUpgrade() {
};
}
+export function doAutoUpdate() {
+ return function(dispatch, getState) {
+ const state = getState();
+ dispatch({
+ type: types.OPEN_MODAL,
+ data: modals.AUTO_UPDATE_DOWNLOADED,
+ });
+ };
+}
+
export function doCancelUpgrade() {
return (dispatch, getState) => {
const state = getState();
@@ -135,6 +146,12 @@ export function doCheckUpgradeAvailable() {
type: ACTIONS.CHECK_UPGRADE_START,
});
+ if (["win32", "darwin"].includes(process.platform)) {
+ // On Windows and Mac, updates happen silently
+ autoUpdater.checkForUpdates();
+ return;
+ }
+
const success = ({ remoteVersion, upgradeAvailable }) => {
dispatch({
type: ACTIONS.CHECK_UPGRADE_SUCCESS,
From 565f4119860e6e38335c5bba19ae955f66bffcb5 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sun, 10 Dec 2017 03:01:24 -0500
Subject: [PATCH 11/34] Make app actually quit for update
Before, it was just minimizing and the app wouldn't even update because
electron-updater expects to be able to close the app.
---
src/main/index.js | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/main/index.js b/src/main/index.js
index a774cf8ee..1dfb4145b 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -436,6 +436,9 @@ app.on('before-quit', event => {
shutdownDaemonAndQuit();
} else {
console.log('Quitting.');
+ if (autoUpdating) {
+ minimize = false;
+ }
}
});
@@ -522,6 +525,11 @@ ipcMain.on('version-info-requested', () => {
});
});
+ipcMain.on('autoUpdate', () => {
+ minimize = false;
+ autoUpdater.quitAndInstall();
+});
+
ipcMain.on('get-auth-token', event => {
Keytar.getPassword('LBRY', 'auth_token').then(token => {
event.sender.send('auth-token-response', token ? token.toString().trim() : null);
From 3957bf2afc7aaa614824d28dd06826049d9c2e3f Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sun, 10 Dec 2017 03:06:30 -0500
Subject: [PATCH 12/34] Finish core UI for auto update
---
src/main/index.js | 3 ---
src/renderer/constants/action_types.js | 1 -
src/renderer/index.js | 14 ++++++++++++++
.../modal/modalAutoUpdateDownloaded/view.jsx | 7 ++++---
src/renderer/redux/actions/app.js | 2 +-
5 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/main/index.js b/src/main/index.js
index 1dfb4145b..e4c3e1ffb 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -436,9 +436,6 @@ app.on('before-quit', event => {
shutdownDaemonAndQuit();
} else {
console.log('Quitting.');
- if (autoUpdating) {
- minimize = false;
- }
}
});
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js
index f09e13167..3c828f5cb 100644
--- a/src/renderer/constants/action_types.js
+++ b/src/renderer/constants/action_types.js
@@ -19,7 +19,6 @@ 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 AUTO_UPDATE_DOWNLOAD_COMPLETED = "AUTO_UPDATE_DOWNLOAD_COMPLETED";
export const CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE';
export const CHECK_UPGRADE_START = 'CHECK_UPGRADE_START';
export const CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS';
diff --git a/src/renderer/index.js b/src/renderer/index.js
index d7152880a..cafd41c35 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -20,6 +20,8 @@ import app from './app';
const { autoUpdater } = remote.require('electron-updater');
const { contextMenu } = remote.require('./main.js');
+autoUpdater.logger = remote.require("electron-log");
+
window.addEventListener('contextmenu', event => {
contextMenu(remote.getCurrentWindow(), event.x, event.y, app.env === 'development');
event.preventDefault();
@@ -102,6 +104,18 @@ const init = () => {
app.store.dispatch(doAutoUpdate());
});
+ if (["win32", "darwin"].includes(process.platform)) {
+ autoUpdater.on("update-available", () => {
+ console.log("Update available");
+ });
+ autoUpdater.on("update-not-available", () => {
+ console.log("Update not available");
+ });
+ autoUpdater.on("update-downloaded", () => {
+ console.log("Update downloaded");
+ app.store.dispatch(doAutoUpdate());
+ });
+ }
app.store.dispatch(doDownloadLanguages());
function onDaemonReady() {
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index 46803c645..2d136071a 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -3,8 +3,7 @@ import { Modal } from "modal/modal";
import { Line } from "rc-progress";
import Link from "component/link/index";
-const { remote } = require("electron");
-const { autoUpdater } = remote.require("electron-updater");
+const { ipcRenderer } = require("electron");
class ModalAutoUpdateDownloaded extends React.PureComponent {
render() {
@@ -13,7 +12,9 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
isOpen={true}
contentLabel={__("Update downloaded")}
confirmButtonLabel={__("Update and Restart")}
- onConfirmed={autoUpdater.quitAndInstall()}
+ onConfirmed={() => {
+ ipcRenderer.send("autoUpdate");
+ }}
>
{__("LBRY Leveled Up")}
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index 26eb5bd7b..e2b36470b 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -111,7 +111,7 @@ export function doAutoUpdate() {
const state = getState();
dispatch({
type: types.OPEN_MODAL,
- data: modals.AUTO_UPDATE_DOWNLOADED,
+ data: { modal: modals.AUTO_UPDATE_DOWNLOADED },
});
};
}
From acec4a745f219c52379156bd1b9c7280ee1df7c6 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Sat, 16 Dec 2017 19:42:40 -0500
Subject: [PATCH 13/34] Remove S3 upload from upload_assets.py
---
build/upload_assets.py | 59 ------------------------------------------
1 file changed, 59 deletions(-)
diff --git a/build/upload_assets.py b/build/upload_assets.py
index 59817cf60..b0fb5513c 100644
--- a/build/upload_assets.py
+++ b/build/upload_assets.py
@@ -9,13 +9,8 @@ import github
import uritemplate
import boto3
-S3_BUCKET = 'releases.lbry.io'
-RELEASES_S3_PATH = 'app'
-LATEST_S3_PATH = 'app/latest'
-
def main():
upload_to_github_if_tagged('lbryio/lbry-app')
- upload_to_s3(RELEASES_S3_PATH)
def get_asset_path():
@@ -51,60 +46,6 @@ def get_latest_file_path():
return latestfilematches[0] if latestfilematches else None
-
-def upload_to_s3(folder):
- asset_path = get_asset_path()
-
- if 'AWS_ACCESS_KEY_ID' not in os.environ or 'AWS_SECRET_ACCESS_KEY' not in os.environ:
- print 'Must set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to publish assets to s3'
- return 1
-
- asset_filename = os.path.basename(asset_path)
-
- tag = subprocess.check_output(['git', 'describe', '--always', '--abbrev=8', 'HEAD']).strip()
- commit_date = subprocess.check_output([
- 'git', 'show', '-s', '--format=%cd', '--date=format:%Y%m%d-%H%I%S', 'HEAD']).strip()
- key = folder + '/' + commit_date + '-' + tag + '/' + asset_filename
-
- print "Uploading asset file at " + asset_path + " to s3://" + S3_BUCKET + '/' + key
-
- s3 = boto3.resource(
- 's3',
- aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
- aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
- config=boto3.session.Config(signature_version='s3v4')
- )
-
- s3.Object(S3_BUCKET, key).upload_file(asset_path)
-
- # Populate the update bucket (update.lbry.io)
-
- update_asset_path = get_update_asset_path()
- if asset_path == update_asset_path:
- # If the update asset and the regular built file are the same, we can
- # just copy over.
- print "Copying asset file to s3://" + S3_BUCKET + "/" + LATEST_S3_PATH + "/" + asset_filename
- s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + asset_filename).copy_from(CopySource={
- 'Bucket': S3_BUCKET,
- 'Key': key
- })
- else:
- update_asset_filename = os.path.basename(update_asset_path)
- print "Uploading update asset file at", update_asset_path, \
- "to s3://" + S3_BUCKET + "/" + LATEST_S3_PATH + "/" + update_asset_filename
- s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + update_asset_filename).upload_file(update_asset_path)
-
- metadatafilepath = get_latest_file_path()
-
- if metadatafilepath is not None:
- # For some reason latest-linux.yml isn't being created, but it's OK because updates don't
- # work on Linux yet anyway.
- metadatafilename = os.path.basename(metadatafilepath)
-
- print "Uploading update metadata file at", metadatafilepath, "to S3"
- s3.Object(S3_BUCKET, LATEST_S3_PATH + "/" + metadatafilename).upload_file(metadatafilepath)
-
-
def upload_to_github_if_tagged(repo_name):
try:
current_tag = subprocess.check_output(
From bc15d24d66954d07b7f416146241d0bb3419ef1b Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Fri, 22 Dec 2017 01:42:04 -0500
Subject: [PATCH 14/34] Add ability to decline updates
---
src/main/index.js | 2 ++
src/renderer/modal/modalAutoUpdateDownloaded/index.js | 7 ++++++-
src/renderer/modal/modalAutoUpdateDownloaded/view.jsx | 5 +++++
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/main/index.js b/src/main/index.js
index e4c3e1ffb..eb5d53b6a 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -21,6 +21,8 @@ const isDevelopment = process.env.NODE_ENV === 'development';
// For now, log info messages in production for easier debugging of built apps
log.transports.file.level = 'info';
+autoUpdater.autoDownload = true;
+
// Misc constants
const LATEST_RELEASE_API_URL = 'https://api.github.com/repos/lbryio/lbry-app/releases/latest';
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/index.js b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
index 921271126..740a2dca2 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/index.js
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
@@ -1,5 +1,10 @@
import React from "react";
import { connect } from "react-redux";
+import { doCloseModal } from "redux/actions/app";
import ModalAutoUpdateDownloaded from "./view";
-export default connect(null, null)(ModalAutoUpdateDownloaded);
+const perform = dispatch => ({
+ closeModal: () => dispatch(doCloseModal()),
+});
+
+export default connect(null, perform)(ModalAutoUpdateDownloaded);
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index 2d136071a..39971118a 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -7,14 +7,19 @@ const { ipcRenderer } = require("electron");
class ModalAutoUpdateDownloaded extends React.PureComponent {
render() {
+ const { closeModal } = this.props;
+
return (
{
ipcRenderer.send("autoUpdate");
}}
+ onAborted={closeModal}
>
{__("LBRY Leveled Up")}
From b08d96da1e942c7ad177dbacdda31ecac6f0a484 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 2 Jan 2018 06:51:37 -0500
Subject: [PATCH 15/34] Add alert before close after update is declined on
Windows
---
src/main/index.js | 25 ++++++++++++++++++-
src/renderer/constants/modal_types.js | 1 +
src/renderer/index.js | 4 +--
.../modal/modalAutoUpdateDownloaded/index.js | 1 +
src/renderer/modal/modalRouter/view.jsx | 3 +++
.../modal/modalUpdateCloseAlert/index.js | 12 +++++++++
.../modal/modalUpdateCloseAlert/view.jsx | 23 +++++++++++++++++
src/renderer/redux/actions/app.js | 4 +--
8 files changed, 68 insertions(+), 5 deletions(-)
create mode 100644 src/renderer/modal/modalUpdateCloseAlert/index.js
create mode 100644 src/renderer/modal/modalUpdateCloseAlert/view.jsx
diff --git a/src/main/index.js b/src/main/index.js
index eb5d53b6a..e880d562c 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -48,6 +48,20 @@ let daemonSubprocess;
// if it dies when we didn't ask it to shut down, we want to alert the user.
let daemonStopRequested = false;
+// This keeps track of whether a new file has been downloaded. We mostly
+// handle auto-update stuff in the render process, but need to know this
+// in order to display the extra confirmation dialog we show on close
+// on Windows.
+let updateDownloaded;
+if (process.platform === 'win32') {
+ updateDownloaded = false;
+}
+
+// This is used to keep track of whether we are showing he special dialog
+// that we show on Windows after you decline an upgrade and close the app later.
+let showingUpdateCloseAlert = false;
+
+
// When a quit is attempted, we cancel the quit, do some preparations, then
// this is set to true and app.quit() is called again to quit for real.
let readyToQuit = false;
@@ -406,6 +420,10 @@ if (isDevelopment) {
});
}
+autoUpdater.on('update-downloaded', () => {
+ updateDownloaded = true;
+});
+
app.setAsDefaultProtocolClient('lbry');
app.on('ready', () => {
@@ -431,7 +449,12 @@ app.on('window-all-closed', () => {
});
app.on('before-quit', event => {
- if (!readyToQuit) {
+ if (process.platform === 'darwin' && updateDownloaded && !showingUpdateCloseAlert) {
+ // We haven't shown the special dialog that we show on Windows
+ // if the user declines an update and then quits later
+ rendererWindow.webContents.send('quitRequested');
+ showingUpdateCloseAlert = true;
+ } else if (!readyToQuit) {
// We need to shutdown the daemon before we're ready to actually quit. This
// event will be triggered re-entrantly once preparation is done.
event.preventDefault();
diff --git a/src/renderer/constants/modal_types.js b/src/renderer/constants/modal_types.js
index 8e56e8237..aba7e21aa 100644
--- a/src/renderer/constants/modal_types.js
+++ b/src/renderer/constants/modal_types.js
@@ -3,6 +3,7 @@ export const INCOMPATIBLE_DAEMON = 'incompatibleDaemon';
export const FILE_TIMEOUT = 'file_timeout';
export const DOWNLOADING = 'downloading';
export const AUTO_UPDATE_DOWNLOADED = "auto_update_downloaded";
+export const UPDATE_CLOSE_ALERT = "updateCloseAlert";
export const ERROR = 'error';
export const INSUFFICIENT_CREDITS = 'insufficient_credits';
export const UPGRADE = 'upgrade';
diff --git a/src/renderer/index.js b/src/renderer/index.js
index cafd41c35..cd9ab98ff 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -9,7 +9,7 @@ import lbry from 'lbry';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
-import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar, doAutoUpdate } from 'redux/actions/app';
+import { doConditionalAuthNavigate, doOpenModal, doDaemonReady, doShowSnackBar, doAutoUpdate } from 'redux/actions/app';
import { doNavigate } from 'redux/actions/navigation';
import { doDownloadLanguages } from 'redux/actions/settings';
import { doUserEmailVerify } from 'redux/actions/user';
@@ -62,7 +62,7 @@ ipcRenderer.on('window-is-focused', () => {
dock.setBadge('');
});
-((history, ...args) => {
+(function(history, ...args) {
const { replaceState } = history;
const newHistory = history;
newHistory.replaceState = (_, __, path) => {
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/index.js b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
index 740a2dca2..0ce6cdcbe 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/index.js
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
@@ -2,6 +2,7 @@ import React from "react";
import { connect } from "react-redux";
import { doCloseModal } from "redux/actions/app";
import ModalAutoUpdateDownloaded from "./view";
+import { doCloseModal } from "redux/actions/app";
const perform = dispatch => ({
closeModal: () => dispatch(doCloseModal()),
diff --git a/src/renderer/modal/modalRouter/view.jsx b/src/renderer/modal/modalRouter/view.jsx
index 81925c966..a8fa1dfbf 100644
--- a/src/renderer/modal/modalRouter/view.jsx
+++ b/src/renderer/modal/modalRouter/view.jsx
@@ -3,6 +3,7 @@ import ModalError from 'modal/modalError';
import ModalAuthFailure from 'modal/modalAuthFailure';
import ModalDownloading from 'modal/modalDownloading';
import ModalAutoUpdateDownloaded from "modal/modalAutoUpdateDownloaded";
+import ModalUpdateCloseAlert from "modal/modalUpdateCloseAlert";
import ModalUpgrade from 'modal/modalUpgrade';
import ModalWelcome from 'modal/modalWelcome';
import ModalFirstReward from 'modal/modalFirstReward';
@@ -105,6 +106,8 @@ class ModalRouter extends React.PureComponent {
return ;
case modals.AUTO_UPDATE_DOWNLOADED:
return ;
+ case modals.UPDATE_CLOSE_ALERT:
+ return ;
case modals.ERROR:
return ;
case modals.FILE_TIMEOUT:
diff --git a/src/renderer/modal/modalUpdateCloseAlert/index.js b/src/renderer/modal/modalUpdateCloseAlert/index.js
new file mode 100644
index 000000000..caff049a6
--- /dev/null
+++ b/src/renderer/modal/modalUpdateCloseAlert/index.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { doQuit } from 'redux/actions/app';
+import ModalUpdateCloseAlert from './view';
+
+const select = state => ({});
+
+const perform = dispatch => ({
+ quit: () => dispatch(doSkipUpgrade()),
+});
+
+export default connect(select, perform)(ModalUpdateCloseAlert);
diff --git a/src/renderer/modal/modalUpdateCloseAlert/view.jsx b/src/renderer/modal/modalUpdateCloseAlert/view.jsx
new file mode 100644
index 000000000..9f0b28c3a
--- /dev/null
+++ b/src/renderer/modal/modalUpdateCloseAlert/view.jsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { Modal } from 'modal/modal';
+import Link from 'component/link';
+
+class ModalUpdateCloseAlert extends React.PureComponent {
+ render() {
+ const { quit } = this.props;
+
+ return (
+
+
{__('LBRY Will Upgrade')}
+
{__('Please select yes to the upgrade prompt shown after the app closes.')}
+
+ );
+ }
+}
+
+export default ModalUpdateCloseAlert;
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index e2b36470b..8ae003bf7 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -110,8 +110,8 @@ export function doAutoUpdate() {
return function(dispatch, getState) {
const state = getState();
dispatch({
- type: types.OPEN_MODAL,
- data: { modal: modals.AUTO_UPDATE_DOWNLOADED },
+ type: ACTIONS.OPEN_MODAL,
+ data: { modal: MODALS.AUTO_UPDATE_DOWNLOADED },
});
};
}
From b03623eb68ef7624c25539ea500c01183bd1f3bf Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Fri, 5 Jan 2018 01:29:31 -0500
Subject: [PATCH 16/34] Convert Windows update alert dialog to native dialog in
main process
Maybe a bit less polished, but I couldn't find a way to prevent the
main window from closing that works on the current version of Electron,
and in general it was starting to get too complicated.
---
src/main/index.js | 49 ++++++++++---------
src/renderer/constants/modal_types.js | 1 -
src/renderer/index.js | 4 +-
.../modal/modalAutoUpdateDownloaded/index.js | 1 -
.../modal/modalAutoUpdateDownloaded/view.jsx | 5 +-
src/renderer/modal/modalRouter/view.jsx | 3 --
.../modal/modalUpdateCloseAlert/index.js | 12 -----
.../modal/modalUpdateCloseAlert/view.jsx | 23 ---------
8 files changed, 32 insertions(+), 66 deletions(-)
delete mode 100644 src/renderer/modal/modalUpdateCloseAlert/index.js
delete mode 100644 src/renderer/modal/modalUpdateCloseAlert/view.jsx
diff --git a/src/main/index.js b/src/main/index.js
index e880d562c..c5aed361f 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -8,7 +8,7 @@ import Https from 'https';
import Keytar from 'keytar';
import ChildProcess from 'child_process';
import Assert from 'assert';
-import { app, BrowserWindow, globalShortcut, ipcMain, Menu, Tray } from 'electron';
+import { app, dialog, BrowserWindow, globalShortcut, ipcMain, Menu, Tray } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import mainMenu from './menu/mainMenu';
@@ -48,18 +48,14 @@ let daemonSubprocess;
// if it dies when we didn't ask it to shut down, we want to alert the user.
let daemonStopRequested = false;
-// This keeps track of whether a new file has been downloaded. We mostly
-// handle auto-update stuff in the render process, but need to know this
-// in order to display the extra confirmation dialog we show on close
-// on Windows.
-let updateDownloaded;
-if (process.platform === 'win32') {
- updateDownloaded = false;
-}
+// This keeps track of whether the user has declined an update that was downloaded
+// through the Electron auto-update system. When the user declines an update on Windows,
+// they will get a confusing dialog, so we show our own dialog first.
+let autoUpdateDeclined = false;
// This is used to keep track of whether we are showing he special dialog
// that we show on Windows after you decline an upgrade and close the app later.
-let showingUpdateCloseAlert = false;
+let showingAutoUpdateCloseAlert = false;
// When a quit is attempted, we cancel the quit, do some preparations, then
@@ -420,10 +416,6 @@ if (isDevelopment) {
});
}
-autoUpdater.on('update-downloaded', () => {
- updateDownloaded = true;
-});
-
app.setAsDefaultProtocolClient('lbry');
app.on('ready', () => {
@@ -449,18 +441,25 @@ app.on('window-all-closed', () => {
});
app.on('before-quit', event => {
- if (process.platform === 'darwin' && updateDownloaded && !showingUpdateCloseAlert) {
- // We haven't shown the special dialog that we show on Windows
- // if the user declines an update and then quits later
- rendererWindow.webContents.send('quitRequested');
- showingUpdateCloseAlert = true;
- } else if (!readyToQuit) {
+ if (!readyToQuit) {
// We need to shutdown the daemon before we're ready to actually quit. This
// event will be triggered re-entrantly once preparation is done.
event.preventDefault();
shutdownDaemonAndQuit();
- } else {
- console.log('Quitting.');
+ } else if (process.platform == 'win32' && autoUpdateDeclined && !showingAutoUpdateCloseAlert) {
+ // On Windows, if the user declined an update and closes the app later,
+ // they get a confusing permission escalation dialog, so we display a
+ // dialog to warn them.
+ event.preventDefault();
+ showingAutoUpdateCloseAlert = true;
+ dialog.showMessageBox({
+ type: "info",
+ title: "LBRY Will Upgrade",
+ message: "Please select \"Yes\" at the upgrade prompt shown after the app closes.",
+ }, () => {
+ // After the user approves the dialog, we can quit once and for all.
+ quitNow();
+ });
}
});
@@ -549,7 +548,11 @@ ipcMain.on('version-info-requested', () => {
ipcMain.on('autoUpdate', () => {
minimize = false;
- autoUpdater.quitAndInstall();
+ app.quit();
+});
+
+ipcMain.on('autoUpdateDeclined', () => {
+ autoUpdateDeclined = true;
});
ipcMain.on('get-auth-token', event => {
diff --git a/src/renderer/constants/modal_types.js b/src/renderer/constants/modal_types.js
index aba7e21aa..8e56e8237 100644
--- a/src/renderer/constants/modal_types.js
+++ b/src/renderer/constants/modal_types.js
@@ -3,7 +3,6 @@ export const INCOMPATIBLE_DAEMON = 'incompatibleDaemon';
export const FILE_TIMEOUT = 'file_timeout';
export const DOWNLOADING = 'downloading';
export const AUTO_UPDATE_DOWNLOADED = "auto_update_downloaded";
-export const UPDATE_CLOSE_ALERT = "updateCloseAlert";
export const ERROR = 'error';
export const INSUFFICIENT_CREDITS = 'insufficient_credits';
export const UPGRADE = 'upgrade';
diff --git a/src/renderer/index.js b/src/renderer/index.js
index cd9ab98ff..cafd41c35 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -9,7 +9,7 @@ import lbry from 'lbry';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
-import { doConditionalAuthNavigate, doOpenModal, doDaemonReady, doShowSnackBar, doAutoUpdate } from 'redux/actions/app';
+import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar, doAutoUpdate } from 'redux/actions/app';
import { doNavigate } from 'redux/actions/navigation';
import { doDownloadLanguages } from 'redux/actions/settings';
import { doUserEmailVerify } from 'redux/actions/user';
@@ -62,7 +62,7 @@ ipcRenderer.on('window-is-focused', () => {
dock.setBadge('');
});
-(function(history, ...args) {
+((history, ...args) => {
const { replaceState } = history;
const newHistory = history;
newHistory.replaceState = (_, __, path) => {
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/index.js b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
index 0ce6cdcbe..740a2dca2 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/index.js
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
@@ -2,7 +2,6 @@ import React from "react";
import { connect } from "react-redux";
import { doCloseModal } from "redux/actions/app";
import ModalAutoUpdateDownloaded from "./view";
-import { doCloseModal } from "redux/actions/app";
const perform = dispatch => ({
closeModal: () => dispatch(doCloseModal()),
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index 39971118a..ac347d7c5 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -19,7 +19,10 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
onConfirmed={() => {
ipcRenderer.send("autoUpdate");
}}
- onAborted={closeModal}
+ onAborted={() => {
+ ipcRenderer.send("autoUpdateDeclined");
+ closeModal();
+ }}
>
{__("LBRY Leveled Up")}
diff --git a/src/renderer/modal/modalRouter/view.jsx b/src/renderer/modal/modalRouter/view.jsx
index a8fa1dfbf..81925c966 100644
--- a/src/renderer/modal/modalRouter/view.jsx
+++ b/src/renderer/modal/modalRouter/view.jsx
@@ -3,7 +3,6 @@ import ModalError from 'modal/modalError';
import ModalAuthFailure from 'modal/modalAuthFailure';
import ModalDownloading from 'modal/modalDownloading';
import ModalAutoUpdateDownloaded from "modal/modalAutoUpdateDownloaded";
-import ModalUpdateCloseAlert from "modal/modalUpdateCloseAlert";
import ModalUpgrade from 'modal/modalUpgrade';
import ModalWelcome from 'modal/modalWelcome';
import ModalFirstReward from 'modal/modalFirstReward';
@@ -106,8 +105,6 @@ class ModalRouter extends React.PureComponent {
return ;
case modals.AUTO_UPDATE_DOWNLOADED:
return ;
- case modals.UPDATE_CLOSE_ALERT:
- return ;
case modals.ERROR:
return ;
case modals.FILE_TIMEOUT:
diff --git a/src/renderer/modal/modalUpdateCloseAlert/index.js b/src/renderer/modal/modalUpdateCloseAlert/index.js
deleted file mode 100644
index caff049a6..000000000
--- a/src/renderer/modal/modalUpdateCloseAlert/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { doQuit } from 'redux/actions/app';
-import ModalUpdateCloseAlert from './view';
-
-const select = state => ({});
-
-const perform = dispatch => ({
- quit: () => dispatch(doSkipUpgrade()),
-});
-
-export default connect(select, perform)(ModalUpdateCloseAlert);
diff --git a/src/renderer/modal/modalUpdateCloseAlert/view.jsx b/src/renderer/modal/modalUpdateCloseAlert/view.jsx
deleted file mode 100644
index 9f0b28c3a..000000000
--- a/src/renderer/modal/modalUpdateCloseAlert/view.jsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from 'react';
-import { Modal } from 'modal/modal';
-import Link from 'component/link';
-
-class ModalUpdateCloseAlert extends React.PureComponent {
- render() {
- const { quit } = this.props;
-
- return (
-
-
{__('LBRY Will Upgrade')}
-
{__('Please select yes to the upgrade prompt shown after the app closes.')}
-
- );
- }
-}
-
-export default ModalUpdateCloseAlert;
From 3959d4aeee7ad91735865f3498aedf1009868f07 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Mon, 8 Jan 2018 15:43:25 -0500
Subject: [PATCH 17/34] Make app restart after user approves update
Forgot to call quitAndInstall(). If you don't, it will still install
the update, but won't restart.
---
src/main/index.js | 57 ++++++++++++-------
.../modal/modalAutoUpdateDownloaded/view.jsx | 2 +-
2 files changed, 36 insertions(+), 23 deletions(-)
diff --git a/src/main/index.js b/src/main/index.js
index c5aed361f..5d6b4b451 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -48,10 +48,14 @@ let daemonSubprocess;
// if it dies when we didn't ask it to shut down, we want to alert the user.
let daemonStopRequested = false;
-// This keeps track of whether the user has declined an update that was downloaded
-// through the Electron auto-update system. When the user declines an update on Windows,
-// they will get a confusing dialog, so we show our own dialog first.
-let autoUpdateDeclined = false;
+
+// This is set to true if an auto update has been downloaded through the Electron
+// auto-update system and is ready to install. If the user declined an update earlier,
+// it will still install on shutdown.
+let autoUpdateDownloaded = false;
+
+// Keeps track of whether the user has accepted an auto-update through the interface.
+let autoUpdateAccepted = false;
// This is used to keep track of whether we are showing he special dialog
// that we show on Windows after you decline an upgrade and close the app later.
@@ -446,20 +450,26 @@ app.on('before-quit', event => {
// event will be triggered re-entrantly once preparation is done.
event.preventDefault();
shutdownDaemonAndQuit();
- } else if (process.platform == 'win32' && autoUpdateDeclined && !showingAutoUpdateCloseAlert) {
- // On Windows, if the user declined an update and closes the app later,
- // they get a confusing permission escalation dialog, so we display a
- // dialog to warn them.
- event.preventDefault();
- showingAutoUpdateCloseAlert = true;
- dialog.showMessageBox({
- type: "info",
- title: "LBRY Will Upgrade",
- message: "Please select \"Yes\" at the upgrade prompt shown after the app closes.",
- }, () => {
- // After the user approves the dialog, we can quit once and for all.
- quitNow();
- });
+ } else if (autoUpdateDownloaded) {
+ if (autoUpdateAccepted) {
+ // User accepted the update, so install the update and restart.
+ autoUpdater.quitAndInstall();
+ } else if (process.platform == 'win32' && !showingAutoUpdateCloseAlert) {
+ // We have an update downloaded, but the user declined it (or closed the app without
+ // accepting it). Now the user is closing the app, so the new update will install.
+ // On Mac this is silent, but on Windows they get a confusing permission escalation
+ // dialog, so we show Windows users a warning dialog first.
+ event.preventDefault();
+ showingAutoUpdateCloseAlert = true;
+ dialog.showMessageBox({
+ type: "info",
+ title: "LBRY Will Upgrade",
+ message: "Please select \"Yes\" at the upgrade prompt shown after the app closes.",
+ }, () => {
+ // After the user approves the dialog, we can quit once and for all.
+ quitNow();
+ });
+ }
}
});
@@ -546,14 +556,17 @@ ipcMain.on('version-info-requested', () => {
});
});
-ipcMain.on('autoUpdate', () => {
+
+autoUpdater.on('update-downloaded', () => {
+ autoUpdateDownloaded = true;
+});
+
+ipcMain.on('autoUpdateAccepted', () => {
+ autoUpdateAccepted = true;
minimize = false;
app.quit();
});
-ipcMain.on('autoUpdateDeclined', () => {
- autoUpdateDeclined = true;
-});
ipcMain.on('get-auth-token', event => {
Keytar.getPassword('LBRY', 'auth_token').then(token => {
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index ac347d7c5..a5b4cb722 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -17,7 +17,7 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
confirmButtonLabel={__("Update and Restart")}
abortButtonLabel={__("Don't Update")}
onConfirmed={() => {
- ipcRenderer.send("autoUpdate");
+ ipcRenderer.send("autoUpdateAccepted");
}}
onAborted={() => {
ipcRenderer.send("autoUpdateDeclined");
From cf3406f926d93e59720e837c39fb358592b76ea3 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Mon, 8 Jan 2018 15:53:48 -0500
Subject: [PATCH 18/34] Remove icon from the Windows auto-update alert dialog
shown on closing
---
src/main/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/index.js b/src/main/index.js
index 5d6b4b451..bc7945245 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -463,7 +463,7 @@ app.on('before-quit', event => {
showingAutoUpdateCloseAlert = true;
dialog.showMessageBox({
type: "info",
- title: "LBRY Will Upgrade",
+ title: "LBRY will upgrade",
message: "Please select \"Yes\" at the upgrade prompt shown after the app closes.",
}, () => {
// After the user approves the dialog, we can quit once and for all.
From fb8aee46323d659c7f77c97de41a4940168d514b Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Mon, 8 Jan 2018 15:57:13 -0500
Subject: [PATCH 19/34] Version 0.31 [temp, for testing]
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 8cd6c8cb0..3951c7723 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.19.4",
+ "version": "0.31.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
From 5a475f4ba458f1a5a6c2a0575181a5e02b7a2fbd Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Mon, 8 Jan 2018 15:57:49 -0500
Subject: [PATCH 20/34] Version 0.32 [temp, for testing]
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 3951c7723..ab612689e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.31.0",
+ "version": "0.32.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
From 0c8ba50207553fbd27caae183feb3974c7007548 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Fri, 12 Jan 2018 22:18:55 -0500
Subject: [PATCH 21/34] Update Auto Update-related copy
---
src/main/index.js | 6 +++---
src/renderer/modal/modalAutoUpdateDownloaded/view.jsx | 8 ++++----
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/main/index.js b/src/main/index.js
index bc7945245..b3330c129 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -462,9 +462,9 @@ app.on('before-quit', event => {
event.preventDefault();
showingAutoUpdateCloseAlert = true;
dialog.showMessageBox({
- type: "info",
- title: "LBRY will upgrade",
- message: "Please select \"Yes\" at the upgrade prompt shown after the app closes.",
+ type: 'info',
+ title: 'LBRY Will Upgrade',
+ message: 'LBRY has a pending upgrade. Please select "Yes" to install it on the prompt shown after this one.',
}, () => {
// After the user approves the dialog, we can quit once and for all.
quitNow();
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index a5b4cb722..12aa2d819 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -13,9 +13,9 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
{
ipcRenderer.send("autoUpdateAccepted");
}}
@@ -28,7 +28,7 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
{__("LBRY Leveled Up")}
{__(
- "A new version of LBRY has been downloaded and is ready to install."
+ 'A new version of LBRY has been released, downloaded, and is ready for you to use pending a restart.'
)}
+ {__(
+ 'Your LBRY update is ready. Restart LBRY now to use it!'
+ )}
+
+
+
+ );
+ }
+}
+
+export default ModalAutoUpdateConfirm;
diff --git a/src/renderer/modal/modalRouter/view.jsx b/src/renderer/modal/modalRouter/view.jsx
index 81925c966..8dd7e4bc6 100644
--- a/src/renderer/modal/modalRouter/view.jsx
+++ b/src/renderer/modal/modalRouter/view.jsx
@@ -3,6 +3,7 @@ import ModalError from 'modal/modalError';
import ModalAuthFailure from 'modal/modalAuthFailure';
import ModalDownloading from 'modal/modalDownloading';
import ModalAutoUpdateDownloaded from "modal/modalAutoUpdateDownloaded";
+import ModalAutoUpdateConfirm from "modal/modalAutoUpdateDownloaded";
import ModalUpgrade from 'modal/modalUpgrade';
import ModalWelcome from 'modal/modalWelcome';
import ModalFirstReward from 'modal/modalFirstReward';
@@ -105,6 +106,8 @@ class ModalRouter extends React.PureComponent {
return ;
case modals.AUTO_UPDATE_DOWNLOADED:
return ;
+ case modals.AUTO_UPDATE_CONFIRM:
+ return ;
case modals.ERROR:
return ;
case modals.FILE_TIMEOUT:
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index 8ae003bf7..92dc52c66 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -67,6 +67,26 @@ export function doStartUpgrade() {
};
}
+export function doDownloadUpgradeRequested() {
+ // This means the user requested an upgrade by clicking the "upgrade" button in the navbar.
+ // If on Mac and Windows, we do some new behavior for the auto-update system.
+ // This will probably be reorganized once we get auto-update going on Linux and remove
+ // the old logic.
+
+ return (dispatch, getState) => {
+ const state = getState();
+
+ if (['win32', 'darwin'].includes(process.platform)) { // electron-updater behavior
+ dispatch({
+ type: ACTIONS.OPEN_MODAL,
+ data: { modal: MODALS.AUTO_UPDATE_CONFIRM },
+ });
+ } else { // Old behavior for Linux
+ doDownloadUpgrade();
+ }
+ };
+}
+
export function doDownloadUpgrade() {
return (dispatch, getState) => {
const state = getState();
@@ -109,6 +129,10 @@ export function doDownloadUpgrade() {
export function doAutoUpdate() {
return function(dispatch, getState) {
const state = getState();
+ dispatch({
+ type: ACTIONS.AUTO_UPDATE_DOWNLOADED,
+ });
+
dispatch({
type: ACTIONS.OPEN_MODAL,
data: { modal: MODALS.AUTO_UPDATE_DOWNLOADED },
diff --git a/src/renderer/redux/reducers/app.js b/src/renderer/redux/reducers/app.js
index 87a588f3c..7e478597d 100644
--- a/src/renderer/redux/reducers/app.js
+++ b/src/renderer/redux/reducers/app.js
@@ -46,6 +46,7 @@ const defaultState: AppState = {
hasSignature: false,
badgeNumber: 0,
volume: Number(sessionStorage.getItem('volume')) || 1,
+ autoUpdateDownloaded: false,
downloadProgress: undefined,
upgradeDownloading: undefined,
@@ -79,6 +80,11 @@ reducers[ACTIONS.UPGRADE_CANCELLED] = state =>
modal: null,
});
+reducers[ACTIONS.AUTO_UPDATE_DOWNLOADED] = state =>
+ Object.assign({}, state, {
+ autoUpdateDownloaded: true,
+ });
+
reducers[ACTIONS.UPGRADE_DOWNLOAD_COMPLETED] = (state, action) =>
Object.assign({}, state, {
downloadPath: action.data.path,
diff --git a/src/renderer/redux/selectors/app.js b/src/renderer/redux/selectors/app.js
index 052fe7096..04c04baa9 100644
--- a/src/renderer/redux/selectors/app.js
+++ b/src/renderer/redux/selectors/app.js
@@ -56,6 +56,8 @@ export const selectUpgradeDownloadPath = createSelector(selectState, state => st
export const selectUpgradeDownloadItem = createSelector(selectState, state => state.downloadItem);
+export const selectAutoUpdateDownloaded = createSelector(selectState, state => state.autoUpdateDownloaded);
+
export const selectModalProps = createSelector(selectState, state => state.modalProps);
export const selectDaemonVersionMatched = createSelector(
From dccb06c13c3fe22fbb16ea780313c388f250b117 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 16 Jan 2018 19:21:22 -0500
Subject: [PATCH 23/34] Version 0.35 [temp, for testing]
---
package.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/package.json b/package.json
index ab612689e..00ba9a931 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.32.0",
+ "version": "0.35.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
@@ -20,7 +20,6 @@
"dev": "electron-webpack dev",
"compile": "electron-webpack && yarn extract-langs",
"build": "yarn compile && electron-builder build",
- "build:dir": "yarn build -- --dir -c.compression=store -c.mac.identity=null",
"postinstall": "electron-builder install-app-deps",
"precommit": "lint-staged",
"lint": "eslint 'src/**/*.{js,jsx}' --fix",
From 863f7dc23b0341a70f7bbe1bf47dedc8eb87f6f6 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Wed, 17 Jan 2018 05:50:02 -0500
Subject: [PATCH 24/34] Make new dialogs behave correctly when video is playing
---
src/renderer/constants/action_types.js | 1 +
.../modal/modalAutoUpdateConfirm/index.js | 3 +-
.../modal/modalAutoUpdateConfirm/view.jsx | 3 +-
.../modal/modalAutoUpdateDownloaded/index.js | 3 +-
.../modal/modalAutoUpdateDownloaded/view.jsx | 3 +-
src/renderer/modal/modalRouter/index.js | 3 +-
src/renderer/modal/modalRouter/view.jsx | 2 +-
src/renderer/redux/actions/app.js | 29 ++++++++--
src/renderer/redux/reducers/app.js | 54 ++++++++++++++++---
src/renderer/redux/selectors/app.js | 4 ++
10 files changed, 89 insertions(+), 16 deletions(-)
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js
index 4a952d780..425955815 100644
--- a/src/renderer/constants/action_types.js
+++ b/src/renderer/constants/action_types.js
@@ -28,6 +28,7 @@ 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';
+export const AUTO_UPDATE_DECLINED = 'AUTO_UPDATE_DECLINED';
export const AUTO_UPDATE_DOWNLOADED = 'AUTO_UPDATE_DOWNLOADED';
// Wallet
diff --git a/src/renderer/modal/modalAutoUpdateConfirm/index.js b/src/renderer/modal/modalAutoUpdateConfirm/index.js
index 52b3bca01..a00df7e2f 100644
--- a/src/renderer/modal/modalAutoUpdateConfirm/index.js
+++ b/src/renderer/modal/modalAutoUpdateConfirm/index.js
@@ -1,10 +1,11 @@
import React from "react";
import { connect } from "react-redux";
-import { doCloseModal } from "redux/actions/app";
+import { doCloseModal, doAutoUpdateDeclined } from "redux/actions/app";
import ModalAutoUpdateConfirm from "./view";
const perform = dispatch => ({
closeModal: () => dispatch(doCloseModal()),
+ declineAutoUpdate: () => dispatch(doAutoUpdateDeclined()),
});
export default connect(null, perform)(ModalAutoUpdateConfirm);
diff --git a/src/renderer/modal/modalAutoUpdateConfirm/view.jsx b/src/renderer/modal/modalAutoUpdateConfirm/view.jsx
index a96458e09..88218c4da 100644
--- a/src/renderer/modal/modalAutoUpdateConfirm/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateConfirm/view.jsx
@@ -7,7 +7,7 @@ const { ipcRenderer } = require("electron");
class ModalAutoUpdateConfirm extends React.PureComponent {
render() {
- const { closeModal } = this.props;
+ const { closeModal, declineAutoUpdate } = this.props;
return (
{
+ declineAutoUpdate();
closeModal();
}}
>
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/index.js b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
index 740a2dca2..7283489aa 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/index.js
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/index.js
@@ -1,10 +1,11 @@
import React from "react";
import { connect } from "react-redux";
-import { doCloseModal } from "redux/actions/app";
+import { doCloseModal, doAutoUpdateDeclined } from "redux/actions/app";
import ModalAutoUpdateDownloaded from "./view";
const perform = dispatch => ({
closeModal: () => dispatch(doCloseModal()),
+ declineAutoUpdate: () => dispatch(doAutoUpdateDeclined()),
});
export default connect(null, perform)(ModalAutoUpdateDownloaded);
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index 12aa2d819..5a1b69885 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -7,7 +7,7 @@ const { ipcRenderer } = require("electron");
class ModalAutoUpdateDownloaded extends React.PureComponent {
render() {
- const { closeModal } = this.props;
+ const { closeModal, declineAutoUpdate } = this.props;
return (
{
+ declineAutoUpdate();
ipcRenderer.send("autoUpdateDeclined");
closeModal();
}}
diff --git a/src/renderer/modal/modalRouter/index.js b/src/renderer/modal/modalRouter/index.js
index 313c82528..cea033096 100644
--- a/src/renderer/modal/modalRouter/index.js
+++ b/src/renderer/modal/modalRouter/index.js
@@ -2,7 +2,7 @@ import React from 'react';
import { connect } from 'react-redux';
import { doOpenModal } from 'redux/actions/app';
import * as settings from 'constants/settings';
-import { selectCurrentModal, selectModalProps } from 'redux/selectors/app';
+import { selectCurrentModal, selectModalProps, selectModalsAllowed } from 'redux/selectors/app';
import { selectCurrentPage } from 'redux/selectors/navigation';
import { selectCostForCurrentPageUri } from 'redux/selectors/cost_info';
import { makeSelectClientSetting } from 'redux/selectors/settings';
@@ -24,6 +24,7 @@ const select = (state, props) => ({
),
isWelcomeAcknowledged: makeSelectClientSetting(settings.NEW_USER_ACKNOWLEDGED)(state),
user: selectUser(state),
+ modalsAllowed: selectModalsAllowed(state),
});
const perform = dispatch => ({
diff --git a/src/renderer/modal/modalRouter/view.jsx b/src/renderer/modal/modalRouter/view.jsx
index 8dd7e4bc6..924444687 100644
--- a/src/renderer/modal/modalRouter/view.jsx
+++ b/src/renderer/modal/modalRouter/view.jsx
@@ -97,7 +97,7 @@ class ModalRouter extends React.PureComponent {
}
render() {
- const { modal, modalProps } = this.props;
+ const { modal, modalsAllowed, modalProps } = this.props;
switch (modal) {
case modals.UPGRADE:
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index 92dc52c66..45d99b364 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -18,6 +18,7 @@ import {
selectUpgradeDownloadItem,
selectUpgradeDownloadPath,
selectUpgradeFilename,
+ selectAutoUpdateDeclined,
} from 'redux/selectors/app';
const { autoUpdater } = remote.require('electron-updater');
@@ -75,12 +76,23 @@ export function doDownloadUpgradeRequested() {
return (dispatch, getState) => {
const state = getState();
+ const autoUpdateDeclined = selectAutoUpdateDeclined(state);
if (['win32', 'darwin'].includes(process.platform)) { // electron-updater behavior
- dispatch({
- type: ACTIONS.OPEN_MODAL,
- data: { modal: MODALS.AUTO_UPDATE_CONFIRM },
- });
+ if (autoUpdateDeclined) {
+ // The user declined an update before, so show the "confirm" dialog
+ dispatch({
+ type: ACTIONS.OPEN_MODAL,
+ data: { modal: MODALS.AUTO_UPDATE_CONFIRM },
+ });
+ } else {
+ // The user was never shown the original update dialog (e.g. because they were
+ // watching a video). So show the inital "update downloaded" dialog.
+ dispatch({
+ type: ACTIONS.OPEN_MODAL,
+ data: { modal: MODALS.AUTO_UPDATE_DOWNLOADED },
+ });
+ }
} else { // Old behavior for Linux
doDownloadUpgrade();
}
@@ -140,6 +152,15 @@ export function doAutoUpdate() {
};
}
+export function doAutoUpdateDeclined() {
+ return function(dispatch, getState) {
+ const state = getState();
+ dispatch({
+ type: ACTIONS.AUTO_UPDATE_DECLINED,
+ });
+ }
+}
+
export function doCancelUpgrade() {
return (dispatch, getState) => {
const state = getState();
diff --git a/src/renderer/redux/reducers/app.js b/src/renderer/redux/reducers/app.js
index 7e478597d..f1899a021 100644
--- a/src/renderer/redux/reducers/app.js
+++ b/src/renderer/redux/reducers/app.js
@@ -26,6 +26,8 @@ export type AppState = {
hasSignature: boolean,
badgeNumber: number,
volume: number,
+ autoUpdateDeclined: boolean,
+ modalsAllowed: boolean,
downloadProgress: ?number,
upgradeDownloading: ?boolean,
upgradeDownloadComplete: ?boolean,
@@ -47,6 +49,8 @@ const defaultState: AppState = {
badgeNumber: 0,
volume: Number(sessionStorage.getItem('volume')) || 1,
autoUpdateDownloaded: false,
+ autoUpdateDeclined: false,
+ modalsAllowed: true,
downloadProgress: undefined,
upgradeDownloading: undefined,
@@ -85,6 +89,13 @@ reducers[ACTIONS.AUTO_UPDATE_DOWNLOADED] = state =>
autoUpdateDownloaded: true,
});
+reducers[ACTIONS.AUTO_UPDATE_DECLINED] = state => {
+ console.log('in AUTO_UPDATE_DECLINED reducer')
+ return Object.assign({}, state, {
+ autoUpdateDeclined: true,
+ });
+}
+
reducers[ACTIONS.UPGRADE_DOWNLOAD_COMPLETED] = (state, action) =>
Object.assign({}, state, {
downloadPath: action.data.path,
@@ -97,6 +108,11 @@ reducers[ACTIONS.UPGRADE_DOWNLOAD_STARTED] = state =>
upgradeDownloading: true,
});
+reducers[ACTIONS.CHANGE_MODALS_ALLOWED] = (state, action) =>
+ Object.assign({}, state, {
+ modalsAllowed: action.data.modalsAllowed,
+ });
+
reducers[ACTIONS.SKIP_UPGRADE] = state => {
sessionStorage.setItem('upgradeSkipped', 'true');
@@ -106,6 +122,28 @@ reducers[ACTIONS.SKIP_UPGRADE] = state => {
});
};
+reducers[ACTIONS.MEDIA_PLAY] = state => {
+ return Object.assign({}, state, {
+ modalsAllowed: false,
+ });
+};
+
+reducers[ACTIONS.MEDIA_PAUSE] = state => {
+ return Object.assign({}, state, {
+ modalsAllowed: true,
+ });
+};
+
+reducers[ACTIONS.SET_PLAYING_URI] = (state, action) => {
+ if (action.data.uri === null) {
+ return Object.assign({}, state, {
+ modalsAllowed: true,
+ });
+ } else {
+ return state;
+ }
+};
+
reducers[ACTIONS.UPDATE_VERSION] = (state, action) =>
Object.assign({}, state, {
version: action.data.version,
@@ -122,12 +160,16 @@ reducers[ACTIONS.CHECK_UPGRADE_SUBSCRIBE] = (state, action) =>
checkUpgradeTimer: action.data.checkUpgradeTimer,
});
-reducers[ACTIONS.OPEN_MODAL] = (state, action) =>
- Object.assign({}, state, {
- modal: action.data.modal,
- modalProps: action.data.modalProps || {},
- });
-
+reducers[ACTIONS.OPEN_MODAL] = (state, action) => {
+ if (!state.modalsAllowed) {
+ return state;
+ } else {
+ return Object.assign({}, state, {
+ modal: action.data.modal,
+ modalProps: action.data.modalProps || {},
+ });
+ }
+};
reducers[ACTIONS.CLOSE_MODAL] = state =>
Object.assign({}, state, {
modal: undefined,
diff --git a/src/renderer/redux/selectors/app.js b/src/renderer/redux/selectors/app.js
index 04c04baa9..283e46f51 100644
--- a/src/renderer/redux/selectors/app.js
+++ b/src/renderer/redux/selectors/app.js
@@ -58,6 +58,10 @@ export const selectUpgradeDownloadItem = createSelector(selectState, state => st
export const selectAutoUpdateDownloaded = createSelector(selectState, state => state.autoUpdateDownloaded);
+export const selectAutoUpdateDeclined = createSelector(selectState, state => state.autoUpdateDeclined);
+
+export const selectModalsAllowed = createSelector(selectState, state => state.modalsAllowed);
+
export const selectModalProps = createSelector(selectState, state => state.modalProps);
export const selectDaemonVersionMatched = createSelector(
From 853bf2cfe748c78cd1b1ad2291c6a0a766d1dd57 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Wed, 17 Jan 2018 07:10:45 -0500
Subject: [PATCH 25/34] Make video pause when you hit the "Upgrade Now" button
on Mac/Win
---
build/build.sh | 6 +++---
src/renderer/redux/actions/app.js | 6 ++++++
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/build/build.sh b/build/build.sh
index 1ace2ad48..2619fb5b0 100755
--- a/build/build.sh
+++ b/build/build.sh
@@ -73,9 +73,9 @@ fi
# Build the app #
###################
if [ "$FULL_BUILD" == "true" ]; then
- if $OSX; then
- security unlock-keychain -p ${KEYCHAIN_PASSWORD} osx-build.keychain
- fi
+ # if $OSX; then
+ # security unlock-keychain -p ${KEYCHAIN_PASSWORD} osx-build.keychain
+ # fi
yarn build
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index 45d99b364..955516749 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -10,6 +10,8 @@ import { doAuthNavigate } from 'redux/actions/navigation';
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 {
selectCurrentModal,
selectIsUpgradeSkipped,
@@ -76,6 +78,10 @@ export function doDownloadUpgradeRequested() {
return (dispatch, getState) => {
const state = getState();
+
+ // Pause video if needed
+ dispatch(doPause());
+
const autoUpdateDeclined = selectAutoUpdateDeclined(state);
if (['win32', 'darwin'].includes(process.platform)) { // electron-updater behavior
From 2d33767182190369ad6be0a0d460f84aea80f019 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Wed, 17 Jan 2018 07:27:40 -0500
Subject: [PATCH 26/34] Change version to 0.1.0 [temp, for testing]
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 00ba9a931..fdcd7846e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.35.0",
+ "version": "0.1.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
From 37b5ec92e138502c2b33ea4f0284d2b24bc6cf47 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Wed, 17 Jan 2018 08:03:51 -0500
Subject: [PATCH 27/34] Change version to 0.2.0 [temp, for testing]
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index fdcd7846e..8469c3907 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.1.0",
+ "version": "0.2.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
From 3e84907ac292894cf9ccb291a911df6baee30596 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 23 Jan 2018 10:40:03 -0500
Subject: [PATCH 28/34] Version 0.3.0 [temp, for testing]
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 0cad777b0..45f9687f1 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.2.0",
+ "version": "0.3.0",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
From fbc143aaafb15b3e10e833bc306444f66f0fdd68 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 23 Jan 2018 19:22:02 -0500
Subject: [PATCH 29/34] Reword "Upgrade on Restart" to "Upgrade on Close"
---
src/renderer/modal/modalAutoUpdateDownloaded/view.jsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
index 5a1b69885..fda5ed519 100644
--- a/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateDownloaded/view.jsx
@@ -15,7 +15,7 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
type="confirm"
contentLabel={__("Update Downloaded")}
confirmButtonLabel={__("Use it Now")}
- abortButtonLabel={__("Upgrade on Restart")}
+ abortButtonLabel={__("Upgrade on Close")}
onConfirmed={() => {
ipcRenderer.send("autoUpdateAccepted");
}}
From daca49dc15caa0da30559e26a8fa8317bc5f480e Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 23 Jan 2018 19:39:17 -0500
Subject: [PATCH 30/34] Add release notes to auto update dialogs
---
src/renderer/modal/modalAutoUpdateConfirm/view.jsx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/renderer/modal/modalAutoUpdateConfirm/view.jsx b/src/renderer/modal/modalAutoUpdateConfirm/view.jsx
index ba9a32d4a..2c8d8e3b2 100644
--- a/src/renderer/modal/modalAutoUpdateConfirm/view.jsx
+++ b/src/renderer/modal/modalAutoUpdateConfirm/view.jsx
@@ -31,6 +31,10 @@ class ModalAutoUpdateConfirm extends React.PureComponent {
'Your LBRY update is ready. Restart LBRY now to use it!'
)}
+
+ {__('Want to know what has changed?')} See the{' '}
+ .
+
);
From 8c0bf32fe52b0762d7f1210d72735823fe30d3d2 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 23 Jan 2018 19:46:49 -0500
Subject: [PATCH 31/34] Small changes to prepare auto update for release
---
package.json | 1 +
src/main/index.js | 7 +++----
src/renderer/index.js | 1 +
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/package.json b/package.json
index 45f9687f1..42d1dce3a 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"dev": "electron-webpack dev",
"compile": "electron-webpack && yarn extract-langs",
"build": "yarn compile && electron-builder build",
+ "build:dir": "yarn build -- --dir -c.compression=store -c.mac.identity=null",
"postinstall": "electron-builder install-app-deps",
"postmerge": "yarnhook",
"postcheckout": "yarnhook",
diff --git a/src/main/index.js b/src/main/index.js
index 22de0ce76..16f9648aa 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -6,7 +6,6 @@ import url from 'url';
import https from 'https';
import { shell, app, ipcMain, dialog } from 'electron';
import { autoUpdater } from 'electron-updater';
-import log from 'electron-log';
import Daemon from './Daemon';
import Tray from './Tray';
import createWindow from './createWindow';
@@ -23,7 +22,7 @@ let autoUpdateDownloaded = false;
// Keeps track of whether the user has accepted an auto-update through the interface.
let autoUpdateAccepted = false;
-// This is used to keep track of whether we are showing he special dialog
+// This is used to keep track of whether we are showing the special dialog
// that we show on Windows after you decline an upgrade and close the app later.
let showingAutoUpdateCloseAlert = false;
@@ -86,7 +85,7 @@ app.on('activate', () => {
if (!rendererWindow) rendererWindow = createWindow();
});
-app.on('will-quit', (e) => {
+app.on('will-quit', (event) => {
if (process.platform === 'win32' && autoUpdateDownloaded && !autoUpdateAccepted && !showingAutoUpdateCloseAlert) {
// We're on Win and have an update downloaded, but the user declined it (or closed
// the app without accepting it). Now the user is closing the app, so the new update
@@ -102,7 +101,7 @@ app.on('will-quit', (e) => {
app.quit();
});
- e.preventDefault();
+ event.preventDefault();
return;
}
diff --git a/src/renderer/index.js b/src/renderer/index.js
index 5ee4a84bf..bcf092707 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -10,6 +10,7 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { doConditionalAuthNavigate, doDaemonReady, doShowSnackBar, doAutoUpdate } from 'redux/actions/app';
+import { doUpdateIsNightAsync } from 'redux/actions/settings';
import { doNavigate } from 'redux/actions/navigation';
import { doDownloadLanguages } from 'redux/actions/settings';
import { doUserEmailVerify } from 'redux/actions/user';
From eef3f6a816c63b0bf449a7bc6959a06ea9b610bf Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 23 Jan 2018 20:09:30 -0500
Subject: [PATCH 32/34] Restore version number with -dev suffix (needed for new
build process)
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index b02867682..00ae8ed48 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "LBRY",
- "version": "0.3.0",
+ "version": "0.19.4-dev",
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
"homepage": "https://lbry.io/",
"bugs": {
From 76f6b1efa94f74849a2233a708a8ff299aab6b14 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Tue, 23 Jan 2018 20:30:58 -0500
Subject: [PATCH 33/34] Remove remaining traces of logging code from
main/index.js
We might need this later, but right now no logging is happening here.
---
src/main/index.js | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/main/index.js b/src/main/index.js
index 16f9648aa..6894ee5a1 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -10,8 +10,6 @@ import Daemon from './Daemon';
import Tray from './Tray';
import createWindow from './createWindow';
-// For now, log info messages in production for easier debugging
-log.transports.file.level = '';
autoUpdater.autoDownload = true;
// This is set to true if an auto update has been downloaded through the Electron
From e98231fed37fcf111707fd534635384234af89e5 Mon Sep 17 00:00:00 2001
From: Alex Liebowitz
Date: Wed, 24 Jan 2018 15:42:49 -0500
Subject: [PATCH 34/34] Don't show auto-update dialog after decline on Win/Mac
---
src/renderer/redux/actions/app.js | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js
index ef79a0f6a..0d94fe4d4 100644
--- a/src/renderer/redux/actions/app.js
+++ b/src/renderer/redux/actions/app.js
@@ -198,8 +198,13 @@ export function doCheckUpgradeAvailable() {
});
if (["win32", "darwin"].includes(process.platform)) {
- // On Windows and Mac, updates happen silently
- autoUpdater.checkForUpdates();
+ // On Windows and Mac, updates happen silently through
+ // electron-updater.
+ const autoUpdateDeclined = selectAutoUpdateDeclined(state);
+
+ if (!autoUpdateDeclined) {
+ autoUpdater.checkForUpdates();
+ }
return;
}