chore: migrate to AppImage and update publish workflow (#1010)
The app now uses AppImage instead of .deb files for Linux. Thanks to this change, the app supports now auto-updates on Linux too. The publishing workflow has been updated. It uses now the publishing mechanisms offered by electron-builder.
This commit is contained in:
parent
52f2d6140d
commit
b9f4d7b307
17 changed files with 2064 additions and 1028 deletions
|
@ -1,10 +1,9 @@
|
||||||
[ignore]
|
[ignore]
|
||||||
.*/node_modules/**
|
|
||||||
|
|
||||||
[include]
|
[include]
|
||||||
|
|
||||||
[libs]
|
[libs]
|
||||||
flow-typed
|
./flow-typed
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
|
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
/node_modules
|
/node_modules
|
||||||
/dist
|
/dist
|
||||||
/build/daemon.ver
|
/build/daemon.ver
|
||||||
|
/build/daemon.zip
|
||||||
/build/venv
|
/build/venv
|
||||||
*.pyc
|
*.pyc
|
||||||
/static/daemon/lbrynet*
|
/static/daemon/lbrynet*
|
||||||
|
|
71
.travis.yml
71
.travis.yml
|
@ -1,28 +1,45 @@
|
||||||
env:
|
matrix:
|
||||||
global:
|
include:
|
||||||
- TRANSIFEX_USER: api
|
- os: osx
|
||||||
- secure: u6gwnZlPGJLnvpoPPCpUZ+jBPajQuIW1+aq6UGW57z54AUjTAECxaYpqcGTGtDBjYark/yeiso887wP/EmJva7hMHeNMf6uLqwzP3YFsIv/Iv+9c1f4MXbJNgOrEKN834o/BdkD4ifi9CCiH9uPPVYGPx1bvfaxGpcHmQXdW4F4S0uj+jePB257mt+afGiNlz9wET6kWJKNNZf/4BNmefldVNq7h6oTSLsyO1TBhDcvSjatpKIwmXUNQfSUTFWvrtpWUB/m/IzitGuUtrt82vU2fPl7tuH6BHNrNp58MINjFzXXJLC+mMybb2UBDIAuc3+k7vj4J0U2rkcTloxDNCKNmYa1jBogOKBRgGp98Ct7E0V2vuLGAPniUbvBcCGK1wwed7uwDjsz3YNCGxUEcyyWc3OVDgN/up4+gXHxkh9FTpZy8Q3rSZx4Lwj700impBUQIVh/5p7Vgv+bSUdOeVRAMlcP9yT83jX50w9LkJMfICFPNv1tOZ3/SOnnB+JdW/ahpplFI4Z68/fBLttZTeaNcU4f28oJvPer8Wll+Elx5kxwLqLbwVUFNlxTxY1LYnPB7SPjGxrFNy3mVTRq5Pxp1hMiTZF4TlapkfHgR+gEzk2wpcJGmub70tW2baZaJF0jDBWIh7GXV+EGve53BKDhpX2Z6jTK0gkhrSUW1MT8=
|
osx_image: xcode9.2
|
||||||
- secure: h1r9Qzv2xHRQl7nDHcscB4qDv7KlF/ncgHko1YuoY4oLZipBV8mzQXDmn3nlMKwaKOe1/Tty/bjoZexkWict4cwKBzU7/1HtJeMa6nxRICuS6DiVhLUNGZEddK6jQLxeEZFxkFPSCZyjybPWtasF8f8jd0lqqLIL4/FcIVV56aRCKAsUwCbedxi8Vnc19l74xjaQIK82xBFYOQPK078OBovk9DDOnicTjMulUo3/pKEZD1njSdcEhfSRv+MFE+31B/a6lpoLo7twPlyzLMfpo30NlEzIN0TeMAk44e4PV6DYg0wntC2GJ21p4BqMnDGocwnZwm7gpjflzUZdW6hF0esGLcqOdbyJLUb3rNX9AzQmn0p9KwDC3S80peZFxSiuLJGL8eivceVDUK/jwWinu3OHDJ/eO5iMDm9odm2ALemPtrDTSlRNT8HzNCY9PQTU9Dhdm4Q/dGDsRPWibFJSJ/qGKhVgadk2CUEAPua0hB1zZ556PkTGx4R1JDscgFDAkgemzgKl4Z/4qK3xGDoEtz1HmBlvQtn+B/PuhA2essADj0iTDiItxb7AYTA7EzsHEcRMmrbYarZ3Eh2onWy2GOpAGRN5Xl9cBIDbibcSC6BLI1m2PcLABpP7DhUX4bJbsVNSiGesHEU7o9Dgn8Ig09eHW/8F9i0VVoGUZXxKMJ8=
|
language: node_js
|
||||||
|
node_js: "9"
|
||||||
os: linux
|
env:
|
||||||
dist: xenial
|
- ELECTRON_CACHE=$HOME/.cache/electron
|
||||||
|
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
|
||||||
branches:
|
- os: linux
|
||||||
only:
|
services: docker
|
||||||
- "/^v\\d+\\.\\d+\\.\\d+$/"
|
language: generic
|
||||||
|
before_cache:
|
||||||
install:
|
- rm -rf $HOME/.cache/electron-builder/wine
|
||||||
- rvm install 2.3.1
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
||||||
|
- $HOME/.cache/electron
|
||||||
|
- $HOME/.cache/electron-builder
|
||||||
|
before_install:
|
||||||
|
- |
|
||||||
|
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
|
||||||
|
mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v2.3.1/git-lfs-$([ "$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-2.3.1.tar.gz | tar -xz -C /tmp/git-lfs --strip-components 1
|
||||||
|
export PATH="/tmp/git-lfs:$PATH"
|
||||||
|
fi
|
||||||
|
before_script:
|
||||||
|
- git lfs pull
|
||||||
script:
|
script:
|
||||||
- rvm use 2.3.1 && gem install danger --version '~> 4.0' && danger
|
- |
|
||||||
- FULL_BUILD=true ./build.sh
|
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||||
|
docker run --rm \
|
||||||
sudo: required
|
--env-file <(env | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \
|
||||||
after_success:
|
-v ${PWD}:/project \
|
||||||
- pip install virtualenv
|
-v ~/.cache/electron:/root/.cache/electron \
|
||||||
- virtualenv ~/env
|
-v ~/.cache/electron-builder:/root/.cache/electron-builder \
|
||||||
- source ~/env/bin/activate
|
electronuserland/builder:wine \
|
||||||
- pip install transifex-client
|
/bin/bash -c "yarn --link-duplicates --pure-lockfile && yarn build --linux --win"
|
||||||
- sudo echo $'[https://www.transifex.com]\nhostname = https://www.transifex.com\nusername= '"$TRANSIFEX_USER"$'\npassword = '"$TRANSIFEX_PASSWORD"$'\ntoken = '"$TRANSIFEX_API_TOKEN"$'\n' > ~/.transifexrc
|
else
|
||||||
- tx push -s
|
yarn build
|
||||||
|
fi
|
||||||
|
branches:
|
||||||
|
except:
|
||||||
|
- "/^v\\d+\\.\\d+\\.\\d+$/"
|
||||||
|
addons:
|
||||||
|
artifacts: true
|
|
@ -59,7 +59,7 @@ DAEMON_VER_PATH="$BUILD_DIR/daemon.ver"
|
||||||
echo "$DAEMON_VER_PATH"
|
echo "$DAEMON_VER_PATH"
|
||||||
if [[ ! -f $DAEMON_VER_PATH || ! -f $ROOT/static/daemon/lbrynet-daemon || "$(< "$DAEMON_VER_PATH")" != "$DAEMON_VER" ]]; then
|
if [[ ! -f $DAEMON_VER_PATH || ! -f $ROOT/static/daemon/lbrynet-daemon || "$(< "$DAEMON_VER_PATH")" != "$DAEMON_VER" ]]; then
|
||||||
curl -sL -o "$BUILD_DIR/daemon.zip" "$DAEMON_URL"
|
curl -sL -o "$BUILD_DIR/daemon.zip" "$DAEMON_URL"
|
||||||
unzip "$BUILD_DIR/daemon.zip" -d "$ROOT/static/daemon/"
|
unzip -o "$BUILD_DIR/daemon.zip" -d "$ROOT/static/daemon/"
|
||||||
rm "$BUILD_DIR/daemon.zip"
|
rm "$BUILD_DIR/daemon.zip"
|
||||||
echo "$DAEMON_VER" > "$DAEMON_VER_PATH"
|
echo "$DAEMON_VER" > "$DAEMON_VER_PATH"
|
||||||
else
|
else
|
||||||
|
|
47
build/downloadDaemon.js
Normal file
47
build/downloadDaemon.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* eslint-disable no-console,import/no-commonjs */
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const packageJSON = require('../package.json');
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
|
const axios = require('axios');
|
||||||
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||||
|
const decompress = require('decompress');
|
||||||
|
const os = require('os');
|
||||||
|
|
||||||
|
const daemonURLTemplate = packageJSON.lbrySettings.lbrynetDaemonUrlTemplate;
|
||||||
|
const daemonVersion = packageJSON.lbrySettings.lbrynetDaemonVersion;
|
||||||
|
let currentPlatform = os.platform();
|
||||||
|
if (currentPlatform === 'darwin') currentPlatform = 'macos';
|
||||||
|
if (currentPlatform === 'win32') currentPlatform = 'windows';
|
||||||
|
|
||||||
|
const daemonURL = daemonURLTemplate
|
||||||
|
.replace(/DAEMONVER/g, daemonVersion)
|
||||||
|
.replace(/OSNAME/g, currentPlatform);
|
||||||
|
const tmpZipPath = 'build/daemon.zip';
|
||||||
|
|
||||||
|
console.log('\x1b[34minfo\x1b[0m Downloading daemon...');
|
||||||
|
axios
|
||||||
|
.request({
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
url: daemonURL,
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/zip',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
fs.writeFileSync(tmpZipPath, result.data);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
decompress(tmpZipPath, 'static/daemon', {
|
||||||
|
filter: file =>
|
||||||
|
path.basename(file.path).replace(path.extname(file.path), '') === 'lbrynet-daemon',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log('\x1b[32msuccess\x1b[0m Daemon downloaded!');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error(`\x1b[31merror\x1b[0m Daemon download failed due to: \x1b[35m${error}\x1b[0m`);
|
||||||
|
});
|
|
@ -1,11 +1,13 @@
|
||||||
{
|
{
|
||||||
"appId": "io.lbry.LBRY",
|
"appId": "io.lbry.LBRY",
|
||||||
"publish": {
|
"productName": "LBRY",
|
||||||
|
"publish": [{
|
||||||
"provider": "s3",
|
"provider": "s3",
|
||||||
"bucket": "releases.lbry.io",
|
"bucket": "releases.lbry.io",
|
||||||
"path": "app/latest"
|
"path": "app/latest"
|
||||||
},
|
}, "github"],
|
||||||
"mac": {
|
"mac": {
|
||||||
|
"target": "dmg",
|
||||||
"category": "public.app-category.entertainment"
|
"category": "public.app-category.entertainment"
|
||||||
},
|
},
|
||||||
"dmg": {
|
"dmg": {
|
||||||
|
@ -28,36 +30,24 @@
|
||||||
"width": 500,
|
"width": 500,
|
||||||
"height": 300
|
"height": 300
|
||||||
},
|
},
|
||||||
"background": "build/background.png"
|
"background": "./build/background.png"
|
||||||
},
|
},
|
||||||
"protocols": [
|
"protocols": [
|
||||||
{
|
{
|
||||||
"name": "lbry",
|
"name": "LBRY URI",
|
||||||
"schemes": ["lbry"],
|
"schemes": ["lbry"],
|
||||||
"role": "Viewer"
|
"role": "Viewer"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"linux": {
|
"linux": {
|
||||||
"target": "deb",
|
"target": "AppImage",
|
||||||
"category": "Video;AudioVideo;",
|
"category": "AudioVideo;Video",
|
||||||
"desktop": {
|
"desktop": {
|
||||||
"MimeType": "x-scheme-handler/lbry",
|
"MimeType": "x-scheme-handler/lbry;"
|
||||||
"Exec": "/opt/LBRY/lbry %U"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deb": {
|
|
||||||
"depends": [
|
|
||||||
"gconf2",
|
|
||||||
"gconf-service",
|
|
||||||
"libnotify4",
|
|
||||||
"libappindicator1",
|
|
||||||
"libxtst6",
|
|
||||||
"libnss3",
|
|
||||||
"libsecret-1-0"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nsis": {
|
"nsis": {
|
||||||
"perMachine": true
|
"perMachine": true
|
||||||
},
|
},
|
||||||
"artifactName": "${productName}_${version}_${arch}.${ext}"
|
"artifactName": "${productName}_${version}.${ext}"
|
||||||
}
|
}
|
||||||
|
|
56
package.json
56
package.json
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "LBRY",
|
"name": "lbry-app",
|
||||||
"version": "0.20.0",
|
"version": "0.20.0",
|
||||||
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
"description": "A browser for the LBRY network, a digital marketplace controlled by its users.",
|
||||||
"homepage": "https://lbry.io/",
|
"homepage": "https://lbry.io/",
|
||||||
|
@ -21,7 +21,8 @@
|
||||||
"compile": "electron-webpack && yarn extract-langs",
|
"compile": "electron-webpack && yarn extract-langs",
|
||||||
"build": "yarn compile && electron-builder build",
|
"build": "yarn compile && electron-builder build",
|
||||||
"build:dir": "yarn build -- --dir -c.compression=store -c.mac.identity=null",
|
"build:dir": "yarn build -- --dir -c.compression=store -c.mac.identity=null",
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"release": "yarn compile && electron-builder build",
|
||||||
|
"postinstall": "electron-builder install-app-deps && node build/downloadDaemon.js",
|
||||||
"lint": "eslint 'src/**/*.{js,jsx}' --fix",
|
"lint": "eslint 'src/**/*.{js,jsx}' --fix",
|
||||||
"format": "prettier 'src/**/*.{js,jsx,scss,json}' --write"
|
"format": "prettier 'src/**/*.{js,jsx,scss,json}' --write"
|
||||||
},
|
},
|
||||||
|
@ -33,16 +34,17 @@
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"country-data": "^0.0.31",
|
"country-data": "^0.0.31",
|
||||||
"electron-dl": "^1.6.0",
|
"electron-dl": "^1.6.0",
|
||||||
|
"electron-is-dev": "^0.3.0",
|
||||||
"electron-log": "^2.2.12",
|
"electron-log": "^2.2.12",
|
||||||
"electron-publisher-s3": "^19.47.0",
|
"electron-publisher-s3": "^20.2.0",
|
||||||
"electron-updater": "^2.18.2",
|
"electron-updater": "^2.21.0",
|
||||||
"find-process": "^1.1.0",
|
"find-process": "^1.1.0",
|
||||||
"formik": "^0.10.4",
|
"formik": "^0.10.4",
|
||||||
"from2": "^2.3.0",
|
"from2": "^2.3.0",
|
||||||
"install": "^0.10.2",
|
"install": "^0.10.2",
|
||||||
"jayson": "^2.0.2",
|
"jayson": "^2.0.2",
|
||||||
"jshashes": "^1.0.7",
|
"jshashes": "^1.0.7",
|
||||||
"keytar-prebuild": "^4.0.4",
|
"keytar-prebuild": "^4.1.1",
|
||||||
"localforage": "^1.5.0",
|
"localforage": "^1.5.0",
|
||||||
"mixpanel-browser": "^2.17.1",
|
"mixpanel-browser": "^2.17.1",
|
||||||
"moment": "^2.20.1",
|
"moment": "^2.20.1",
|
||||||
|
@ -72,43 +74,41 @@
|
||||||
"y18n": "^4.0.0"
|
"y18n": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^8.0.3",
|
"axios": "^0.18.0",
|
||||||
"babel-plugin-module-resolver": "^3.0.0",
|
"babel-eslint": "^8.2.2",
|
||||||
"babel-plugin-react-require": "^3.0.0",
|
"babel-plugin-module-resolver": "^3.1.0",
|
||||||
"babel-polyfill": "^6.20.0",
|
"babel-polyfill": "^6.20.0",
|
||||||
"babel-preset-env": "^1.6.1",
|
"babel-preset-env": "^1.6.1",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
"babel-preset-stage-2": "^6.18.0",
|
"babel-preset-stage-2": "^6.18.0",
|
||||||
|
"decompress": "^4.2.0",
|
||||||
"devtron": "^1.4.0",
|
"devtron": "^1.4.0",
|
||||||
"electron": "^1.7.11",
|
"electron": "^1.8.3",
|
||||||
"electron-builder": "^19.55.2",
|
"electron-builder": "^20.3.1",
|
||||||
"electron-devtools-installer": "^2.2.1",
|
"electron-devtools-installer": "^2.2.3",
|
||||||
"electron-webpack": "^1.11.0",
|
"electron-webpack": "^1.13.0",
|
||||||
"eslint": "^4.13.1",
|
"eslint": "^4.18.2",
|
||||||
"eslint-config-airbnb": "^16.1.0",
|
"eslint-config-airbnb": "^16.1.0",
|
||||||
"eslint-config-prettier": "^2.9.0",
|
"eslint-config-prettier": "^2.9.0",
|
||||||
"eslint-import-resolver-webpack": "^0.8.3",
|
"eslint-import-resolver-webpack": "^0.8.4",
|
||||||
"eslint-plugin-flowtype": "^2.40.1",
|
"eslint-plugin-flowtype": "^2.46.1",
|
||||||
"eslint-plugin-import": "^2.8.0",
|
"eslint-plugin-import": "^2.9.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.0.3",
|
"eslint-plugin-jsx-a11y": "^6.0.3",
|
||||||
"eslint-plugin-prettier": "^2.4.0",
|
"eslint-plugin-prettier": "^2.6.0",
|
||||||
"eslint-plugin-react": "^7.5.1",
|
"eslint-plugin-react": "^7.7.0",
|
||||||
"flow-babel-webpack-plugin": "^1.1.0",
|
"flow-babel-webpack-plugin": "^1.1.1",
|
||||||
"flow-bin": "^0.61.0",
|
"flow-bin": "^0.66.0",
|
||||||
"flow-typed": "^2.2.3",
|
"flow-typed": "^2.3.0",
|
||||||
"husky": "^0.14.3",
|
"husky": "^0.14.3",
|
||||||
"i18n-extract": "^0.5.1",
|
"i18n-extract": "^0.5.1",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"lint-staged": "^6.0.0",
|
"lint-staged": "^7.0.0",
|
||||||
"node-loader": "^0.6.0",
|
"node-loader": "^0.6.0",
|
||||||
"node-sass": "^4.7.2",
|
"node-sass": "^4.7.2",
|
||||||
"prettier": "^1.4.2",
|
"prettier": "^1.11.1",
|
||||||
"sass-loader": "^6.0.6",
|
"sass-loader": "^6.0.7",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"webpack-build-notifier": "^0.1.18"
|
"webpack-build-notifier": "^0.1.23"
|
||||||
},
|
|
||||||
"resolutions": {
|
|
||||||
"webpack/webpack-sources": "1.0.1"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6",
|
"node": ">=6",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { app, BrowserWindow, dialog } from 'electron';
|
import { app, BrowserWindow, dialog } from 'electron';
|
||||||
|
import isDev from 'electron-is-dev';
|
||||||
import setupBarMenu from './menu/setupBarMenu';
|
import setupBarMenu from './menu/setupBarMenu';
|
||||||
import setupContextMenu from './menu/setupContextMenu';
|
import setupContextMenu from './menu/setupContextMenu';
|
||||||
|
|
||||||
|
@ -12,20 +13,18 @@ export default appState => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Disable renderer process's webSecurity on development to enable CORS.
|
// Disable renderer process's webSecurity on development to enable CORS.
|
||||||
windowConfiguration =
|
windowConfiguration = isDev
|
||||||
process.env.NODE_ENV === 'development'
|
? {
|
||||||
? {
|
...windowConfiguration,
|
||||||
...windowConfiguration,
|
webPreferences: {
|
||||||
webPreferences: {
|
webSecurity: false,
|
||||||
webSecurity: false,
|
},
|
||||||
},
|
}
|
||||||
}
|
: windowConfiguration;
|
||||||
: windowConfiguration;
|
|
||||||
|
|
||||||
const rendererURL =
|
const rendererURL = isDev
|
||||||
process.env.NODE_ENV === 'development'
|
? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`
|
||||||
? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`
|
: `file://${__dirname}/index.html`;
|
||||||
: `file://${__dirname}/index.html`;
|
|
||||||
|
|
||||||
let window = new BrowserWindow(windowConfiguration);
|
let window = new BrowserWindow(windowConfiguration);
|
||||||
|
|
||||||
|
@ -84,7 +83,7 @@ export default appState => {
|
||||||
window.webContents.on('did-finish-load', () => {
|
window.webContents.on('did-finish-load', () => {
|
||||||
window.webContents.send('open-uri-requested', deepLinkingURI, true);
|
window.webContents.send('open-uri-requested', deepLinkingURI, true);
|
||||||
window.webContents.session.setUserAgent(`LBRY/${app.getVersion()}`);
|
window.webContents.session.setUserAgent(`LBRY/${app.getVersion()}`);
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (isDev) {
|
||||||
window.webContents.openDevTools();
|
window.webContents.openDevTools();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@ import url from 'url';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import { shell, app, ipcMain, dialog } from 'electron';
|
import { shell, app, ipcMain, dialog } from 'electron';
|
||||||
import { autoUpdater } from 'electron-updater';
|
import { autoUpdater } from 'electron-updater';
|
||||||
|
import isDev from 'electron-is-dev';
|
||||||
import Daemon from './Daemon';
|
import Daemon from './Daemon';
|
||||||
import createTray from './createTray';
|
import createTray from './createTray';
|
||||||
import createWindow from './createWindow';
|
import createWindow from './createWindow';
|
||||||
|
@ -64,15 +65,15 @@ app.on('ready', async () => {
|
||||||
dialog.showErrorBox(
|
dialog.showErrorBox(
|
||||||
'Daemon has Exited',
|
'Daemon has Exited',
|
||||||
'The daemon may have encountered an unexpected error, or another daemon instance is already running. \n\n' +
|
'The daemon may have encountered an unexpected error, or another daemon instance is already running. \n\n' +
|
||||||
'For more information please visit: \n' +
|
'For more information please visit: \n' +
|
||||||
'https://lbry.io/faq/startup-troubleshooting'
|
'https://lbry.io/faq/startup-troubleshooting'
|
||||||
);
|
);
|
||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
daemon.launch();
|
daemon.launch();
|
||||||
}
|
}
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (isDev) {
|
||||||
await installExtensions();
|
await installExtensions();
|
||||||
}
|
}
|
||||||
rendererWindow = createWindow(appState);
|
rendererWindow = createWindow(appState);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { Menu, BrowserWindow } from 'electron';
|
import { Menu, BrowserWindow } from 'electron';
|
||||||
|
import isDev from 'electron-is-dev';
|
||||||
|
|
||||||
export default (rendererWindow: BrowserWindow) => {
|
export default (rendererWindow: BrowserWindow) => {
|
||||||
rendererWindow.webContents.on('context-menu', (e, params) => {
|
rendererWindow.webContents.on('context-menu', (e, params) => {
|
||||||
|
@ -17,7 +18,7 @@ export default (rendererWindow: BrowserWindow) => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (isDev) {
|
||||||
template.push(...developmentTemplateAddition);
|
template.push(...developmentTemplateAddition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import store from 'store';
|
||||||
import { remote } from 'electron';
|
import { remote } from 'electron';
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
import y18n from 'y18n';
|
import y18n from 'y18n';
|
||||||
|
import isDev from 'electron-is-dev';
|
||||||
|
|
||||||
const env = process.env.NODE_ENV || 'production';
|
const env = process.env.NODE_ENV || 'production';
|
||||||
const i18n = y18n({
|
const i18n = y18n({
|
||||||
|
@ -22,7 +23,7 @@ const app = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Workaround for https://github.com/electron-userland/electron-webpack/issues/52
|
// Workaround for https://github.com/electron-userland/electron-webpack/issues/52
|
||||||
if (env !== 'development') {
|
if (!isDev) {
|
||||||
window.staticResourcesPath = Path.join(remote.app.getAppPath(), '../static').replace(
|
window.staticResourcesPath = Path.join(remote.app.getAppPath(), '../static').replace(
|
||||||
/\\/g,
|
/\\/g,
|
||||||
'\\\\'
|
'\\\\'
|
||||||
|
|
|
@ -23,7 +23,7 @@ class FileList extends React.PureComponent {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
dateOld(fileInfos) {
|
dateOld(fileInfos) {
|
||||||
return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
|
return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
|
||||||
|
@ -35,7 +35,7 @@ class FileList extends React.PureComponent {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
title(fileInfos) {
|
title(fileInfos) {
|
||||||
return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
|
return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
|
||||||
|
|
|
@ -14,9 +14,8 @@ import {
|
||||||
doShowSnackBar,
|
doShowSnackBar,
|
||||||
doAutoUpdate,
|
doAutoUpdate,
|
||||||
} from 'redux/actions/app';
|
} from 'redux/actions/app';
|
||||||
import { doUpdateIsNightAsync } from 'redux/actions/settings';
|
|
||||||
import { doNavigate } from 'redux/actions/navigation';
|
import { doNavigate } from 'redux/actions/navigation';
|
||||||
import { doDownloadLanguages } from 'redux/actions/settings';
|
import { doDownloadLanguages, doUpdateIsNightAsync } from 'redux/actions/settings';
|
||||||
import { doUserEmailVerify } from 'redux/actions/user';
|
import { doUserEmailVerify } from 'redux/actions/user';
|
||||||
import 'scss/all.scss';
|
import 'scss/all.scss';
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
|
@ -27,11 +26,6 @@ const { autoUpdater } = remote.require('electron-updater');
|
||||||
|
|
||||||
autoUpdater.logger = remote.require('electron-log');
|
autoUpdater.logger = remote.require('electron-log');
|
||||||
|
|
||||||
window.addEventListener('contextmenu', event => {
|
|
||||||
contextMenu(remote.getCurrentWindow(), event.x, event.y, app.env === 'development');
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcRenderer.on('open-uri-requested', (event, uri, newSession) => {
|
ipcRenderer.on('open-uri-requested', (event, uri, newSession) => {
|
||||||
if (uri && uri.startsWith('lbry://')) {
|
if (uri && uri.startsWith('lbry://')) {
|
||||||
if (uri.startsWith('lbry://?verify=')) {
|
if (uri.startsWith('lbry://?verify=')) {
|
||||||
|
@ -106,18 +100,17 @@ const init = () => {
|
||||||
app.store.dispatch(doAutoUpdate());
|
app.store.dispatch(doAutoUpdate());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (['win32', 'darwin'].includes(process.platform)) {
|
autoUpdater.on('update-available', () => {
|
||||||
autoUpdater.on('update-available', () => {
|
console.log('Update available');
|
||||||
console.log('Update available');
|
});
|
||||||
});
|
autoUpdater.on('update-not-available', () => {
|
||||||
autoUpdater.on('update-not-available', () => {
|
console.log('Update not available');
|
||||||
console.log('Update not available');
|
});
|
||||||
});
|
autoUpdater.on('update-downloaded', () => {
|
||||||
autoUpdater.on('update-downloaded', () => {
|
console.log('Update downloaded');
|
||||||
console.log('Update downloaded');
|
app.store.dispatch(doAutoUpdate());
|
||||||
app.store.dispatch(doAutoUpdate());
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
app.store.dispatch(doUpdateIsNightAsync());
|
app.store.dispatch(doUpdateIsNightAsync());
|
||||||
app.store.dispatch(doDownloadLanguages());
|
app.store.dispatch(doDownloadLanguages());
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
/* eslint-disable import/no-commonjs */
|
import isDev from 'electron-is-dev';
|
||||||
|
import Lbry from 'lbry';
|
||||||
|
import path from 'path';
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import { ipcRenderer, remote } from 'electron';
|
import { ipcRenderer, remote } from 'electron';
|
||||||
import Lbry from 'lbry';
|
|
||||||
import Path from 'path';
|
|
||||||
import { doFetchRewardedContent } from 'redux/actions/content';
|
import { doFetchRewardedContent } from 'redux/actions/content';
|
||||||
import { doFetchFileInfosAndPublishedClaims } from 'redux/actions/file_info';
|
import { doFetchFileInfosAndPublishedClaims } from 'redux/actions/file_info';
|
||||||
import { doAuthNavigate } from 'redux/actions/navigation';
|
import { doAuthNavigate } from 'redux/actions/navigation';
|
||||||
|
@ -11,22 +11,20 @@ import { doFetchDaemonSettings } from 'redux/actions/settings';
|
||||||
import { doAuthenticate } from 'redux/actions/user';
|
import { doAuthenticate } from 'redux/actions/user';
|
||||||
import { doBalanceSubscribe } from 'redux/actions/wallet';
|
import { doBalanceSubscribe } from 'redux/actions/wallet';
|
||||||
import { doPause } from 'redux/actions/media';
|
import { doPause } from 'redux/actions/media';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
selectCurrentModal,
|
selectCurrentModal,
|
||||||
selectIsUpgradeSkipped,
|
selectIsUpgradeSkipped,
|
||||||
selectRemoteVersion,
|
|
||||||
selectUpdateUrl,
|
selectUpdateUrl,
|
||||||
selectUpgradeDownloadItem,
|
selectUpgradeDownloadItem,
|
||||||
selectUpgradeDownloadPath,
|
selectUpgradeDownloadPath,
|
||||||
selectUpgradeFilename,
|
selectUpgradeFilename,
|
||||||
selectAutoUpdateDeclined,
|
selectAutoUpdateDeclined,
|
||||||
} from 'redux/selectors/app';
|
} from 'redux/selectors/app';
|
||||||
|
import { lbrySettings as config } from 'package.json';
|
||||||
|
|
||||||
const { autoUpdater } = remote.require('electron-updater');
|
const { autoUpdater } = remote.require('electron-updater');
|
||||||
const { download } = remote.require('electron-dl');
|
const { download } = remote.require('electron-dl');
|
||||||
const Fs = remote.require('fs');
|
const Fs = remote.require('fs');
|
||||||
const { lbrySettings: config } = require('package.json');
|
|
||||||
|
|
||||||
const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000;
|
const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000;
|
||||||
|
|
||||||
|
@ -84,25 +82,19 @@ export function doDownloadUpgradeRequested() {
|
||||||
|
|
||||||
const autoUpdateDeclined = selectAutoUpdateDeclined(state);
|
const autoUpdateDeclined = selectAutoUpdateDeclined(state);
|
||||||
|
|
||||||
if (['win32', 'darwin'].includes(process.platform)) {
|
if (autoUpdateDeclined) {
|
||||||
// electron-updater behavior
|
// The user declined an update before, so show the "confirm" dialog
|
||||||
if (autoUpdateDeclined) {
|
dispatch({
|
||||||
// The user declined an update before, so show the "confirm" dialog
|
type: ACTIONS.OPEN_MODAL,
|
||||||
dispatch({
|
data: { modal: MODALS.AUTO_UPDATE_CONFIRM },
|
||||||
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 {
|
} else {
|
||||||
// Old behavior for Linux
|
// The user was never shown the original update dialog (e.g. because they were
|
||||||
dispatch(doDownloadUpgrade());
|
// watching a video). So show the initial "update downloaded" dialog.
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.OPEN_MODAL,
|
||||||
|
data: { modal: MODALS.AUTO_UPDATE_DOWNLOADED },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -111,7 +103,7 @@ export function doDownloadUpgrade() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
// Make a new directory within temp directory so the filename is guaranteed to be available
|
// Make a new directory within temp directory so the filename is guaranteed to be available
|
||||||
const dir = Fs.mkdtempSync(remote.app.getPath('temp') + Path.sep);
|
const dir = Fs.mkdtempSync(remote.app.getPath('temp') + path.sep);
|
||||||
const upgradeFilename = selectUpgradeFilename(state);
|
const upgradeFilename = selectUpgradeFilename(state);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
|
@ -129,7 +121,7 @@ export function doDownloadUpgrade() {
|
||||||
type: ACTIONS.UPGRADE_DOWNLOAD_COMPLETED,
|
type: ACTIONS.UPGRADE_DOWNLOAD_COMPLETED,
|
||||||
data: {
|
data: {
|
||||||
downloadItem,
|
downloadItem,
|
||||||
path: Path.join(dir, upgradeFilename),
|
path: path.join(dir, upgradeFilename),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -147,8 +139,7 @@ export function doDownloadUpgrade() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doAutoUpdate() {
|
export function doAutoUpdate() {
|
||||||
return function(dispatch, getState) {
|
return dispatch => {
|
||||||
const state = getState();
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.AUTO_UPDATE_DOWNLOADED,
|
type: ACTIONS.AUTO_UPDATE_DOWNLOADED,
|
||||||
});
|
});
|
||||||
|
@ -161,8 +152,7 @@ export function doAutoUpdate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doAutoUpdateDeclined() {
|
export function doAutoUpdateDeclined() {
|
||||||
return function(dispatch, getState) {
|
return dispatch => {
|
||||||
const state = getState();
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.AUTO_UPDATE_DECLINED,
|
type: ACTIONS.AUTO_UPDATE_DECLINED,
|
||||||
});
|
});
|
||||||
|
@ -183,6 +173,7 @@ export function doCancelUpgrade() {
|
||||||
try {
|
try {
|
||||||
upgradeDownloadItem.cancel();
|
upgradeDownloadItem.cancel();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
console.error(err);
|
console.error(err);
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
@ -199,47 +190,11 @@ export function doCheckUpgradeAvailable() {
|
||||||
type: ACTIONS.CHECK_UPGRADE_START,
|
type: ACTIONS.CHECK_UPGRADE_START,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (['win32', 'darwin'].includes(process.platform)) {
|
const autoUpdateDeclined = selectAutoUpdateDeclined(state);
|
||||||
// On Windows and Mac, updates happen silently through
|
|
||||||
// electron-updater.
|
|
||||||
const autoUpdateDeclined = selectAutoUpdateDeclined(state);
|
|
||||||
|
|
||||||
if (!autoUpdateDeclined) {
|
if (!autoUpdateDeclined && !isDev) {
|
||||||
autoUpdater.checkForUpdates();
|
autoUpdater.checkForUpdates();
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const success = ({ remoteVersion, upgradeAvailable }) => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CHECK_UPGRADE_SUCCESS,
|
|
||||||
data: {
|
|
||||||
upgradeAvailable,
|
|
||||||
remoteVersion,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
|
||||||
upgradeAvailable &&
|
|
||||||
!selectCurrentModal(state) &&
|
|
||||||
(!selectIsUpgradeSkipped(state) || remoteVersion !== selectRemoteVersion(state))
|
|
||||||
) {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.OPEN_MODAL,
|
|
||||||
data: {
|
|
||||||
modal: MODALS.UPGRADE,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fail = () => {
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CHECK_UPGRADE_FAIL,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Lbry.getAppVersionInfo().then(success, fail);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,20 @@ export function doGetThemes() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doUpdateIsNight() {
|
||||||
|
const momentNow = moment();
|
||||||
|
return {
|
||||||
|
type: ACTIONS.UPDATE_IS_NIGHT,
|
||||||
|
data: {
|
||||||
|
isNight: (() => {
|
||||||
|
const startNightMoment = moment('21:00', 'HH:mm');
|
||||||
|
const endNightMoment = moment('8:00', 'HH:mm');
|
||||||
|
return !(momentNow.isAfter(endNightMoment) && momentNow.isBefore(startNightMoment));
|
||||||
|
})(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function doUpdateIsNightAsync() {
|
export function doUpdateIsNightAsync() {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
dispatch(doUpdateIsNight());
|
dispatch(doUpdateIsNight());
|
||||||
|
@ -66,19 +80,6 @@ export function doUpdateIsNightAsync() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doUpdateIsNight() {
|
|
||||||
const momentNow = moment();
|
|
||||||
return {
|
|
||||||
type: ACTIONS.UPDATE_IS_NIGHT,
|
|
||||||
data: { isNight: (() => {
|
|
||||||
const startNightMoment = moment('21:00', 'HH:mm');
|
|
||||||
const endNightMoment = moment('8:00', 'HH:mm');
|
|
||||||
return !(momentNow.isAfter(endNightMoment) && momentNow.isBefore(startNightMoment));
|
|
||||||
})(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doDownloadLanguage(langFile) {
|
export function doDownloadLanguage(langFile) {
|
||||||
return dispatch => {
|
return dispatch => {
|
||||||
const destinationPath = `${app.i18n.directory}/${langFile}`;
|
const destinationPath = `${app.i18n.directory}/${langFile}`;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const FlowFlowPlugin = require('./flowtype-plugin');
|
const FlowFlowPlugin = require('./flowtype-plugin');
|
||||||
|
const isDev = require('electron-is-dev');
|
||||||
|
|
||||||
const ELECTRON_RENDERER_PROCESS_ROOT = path.resolve(__dirname, 'src/renderer/');
|
const ELECTRON_RENDERER_PROCESS_ROOT = path.resolve(__dirname, 'src/renderer/');
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (isDev) {
|
||||||
module.exports.plugins = [
|
module.exports.plugins = [
|
||||||
new FlowFlowPlugin({
|
new FlowFlowPlugin({
|
||||||
warn: true,
|
warn: true,
|
||||||
|
|
Loading…
Reference in a new issue