Merge branch 'master' of github.com:lbryio/lbry-app

This commit is contained in:
Jeremy Kauffman 2017-06-26 13:17:46 -04:00
commit de5af5d2bc
18 changed files with 8993 additions and 75 deletions

View file

@ -3,13 +3,21 @@ const url = require('url');
const isDebug = process.env.NODE_ENV === 'development' const isDebug = process.env.NODE_ENV === 'development'
if (isDebug) { if (isDebug) {
require('electron-debug')({showDevTools: true}); try
{
require('electron-debug')({showDevTools: true});
}
catch (err) // electron-debug is in devDependencies, but some
{
console.error(err)
}
} }
const path = require('path'); const path = require('path');
const jayson = require('jayson'); const jayson = require('jayson');
const semver = require('semver'); const semver = require('semver');
const https = require('https'); const https = require('https');
const keytar = require('keytar');
// tree-kill has better cross-platform handling of // tree-kill has better cross-platform handling of
// killing a process. child-process.kill was unreliable // killing a process. child-process.kill was unreliable
const kill = require('tree-kill'); const kill = require('tree-kill');
@ -389,3 +397,13 @@ if (process.platform == 'darwin') {
win.webContents.send('open-uri-requested', denormalizeUri(process.argv[1])); win.webContents.send('open-uri-requested', denormalizeUri(process.argv[1]));
} }
} }
ipcMain.on('get-auth-token', (event) => {
keytar.getPassword("LBRY", "auth_token").then(token => {
event.sender.send('auth-token-response', token ? token.toString().trim() : null)
});
});
ipcMain.on('set-auth-token', (event, token) => {
keytar.setPassword("LBRY", "auth_token", token ? token.toString().trim() : null);
});

View file

@ -11,8 +11,12 @@
"electron-dl": "^1.6.0", "electron-dl": "^1.6.0",
"install": "^0.8.7", "install": "^0.8.7",
"jayson": "^2.0.2", "jayson": "^2.0.2",
"keytar": "^4.0.3",
"npm": "^4.2.0", "npm": "^4.2.0",
"semver": "^5.3.0", "semver": "^5.3.0",
"tree-kill": "^1.1.0" "tree-kill": "^1.1.0"
},
"devDependencies": {
"electron-rebuild": "^1.5.11"
} }
} }

2016
app/yarn.lock Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,30 +1,34 @@
pip install -r build\requirements.txt pip install -r build\requirements.txt
python build\set_version.py python build\set_version.py
# Get the latest stable version of Node.js or io.js # Get the latest stable version of Node.js or io.js
Install-Product node $env:nodejs_version Install-Product node $env:nodejs_version
npm install -g yarn
yarn install
# install node modules
npm install # do app
cd app cd app
npm install yarn install
cd ..
# build ui
cd ui
npm install
# necessary to ensure native Node modules (e.g. keytar) are built against the correct version of Node) # necessary to ensure native Node modules (e.g. keytar) are built against the correct version of Node)
# yes, it needs to be run twice. it fails the first time, not sure why # yes, it needs to be run twice. it fails the first time, not sure why
node_modules\.bin\electron-rebuild node_modules\.bin\electron-rebuild
node_modules\.bin\electron-rebuild node_modules\.bin\electron-rebuild
cd ..
# build ui
cd ui
yarn install
npm rebuild node-sass
node extractLocals.js node extractLocals.js
node_modules\.bin\node-sass --output dist\css --sourcemap=none scss\ node_modules\.bin\node-sass --output dist\css --sourcemap=none scss\
node_modules\.bin\webpack node_modules\.bin\webpack
Copy-Item dist ..\app\ -recurse Copy-Item dist ..\app\ -recurse
cd .. cd ..
# get daemon and cli executable # get daemon and cli executable
$daemon_url = (Get-Content build\DAEMON_URL -Raw).replace("OSNAME", "windows") $daemon_url = (Get-Content build\DAEMON_URL -Raw).replace("OSNAME", "windows")
Invoke-WebRequest -Uri $daemon_url -OutFile daemon.zip Invoke-WebRequest -Uri $daemon_url -OutFile daemon.zip
@ -32,6 +36,7 @@ Expand-Archive daemon.zip -DestinationPath app\dist\
dir app\dist\ # verify that daemon binary is there dir app\dist\ # verify that daemon binary is there
rm daemon.zip rm daemon.zip
# build electron app # build electron app
node_modules\.bin\build -p never node_modules\.bin\build -p never
$binary_name = Get-ChildItem -Path dist -Filter '*.exe' -Name $binary_name = Get-ChildItem -Path dist -Filter '*.exe' -Name
@ -39,9 +44,11 @@ $new_name = $binary_name -replace '^LBRY Setup (.*)\.exe$', 'LBRY_$1.exe'
Rename-Item -Path "dist\$binary_name" -NewName $new_name Rename-Item -Path "dist\$binary_name" -NewName $new_name
dir dist # verify that binary was built/named correctly dir dist # verify that binary was built/named correctly
# sign binary # sign binary
nuget install secure-file -ExcludeVersion nuget install secure-file -ExcludeVersion
secure-file\tools\secure-file -decrypt build\lbry2.pfx.enc -secret "$env:pfx_key" secure-file\tools\secure-file -decrypt build\lbry2.pfx.enc -secret "$env:pfx_key"
& ${env:SIGNTOOL_PATH} sign /f build\lbry2.pfx /p "$env:key_pass" /tr http://tsa.starfieldtech.com /td SHA256 /fd SHA256 dist\*.exe & ${env:SIGNTOOL_PATH} sign /f build\lbry2.pfx /p "$env:key_pass" /tr http://tsa.starfieldtech.com /td SHA256 /fd SHA256 dist\*.exe
python build\upload_assets.py python build\upload_assets.py

View file

@ -45,19 +45,12 @@ if [ "$FULL_BUILD" == "true" ]; then
python "$BUILD_DIR/set_version.py" python "$BUILD_DIR/set_version.py"
fi fi
libsecret="libsecret-1-dev"
if $LINUX && [ -z "$(dpkg-query --show --showformat='${Status}\n' "$libsecret" 2>/dev/null | grep "install ok installed")" ]; then
# this is needed for keytar, which does secure password/token management
sudo apt-get install --no-install-recommends -y "$libsecret"
fi
[ -d "$ROOT/dist" ] && rm -rf "$ROOT/dist" [ -d "$ROOT/dist" ] && rm -rf "$ROOT/dist"
mkdir -p "$ROOT/dist" mkdir -p "$ROOT/dist"
[ -d "$ROOT/app/dist" ] && rm -rf "$ROOT/app/dist" [ -d "$ROOT/app/dist" ] && rm -rf "$ROOT/app/dist"
mkdir -p "$ROOT/app/dist" mkdir -p "$ROOT/app/dist"
npm install yarn install
@ -67,16 +60,8 @@ npm install
( (
cd "$ROOT/ui" cd "$ROOT/ui"
npm install yarn install
npm rebuild node-sass
# necessary to ensure native Node modules (e.g. keytar) are built against the correct version of Node)
# yes, it needs to be run twice. it fails the first time, not sure why
set +e
# DEBUG=electron-rebuild node_modules/.bin/electron-rebuild .
node_modules/.bin/electron-rebuild "$ROOT/ui"
set -e
node_modules/.bin/electron-rebuild "$ROOT/ui"
node extractLocals.js node extractLocals.js
node_modules/.bin/node-sass --output dist/css --sourcemap=none scss/ node_modules/.bin/node-sass --output dist/css --sourcemap=none scss/
node_modules/.bin/webpack node_modules/.bin/webpack
@ -105,7 +90,15 @@ rm "$BUILD_DIR/daemon.zip"
( (
cd "$ROOT/app" cd "$ROOT/app"
npm install yarn install
# necessary to ensure native Node modules (e.g. keytar) are built against the correct version of Node)
# yes, it needs to be run twice. it fails the first time, not sure why
set +e
# DEBUG=electron-rebuild node_modules/.bin/electron-rebuild .
node_modules/.bin/electron-rebuild "$ROOT/app"
set -e
node_modules/.bin/electron-rebuild "$ROOT/app"
) )
if [ "$FULL_BUILD" == "true" ]; then if [ "$FULL_BUILD" == "true" ]; then

View file

@ -41,7 +41,7 @@ set -eu
if $LINUX; then if $LINUX; then
INSTALL="$SUDO apt-get install --no-install-recommends -y" INSTALL="$SUDO apt-get install --no-install-recommends -y"
$INSTALL build-essential libssl-dev libffi-dev libgmp3-dev python2.7-dev $INSTALL build-essential libssl-dev libffi-dev libgmp3-dev python2.7-dev libsecret-1-dev
elif $OSX && ! cmd_exists brew ; then elif $OSX && ! cmd_exists brew ; then
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
fi fi
@ -88,6 +88,17 @@ if ! cmd_exists node; then
fi fi
fi fi
if ! cmd_exists yarn; then
if $LINUX; then
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | $SUDO apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | $SUDO tee /etc/apt/sources.list.d/yarn.list
$SUDO apt-get update
$SUDO apt-get install yarn
elif $OSX; then
brew install yarn
fi
fi
if ! cmd_exists unzip; then if ! cmd_exists unzip; then
if $LINUX; then if $LINUX; then
$INSTALL unzip $INSTALL unzip

View file

@ -1,7 +1,5 @@
GitPython==2.1.1
PyGithub==1.32 PyGithub==1.32
requests[security]==2.13.0 requests[security]==2.13.0
PyInstaller==3.2.1
uritemplate==3.0.0 uritemplate==3.0.0
git+https://github.com/lbryio/bumpversion.git git+https://github.com/lbryio/bumpversion.git
boto3==1.4.4 boto3==1.4.4

View file

@ -56,6 +56,7 @@
} }
}, },
"devDependencies": { "devDependencies": {
"devtron": "^1.4.0",
"electron": "^1.4.15", "electron": "^1.4.15",
"electron-builder": "^11.7.0", "electron-builder": "^11.7.0",
"electron-debug": "^1.1.0" "electron-debug": "^1.1.0"

View file

@ -1,5 +1,6 @@
## Development Setup ## Development Setup
- Install node and npm (linux users: [use this](https://github.com/nodesource/distributions). if that doesn't work, [this gist may be useful](https://gist.github.com/isaacs/579814)) - Install node and npm (linux users: [use this](https://github.com/nodesource/distributions). if that doesn't work, [this gist may be useful](https://gist.github.com/isaacs/579814))
- Run `./watch.sh` (this will `npm install` dependencies) - `npm install -g yarn` (or see https://yarnpkg.com/en/docs/install)
- Run `./watch.sh` (this will `yarn install` dependencies)

View file

@ -61,6 +61,8 @@ export function doChangePath(path) {
export function doHistoryBack() { export function doHistoryBack() {
return function(dispatch, getState) { return function(dispatch, getState) {
if (!history.state) return;
history.back(); history.back();
}; };
} }

View file

@ -1,7 +1,7 @@
import lbry from "./lbry.js"; import lbry from "./lbry.js";
const querystring = require("querystring"); const querystring = require("querystring");
const keytar = require("keytar"); const { ipcRenderer } = require("electron");
const lbryio = { const lbryio = {
enabled: true, enabled: true,
@ -114,17 +114,16 @@ lbryio.call = function(resource, action, params = {}, method = "get") {
}; };
lbryio.getAuthToken = () => { lbryio.getAuthToken = () => {
return keytar.getPassword("LBRY", "auth_token").then(token => { return new Promise((resolve, reject) => {
return token ? token.toString().trim() : null; ipcRenderer.once("auth-token-response", (event, token) => {
return resolve(token);
});
ipcRenderer.send("get-auth-token");
}); });
}; };
lbryio.setAuthToken = token => { lbryio.setAuthToken = token => {
return keytar.setPassword( ipcRenderer.send("set-auth-token", token);
"LBRY",
"auth_token",
token ? token.toString().trim() : null
);
}; };
lbryio.getCurrentUser = () => { lbryio.getCurrentUser = () => {

View file

@ -12,7 +12,7 @@ class ShowPage extends React.PureComponent {
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
const { isResolvingUri, resolveUri, claim, uri } = this.props; const { isResolvingUri, resolveUri, claim, uri } = nextProps;
if (!isResolvingUri && claim === undefined && uri) { if (!isResolvingUri && claim === undefined && uri) {
resolveUri(uri); resolveUri(uri);

View file

@ -13,16 +13,16 @@ reducers[types.FILE_LIST_STARTED] = function(state, action) {
reducers[types.FILE_LIST_COMPLETED] = function(state, action) { reducers[types.FILE_LIST_COMPLETED] = function(state, action) {
const { fileInfos } = action.data; const { fileInfos } = action.data;
const newFileInfos = Object.assign({}, state.fileInfos); const newByOutpoint = Object.assign({}, state.byOutpoint);
fileInfos.forEach(fileInfo => { fileInfos.forEach(fileInfo => {
const { outpoint } = fileInfo; const { outpoint } = fileInfo;
if (outpoint) newFileInfos[fileInfo.outpoint] = fileInfo; if (outpoint) newByOutpoint[fileInfo.outpoint] = fileInfo;
}); });
return Object.assign({}, state, { return Object.assign({}, state, {
isFileListPending: false, isFileListPending: false,
fileInfos: newFileInfos, byOutpoint: newByOutpoint,
}); });
}; };
@ -40,14 +40,14 @@ reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) {
reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) { reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) {
const { fileInfo, outpoint } = action.data; const { fileInfo, outpoint } = action.data;
const newFileInfos = Object.assign({}, state.fileInfos); const newByOutpoint = Object.assign({}, state.byOutpoint);
const newFetching = Object.assign({}, state.fetching); const newFetching = Object.assign({}, state.fetching);
newFileInfos[outpoint] = fileInfo; newByOutpoint[outpoint] = fileInfo;
delete newFetching[outpoint]; delete newFetching[outpoint];
return Object.assign({}, state, { return Object.assign({}, state, {
fileInfos: newFileInfos, byOutpoint: newByOutpoint,
fetching: newFetching, fetching: newFetching,
}); });
}; };
@ -55,32 +55,32 @@ reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) {
reducers[types.DOWNLOADING_STARTED] = function(state, action) { reducers[types.DOWNLOADING_STARTED] = function(state, action) {
const { uri, outpoint, fileInfo } = action.data; const { uri, outpoint, fileInfo } = action.data;
const newFileInfos = Object.assign({}, state.fileInfos); const newByOutpoint = Object.assign({}, state.byOutpoint);
const newDownloading = Object.assign({}, state.urisDownloading); const newDownloading = Object.assign({}, state.urisDownloading);
const newLoading = Object.assign({}, state.urisLoading); const newLoading = Object.assign({}, state.urisLoading);
newDownloading[uri] = true; newDownloading[uri] = true;
newFileInfos[outpoint] = fileInfo; newByOutpoint[outpoint] = fileInfo;
delete newLoading[uri]; delete newLoading[uri];
return Object.assign({}, state, { return Object.assign({}, state, {
urisDownloading: newDownloading, urisDownloading: newDownloading,
urisLoading: newLoading, urisLoading: newLoading,
fileInfos: newFileInfos, byOutpoint: newByOutpoint,
}); });
}; };
reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) { reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) {
const { uri, outpoint, fileInfo } = action.data; const { uri, outpoint, fileInfo } = action.data;
const newFileInfos = Object.assign({}, state.fileInfos); const newByOutpoint = Object.assign({}, state.byOutpoint);
const newDownloading = Object.assign({}, state.urisDownloading); const newDownloading = Object.assign({}, state.urisDownloading);
newFileInfos[outpoint] = fileInfo; byOutpoint[outpoint] = fileInfo;
newDownloading[uri] = true; newDownloading[uri] = true;
return Object.assign({}, state, { return Object.assign({}, state, {
fileInfos: newFileInfos, byOutpoint: newByOutpoint,
urisDownloading: newDownloading, urisDownloading: newDownloading,
}); });
}; };
@ -88,14 +88,14 @@ reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) {
reducers[types.DOWNLOADING_COMPLETED] = function(state, action) { reducers[types.DOWNLOADING_COMPLETED] = function(state, action) {
const { uri, outpoint, fileInfo } = action.data; const { uri, outpoint, fileInfo } = action.data;
const newFileInfos = Object.assign({}, state.fileInfos); const newByOutpoint = Object.assign({}, state.byOutpoint);
const newDownloading = Object.assign({}, state.urisDownloading); const newDownloading = Object.assign({}, state.urisDownloading);
newFileInfos[outpoint] = fileInfo; newByOutpoint[outpoint] = fileInfo;
delete newDownloading[uri]; delete newDownloading[uri];
return Object.assign({}, state, { return Object.assign({}, state, {
fileInfos: newFileInfos, byOutpoint: newByOutpoint,
urisDownloading: newDownloading, urisDownloading: newDownloading,
}); });
}; };
@ -103,12 +103,12 @@ reducers[types.DOWNLOADING_COMPLETED] = function(state, action) {
reducers[types.FILE_DELETE] = function(state, action) { reducers[types.FILE_DELETE] = function(state, action) {
const { outpoint } = action.data; const { outpoint } = action.data;
const newFileInfos = Object.assign({}, state.fileInfos); const newByOutpoint = Object.assign({}, state.byOutpoint);
delete newFileInfos[outpoint]; delete newByOutpoint[outpoint];
return Object.assign({}, state, { return Object.assign({}, state, {
fileInfos: newFileInfos, byOutpoint: newByOutpoint,
}); });
}; };

View file

@ -8,9 +8,9 @@ import {
export const _selectState = state => state.fileInfo || {}; export const _selectState = state => state.fileInfo || {};
export const selectAllFileInfos = createSelector( export const selectFileInfosByOutpoint = createSelector(
_selectState, _selectState,
state => state.fileInfos || {} state => state.byOutpoint || {}
); );
export const selectFileListIsPending = createSelector( export const selectFileListIsPending = createSelector(
@ -28,10 +28,10 @@ export const selectFileListDownloadedOrPublishedIsPending = createSelector(
export const selectFileInfoForUri = (state, props) => { export const selectFileInfoForUri = (state, props) => {
const claims = selectClaimsByUri(state), const claims = selectClaimsByUri(state),
claim = claims[props.uri], claim = claims[props.uri],
fileInfos = selectAllFileInfos(state), byOutpoint = selectFileInfosByOutpoint(state),
outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined;
return outpoint && fileInfos ? fileInfos[outpoint] : undefined; return outpoint ? byOutpoint[outpoint] : undefined;
}; };
export const makeSelectFileInfoForUri = () => { export const makeSelectFileInfoForUri = () => {
@ -70,11 +70,11 @@ export const makeSelectLoadingForUri = () => {
}; };
export const selectFileInfosDownloaded = createSelector( export const selectFileInfosDownloaded = createSelector(
selectAllFileInfos, selectFileInfosByOutpoint,
selectMyClaimsOutpoints, selectMyClaimsOutpoints,
(fileInfos, myClaimOutpoints) => { (byOutpoint, myClaimOutpoints) => {
const fileInfoList = []; const fileInfoList = [];
Object.values(fileInfos).forEach(fileInfo => { Object.values(byOutpoint).forEach(fileInfo => {
if ( if (
fileInfo && fileInfo &&
myClaimOutpoints.indexOf(fileInfo.outpoint) === -1 && myClaimOutpoints.indexOf(fileInfo.outpoint) === -1 &&
@ -95,15 +95,14 @@ export const selectFileInfosPendingPublish = createSelector(
); );
export const selectFileInfosPublished = createSelector( export const selectFileInfosPublished = createSelector(
selectAllFileInfos, selectFileInfosByOutpoint,
selectFileInfosPendingPublish, selectFileInfosPendingPublish,
selectMyClaimsOutpoints, selectMyClaimsOutpoints,
(allFileInfos, pendingFileInfos, outpoints) => { (byOutpoint, pendingFileInfos, outpoints) => {
const fileInfos = []; const fileInfos = [];
outpoints.forEach(outpoint => { outpoints.forEach(outpoint => {
if (allFileInfos[outpoint]) { const fileInfo = byOutpoint[outpoint];
fileInfos.push(allFileInfos[outpoint]); if (fileInfo) fileInfos.push(fileInfo);
}
}); });
return [...fileInfos, ...pendingFileInfos]; return [...fileInfos, ...pendingFileInfos];
} }

View file

@ -28,7 +28,6 @@
"from2": "^2.3.0", "from2": "^2.3.0",
"jshashes": "^1.0.6", "jshashes": "^1.0.6",
"localforage": "^1.5.0", "localforage": "^1.5.0",
"keytar": "^4.0.3",
"node-sass": "^3.8.0", "node-sass": "^3.8.0",
"rc-progress": "^2.0.6", "rc-progress": "^2.0.6",
"react": "^15.4.0", "react": "^15.4.0",
@ -55,7 +54,6 @@
"babel-preset-es2015": "^6.18.0", "babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0", "babel-preset-react": "^6.16.0",
"babel-preset-stage-2": "^6.18.0", "babel-preset-stage-2": "^6.18.0",
"electron-rebuild": "^1.5.11",
"eslint": "^3.10.2", "eslint": "^3.10.2",
"eslint-config-airbnb": "^13.0.0", "eslint-config-airbnb": "^13.0.0",
"eslint-loader": "^1.6.1", "eslint-loader": "^1.6.1",

View file

@ -14,7 +14,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if [ ! -d "$DIR/node_modules" ]; then if [ ! -d "$DIR/node_modules" ]; then
echo "Installing NPM modules" echo "Installing NPM modules"
npm install yarn install
fi fi
# run sass once without --watch to force update. then run with --watch to keep watching # run sass once without --watch to force update. then run with --watch to keep watching

5285
ui/yarn.lock Normal file

File diff suppressed because it is too large Load diff

1586
yarn.lock Normal file

File diff suppressed because it is too large Load diff