From 2aa80ed796e032210072f60aca0b0668be95992f Mon Sep 17 00:00:00 2001 From: hackrush Date: Wed, 13 Dec 2017 14:55:14 +0530 Subject: [PATCH 01/66] Reworked abandon to not be depenedent on txn list --- src/renderer/redux/actions/app.js | 3 +-- src/renderer/redux/actions/content.js | 11 +++++++---- src/renderer/redux/actions/wallet.js | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 46b2e5fa1..bf82fb269 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -9,7 +9,7 @@ import { selectRemoteVersion, } from "redux/selectors/app"; import { doFetchDaemonSettings } from "redux/actions/settings"; -import { doBalanceSubscribe, doFetchTransactions } from "redux/actions/wallet"; +import { doBalanceSubscribe } from "redux/actions/wallet"; import { doAuthenticate } from "redux/actions/user"; import { doFetchFileInfosAndPublishedClaims } from "redux/actions/file_info"; import * as modals from "constants/modal_types"; @@ -222,7 +222,6 @@ export function doDaemonReady() { dispatch(doBalanceSubscribe()); dispatch(doFetchFileInfosAndPublishedClaims()); dispatch(doFetchRewardedContent()); - dispatch(doFetchTransactions(false)); if (!selectIsUpgradeSkipped(state)) { dispatch(doCheckUpgradeAvailable()); } diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index cb0b3d766..8d7a92a4e 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -4,7 +4,8 @@ import lbry from "lbry"; import lbryio from "lbryio"; import lbryuri from "lbryuri"; import { makeSelectClientSetting } from "redux/selectors/settings"; -import { selectBalance, selectTransactionItems } from "redux/selectors/wallet"; +import { selectMyClaimsRaw } from "redux/selectors/claims"; +import { selectBalance } from "redux/selectors/wallet"; import { makeSelectFileInfoForUri, selectDownloadingByOutpoint, @@ -288,7 +289,9 @@ export function doLoadVideo(uri) { }); dispatch( doAlertError( - `Failed to download ${uri}, please try again. If this problem persists, visit https://lbry.io/faq/support for support.` + `Failed to download ${ + uri + }, please try again. If this problem persists, visit https://lbry.io/faq/support for support.` ) ); }); @@ -503,8 +506,8 @@ export function doPublish(params) { export function doAbandonClaim(txid, nout) { return function(dispatch, getState) { const state = getState(); - const transactionItems = selectTransactionItems(state); - const { claim_id: claimId, claim_name: name } = transactionItems.find( + const myClaims = selectMyClaimsRaw(state); + const { claim_id: claimId, name: name } = myClaims.find( claim => claim.txid == txid && claim.nout == nout ); diff --git a/src/renderer/redux/actions/wallet.js b/src/renderer/redux/actions/wallet.js index 5db24d939..09efea390 100644 --- a/src/renderer/redux/actions/wallet.js +++ b/src/renderer/redux/actions/wallet.js @@ -29,13 +29,13 @@ export function doBalanceSubscribe() { }; } -export function doFetchTransactions(fetch_tip_info = true) { +export function doFetchTransactions() { return function(dispatch, getState) { dispatch({ type: types.FETCH_TRANSACTIONS_STARTED, }); - lbry.transaction_list({ include_tip_info: fetch_tip_info }).then(results => { + lbry.transaction_list({ include_tip_info: true }).then(results => { dispatch({ type: types.FETCH_TRANSACTIONS_COMPLETED, data: { From f2e13506dc12657f7491a0322bd9031ba02a5722 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 10:32:41 -0300 Subject: [PATCH 02/66] Overwrite cmdtest when installing yarn (https://yarnpkg.com/lang/en/docs/install/#linux-tab) --- build/install_deps.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/install_deps.sh b/build/install_deps.sh index 34a212dfe..2e88c67d9 100755 --- a/build/install_deps.sh +++ b/build/install_deps.sh @@ -99,7 +99,7 @@ if ! cmd_exists yarn; 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 + $SUDO apt-get -o Dpkg::Options::="--force-overwrite" install yarn elif $OSX; then brew install yarn else From 040b57352f0cbfc6e7439c7dfb12e2bfc4b10f35 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 18:35:07 -0300 Subject: [PATCH 03/66] Add and configure ESLint --- .eslintrc.json | 26 ++ package.json | 11 +- yarn.lock | 772 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 781 insertions(+), 28 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..39d1f5f24 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "plugins": [ + "flowtype" + ], + "extends": [ + "airbnb", + "plugin:flowtype/recommended", + "prettier" + ], + "settings": { + "import/resolver": { + "webpack": { + "config": "webpack.renderer.additions.js" + } + } + }, + "parser": "babel-eslint", + "env": { + "browser": true, + "node": true + }, + "globals": { + "__static": true, + "__": true + } +} \ No newline at end of file diff --git a/package.json b/package.json index ff83432b9..60b51013a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "dist": "yarn compile && electron-builder", "dist:dir": "yarn dist -- --dir -c.compression=store -c.mac.identity=null", "postinstall": "electron-builder install-app-deps", - "precommit": "lint-staged" + "precommit": "lint-staged", + "lint": "eslint src/" }, "main": "src/main/index.js", "keywords": [ @@ -76,6 +77,14 @@ "electron-builder": "^19.48.2", "electron-devtools-installer": "^2.2.1", "electron-webpack": "^1.11.0", + "electron-webpack-eslint": "^1.2.0", + "eslint-config-airbnb": "^16.1.0", + "eslint-config-prettier": "^2.9.0", + "eslint-import-resolver-webpack": "^0.8.3", + "eslint-plugin-flowtype": "^2.40.1", + "eslint-plugin-import": "^2.8.0", + "eslint-plugin-jsx-a11y": "^6.0.3", + "eslint-plugin-react": "^7.5.1", "flow-babel-webpack-plugin": "^1.1.0", "flow-bin": "^0.61.0", "flow-typed": "^2.2.3", diff --git a/yarn.lock b/yarn.lock index 65aa0ebaf..c66b37252 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,6 +34,59 @@ version "0.0.6" resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" +"@babel/code-frame@7.0.0-beta.31": + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.31.tgz#473d021ecc573a2cce1c07d5b509d5215f46ba35" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/helper-function-name@7.0.0-beta.31": + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.31.tgz#afe63ad799209989348b1109b44feb66aa245f57" + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.31" + "@babel/template" "7.0.0-beta.31" + "@babel/traverse" "7.0.0-beta.31" + "@babel/types" "7.0.0-beta.31" + +"@babel/helper-get-function-arity@7.0.0-beta.31": + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.31.tgz#1176d79252741218e0aec872ada07efb2b37a493" + dependencies: + "@babel/types" "7.0.0-beta.31" + +"@babel/template@7.0.0-beta.31": + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda" + dependencies: + "@babel/code-frame" "7.0.0-beta.31" + "@babel/types" "7.0.0-beta.31" + babylon "7.0.0-beta.31" + lodash "^4.2.0" + +"@babel/traverse@7.0.0-beta.31": + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.31.tgz#db399499ad74aefda014f0c10321ab255134b1df" + dependencies: + "@babel/code-frame" "7.0.0-beta.31" + "@babel/helper-function-name" "7.0.0-beta.31" + "@babel/types" "7.0.0-beta.31" + babylon "7.0.0-beta.31" + debug "^3.0.1" + globals "^10.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/types@7.0.0-beta.31": + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.31.tgz#42c9c86784f674c173fb21882ca9643334029de4" + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + "@segment/top-domain@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@segment/top-domain/-/top-domain-3.0.0.tgz#02e5a5a4fd42a9f6cf886b05e82f104012a3c3a7" @@ -84,10 +137,20 @@ acorn-dynamic-import@^2.0.0: dependencies: acorn "^4.0.3" +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + acorn@^1.0.3: version "1.2.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014" +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -128,6 +191,15 @@ ajv@^5.0.0, ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.3: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^5.3.0: + version "5.5.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -164,6 +236,10 @@ ansi-escapes@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -241,6 +317,12 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +aria-query@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.7.0.tgz#4af10a1e61573ddea0cf3b99b51c52c05b424d24" + dependencies: + ast-types-flow "0.0.7" + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -255,6 +337,10 @@ array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" +array-find@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -284,6 +370,10 @@ array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asap@^2.0.0, asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -321,6 +411,10 @@ assert@^1.1.1: dependencies: util "0.10.3" +ast-types-flow@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + ast-types@0.8.15: version "0.8.15" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52" @@ -378,7 +472,13 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-code-frame@^6.11.0, babel-code-frame@^6.26.0: +axobject-query@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0" + dependencies: + ast-types-flow "0.0.7" + +babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -410,6 +510,15 @@ babel-core@^6.24.1, babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" +babel-eslint@^8.0.1: + version "8.0.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.3.tgz#f29ecf02336be438195325cd47c468da81ee4e98" + dependencies: + "@babel/code-frame" "7.0.0-beta.31" + "@babel/traverse" "7.0.0-beta.31" + "@babel/types" "7.0.0-beta.31" + babylon "7.0.0-beta.31" + babel-generator@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" @@ -1208,6 +1317,10 @@ babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: lodash "^4.17.4" to-fast-properties "^1.0.3" +babylon@7.0.0-beta.31: + version "7.0.0-beta.31" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.31.tgz#7ec10f81e0e456fd0f855ad60fa30c2ac454283f" + babylon@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -1420,6 +1533,12 @@ browserify-sign@^4.0.0: inherits "^2.0.1" parse-asn1 "^5.0.0" +browserify-zlib@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + dependencies: + pako "~0.2.0" + browserify-zlib@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" @@ -1490,7 +1609,7 @@ builder-util@3.4.3, builder-util@^3.4.2, builder-util@^3.4.3: temp-file "^3.0.0" tunnel-agent "^0.6.0" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1546,6 +1665,16 @@ call-limit@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.0.tgz#6fd61b03f3da42a2cd0ec2b60f02bd0e71991fea" +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + camel-case@3.0.x: version "3.0.0" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" @@ -1628,7 +1757,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" dependencies: @@ -1636,6 +1765,10 @@ chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -1678,6 +1811,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + clap@^1.0.9: version "1.2.3" resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" @@ -1704,6 +1841,12 @@ cli-cursor@^1.0.2: dependencies: restore-cursor "^1.0.1" +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + cli-spinners@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" @@ -1724,6 +1867,10 @@ cli-truncate@^0.2.1: slice-ansi "0.0.4" string-width "^1.0.1" +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" @@ -1770,6 +1917,10 @@ coa@~1.0.1: dependencies: q "^1.1.2" +coalescy@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/coalescy/-/coalescy-1.0.0.tgz#4b065846b836361ada6c4b4a4abf4bc1cac31bf1" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -1918,7 +2069,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@1.6.0, concat-stream@^1.5.0, concat-stream@^1.5.2: +concat-stream@1.6.0, concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1962,6 +2113,10 @@ constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" @@ -2060,7 +2215,7 @@ cross-spawn@^3.0.0: lru-cache "^4.0.1" which "^1.2.9" -cross-spawn@^5.0.1: +cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -2223,6 +2378,10 @@ d@1: dependencies: es5-ext "^0.10.9" +damerau-levenshtein@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -2237,7 +2396,7 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@*, debug@^3.0.0, debug@^3.1.0: +debug@*, debug@^3.0.0, debug@^3.0.1, debug@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: @@ -2295,6 +2454,10 @@ deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -2312,6 +2475,18 @@ defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + del@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" @@ -2423,6 +2598,19 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0, doctrine@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" + dependencies: + esutils "^2.0.2" + dom-converter@~0.1: version "0.1.4" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.1.4.tgz#a45ef5727b890c9bffe6d7c876e7b19cb0e17f3b" @@ -2636,6 +2824,15 @@ electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.27: version "1.3.27" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" +electron-webpack-eslint@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/electron-webpack-eslint/-/electron-webpack-eslint-1.2.0.tgz#34772534e3941273ce6dcae7f26366c28bd7dfa1" + dependencies: + babel-eslint "^8.0.1" + eslint "^4.9.0" + eslint-friendly-formatter "^3.0.0" + eslint-loader "^1.9.0" + electron-webpack-js@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/electron-webpack-js/-/electron-webpack-js-1.1.0.tgz#c7c1cf375f6d32638ba62f46e1bd31445b7f1018" @@ -2702,6 +2899,10 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +emoji-regex@^6.1.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -2731,6 +2932,14 @@ enhanced-resolve@^3.4.0: object-assign "^4.0.1" tapable "^0.2.7" +enhanced-resolve@~0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.2.0" + tapable "^0.1.8" + "entities@~ 1.1.1", entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -2884,10 +3093,180 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-config-airbnb-base@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944" + dependencies: + eslint-restricted-globals "^0.1.1" + +eslint-config-airbnb@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz#2546bfb02cc9fe92284bf1723ccf2e87bc45ca46" + dependencies: + eslint-config-airbnb-base "^12.1.0" + +eslint-config-prettier@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.9.0.tgz#5ecd65174d486c22dff389fe036febf502d468a3" + dependencies: + get-stdin "^5.0.1" + +eslint-friendly-formatter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-friendly-formatter/-/eslint-friendly-formatter-3.0.0.tgz#278874435a6c46ec1d94fa0b1ff494e30ef04290" + dependencies: + chalk "^1.0.0" + coalescy "1.0.0" + extend "^3.0.0" + minimist "^1.2.0" + text-table "^0.2.0" + +eslint-import-resolver-node@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" + dependencies: + debug "^2.6.8" + resolve "^1.2.0" + +eslint-import-resolver-webpack@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.8.3.tgz#ad61e28df378a474459d953f246fd43f92675385" + dependencies: + array-find "^1.0.0" + debug "^2.6.8" + enhanced-resolve "~0.9.0" + find-root "^0.1.1" + has "^1.0.1" + interpret "^1.0.0" + is-absolute "^0.2.3" + lodash.get "^3.7.0" + node-libs-browser "^1.0.0" + resolve "^1.2.0" + semver "^5.3.0" + +eslint-loader@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-1.9.0.tgz#7e1be9feddca328d3dcfaef1ad49d5beffe83a13" + dependencies: + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-module-utils@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-flowtype@^2.40.1: + version "2.40.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.40.1.tgz#f78a8e6a4cc6da831dd541eb61e803ff0279b796" + dependencies: + lodash "^4.15.0" + +eslint-plugin-import@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz#fa1b6ef31fcb3c501c09859c1b86f1fc5b986894" + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + +eslint-plugin-jsx-a11y@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz#54583d1ae442483162e040e13cc31865465100e5" + dependencies: + aria-query "^0.7.0" + array-includes "^3.0.3" + ast-types-flow "0.0.7" + axobject-query "^0.1.0" + damerau-levenshtein "^1.0.0" + emoji-regex "^6.1.0" + jsx-ast-utils "^2.0.0" + +eslint-plugin-react@^7.5.1: + version "7.5.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b" + dependencies: + doctrine "^2.0.0" + has "^1.0.1" + jsx-ast-utils "^2.0.0" + prop-types "^15.6.0" + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^4.9.0: + version "4.13.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f" + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.0.1" + doctrine "^2.0.2" + eslint-scope "^3.7.1" + espree "^3.5.2" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "^4.0.1" + text-table "~0.2.0" + esmangle-evaluator@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz#620d866ef4861b3311f75766d52a8572bb3c6336" +espree@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.2.tgz#756ada8b979e9dcfcdb30aad8d1a9304a905e1ca" + dependencies: + acorn "^5.2.1" + acorn-jsx "^3.0.0" + esprima-fb@^15001.1.0-dev-harmony-fb: version "15001.1.0-dev-harmony-fb" resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz#30a947303c6b8d5e955bee2b99b1d233206a6901" @@ -2912,6 +3291,12 @@ esprima@~3.1.0: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + esrecurse@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" @@ -2919,7 +3304,7 @@ esrecurse@^4.1.0: estraverse "^4.1.0" object-assign "^4.0.1" -estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -3055,10 +3440,18 @@ ext-name@^5.0.0: ext-list "^2.0.0" sort-keys-length "^1.0.0" -extend@~3.0.0, extend@~3.0.1: +extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +external-editor@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.1.0.tgz#3d026a21b7f95b5726387d4200ac160d372c3b48" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -3108,6 +3501,10 @@ fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" @@ -3159,6 +3556,19 @@ figures@^1.7.0: escape-string-regexp "^1.0.5" object-assign "^4.1.0" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + file-loader@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-1.1.5.tgz#91c25b6b6fbe56dae99f10a425fd64933b5c9daa" @@ -3199,6 +3609,14 @@ find-babel-config@^1.1.0: json5 "^0.5.1" path-exists "^3.0.0" +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" @@ -3211,6 +3629,10 @@ find-parent-dir@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" +find-root@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-0.1.2.tgz#98d2267cff1916ccaf2743b3a0eea81d79d7dcd1" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -3224,6 +3646,15 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +flat-cache@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" @@ -3431,6 +3862,10 @@ function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -3476,6 +3911,10 @@ get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -3560,10 +3999,29 @@ global@~4.3.0: min-document "^2.19.0" process "~0.5.1" +globals@^10.0.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7" + +globals@^11.0.1: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.1.0.tgz#632644457f5f0e3ae711807183700ebf2e4633e4" + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -3901,6 +4359,10 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +https-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -3939,7 +4401,7 @@ i18n-extract@^0.5.1: gettext-parser "^1.2.0" glob "^7.1.1" -iconv-lite@0.4.19, iconv-lite@^0.4.19, iconv-lite@^0.4.5, iconv-lite@~0.4.13: +iconv-lite@0.4.19, iconv-lite@^0.4.17, iconv-lite@^0.4.19, iconv-lite@^0.4.5, iconv-lite@~0.4.13: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -3967,6 +4429,10 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +ignore@^3.3.3: + version "3.3.7" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -4047,6 +4513,25 @@ inline-process-browser@^1.0.0: falafel "^1.0.1" through2 "^0.6.5" +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + install@^0.10.2: version "0.10.2" resolved "https://registry.yarnpkg.com/install/-/install-0.10.2.tgz#f1f71902797e5a900069fb9ab80c94055025ffdc" @@ -4065,7 +4550,7 @@ interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" -invariant@^2.0.0, invariant@^2.2.2: +invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" dependencies: @@ -4087,6 +4572,13 @@ is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" +is-absolute@^0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" + dependencies: + is-relative "^0.2.1" + is-windows "^0.2.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4297,6 +4789,16 @@ is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" +is-relative@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" + dependencies: + is-unc-path "^0.1.1" + +is-resolvable@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" + is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -4319,10 +4821,20 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" +is-unc-path@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" + dependencies: + unc-path-regex "^0.1.0" + is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is-windows@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" + is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" @@ -4403,7 +4915,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.10.0, js-yaml@^3.9.0: +js-yaml@^3.10.0, js-yaml@^3.9.0, js-yaml@^3.9.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: @@ -4449,6 +4961,10 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -4522,6 +5038,12 @@ jstransform@~3.0.0: esprima-fb "~3001.1.0-dev-harmony-fb" source-map "0.1.31" +jsx-ast-utils@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" + dependencies: + array-includes "^3.0.3" + keypress@0.1.x: version "0.1.0" resolved "https://registry.yarnpkg.com/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a" @@ -4592,6 +5114,13 @@ leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + libnpx@~9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-9.6.0.tgz#c441ddd698b043bd8e8dc78384fa8eb7d77991e5" @@ -4706,6 +5235,13 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" +loader-fs-cache@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc" + dependencies: + find-cache-dir "^0.1.1" + mkdirp "0.5.1" + loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -4748,6 +5284,10 @@ lodash-es@^4.17.4, lodash-es@^4.2.0, lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" +lodash._baseget@^3.0.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/lodash._baseget/-/lodash._baseget-3.7.2.tgz#1b6ae1d5facf3c25532350a13c1197cb8bb674f4" + lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -4763,6 +5303,12 @@ lodash._root@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" +lodash._topath@^3.0.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/lodash._topath/-/lodash._topath-3.8.1.tgz#3ec5e2606014f4cb97f755fe6914edd8bfc00eac" + dependencies: + lodash.isarray "^3.0.0" + lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" @@ -4775,14 +5321,29 @@ lodash.clonedeep@^4.3.2, lodash.clonedeep@~4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + lodash.forin@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.forin/-/lodash.forin-4.4.0.tgz#5d3f20ae564011fbe88381f7d98949c9c9519731" +lodash.get@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-3.7.0.tgz#3ce68ae2c91683b281cc5394128303cbf75e691f" + dependencies: + lodash._baseget "^3.0.0" + lodash._topath "^3.0.0" + lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + lodash.isempty@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" @@ -4851,7 +5412,7 @@ lodash@^3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@~4.17.4: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -5000,6 +5561,10 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +memory-fs@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -5103,7 +5668,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -5151,7 +5716,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -5219,7 +5784,7 @@ multistream@^2.0.2: inherits "^2.0.1" readable-stream "^2.0.5" -mute-stream@~0.0.4: +mute-stream@0.0.7, mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -5235,6 +5800,10 @@ natives@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.1.tgz#011acce1f7cbd87f7ba6b3093d6cd9392be1c574" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + ncname@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/ncname/-/ncname-1.0.0.tgz#5b57ad18b1ca092864ef62b0b1ed8194f383b71c" @@ -5304,6 +5873,34 @@ node-gyp@^3.3.1, node-gyp@~3.6.2: tar "^2.0.0" which "1" +node-libs-browser@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-1.1.1.tgz#2a38243abedd7dffcd07a97c9aca5668975a6fea" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.1.4" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "0.0.1" + os-browserify "^0.2.0" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.0.5" + stream-browserify "^2.0.1" + stream-http "^2.3.1" + string_decoder "^0.10.25" + timers-browserify "^1.4.2" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + node-libs-browser@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" @@ -5675,6 +6272,10 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-hash@^1.1.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.2.0.tgz#e96af0e96981996a1d47f88ead8f74f1ebc4422b" + object-keys@^1.0.6, object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -5714,6 +6315,12 @@ onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + opener@~1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" @@ -5724,6 +6331,17 @@ opn@^5.1.0: dependencies: is-wsl "^1.1.0" +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + ora@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" @@ -5739,6 +6357,10 @@ original@>=0.0.5: dependencies: url-parse "1.0.x" +os-browserify@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" + os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -5761,7 +6383,7 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -5839,6 +6461,10 @@ pacote@~6.0.2: unique-filename "^1.1.0" which "^1.3.0" +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" @@ -5997,6 +6623,12 @@ pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -6017,6 +6649,10 @@ plist@^2.1.0: xmlbuilder "8.2.2" xmldom "0.1.x" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + portfinder@^1.0.9: version "1.0.13" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" @@ -6290,6 +6926,10 @@ prebuild-install@^2.3.0: tunnel-agent "^0.6.0" xtend "4.0.1" +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + prepend-http@^1.0.0, prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -6331,7 +6971,7 @@ process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" -process@^0.11.10: +process@^0.11.0, process@^0.11.10, process@~0.11.0: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -6346,6 +6986,10 @@ progress-stream@^1.1.0: speedometer "~0.1.2" through2 "~0.2.3" +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + promise-inflight@^1.0.1, promise-inflight@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -7089,6 +7733,13 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -7103,11 +7754,15 @@ resolve-cwd@^2.0.0: dependencies: resolve-from "^3.0.0" +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" -resolve@^1.4.0: +resolve@^1.2.0, resolve@^1.4.0: version "1.5.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" dependencies: @@ -7120,6 +7775,13 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + retry@^0.10.0, retry@~0.10.1: version "0.10.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" @@ -7143,12 +7805,28 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^2.0.0" inherits "^2.0.1" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" dependencies: aproba "^1.1.1" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + rxjs@^5.4.2: version "5.5.5" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.5.tgz#e164f11d38eaf29f56f08c3447f74ff02dd84e97" @@ -7328,7 +8006,7 @@ shellwords@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" -signal-exit@^3.0.0: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" @@ -7588,7 +8266,7 @@ stream-each@^1.1.0: end-of-stream "^1.1.0" stream-shift "^1.0.0" -stream-http@^2.7.2: +stream-http@^2.3.1, stream-http@^2.7.2: version "2.7.2" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" dependencies: @@ -7639,7 +8317,7 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.1: +string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -7650,16 +8328,16 @@ string.prototype.repeat@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz#aba36de08dcee6a5a337d49b2ea1da1b28fc0ecf" +string_decoder@^0.10.25, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + string_decoder@^1.0.0, string_decoder@~1.0.0, string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: safe-buffer "~5.1.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - stringify-object@^3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.1.tgz#2720c2eff940854c819f6ee252aaeb581f30624d" @@ -7783,6 +8461,10 @@ table@^4.0.1: slice-ansi "1.0.0" string-width "^2.1.1" +tapable@^0.1.8: + version "0.1.10" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" + tapable@^0.2.7: version "0.2.8" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" @@ -7851,7 +8533,7 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -text-table@~0.2.0: +text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -7880,7 +8562,7 @@ through2@~0.2.3: readable-stream "~1.1.9" xtend "~2.1.1" -"through@>=2.2.7 <3", through@^2.3.8, through@~2.3.4, through@~2.3.6: +"through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8, through@~2.3.4, through@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7896,12 +8578,24 @@ timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" +timers-browserify@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" + dependencies: + process "~0.11.0" + timers-browserify@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.4.tgz#96ca53f4b794a5e7c0e1bd7cc88a372298fa01e6" dependencies: setimmediate "^1.0.4" +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + to-arraybuffer@^1.0.0, to-arraybuffer@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -7910,6 +8604,10 @@ to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" @@ -7970,6 +8668,12 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + type-is@~1.6.15: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" @@ -8029,6 +8733,10 @@ umask@^1.1.0, umask@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" +unc-path-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" @@ -8438,6 +9146,10 @@ wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + worker-farm@~1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae" @@ -8464,6 +9176,12 @@ write-file-atomic@^2.0.0, write-file-atomic@~2.1.0: imurmurhash "^0.1.4" slide "^1.1.5" +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" From a40aecfb683992dbe7352d20b72d7b63d9165dcf Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 18:36:30 -0300 Subject: [PATCH 04/66] Apply ESLint auto fixing --- src/main/index.js | 439 ++++++++++-------- src/main/menu/context-menu.js | 29 +- src/main/menu/main-menu.js | 110 ++--- src/renderer/app.js | 15 +- src/renderer/component/common.js | 19 +- src/renderer/component/file-selector.js | 3 +- src/renderer/component/fileActions/index.js | 2 +- .../component/fileDownloadLink/index.js | 2 +- src/renderer/component/form.js | 26 +- src/renderer/component/load_screen.js | 9 +- src/renderer/component/menu.js | 4 +- src/renderer/component/splash/index.js | 10 +- .../component/subscribeButton/index.js | 5 +- src/renderer/component/tooltip.js | 6 +- src/renderer/constants/action_types.js | 2 +- src/renderer/constants/settings.js | 6 +- src/renderer/extractLocals.js | 18 +- src/renderer/index.js | 23 +- src/renderer/jsonrpc.js | 34 +- src/renderer/lbry.js | 30 +- src/renderer/lbryio.js | 51 +- src/renderer/lbryuri.js | 4 +- src/renderer/modal/modal.js | 2 +- src/renderer/modal/modalCreditIntro/index.js | 24 +- src/renderer/page/report.js | 7 +- src/renderer/page/rewards/index.js | 12 +- src/renderer/redux/actions/app.js | 6 +- src/renderer/redux/actions/content.js | 22 +- src/renderer/redux/actions/file_info.js | 20 +- src/renderer/redux/actions/navigation.js | 2 +- src/renderer/redux/actions/rewards.js | 2 +- src/renderer/redux/actions/search.js | 19 +- src/renderer/redux/actions/settings.js | 25 +- src/renderer/redux/actions/shape_shift.js | 2 +- src/renderer/redux/actions/subscriptions.js | 21 +- src/renderer/redux/actions/user.js | 30 +- src/renderer/redux/actions/wallet.js | 32 +- src/renderer/redux/reducers/claims.js | 13 +- src/renderer/redux/reducers/content.js | 11 +- src/renderer/redux/reducers/navigation.js | 8 +- src/renderer/redux/reducers/rewards.js | 9 +- src/renderer/redux/reducers/settings.js | 13 +- src/renderer/redux/reducers/subscriptions.js | 26 +- src/renderer/redux/reducers/user.js | 10 +- src/renderer/redux/reducers/wallet.js | 2 +- src/renderer/redux/selectors/availability.js | 13 +- src/renderer/redux/selectors/claims.js | 29 +- src/renderer/redux/selectors/content.js | 15 +- src/renderer/redux/selectors/cost_info.js | 10 +- src/renderer/redux/selectors/file_info.js | 24 +- src/renderer/redux/selectors/navigation.js | 11 +- src/renderer/redux/selectors/rewards.js | 56 +-- src/renderer/redux/selectors/search.js | 9 +- src/renderer/redux/selectors/settings.js | 9 +- src/renderer/redux/selectors/subscriptions.js | 8 +- src/renderer/redux/selectors/wallet.js | 27 +- src/renderer/rewards.js | 32 +- src/renderer/util/batchActions.js | 2 +- src/renderer/util/formatCredits.js | 2 +- src/renderer/util/query_params.js | 8 +- src/renderer/util/redux-utils.js | 23 +- src/renderer/util/setBadge.js | 1 + src/renderer/util/setProgressBar.js | 1 + src/renderer/util/shape_shift.js | 6 +- 64 files changed, 729 insertions(+), 722 deletions(-) diff --git a/src/main/index.js b/src/main/index.js index e43a71d7f..67e16acca 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,52 +1,63 @@ // Module imports -const {app, BrowserWindow, ipcMain, Menu, Tray, globalShortcut} = require('electron'); -const path = require('path'); -const url = require('url'); -const jayson = require('jayson'); -const semver = require('semver'); -const https = require('https'); -const keytar = require('keytar'); +const { + app, + BrowserWindow, + ipcMain, + Menu, + Tray, + globalShortcut, +} = require("electron"); +const path = require("path"); +const url = require("url"); +const jayson = require("jayson"); +const semver = require("semver"); +const https = require("https"); +const keytar = require("keytar"); // tree-kill has better cross-platform handling of // killing a process. child-process.kill was unreliable -const kill = require('tree-kill'); -const child_process = require('child_process'); -const assert = require('assert'); +const kill = require("tree-kill"); +const child_process = require("child_process"); +const assert = require("assert"); + const localVersion = app.getVersion(); -const setMenu = require('./menu/main-menu.js'); -export const contextMenu = require('./menu/context-menu'); +const setMenu = require("./menu/main-menu.js"); +export const contextMenu = require("./menu/context-menu"); // Debug configs -const isDevelopment = process.env.NODE_ENV === 'development'; +const isDevelopment = process.env.NODE_ENV === "development"; if (isDevelopment) { - try - { - const { default: installExtension, REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS } = require('electron-devtools-installer'); - app.on('ready', () => { + try { + const { + default: installExtension, + REACT_DEVELOPER_TOOLS, + REDUX_DEVTOOLS, + } = require("electron-devtools-installer"); + app.on("ready", () => { [REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS].forEach(extension => { installExtension(extension) - .then((name) => console.log(`Added Extension: ${name}`)) - .catch((err) => console.log('An error occurred: ', err)); + .then(name => console.log(`Added Extension: ${name}`)) + .catch(err => console.log("An error occurred: ", err)); }); }); - } - catch (err) - { - console.error(err) + } catch (err) { + console.error(err); } } // 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'); +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"); const rendererUrl = isDevelopment ? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}` : `file://${__dirname}/index.html`; -let client = jayson.client.http({ - host: 'localhost', +const client = jayson.client.http({ + host: "localhost", port: 5279, - path: '/', - timeout: 1000 + path: "/", + timeout: 1000, }); // Keep a global reference of the window object, if you don't, the window will @@ -84,11 +95,10 @@ function processRequestedUri(uri) { // lbry://channel/#claimid. We remove the slash here as well. // On Linux and Mac, we just return the URI as given. - if (process.platform === 'win32') { - return uri.replace(/\/$/, '').replace('/#', '#'); - } else { - return uri; + if (process.platform === "win32") { + return uri.replace(/\/$/, "").replace("/#", "#"); } + return uri; } /* @@ -97,69 +107,85 @@ function processRequestedUri(uri) { * when no windows are open. */ function openItem(fullPath) { - const subprocOptions = { - detached: true, - stdio: 'ignore', - }; + const subprocOptions = { + detached: true, + stdio: "ignore", + }; - let child; - if (process.platform === 'darwin') { - child = child_process.spawn('open', [fullPath], subprocOptions); - } else if (process.platform === 'linux') { - child = child_process.spawn('xdg-open', [fullPath], subprocOptions); - } else if (process.platform === 'win32') { - child = child_process.spawn(fullPath, Object.assign({}, subprocOptions, {shell: true})); - } + let child; + if (process.platform === "darwin") { + child = child_process.spawn("open", [fullPath], subprocOptions); + } else if (process.platform === "linux") { + child = child_process.spawn("xdg-open", [fullPath], subprocOptions); + } else if (process.platform === "win32") { + child = child_process.spawn( + fullPath, + Object.assign({}, subprocOptions, { shell: true }) + ); + } - // Causes child process reference to be garbage collected, allowing main process to exit - child.unref(); + // Causes child process reference to be garbage collected, allowing main process to exit + child.unref(); } function getPidsForProcessName(name) { - if (process.platform === 'win32') { - const tasklistOut = child_process.execSync(`tasklist /fi "Imagename eq ${name}.exe" /nh`, {encoding: 'utf8'}); - if (tasklistOut.startsWith('INFO')) { + if (process.platform === "win32") { + const tasklistOut = child_process.execSync( + `tasklist /fi "Imagename eq ${name}.exe" /nh`, + { encoding: "utf8" } + ); + if (tasklistOut.startsWith("INFO")) { return []; - } else { - return tasklistOut.match(/[^\r\n]+/g).map((line) => line.split(/\s+/)[1]); // Second column of every non-empty line } - } else { - const pgrepOut = child_process.spawnSync('pgrep', ['-x', name], {encoding: 'utf8'}).stdout; - return pgrepOut.match(/\d+/g); + return tasklistOut.match(/[^\r\n]+/g).map(line => line.split(/\s+/)[1]); // Second column of every non-empty line } + const pgrepOut = child_process.spawnSync("pgrep", ["-x", name], { + encoding: "utf8", + }).stdout; + return pgrepOut.match(/\d+/g); } -function createWindow () { +function createWindow() { // Disable renderer process's webSecurity on development to enable CORS. win = isDevelopment - ? new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600, webPreferences: {webSecurity: false}}) - : new BrowserWindow({backgroundColor: '#155B4A', minWidth: 800, minHeight: 600}); + ? new BrowserWindow({ + backgroundColor: "#155B4A", + minWidth: 800, + minHeight: 600, + webPreferences: { webSecurity: false }, + }) + : new BrowserWindow({ + backgroundColor: "#155B4A", + minWidth: 800, + minHeight: 600, + }); win.webContents.session.setUserAgent(`LBRY/${localVersion}`); - win.maximize() + win.maximize(); if (isDevelopment) { win.webContents.openDevTools(); } - win.loadURL(rendererUrl) - if (openUri) { // We stored and received a URI that an external app requested before we had a window object - win.webContents.on('did-finish-load', () => { - win.webContents.send('open-uri-requested', openUri); + win.loadURL(rendererUrl); + if (openUri) { + // We stored and received a URI that an external app requested before we had a window object + win.webContents.on("did-finish-load", () => { + win.webContents.send("open-uri-requested", openUri); }); } win.removeAllListeners(); - win.on('close', function(event) { + win.on("close", event => { if (minimize) { event.preventDefault(); win.hide(); } - }) + }); - win.on('closed', () => { - win = null - }) + win.on("closed", () => { + win = null; + }); win.on("hide", () => { // Checks what to show in the tray icon menu @@ -176,7 +202,7 @@ function createWindow () { if (minimize) updateTray(); // Unregisters Alt+F4 shortcut - globalShortcut.unregister('Alt+F4'); + globalShortcut.unregister("Alt+F4"); }); win.on("focus", () => { @@ -184,23 +210,22 @@ function createWindow () { if (minimize) updateTray(); // Registers shortcut for closing(quitting) the app - globalShortcut.register('Alt+F4', () => safeQuit()); + globalShortcut.register("Alt+F4", () => safeQuit()); - win.webContents.send('window-is-focused', null); + win.webContents.send("window-is-focused", null); }); // Menu bar win.setAutoHideMenuBar(true); win.setMenuBarVisibility(isDevelopment); setMenu(); +} -}; - -function createTray () { +function createTray() { // Minimize to tray logic follows: // Set the tray icon let iconPath; - if (process.platform === 'darwin') { + if (process.platform === "darwin") { // Using @2x for mac retina screens so the icon isn't blurry // file name needs to include "Template" at the end for dark menu bar iconPath = path.join(__static, "/img/fav/macTemplate@2x.png"); @@ -211,14 +236,14 @@ function createTray () { tray = new Tray(iconPath); tray.setToolTip("LBRY App"); tray.setTitle("LBRY"); - tray.on('double-click', () => { - win.show() - }) + tray.on("double-click", () => { + win.show(); + }); } // This needs to be done as for linux the context menu doesn't update automatically(docs) function updateTray() { - let contextMenu = Menu.buildFromTemplate(getMenuTemplate()); + const contextMenu = Menu.buildFromTemplate(getMenuTemplate()); if (tray) { tray.setContextMenu(contextMenu); } else { @@ -226,28 +251,26 @@ function updateTray() { } } -function getMenuTemplate () { +function getMenuTemplate() { return [ getToggleItem(), { label: "Quit", click: () => safeQuit(), }, - ] + ]; - function getToggleItem () { + function getToggleItem() { if (win.isVisible() && win.isFocused()) { return { - label: 'Hide LBRY App', - click: () => win.hide() - - } - } else { - return { - label: 'Show LBRY App', - click: () => win.show() - } + label: "Hide LBRY App", + click: () => win.hide(), + }; } + return { + label: "Show LBRY App", + click: () => win.show(), + }; } } @@ -256,20 +279,19 @@ function handleOpenUriRequested(uri) { // Window not created yet, so store up requested URI for when it is openUri = processRequestedUri(uri); } else { - if (win.isMinimized()) { - win.restore() + win.restore(); } else if (!win.isVisible()) { - win.show() + win.show(); } win.focus(); - win.webContents.send('open-uri-requested', processRequestedUri(uri)); + win.webContents.send("open-uri-requested", processRequestedUri(uri)); } } function handleDaemonSubprocessExited() { - console.log('The daemon has exited.'); + console.log("The daemon has exited."); daemonSubprocess = null; if (!daemonStopRequested) { // We didn't request to stop the daemon, so display a @@ -277,27 +299,31 @@ function handleDaemonSubprocessExited() { // // TODO: maybe it would be better to restart the daemon? if (win) { - console.log('Did not request daemon stop, so quitting in 5 seconds.'); + console.log("Did not request daemon stop, so quitting in 5 seconds."); win.loadURL(`file://${__static}/warning.html`); setTimeout(quitNow, 5000); } else { - console.log('Did not request daemon stop, so quitting.'); + console.log("Did not request daemon stop, so quitting."); quitNow(); } } } function launchDaemon() { - assert(!daemonSubprocess, 'Tried to launch daemon twice'); + assert(!daemonSubprocess, "Tried to launch daemon twice"); - console.log('Launching daemon:', DAEMON_PATH) - daemonSubprocess = child_process.spawn(DAEMON_PATH) + console.log("Launching daemon:", DAEMON_PATH); + daemonSubprocess = child_process.spawn(DAEMON_PATH); // Need to handle the data event instead of attaching to // process.stdout because the latter doesn't work. I believe on // windows it buffers stdout and we don't get any meaningful output - daemonSubprocess.stdout.on('data', (buf) => {console.log(String(buf).trim());}); - daemonSubprocess.stderr.on('data', (buf) => {console.log(String(buf).trim());}); - daemonSubprocess.on('exit', handleDaemonSubprocessExited); + daemonSubprocess.stdout.on("data", buf => { + console.log(String(buf).trim()); + }); + daemonSubprocess.stderr.on("data", buf => { + console.log(String(buf).trim()); + }); + daemonSubprocess.on("exit", handleDaemonSubprocessExited); } /* @@ -318,7 +344,7 @@ function quitNow() { safeQuit(); } -const isSecondaryInstance = app.makeSingleInstance((argv) => { +const isSecondaryInstance = app.makeSingleInstance(argv => { if (argv.length >= 2) { handleOpenUriRequested(argv[1]); // This will handle restoring and focusing the window } else if (win) { @@ -331,25 +357,23 @@ const isSecondaryInstance = app.makeSingleInstance((argv) => { } }); -if (isSecondaryInstance) { // We're not in the original process, so quit +if (isSecondaryInstance) { + // We're not in the original process, so quit quitNow(); } function launchDaemonIfNotRunning() { // Check if the daemon is already running. If we get // an error its because its not running - console.log('Checking for lbrynet daemon'); - client.request( - 'status', [], - function (err, res) { - if (err) { - console.log('lbrynet daemon needs to be launched') - launchDaemon(); - } else { - console.log('lbrynet daemon is already running') - } + console.log("Checking for lbrynet daemon"); + client.request("status", [], (err, res) => { + if (err) { + console.log("lbrynet daemon needs to be launched"); + launchDaemon(); + } else { + console.log("lbrynet daemon is already running"); } - ); + }); } /* @@ -358,21 +382,31 @@ function launchDaemonIfNotRunning() { * tries to force kill them. */ function forceKillAllDaemonsAndQuit() { - console.log('Attempting to force kill any running lbrynet-daemon instances...'); + console.log( + "Attempting to force kill any running lbrynet-daemon instances..." + ); - const daemonPids = getPidsForProcessName('lbrynet-daemon'); + const daemonPids = getPidsForProcessName("lbrynet-daemon"); if (!daemonPids) { - console.log('No lbrynet-daemon found running.'); + console.log("No lbrynet-daemon found running."); quitNow(); } else { - console.log(`Found ${daemonPids.length} running daemon instances. Attempting to force kill...`); + console.log( + `Found ${ + daemonPids.length + } running daemon instances. Attempting to force kill...` + ); for (const pid of daemonPids) { let daemonKillAttemptsComplete = 0; - kill(pid, 'SIGKILL', (err) => { + kill(pid, "SIGKILL", err => { daemonKillAttemptsComplete++; if (err) { - console.log(`Failed to force kill daemon task with pid ${pid}. Error message: ${err.message}`); + console.log( + `Failed to force kill daemon task with pid ${pid}. Error message: ${ + err.message + }` + ); } else { console.log(`Force killed daemon task with pid ${pid}.`); } @@ -384,15 +418,15 @@ function forceKillAllDaemonsAndQuit() { } } -app.setAsDefaultProtocolClient('lbry'); +app.setAsDefaultProtocolClient("lbry"); -app.on('ready', function() { +app.on("ready", () => { launchDaemonIfNotRunning(); if (process.platform === "linux") { - checkLinuxTraySupport( err => { + checkLinuxTraySupport(err => { if (!err) createTray(); else minimize = false; - }) + }); } else { createTray(); } @@ -400,36 +434,35 @@ app.on('ready', function() { }); // Quit when all windows are closed. -app.on('window-all-closed', () => { +app.on("window-all-closed", () => { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q - if (process.platform !== 'darwin') { - app.quit() + if (process.platform !== "darwin") { + app.quit(); } -}) +}); - -app.on('before-quit', (event) => { +app.on("before-quit", event => { 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.') + console.log("Quitting."); } }); -app.on('activate', () => { +app.on("activate", () => { // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (win === null) { - createWindow() + createWindow(); } }); -if (process.platform === 'darwin') { - app.on('open-url', (event, uri) => { +if (process.platform === "darwin") { + app.on("open-url", (event, uri) => { handleOpenUriRequested(uri); }); } else if (process.argv.length >= 2) { @@ -440,14 +473,18 @@ if (process.platform === 'darwin') { // then calls quitNow() to quit for real. function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) { function doShutdown() { - console.log('Shutting down daemon'); + console.log("Shutting down daemon"); daemonStopRequested = true; - client.request('daemon_stop', [], (err, res) => { + client.request("daemon_stop", [], (err, res) => { if (err) { - console.log(`received error when stopping lbrynet-daemon. Error message: ${err.message}\n`); - console.log('You will need to manually kill the daemon.'); + console.log( + `received error when stopping lbrynet-daemon. Error message: ${ + err.message + }\n` + ); + console.log("You will need to manually kill the daemon."); } else { - console.log('Successfully stopped daemon via RPC call.') + console.log("Successfully stopped daemon via RPC call."); quitNow(); } }); @@ -456,7 +493,7 @@ function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) { if (daemonSubprocess) { doShutdown(); } else if (!evenIfNotStartedByApp) { - console.log('Not killing lbrynet-daemon because app did not start it'); + console.log("Not killing lbrynet-daemon because app did not start it"); quitNow(); } else { doShutdown(); @@ -467,24 +504,27 @@ function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) { } // Taken from webtorrent-desktop -function checkLinuxTraySupport (cb) { +function checkLinuxTraySupport(cb) { // Check that we're on Ubuntu (or another debian system) and that we have // libappindicator1. - child_process.exec('dpkg --get-selections libappindicator1', function (err, stdout) { - if (err) return cb(err) - // Unfortunately there's no cleaner way, as far as I can tell, to check - // whether a debian package is installed: - if (stdout.endsWith('\tinstall\n')) { - cb(null) - } else { - cb(new Error('debian package not installed')) + child_process.exec( + "dpkg --get-selections libappindicator1", + (err, stdout) => { + if (err) return cb(err); + // Unfortunately there's no cleaner way, as far as I can tell, to check + // whether a debian package is installed: + if (stdout.endsWith("\tinstall\n")) { + cb(null); + } else { + cb(new Error("debian package not installed")); + } } - }) + ); } -ipcMain.on('upgrade', (event, installerPath) => { - app.on('quit', () => { - console.log('Launching upgrade installer at', installerPath); +ipcMain.on("upgrade", (event, installerPath) => { + app.on("quit", () => { + console.log("Launching upgrade installer at", installerPath); // This gets triggered called after *all* other quit-related events, so // we'll only get here if we're fully prepared and quitting for real. openItem(installerPath); @@ -497,58 +537,77 @@ ipcMain.on('upgrade', (event, installerPath) => { shutdownDaemonAndQuit(true); // wait for daemon to shut down before upgrading // what to do if no shutdown in a long time? - console.log('Update downloaded to', installerPath); - console.log('The app will close, and you will be prompted to install the latest version of LBRY.'); - console.log('After the install is complete, please reopen the app.'); + console.log("Update downloaded to", installerPath); + console.log( + "The app will close, and you will be prompted to install the latest version of LBRY." + ); + console.log("After the install is complete, please reopen the app."); }); -ipcMain.on('version-info-requested', () => { +ipcMain.on("version-info-requested", () => { function formatRc(ver) { // Adds dash if needed to make RC suffix semver friendly - return ver.replace(/([^-])rc/, '$1-rc'); + return ver.replace(/([^-])rc/, "$1-rc"); } - let result = ''; + let result = ""; const opts = { headers: { - 'User-Agent': `LBRY/${localVersion}`, - } + "User-Agent": `LBRY/${localVersion}`, + }, }; - const req = https.get(Object.assign(opts, url.parse(LATEST_RELEASE_API_URL)), (res) => { - res.on('data', (data) => { - result += data; - }); - res.on('end', () => { - const tagName = JSON.parse(result).tag_name; - const [_, remoteVersion] = tagName.match(/^v([\d.]+(?:-?rc\d+)?)$/); - if (!remoteVersion) { - if (win) { - win.webContents.send('version-info-received', null); + const req = https.get( + Object.assign(opts, url.parse(LATEST_RELEASE_API_URL)), + res => { + res.on("data", data => { + result += data; + }); + res.on("end", () => { + const tagName = JSON.parse(result).tag_name; + const [_, remoteVersion] = tagName.match(/^v([\d.]+(?:-?rc\d+)?)$/); + if (!remoteVersion) { + if (win) { + win.webContents.send("version-info-received", null); + } + } else { + const upgradeAvailable = semver.gt( + formatRc(remoteVersion), + formatRc(localVersion) + ); + if (win) { + win.webContents.send("version-info-received", { + remoteVersion, + localVersion, + upgradeAvailable, + }); + } } - } else { - const upgradeAvailable = semver.gt(formatRc(remoteVersion), formatRc(localVersion)); - if (win) { - win.webContents.send('version-info-received', {remoteVersion, localVersion, upgradeAvailable}); - } - } - }) - }); + }); + } + ); - req.on('error', (err) => { - console.log('Failed to get current version from GitHub. Error:', err); + req.on("error", err => { + console.log("Failed to get current version from GitHub. Error:", err); if (win) { - win.webContents.send('version-info-received', null); + win.webContents.send("version-info-received", null); } }); }); -ipcMain.on('get-auth-token', (event) => { +ipcMain.on("get-auth-token", event => { keytar.getPassword("LBRY", "auth_token").then(token => { - event.sender.send('auth-token-response', token ? token.toString().trim() : null) + 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); +ipcMain.on("set-auth-token", (event, token) => { + keytar.setPassword( + "LBRY", + "auth_token", + token ? token.toString().trim() : null + ); }); diff --git a/src/main/menu/context-menu.js b/src/main/menu/context-menu.js index f38de5d1c..26ed0f7de 100644 --- a/src/main/menu/context-menu.js +++ b/src/main/menu/context-menu.js @@ -1,34 +1,33 @@ -const {Menu} = require('electron'); -const electron = require('electron'); +const { Menu } = require("electron"); +const electron = require("electron"); + const app = electron.app; const contextMenuTemplate = [ { - role: 'cut', + role: "cut", }, { - role: 'copy', + role: "copy", }, { - role: 'paste', + role: "paste", }, ]; module.exports = { showContextMenu(win, posX, posY, showDevItems) { - let template = contextMenuTemplate.slice(); + const template = contextMenuTemplate.slice(); if (showDevItems) { template.push({ - type: 'separator', + type: "separator", + }); + template.push({ + label: "Inspect Element", + click() { + win.inspectElement(posX, posY); + }, }); - template.push( - { - label: 'Inspect Element', - click() { - win.inspectElement(posX, posY); - } - } - ); } Menu.buildFromTemplate(template).popup(win); diff --git a/src/main/menu/main-menu.js b/src/main/menu/main-menu.js index 7b5854d75..c26bfd118 100644 --- a/src/main/menu/main-menu.js +++ b/src/main/menu/main-menu.js @@ -1,136 +1,136 @@ -const { app, shell, Menu } = require('electron'); -const { safeQuit } = require('../index.js'); +const { app, shell, Menu } = require("electron"); +const { safeQuit } = require("../index.js"); const baseTemplate = [ { - label: 'File', + label: "File", submenu: [ { - label: 'Quit', + label: "Quit", accelerator: "CommandOrControl+Q", click: () => safeQuit(), }, - ] + ], }, { - label: 'Edit', + label: "Edit", submenu: [ { - role: 'undo', + role: "undo", }, { - role: 'redo', + role: "redo", }, { - type: 'separator', + type: "separator", }, { - role: 'cut', + role: "cut", }, { - role: 'copy', + role: "copy", }, { - role: 'paste', + role: "paste", }, { - role: 'selectall', + role: "selectall", }, - ] + ], }, { - label: 'View', + label: "View", submenu: [ { - role: 'reload' + role: "reload", }, { - label: 'Developer', + label: "Developer", submenu: [ { - role: 'forcereload' + role: "forcereload", }, { - role: 'toggledevtools' + role: "toggledevtools", }, - ] + ], }, { - type: 'separator' + type: "separator", }, { - role: 'togglefullscreen' - } - ] + role: "togglefullscreen", + }, + ], }, { - role: 'help', + role: "help", submenu: [ { - label: 'Learn More', + label: "Learn More", click(item, focusedWindow) { if (focusedWindow) { - focusedWindow.webContents.send('open-menu', '/help'); + focusedWindow.webContents.send("open-menu", "/help"); } - } + }, }, { - label: 'Frequently Asked Questions', - click(item, focusedWindow){ - shell.openExternal('https://lbry.io/faq') - } + label: "Frequently Asked Questions", + click(item, focusedWindow) { + shell.openExternal("https://lbry.io/faq"); + }, }, { - type: 'separator' + type: "separator", }, { - label: 'Report Issue', - click(item, focusedWindow){ - shell.openExternal('https://lbry.io/faq/contributing#report-a-bug'); - } + label: "Report Issue", + click(item, focusedWindow) { + shell.openExternal("https://lbry.io/faq/contributing#report-a-bug"); + }, }, { - type: 'separator' + type: "separator", }, { - label: 'Developer API Guide', - click(item, focusedWindow){ - shell.openExternal('https://lbry.io/quickstart') - } + label: "Developer API Guide", + click(item, focusedWindow) { + shell.openExternal("https://lbry.io/quickstart"); + }, }, - ] - } + ], + }, ]; const macOSAppMenuTemplate = { label: app.getName(), submenu: [ { - role: 'about', + role: "about", }, { - type: 'separator', + type: "separator", }, { - role: 'hide', + role: "hide", }, { - role: 'hideothers', + role: "hideothers", }, { - role: 'unhide', + role: "unhide", }, { - type: 'separator', + type: "separator", }, { - role: 'quit', + role: "quit", }, - ] + ], }; module.exports = () => { - let template = baseTemplate.slice(); - (process.platform === 'darwin') && template.unshift(macOSAppMenuTemplate); - Menu.setApplicationMenu(Menu.buildFromTemplate(template)); + const template = baseTemplate.slice(); + process.platform === "darwin" && template.unshift(macOSAppMenuTemplate); + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); }; diff --git a/src/renderer/app.js b/src/renderer/app.js index e249810f9..fb64e5a77 100644 --- a/src/renderer/app.js +++ b/src/renderer/app.js @@ -6,18 +6,19 @@ const config = { ...require(`./config/${env}`), }; const i18n = require("y18n")({ - directory: remote.app.getAppPath() + "/locales", + directory: `${remote.app.getAppPath()}/locales`, updateFiles: false, locale: "en", }); + const logs = []; const app = { - env: env, - config: config, - store: store, - i18n: i18n, - logs: logs, - log: function(message) { + env, + config, + store, + i18n, + logs, + log(message) { logs.push(message); }, }; diff --git a/src/renderer/component/common.js b/src/renderer/component/common.js index 2be86b00b..681fc8ab1 100644 --- a/src/renderer/component/common.js +++ b/src/renderer/component/common.js @@ -3,7 +3,7 @@ import PropTypes from "prop-types"; import { formatCredits, formatFullPrice } from "util/formatCredits"; import lbry from "../lbry.js"; -//component/icon.js +// component/icon.js export class Icon extends React.PureComponent { static propTypes = { icon: PropTypes.string.isRequired, @@ -13,12 +13,9 @@ export class Icon extends React.PureComponent { render() { const { fixed, className } = this.props; - const spanClassName = - "icon " + - ("fixed" in this.props ? "icon-fixed-width " : "") + - this.props.icon + - " " + - (this.props.className || ""); + const spanClassName = `icon ${ + "fixed" in this.props ? "icon-fixed-width " : "" + }${this.props.icon} ${this.props.className || ""}`; return ; } } @@ -90,14 +87,14 @@ export class CreditAmount extends React.PureComponent { const { amount, precision, showFullPrice } = this.props; let formattedAmount; - let fullPrice = formatFullPrice(amount, 2); + const fullPrice = formatFullPrice(amount, 2); if (showFullPrice) { formattedAmount = fullPrice; } else { formattedAmount = amount > 0 && amount < minimumRenderableAmount - ? "<" + minimumRenderableAmount + ? `<${minimumRenderableAmount}` : formatCredits(amount, precision); } @@ -111,12 +108,12 @@ export class CreditAmount extends React.PureComponent { ? this.props.label : parseFloat(amount) == 1 ? __("credit") : __("credits"); - amountText = formattedAmount + " " + label; + amountText = `${formattedAmount} ${label}`; } else { amountText = formattedAmount; } if (this.props.showPlus && amount > 0) { - amountText = "+" + amountText; + amountText = `+${amountText}`; } } diff --git a/src/renderer/component/file-selector.js b/src/renderer/component/file-selector.js index adc481782..5b5f06cf6 100644 --- a/src/renderer/component/file-selector.js +++ b/src/renderer/component/file-selector.js @@ -2,6 +2,7 @@ import React from "react"; import PropTypes from "prop-types"; const { remote } = require("electron"); + class FileSelector extends React.PureComponent { static propTypes = { type: PropTypes.oneOf(["file", "directory"]), @@ -40,7 +41,7 @@ class FileSelector extends React.PureComponent { const path = paths[0]; this.setState({ - path: path, + path, }); if (this.props.onFileChosen) { this.props.onFileChosen(path); diff --git a/src/renderer/component/fileActions/index.js b/src/renderer/component/fileActions/index.js index 53030756f..71589679b 100644 --- a/src/renderer/component/fileActions/index.js +++ b/src/renderer/component/fileActions/index.js @@ -8,7 +8,7 @@ import FileActions from "./view"; const select = (state, props) => ({ fileInfo: makeSelectFileInfoForUri(props.uri)(state), - /*availability check is disabled due to poor performance, TBD if it dies forever or requires daemon fix*/ + /* availability check is disabled due to poor performance, TBD if it dies forever or requires daemon fix */ costInfo: makeSelectCostInfoForUri(props.uri)(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state), }); diff --git a/src/renderer/component/fileDownloadLink/index.js b/src/renderer/component/fileDownloadLink/index.js index d7988c067..9ac3982a4 100644 --- a/src/renderer/component/fileDownloadLink/index.js +++ b/src/renderer/component/fileDownloadLink/index.js @@ -13,7 +13,7 @@ import FileDownloadLink from "./view"; const select = (state, props) => ({ fileInfo: makeSelectFileInfoForUri(props.uri)(state), - /*availability check is disabled due to poor performance, TBD if it dies forever or requires daemon fix*/ + /* availability check is disabled due to poor performance, TBD if it dies forever or requires daemon fix */ downloading: makeSelectDownloadingForUri(props.uri)(state), costInfo: makeSelectCostInfoForUri(props.uri)(state), loading: makeSelectLoadingForUri(props.uri)(state), diff --git a/src/renderer/component/form.js b/src/renderer/component/form.js index 820ae251c..229668ffe 100644 --- a/src/renderer/component/form.js +++ b/src/renderer/component/form.js @@ -8,7 +8,7 @@ let formFieldCounter = 0; export const formFieldNestedLabelTypes = ["radio", "checkbox"]; export function formFieldId() { - return "form-field-" + ++formFieldCounter; + return `form-field-${++formFieldCounter}`; } export class Form extends React.PureComponent { @@ -129,21 +129,19 @@ export class FormRow extends React.PureComponent { return (
{this.props.label && !renderLabelInFormField ? (
@@ -178,16 +176,14 @@ export class FormRow extends React.PureComponent { export const Submit = props => { const { title, label, icon, disabled } = props; - const className = - "button-block" + + const className = `${"button-block" + " button-primary" + " button-set-item" + - " button--submit" + - (disabled ? " disabled" : ""); + " button--submit"}${disabled ? " disabled" : ""}`; const content = ( - {"icon" in props ? : null} + {"icon" in props ? : null} {label ? {label} : null} ); diff --git a/src/renderer/component/load_screen.js b/src/renderer/component/load_screen.js index 788e42cf1..c730954d7 100644 --- a/src/renderer/component/load_screen.js +++ b/src/renderer/component/load_screen.js @@ -37,15 +37,14 @@ class LoadScreen extends React.PureComponent { ) : ( - {" " + this.props.message} + {` ${this.props.message}`} )} {this.props.details} diff --git a/src/renderer/component/menu.js b/src/renderer/component/menu.js index d1b533077..7ce07897c 100644 --- a/src/renderer/component/menu.js +++ b/src/renderer/component/menu.js @@ -16,7 +16,7 @@ export class DropDownMenuItem extends React.PureComponent { }; render() { - var icon = this.props.icon ? : null; + const icon = this.props.icon ? : null; return ( { if ( this.state.menuOpen && diff --git a/src/renderer/component/splash/index.js b/src/renderer/component/splash/index.js index 82712fa15..1337d9516 100644 --- a/src/renderer/component/splash/index.js +++ b/src/renderer/component/splash/index.js @@ -8,12 +8,10 @@ import { import { doCheckDaemonVersion } from "redux/actions/app"; import SplashScreen from "./view"; -const select = state => { - return { - modal: selectCurrentModal(state), - daemonVersionMatched: selectDaemonVersionMatched(state), - }; -}; +const select = state => ({ + modal: selectCurrentModal(state), + daemonVersionMatched: selectDaemonVersionMatched(state), +}); const perform = dispatch => ({ checkDaemonVersion: () => dispatch(doCheckDaemonVersion()), diff --git a/src/renderer/component/subscribeButton/index.js b/src/renderer/component/subscribeButton/index.js index d79e53052..ead3c461b 100644 --- a/src/renderer/component/subscribeButton/index.js +++ b/src/renderer/component/subscribeButton/index.js @@ -3,7 +3,8 @@ import { doChannelSubscribe, doChannelUnsubscribe, } from "redux/actions/subscriptions"; -import { selectSubscriptions } from "redux/selectors/subscriptions";; +import { selectSubscriptions } from "redux/selectors/subscriptions"; + import SubscribeButton from "./view"; const select = (state, props) => ({ @@ -12,5 +13,5 @@ const select = (state, props) => ({ export default connect(select, { doChannelSubscribe, - doChannelUnsubscribe + doChannelUnsubscribe, })(SubscribeButton); diff --git a/src/renderer/component/tooltip.js b/src/renderer/component/tooltip.js index 6f1437405..a1fa85349 100644 --- a/src/renderer/component/tooltip.js +++ b/src/renderer/component/tooltip.js @@ -29,7 +29,7 @@ export class ToolTip extends React.PureComponent { render() { return ( - + { @@ -39,9 +39,7 @@ export class ToolTip extends React.PureComponent { {this.props.label}
{ this.handleTooltipMouseOut(); }} diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index f9e8eb836..594aa716a 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -141,7 +141,7 @@ export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE"; export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR"; export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED"; -//Language +// Language export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED"; export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED"; diff --git a/src/renderer/constants/settings.js b/src/renderer/constants/settings.js index c6c0ebd86..e8db70e32 100644 --- a/src/renderer/constants/settings.js +++ b/src/renderer/constants/settings.js @@ -1,6 +1,6 @@ -/*hardcoded names still exist for these in reducers/settings.js - only discovered when debugging*/ -/*Many settings are stored in the localStorage by their name - - be careful about changing the value of a settings constant, as doing so can invalidate existing settings*/ +/* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ +/* Many settings are stored in the localStorage by their name - + be careful about changing the value of a settings constant, as doing so can invalidate existing settings */ export const CREDIT_REQUIRED_ACKNOWLEDGED = "credit_required_acknowledged"; export const NEW_USER_ACKNOWLEDGED = "welcome_acknowledged"; export const EMAIL_COLLECTION_ACKNOWLEDGED = "email_collection_acknowledged"; diff --git a/src/renderer/extractLocals.js b/src/renderer/extractLocals.js index b4437dbf5..328e53294 100644 --- a/src/renderer/extractLocals.js +++ b/src/renderer/extractLocals.js @@ -1,18 +1,18 @@ -var extract = require("i18n-extract"); +const extract = require("i18n-extract"); const fs = require("fs"); -var dir = __dirname + "/../../dist/locales"; -var path = dir + "/en.json"; +const dir = `${__dirname}/../../dist/locales`; +const path = `${dir}/en.json`; if (!fs.existsSync(dir)) { fs.mkdirSync(dir); } -fs.writeFile(path, "{}", "utf8", function(err) { +fs.writeFile(path, "{}", "utf8", err => { if (err) { return console.log(err); } - var enLocale = require(path); + const enLocale = require(path); const keys = extract.extractFromFiles(["js/**/*.{js,jsx}"], { marker: "__", @@ -22,21 +22,21 @@ fs.writeFile(path, "{}", "utf8", function(err) { reports = reports.concat(extract.findMissing(enLocale, keys)); if (reports.length > 0) { - fs.readFile(path, "utf8", function readFileCallback(err, data) { + fs.readFile(path, "utf8", (err, data) => { if (err) { console.log(err); } else { localeObj = JSON.parse(data); - for (var i = 0; i < reports.length; i++) { + for (let i = 0; i < reports.length; i++) { // no need to care for other types than MISSING because starting file will always be empty if (reports[i].type === "MISSING") { localeObj[reports[i].key] = reports[i].key; } } - var json = JSON.stringify(localeObj, null, "\t"); //convert it back to json-string - fs.writeFile(path, json, "utf8", function callback(err) { + const json = JSON.stringify(localeObj, null, "\t"); // convert it back to json-string + fs.writeFile(path, json, "utf8", err => { if (err) { throw err; } diff --git a/src/renderer/index.js b/src/renderer/index.js index 155278bda..66d5784e8 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -15,12 +15,15 @@ import "scss/all.scss"; const env = process.env.NODE_ENV || "production"; const { remote, ipcRenderer, shell } = require("electron"); + const contextMenu = remote.require("./main.js").contextMenu; const app = require("./app"); // Workaround for https://github.com/electron-userland/electron-webpack/issues/52 -if (process.env.NODE_ENV !== 'development') { - window.staticResourcesPath = require("path").join(remote.app.getAppPath(), "../static").replace(/\\/g, "\\\\"); +if (process.env.NODE_ENV !== "development") { + window.staticResourcesPath = require("path") + .join(remote.app.getAppPath(), "../static") + .replace(/\\/g, "\\\\"); } else { window.staticResourcesPath = ""; } @@ -56,12 +59,12 @@ ipcRenderer.on("window-is-focused", (event, data) => { }); document.addEventListener("click", event => { - var target = event.target; + let target = event.target; while (target && target !== document) { if (target.matches("a") || target.matches("button")) { // TODO: Look into using accessiblity labels (this would also make the app more accessible) - let hrefParts = window.location.href.split("#"); - let element = target.title || (target.text && target.text.trim()); + const hrefParts = window.location.href.split("#"); + const element = target.title || (target.text && target.text.trim()); if (element) { amplitude.getInstance().logEvent("CLICK", { target: element, @@ -89,7 +92,7 @@ document.addEventListener("click", event => { const initialState = app.store.getState(); -var init = function() { +const init = function() { app.store.dispatch(doDownloadLanguages()); function onDaemonReady() { @@ -99,8 +102,8 @@ var init = function() { "0b130efdcbdbf86ec2f7f9eff354033e", info.lbry_id, null, - function() { - window.sessionStorage.setItem("loaded", "y"); //once we've made it here once per session, we don't need to show splash again + () => { + window.sessionStorage.setItem("loaded", "y"); // once we've made it here once per session, we don't need to show splash again app.store.dispatch(doDaemonReady()); ReactDOM.render( @@ -110,7 +113,7 @@ var init = function() {
, - document.getElementById('app') + document.getElementById("app") ); } ); @@ -124,7 +127,7 @@ var init = function() { , - document.getElementById('app') + document.getElementById("app") ); } }; diff --git a/src/renderer/jsonrpc.js b/src/renderer/jsonrpc.js index 00e85f30c..bf812d7ed 100644 --- a/src/renderer/jsonrpc.js +++ b/src/renderer/jsonrpc.js @@ -12,8 +12,10 @@ jsonrpc.call = function( function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { return response.json(); - } else { - return response.json().then(json => { + } + return response + .json() + .then(json => { let error; if (json.error) { error = new Error(json.error); @@ -21,10 +23,10 @@ jsonrpc.call = function( error = new Error("Protocol error with unknown response signature"); } return Promise.reject(error); - }).catch(e => { + }) + .catch(e => { console.error(e); }); - } } function makeRequest(url, options) { @@ -35,9 +37,7 @@ jsonrpc.call = function( if (timeout) { const e = new Error(__("Protocol request timed out")); - setTimeout(() => { - return reject(e); - }, timeout); + setTimeout(() => reject(e), timeout); } }); } @@ -48,8 +48,8 @@ jsonrpc.call = function( method: "POST", body: JSON.stringify({ jsonrpc: "2.0", - method: method, - params: params, + method, + params, id: counter, }), }; @@ -70,11 +70,11 @@ jsonrpc.call = function( return errorCallback(error); } - var errorEvent = new CustomEvent("unhandledError", { + const errorEvent = new CustomEvent("unhandledError", { detail: { - connectionString: connectionString, - method: method, - params: params, + connectionString, + method, + params, code: error.code, message: error.message || error, data: error.data, @@ -87,11 +87,11 @@ jsonrpc.call = function( return connectFailedCallback(e); } - var errorEvent = new CustomEvent("unhandledError", { + const errorEvent = new CustomEvent("unhandledError", { detail: { - connectionString: connectionString, - method: method, - params: params, + connectionString, + method, + params, code: e.response && e.response.status, message: __("Connection to API server failed"), }, diff --git a/src/renderer/lbry.js b/src/renderer/lbry.js index 838b3697c..82d701f8a 100644 --- a/src/renderer/lbry.js +++ b/src/renderer/lbry.js @@ -39,17 +39,17 @@ function savePendingPublish({ name, channel_name }) { if (channel_name) { uri = lbryuri.build({ name: channel_name, path: name }, false); } else { - uri = lbryuri.build({ name: name }, false); + uri = lbryuri.build({ name }, false); } ++pendingId; const pendingPublishes = getLocal("pendingPublishes") || []; const newPendingPublish = { name, channel_name, - claim_id: "pending-" + pendingId, - txid: "pending-" + pendingId, + claim_id: `pending-${pendingId}`, + txid: `pending-${pendingId}`, nout: 0, - outpoint: "pending-" + pendingId + ":0", + outpoint: `pending-${pendingId}:0`, time: Date.now(), }; setLocal("pendingPublishes", [...pendingPublishes, newPendingPublish]); @@ -119,7 +119,7 @@ function pendingPublishToDummyFileInfo({ name, outpoint, claim_id }) { return { name, outpoint, claim_id, metadata: null }; } -//core +// core lbry._connectPromise = null; lbry.connect = function() { if (lbry._connectPromise === null) { @@ -203,19 +203,19 @@ lbry.publishDeprecated = function( }; lbry.imagePath = function(file) { - return staticResourcesPath + "/img/" + file; + return `${staticResourcesPath}/img/${file}`; }; lbry.getMediaType = function(contentType, fileName) { if (contentType) { return /^[^/]+/.exec(contentType)[0]; } else if (fileName) { - var dotIndex = fileName.lastIndexOf("."); + const dotIndex = fileName.lastIndexOf("."); if (dotIndex == -1) { return "unknown"; } - var ext = fileName.substr(dotIndex + 1); + const ext = fileName.substr(dotIndex + 1); if (/^mp4|m4v|webm|flv|f4v|ogv$/i.test(ext)) { return "video"; } else if (/^mp3|m4a|aac|wav|flac|ogg|opus$/i.test(ext)) { @@ -224,12 +224,10 @@ lbry.getMediaType = function(contentType, fileName) { /^html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org$/i.test(ext) ) { return "document"; - } else { - return "unknown"; } - } else { return "unknown"; } + return "unknown"; }; lbry.getAppVersionInfo = function() { @@ -273,7 +271,7 @@ lbry.file_list = function(params = {}) { fileInfos => { removePendingPublishIfNeeded({ name, channel_name, outpoint }); - //if a naked file_list call, append the pending file infos + // if a naked file_list call, append the pending file infos if (!name && !channel_name && !outpoint) { const dummyFileInfos = lbry .getPendingPublishes() @@ -295,11 +293,11 @@ lbry.claim_list_mine = function(params = {}) { "claim_list_mine", params, claims => { - for (let { name, channel_name, txid, nout } of claims) { + for (const { name, channel_name, txid, nout } of claims) { removePendingPublishIfNeeded({ name, channel_name, - outpoint: txid + ":" + nout, + outpoint: `${txid}:${nout}`, }); } @@ -318,7 +316,7 @@ lbry.resolve = function(params = {}) { apiCall( "resolve", params, - function(data) { + data => { if ("uri" in params) { // If only a single URI was requested, don't nest the results in an object resolve(data && data[params.uri] ? data[params.uri] : {}); @@ -332,7 +330,7 @@ lbry.resolve = function(params = {}) { }; lbry = new Proxy(lbry, { - get: function(target, name) { + get(target, name) { if (name in target) { return target[name]; } diff --git a/src/renderer/lbryio.js b/src/renderer/lbryio.js index ba7a105cd..430dd7f36 100644 --- a/src/renderer/lbryio.js +++ b/src/renderer/lbryio.js @@ -48,18 +48,17 @@ lbryio.call = function(resource, action, params = {}, method = "get") { function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { return response.json(); - } else { - return response.json().then(json => { - let error; - if (json.error) { - error = new Error(json.error); - } else { - error = new Error("Unknown API error signature"); - } - error.response = response; //this is primarily a hack used in actions/user.js - return Promise.reject(error); - }); } + return response.json().then(json => { + let error; + if (json.error) { + error = new Error(json.error); + } else { + error = new Error("Unknown API error signature"); + } + error.response = response; // this is primarily a hack used in actions/user.js + return Promise.reject(error); + }); } function makeRequest(url, options) { @@ -92,8 +91,8 @@ lbryio.call = function(resource, action, params = {}, method = "get") { lbryio._authToken = null; -lbryio.getAuthToken = () => { - return new Promise((resolve, reject) => { +lbryio.getAuthToken = () => + new Promise((resolve, reject) => { if (lbryio._authToken) { resolve(lbryio._authToken); } else { @@ -104,16 +103,13 @@ lbryio.getAuthToken = () => { ipcRenderer.send("get-auth-token"); } }); -}; lbryio.setAuthToken = token => { lbryio._authToken = token ? token.toString().trim() : null; ipcRenderer.send("set-auth-token", token); }; -lbryio.getCurrentUser = () => { - return lbryio.call("user", "me"); -}; +lbryio.getCurrentUser = () => lbryio.call("user", "me"); lbryio.authenticate = function() { if (!lbryio.enabled) { @@ -141,12 +137,8 @@ lbryio.authenticate = function() { // check that token works return lbryio .getCurrentUser() - .then(() => { - return true; - }) - .catch(() => { - return false; - }); + .then(() => true) + .catch(() => false); }) .then(isTokenValid => { if (isTokenValid) { @@ -155,8 +147,8 @@ lbryio.authenticate = function() { return lbry .status() - .then(status => { - return lbryio.call( + .then(status => + lbryio.call( "user", "new", { @@ -165,8 +157,8 @@ lbryio.authenticate = function() { app_id: status.installation_id, }, "post" - ); - }) + ) + ) .then(response => { if (!response.auth_token) { throw new Error(__("auth_token is missing from response")); @@ -182,10 +174,9 @@ lbryio.authenticate = function() { return lbryio._authenticationPromise; }; -lbryio.getStripeToken = () => { - return CONNECTION_STRING.startsWith("http://localhost:") +lbryio.getStripeToken = () => + CONNECTION_STRING.startsWith("http://localhost:") ? "pk_test_NoL1JWL7i1ipfhVId5KfDZgo" : "pk_live_e8M4dRNnCCbmpZzduEUZBgJO"; -}; export default lbryio; diff --git a/src/renderer/lbryuri.js b/src/renderer/lbryuri.js index 430cc1c30..7d4be33c0 100644 --- a/src/renderer/lbryuri.js +++ b/src/renderer/lbryuri.js @@ -103,7 +103,7 @@ lbryuri.parse = function(uri, requireProto = false) { if ( claimId && (claimId.length > CLAIM_ID_MAX_LEN || !claimId.match(/^[0-9a-f]+$/)) && - !claimId.match(/^pending/) //ought to be dropped when savePendingPublish drops hack + !claimId.match(/^pending/) // ought to be dropped when savePendingPublish drops hack ) { throw new Error(__(`Invalid claim ID %s.`, claimId)); } @@ -166,7 +166,7 @@ lbryuri.build = function(uriObj, includeProto = true, allowExtraProps = false) { if (channelName) { const channelNameFormatted = channelName.startsWith("@") ? channelName - : "@" + channelName; + : `@${channelName}`; if (!name) { name = channelNameFormatted; } else if (name !== channelNameFormatted) { diff --git a/src/renderer/modal/modal.js b/src/renderer/modal/modal.js index a139698e1..a89f9025b 100644 --- a/src/renderer/modal/modal.js +++ b/src/renderer/modal/modal.js @@ -30,7 +30,7 @@ export class Modal extends React.PureComponent { { }; }; -const perform = dispatch => () => { - return { - addBalance: () => { - dispatch(doSetClientSetting(settings.CREDIT_REQUIRED_ACKNOWLEDGED, true)); - dispatch(doNavigate("/getcredits")); - dispatch(doCloseModal()); - }, - closeModal: () => { - dispatch(doSetClientSetting(settings.CREDIT_REQUIRED_ACKNOWLEDGED, true)); - dispatch(doCloseModal()); - }, - }; -}; +const perform = dispatch => () => ({ + addBalance: () => { + dispatch(doSetClientSetting(settings.CREDIT_REQUIRED_ACKNOWLEDGED, true)); + dispatch(doNavigate("/getcredits")); + dispatch(doCloseModal()); + }, + closeModal: () => { + dispatch(doSetClientSetting(settings.CREDIT_REQUIRED_ACKNOWLEDGED, true)); + dispatch(doCloseModal()); + }, +}); export default connect(select, perform)(ModalCreditIntro); diff --git a/src/renderer/page/report.js b/src/renderer/page/report.js index 9bb766aef..489a52d0a 100644 --- a/src/renderer/page/report.js +++ b/src/renderer/page/report.js @@ -71,10 +71,9 @@ class ReportPage extends React.Component { onClick={event => { this.submitMessage(event); }} - className={ - "button-block button-primary " + - (this.state.submitting ? "disabled" : "") - } + className={`button-block button-primary ${ + this.state.submitting ? "disabled" : "" + }`} > {this.state.submitting ? __("Submitting...") diff --git a/src/renderer/page/rewards/index.js b/src/renderer/page/rewards/index.js index 84262e7c2..dd00a2c40 100644 --- a/src/renderer/page/rewards/index.js +++ b/src/renderer/page/rewards/index.js @@ -9,13 +9,11 @@ import { doAuthNavigate, doNavigate } from "redux/actions/navigation"; import { doRewardList } from "redux/actions/rewards"; import RewardsPage from "./view"; -const select = (state, props) => { - return { - fetching: selectFetchingRewards(state), - rewards: selectUnclaimedRewards(state), - user: selectUser(state), - }; -}; +const select = (state, props) => ({ + fetching: selectFetchingRewards(state), + rewards: selectUnclaimedRewards(state), + user: selectUser(state), +}); const perform = dispatch => ({ fetchRewards: () => dispatch(doRewardList()), diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 46b2e5fa1..031b129f1 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -18,9 +18,11 @@ import { selectCurrentModal } from "redux/selectors/app"; const { remote, ipcRenderer, shell } = require("electron"); const path = require("path"); + const { download } = remote.require("electron-dl"); const fs = remote.require("fs"); const { lbrySettings: config } = require("package.json"); + const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000; export function doOpenModal(modal, modalProps = {}) { @@ -43,7 +45,7 @@ export function doUpdateDownloadProgress(percent) { return { type: types.UPGRADE_DOWNLOAD_PROGRESSED, data: { - percent: percent, + percent, }, }; } @@ -72,7 +74,7 @@ export function doDownloadUpgrade() { ), upgradeFilename = selectUpgradeFilename(state); - let options = { + const options = { onProgress: p => dispatch(doUpdateDownloadProgress(Math.round(p * 100))), directory: dir, }; diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index cb0b3d766..10c24791a 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -42,9 +42,9 @@ export function doResolveUris(uris) { data: { uris }, }); - let resolveInfo = {}; + const resolveInfo = {}; lbry.resolve({ uris: urisToResolve }).then(result => { - for (let [uri, uriResolveInfo] of Object.entries(result)) { + for (const [uri, uriResolveInfo] of Object.entries(result)) { const fallbackResolveInfo = { claim: null, claims_in_channel: null, @@ -80,7 +80,7 @@ export function doFetchFeaturedUris() { const success = ({ Uris }) => { let urisToResolve = []; - for (let category in Uris) { + for (const category in Uris) { urisToResolve = [...urisToResolve, ...Uris[category]]; } @@ -144,7 +144,7 @@ export function doUpdateLoadStatus(uri, outpoint) { lbry .file_list({ - outpoint: outpoint, + outpoint, full_status: true, }) .then(([fileInfo]) => { @@ -239,7 +239,7 @@ export function doDownloadFile(uri, streamInfo) { lbryio .call("file", "view", { - uri: uri, + uri, outpoint: streamInfo.outpoint, claim_id: streamInfo.claim_id, }) @@ -288,7 +288,9 @@ export function doLoadVideo(uri) { }); dispatch( doAlertError( - `Failed to download ${uri}, please try again. If this problem persists, visit https://lbry.io/faq/support for support.` + `Failed to download ${ + uri + }, please try again. If this problem persists, visit https://lbry.io/faq/support for support.` ) ); }); @@ -511,7 +513,7 @@ export function doAbandonClaim(txid, nout) { dispatch({ type: types.ABANDON_CLAIM_STARTED, data: { - claimId: claimId, + claimId, }, }); @@ -524,7 +526,7 @@ export function doAbandonClaim(txid, nout) { dispatch({ type: types.ABANDON_CLAIM_SUCCEEDED, data: { - claimId: claimId, + claimId, }, }); dispatch(doResolveUri(lbryuri.build({ name, claimId }))); @@ -536,8 +538,8 @@ export function doAbandonClaim(txid, nout) { lbry .claim_abandon({ - txid: txid, - nout: nout, + txid, + nout, }) .then(successCallback, errorCallback); }; diff --git a/src/renderer/redux/actions/file_info.js b/src/renderer/redux/actions/file_info.js index 2226fd639..68743bd05 100644 --- a/src/renderer/redux/actions/file_info.js +++ b/src/renderer/redux/actions/file_info.js @@ -34,17 +34,15 @@ export function doFetchFileInfo(uri) { }, }); - lbry - .file_list({ outpoint: outpoint, full_status: true }) - .then(fileInfos => { - dispatch({ - type: types.FETCH_FILE_INFO_COMPLETED, - data: { - outpoint, - fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null, - }, - }); + lbry.file_list({ outpoint, full_status: true }).then(fileInfos => { + dispatch({ + type: types.FETCH_FILE_INFO_COMPLETED, + data: { + outpoint, + fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null, + }, }); + }); } }; } @@ -91,7 +89,7 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) { const state = getState(); lbry.file_delete({ - outpoint: outpoint, + outpoint, delete_from_download_dir: deleteFromComputer, }); diff --git a/src/renderer/redux/actions/navigation.js b/src/renderer/redux/actions/navigation.js index a4cbca615..89028458c 100644 --- a/src/renderer/redux/actions/navigation.js +++ b/src/renderer/redux/actions/navigation.js @@ -19,7 +19,7 @@ export function doNavigate(path, params = {}, options = {}) { let url = path; if (params && Object.values(params).length) { - url += "?" + toQueryString(params); + url += `?${toQueryString(params)}`; } const scrollY = options.scrollY; diff --git a/src/renderer/redux/actions/rewards.js b/src/renderer/redux/actions/rewards.js index 4ed2332f3..67200a63e 100644 --- a/src/renderer/redux/actions/rewards.js +++ b/src/renderer/redux/actions/rewards.js @@ -39,7 +39,7 @@ export function doClaimRewardType(rewardType) { userIsRewardApproved = selectUserIsRewardApproved(state); if (!reward || reward.transaction_id) { - //already claimed or doesn't exist, do nothing + // already claimed or doesn't exist, do nothing return; } diff --git a/src/renderer/redux/actions/search.js b/src/renderer/redux/actions/search.js index 80c269882..aa881f50d 100644 --- a/src/renderer/redux/actions/search.js +++ b/src/renderer/redux/actions/search.js @@ -24,17 +24,18 @@ export function doSearch(rawQuery) { }); if (page != "search") { - dispatch(doNavigate("search", { query: query })); + dispatch(doNavigate("search", { query })); } else { - fetch("https://lighthouse.lbry.io/search?s=" + query) - .then(response => { - return response.status === 200 - ? Promise.resolve(response.json()) - : Promise.reject(new Error(response.statusText)); - }) + fetch(`https://lighthouse.lbry.io/search?s=${query}`) + .then( + response => + response.status === 200 + ? Promise.resolve(response.json()) + : Promise.reject(new Error(response.statusText)) + ) .then(data => { - let uris = []; - let actions = []; + const uris = []; + const actions = []; data.forEach(result => { const uri = lbryuri.build({ diff --git a/src/renderer/redux/actions/settings.js b/src/renderer/redux/actions/settings.js index 06b82e9ee..ba8b5ebcd 100644 --- a/src/renderer/redux/actions/settings.js +++ b/src/renderer/redux/actions/settings.js @@ -22,7 +22,7 @@ export function doFetchDaemonSettings() { export function doSetDaemonSetting(key, value) { return function(dispatch, getState) { - let settings = {}; + const settings = {}; settings[key] = value; lbry.settings_set(settings).then(settings); lbry.settings_get().then(settings => { @@ -49,19 +49,13 @@ export function doSetClientSetting(key, value) { export function doGetThemes() { return function(dispatch, getState) { const themes = ["light", "dark"]; - dispatch( - doSetClientSetting( - settings.THEMES, - themes - ) - ); - + dispatch(doSetClientSetting(settings.THEMES, themes)); }; } export function doDownloadLanguage(langFile) { return function(dispatch, getState) { - const destinationPath = app.i18n.directory + "/" + langFile; + const destinationPath = `${app.i18n.directory}/${langFile}`; const language = langFile.replace(".json", ""); const req = http.get( { @@ -82,7 +76,7 @@ export function doDownloadLanguage(langFile) { // push to our local list dispatch({ type: types.DOWNLOAD_LANGUAGE_SUCCEEDED, - data: { language: language }, + data: { language }, }); }); @@ -102,7 +96,7 @@ export function doDownloadLanguage(langFile) { }); }; - req.setTimeout(30000, function() { + req.setTimeout(30000, () => { req.abort(); }); @@ -114,7 +108,7 @@ export function doDownloadLanguage(langFile) { export function doDownloadLanguages() { return function(dispatch, getState) { - //temporarily disable i18n so I can get a working build out -- Jeremy + // temporarily disable i18n so I can get a working build out -- Jeremy return; if (!fs.existsSync(app.i18n.directory)) { @@ -124,11 +118,10 @@ export function doDownloadLanguages() { function checkStatus(response) { if (response.status >= 200 && response.status < 300) { return response; - } else { - throw new Error( - __("The list of available languages could not be retrieved.") - ); } + throw new Error( + __("The list of available languages could not be retrieved.") + ); } function parseJSON(response) { diff --git a/src/renderer/redux/actions/shape_shift.js b/src/renderer/redux/actions/shape_shift.js index 8f3e683f6..520dff9cb 100644 --- a/src/renderer/redux/actions/shape_shift.js +++ b/src/renderer/redux/actions/shape_shift.js @@ -106,7 +106,7 @@ export const createShapeShift = ( const pair = `${originCoin.toLowerCase()}_lbc`; const options = { - returnAddress: returnAddress, + returnAddress, }; dispatch({ type: types.PREPARE_SHAPE_SHIFT_START }); diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 6ec76f2bd..6963b95bf 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -1,26 +1,27 @@ // @flow import * as actions from "constants/action_types"; -import type { Subscription, Action, Dispatch } from "redux/reducers/subscriptions"; +import type { + Subscription, + Action, + Dispatch, +} from "redux/reducers/subscriptions"; import lbry from "lbry"; export const doChannelSubscribe = (subscription: Subscription) => ( dispatch: Dispatch -) => { - return dispatch({ +) => + dispatch({ type: actions.CHANNEL_SUBSCRIBE, data: subscription, }); -}; export const doChannelUnsubscribe = (subscription: Subscription) => ( dispatch: Dispatch -) => { - return dispatch({ +) => + dispatch({ type: actions.CHANNEL_UNSUBSCRIBE, data: subscription, }); -}; -export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) => { - return dispatch({ type: actions.HAS_FETCHED_SUBSCRIPTIONS }) -} +export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) => + dispatch({ type: actions.HAS_FETCHED_SUBSCRIPTIONS }); diff --git a/src/renderer/redux/actions/user.js b/src/renderer/redux/actions/user.js index 7111369e8..3fb7f8f43 100644 --- a/src/renderer/redux/actions/user.js +++ b/src/renderer/redux/actions/user.js @@ -59,7 +59,7 @@ export function doUserEmailNew(email) { return function(dispatch, getState) { dispatch({ type: types.USER_EMAIL_NEW_STARTED, - email: email, + email, }); const success = () => { @@ -68,30 +68,32 @@ export function doUserEmailNew(email) { data: { email }, }); dispatch(doUserFetch()); - } + }; const failure = error => { dispatch({ type: types.USER_EMAIL_NEW_FAILURE, data: { error }, }); - } + }; lbryio .call( "user_email", "new", - { email: email, send_verification_email: true }, + { email, send_verification_email: true }, "post" ) .catch(error => { if (error.response && error.response.status == 409) { - return lbryio.call( - "user_email", - "resend_token", - { email: email, only_if_expired: true }, - "post" - ).then(success, failure); + return lbryio + .call( + "user_email", + "resend_token", + { email, only_if_expired: true }, + "post" + ) + .then(success, failure); } throw error; }) @@ -113,7 +115,7 @@ export function doUserEmailVerify(verificationToken) { .call( "user_email", "confirm", - { verification_token: verificationToken, email: email }, + { verification_token: verificationToken, email }, "post" ) .then(userEmail => { @@ -125,7 +127,7 @@ export function doUserEmailVerify(verificationToken) { dispatch(doClaimRewardType(rewards.TYPE_CONFIRM_EMAIL)), dispatch(doUserFetch()); } else { - throw new Error("Your email is still not verified."); //shouldn't happen + throw new Error("Your email is still not verified."); // shouldn't happen } }) .catch(error => { @@ -156,7 +158,7 @@ export function doUserIdentityVerify(stripeToken) { } else { throw new Error( "Your identity is still not verified. This should not happen." - ); //shouldn't happen + ); // shouldn't happen } }) .catch(error => { @@ -214,7 +216,7 @@ export function doUserInviteNew(email) { }); lbryio - .call("user", "invite", { email: email }, "post") + .call("user", "invite", { email }, "post") .then(invite => { dispatch({ type: types.USER_INVITE_NEW_SUCCESS, diff --git a/src/renderer/redux/actions/wallet.js b/src/renderer/redux/actions/wallet.js index 5db24d939..0d8d44429 100644 --- a/src/renderer/redux/actions/wallet.js +++ b/src/renderer/redux/actions/wallet.js @@ -11,14 +11,14 @@ import * as modals from "constants/modal_types"; export function doUpdateBalance() { return function(dispatch, getState) { - lbry.wallet_balance().then(balance => { - return dispatch({ + lbry.wallet_balance().then(balance => + dispatch({ type: types.UPDATE_BALANCE, data: { - balance: balance, + balance, }, - }); - }); + }) + ); }; } @@ -35,14 +35,16 @@ export function doFetchTransactions(fetch_tip_info = true) { type: types.FETCH_TRANSACTIONS_STARTED, }); - lbry.transaction_list({ include_tip_info: fetch_tip_info }).then(results => { - dispatch({ - type: types.FETCH_TRANSACTIONS_COMPLETED, - data: { - transactions: results, - }, + lbry + .transaction_list({ include_tip_info: fetch_tip_info }) + .then(results => { + dispatch({ + type: types.FETCH_TRANSACTIONS_COMPLETED, + data: { + transactions: results, + }, + }); }); - }); }; } @@ -63,7 +65,7 @@ export function doGetNewAddress() { type: types.GET_NEW_ADDRESS_STARTED, }); - lbry.wallet_new_address().then(function(address) { + lbry.wallet_new_address().then(address => { localStorage.setItem("wallet_address", address); dispatch({ type: types.GET_NEW_ADDRESS_COMPLETED, @@ -201,8 +203,8 @@ export function doSendSupport(amount, claim_id, uri) { lbry .wallet_send({ - claim_id: claim_id, - amount: amount, + claim_id, + amount, }) .then(successCallback, errorCallback); }; diff --git a/src/renderer/redux/reducers/claims.js b/src/renderer/redux/reducers/claims.js index 270790d8f..60f5e042b 100644 --- a/src/renderer/redux/reducers/claims.js +++ b/src/renderer/redux/reducers/claims.js @@ -9,7 +9,7 @@ reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); - for (let [uri, { certificate, claim }] of Object.entries(resolveInfo)) { + for (const [uri, { certificate, claim }] of Object.entries(resolveInfo)) { if (claim) { byId[claim.claim_id] = claim; byUri[uri] = claim.claim_id; @@ -51,12 +51,11 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) { .forEach(claim => { byId[claim.claim_id] = claim; - const pending = Object.values(pendingById).find(pendingClaim => { - return ( + const pending = Object.values(pendingById).find( + pendingClaim => pendingClaim.name == claim.name && pendingClaim.channel_name == claim.channel_name - ); - }); + ); if (pending) { delete pendingById[pending.claim_id]; @@ -115,7 +114,7 @@ reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { const claimsByChannel = Object.assign({}, state.claimsByChannel); const byChannel = Object.assign({}, claimsByChannel[uri]); - const allClaimIds = new Set(byChannel["all"]); + const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); @@ -128,7 +127,7 @@ reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { }); } - byChannel["all"] = allClaimIds; + byChannel.all = allClaimIds; byChannel[page] = currentPageClaimIds; claimsByChannel[uri] = byChannel; delete fetchingChannelClaims[uri]; diff --git a/src/renderer/redux/reducers/content.js b/src/renderer/redux/reducers/content.js index 0d2b8cd09..9c3dabac5 100644 --- a/src/renderer/redux/reducers/content.js +++ b/src/renderer/redux/reducers/content.js @@ -32,12 +32,12 @@ reducers[types.FETCH_REWARD_CONTENT_COMPLETED] = function(state, action) { }; reducers[types.RESOLVE_URIS_STARTED] = function(state, action) { - let { uris } = action.data; + const { uris } = action.data; const oldResolving = state.resolvingUris || []; const newResolving = Object.assign([], oldResolving); - for (let uri of uris) { + for (const uri of uris) { if (!newResolving.includes(uri)) { newResolving.push(uri); } @@ -52,7 +52,7 @@ reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { const { resolveInfo } = action.data; const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - for (let [uri, { certificate, claims_in_channel }] of Object.entries( + for (const [uri, { certificate, claims_in_channel }] of Object.entries( resolveInfo )) { if (certificate && !isNaN(claims_in_channel)) { @@ -66,11 +66,10 @@ reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { }); }; -reducers[types.SET_PLAYING_URI] = (state, action) => { - return Object.assign({}, state, { +reducers[types.SET_PLAYING_URI] = (state, action) => + Object.assign({}, state, { playingUri: action.data.uri, }); -}; reducers[types.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = function(state, action) { const channelClaimCounts = Object.assign({}, state.channelClaimCounts); diff --git a/src/renderer/redux/reducers/navigation.js b/src/renderer/redux/reducers/navigation.js index 2a4fbabdd..990657df7 100644 --- a/src/renderer/redux/reducers/navigation.js +++ b/src/renderer/redux/reducers/navigation.js @@ -4,7 +4,7 @@ import { parseQueryParams } from "util/query_params"; const currentPath = () => { const hash = document.location.hash; if (hash !== "") return hash.replace(/^#/, ""); - else return "/discover"; + return "/discover"; }; const reducers = {}; @@ -34,7 +34,7 @@ reducers[types.HISTORY_NAVIGATE] = (state, action) => { const { stack, index } = state; const { url: path, index: newIndex, scrollY } = action.data; - let newState = { + const newState = { currentPath: path, }; @@ -46,7 +46,7 @@ reducers[types.HISTORY_NAVIGATE] = (state, action) => { newState.index = newState.stack.length - 1; } - history.replaceState(null, null, "#" + path); //this allows currentPath() to retain the URL on reload + history.replaceState(null, null, `#${path}`); // this allows currentPath() to retain the URL on reload return Object.assign({}, state, newState); }; @@ -61,7 +61,7 @@ reducers[types.WINDOW_SCROLLED] = (state, action) => { } return { ...stackItem, - scrollY: scrollY, + scrollY, }; }), }); diff --git a/src/renderer/redux/reducers/rewards.js b/src/renderer/redux/reducers/rewards.js index 42279d01d..77d20064e 100644 --- a/src/renderer/redux/reducers/rewards.js +++ b/src/renderer/redux/reducers/rewards.js @@ -3,7 +3,7 @@ import * as types from "constants/action_types"; const reducers = {}; const defaultState = { fetching: false, - claimedRewardsById: {}, //id => reward + claimedRewardsById: {}, // id => reward unclaimedRewardsByType: {}, claimPendingByType: {}, claimErrorsByType: {}, @@ -64,7 +64,10 @@ reducers[types.CLAIM_REWARD_STARTED] = function(state, action) { reducers[types.CLAIM_REWARD_SUCCESS] = function(state, action) { const { reward } = action.data; - let unclaimedRewardsByType = Object.assign({}, state.unclaimedRewardsByType); + const unclaimedRewardsByType = Object.assign( + {}, + state.unclaimedRewardsByType + ); const existingReward = unclaimedRewardsByType[reward.reward_type]; delete state.unclaimedRewardsByType[reward.reward_type]; @@ -73,7 +76,7 @@ reducers[types.CLAIM_REWARD_SUCCESS] = function(state, action) { reward_description: existingReward.reward_description, }); - let claimedRewardsById = Object.assign({}, state.claimedRewardsById); + const claimedRewardsById = Object.assign({}, state.claimedRewardsById); claimedRewardsById[reward.id] = newReward; const newState = Object.assign({}, state, { diff --git a/src/renderer/redux/reducers/settings.js b/src/renderer/redux/reducers/settings.js index 99d46a87d..28413c504 100644 --- a/src/renderer/redux/reducers/settings.js +++ b/src/renderer/redux/reducers/settings.js @@ -3,7 +3,7 @@ import * as settings from "constants/settings"; import LANGUAGES from "constants/languages"; function getLocalStorageSetting(setting, fallback) { - var localStorageVal = localStorage.getItem("setting_" + setting); + const localStorageVal = localStorage.getItem(`setting_${setting}`); return localStorageVal === null ? fallback : JSON.parse(localStorageVal); } @@ -27,7 +27,7 @@ const defaultState = { email_collection_acknowledged: getLocalStorageSetting( settings.EMAIL_COLLECTION_ACKNOWLEDGED ), - credit_required_acknowledged: false, //this needs to be re-acknowledged every run + credit_required_acknowledged: false, // this needs to be re-acknowledged every run language: getLocalStorageSetting(settings.LANGUAGE, "en"), theme: getLocalStorageSetting(settings.THEME, "light"), themes: getLocalStorageSetting(settings.THEMES, []), @@ -47,8 +47,8 @@ reducers[types.CLIENT_SETTING_CHANGED] = function(state, action) { clientSettings[key] = value; - //this technically probably shouldn't happen here, and should be fixed when we're no longer using localStorage at all for persistent app state - localStorage.setItem("setting_" + key, JSON.stringify(value)); + // this technically probably shouldn't happen here, and should be fixed when we're no longer using localStorage at all for persistent app state + localStorage.setItem(`setting_${key}`, JSON.stringify(value)); return Object.assign({}, state, { clientSettings, @@ -62,8 +62,9 @@ reducers[types.DOWNLOAD_LANGUAGE_SUCCEEDED] = function(state, action) { const langCode = language.substring(0, 2); if (LANGUAGES[langCode]) { - languages[language] = - LANGUAGES[langCode][0] + " (" + LANGUAGES[langCode][1] + ")"; + languages[language] = `${LANGUAGES[langCode][0]} (${ + LANGUAGES[langCode][1] + })`; } else { languages[langCode] = langCode; } diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js index 23e9ef50e..f0de6819c 100644 --- a/src/renderer/redux/reducers/subscriptions.js +++ b/src/renderer/redux/reducers/subscriptions.js @@ -5,7 +5,7 @@ import { handleActions } from "util/redux-utils"; // Subscription redux types export type SubscriptionState = { subscriptions: Array, - hasFetchedSubscriptions: boolean + hasFetchedSubscriptions: boolean, }; export type Subscription = { @@ -25,15 +25,18 @@ type doChannelUnsubscribe = { }; type HasFetchedSubscriptions = { - type: actions.HAS_FETCHED_SUBSCRIPTIONS -} + type: actions.HAS_FETCHED_SUBSCRIPTIONS, +}; -export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions; +export type Action = + | doChannelSubscribe + | doChannelUnsubscribe + | HasFetchedSubscriptions; export type Dispatch = (action: Action) => any; const defaultState = { subscriptions: [], - hasFetchedSubscriptions: false + hasFetchedSubscriptions: false, }; export default handleActions( @@ -43,7 +46,7 @@ export default handleActions( action: doChannelSubscribe ): SubscriptionState => { const newSubscription: Subscription = action.data; - let newSubscriptions: Array = state.subscriptions.slice(); + const newSubscriptions: Array = state.subscriptions.slice(); newSubscriptions.unshift(newSubscription); return { @@ -59,9 +62,10 @@ export default handleActions( const newSubscriptions = state.subscriptions .slice() - .filter(subscription => { - return subscription.channelName !== subscriptionToRemove.channelName; - }); + .filter( + subscription => + subscription.channelName !== subscriptionToRemove.channelName + ); return { ...state, @@ -73,8 +77,8 @@ export default handleActions( action: HasFetchedSubscriptions ): SubscriptionState => ({ ...state, - hasFetchedSubscriptions: true - }) + hasFetchedSubscriptions: true, + }), }, defaultState ); diff --git a/src/renderer/redux/reducers/user.js b/src/renderer/redux/reducers/user.js index bc19f3464..ef4bd6f87 100644 --- a/src/renderer/redux/reducers/user.js +++ b/src/renderer/redux/reducers/user.js @@ -69,17 +69,17 @@ reducers[types.USER_EMAIL_NEW_STARTED] = function(state, action) { }; reducers[types.USER_EMAIL_NEW_SUCCESS] = function(state, action) { - let user = Object.assign({}, state.user); + const user = Object.assign({}, state.user); user.primary_email = action.data.email; return Object.assign({}, state, { emailToVerify: action.data.email, emailNewIsPending: false, - user: user, + user, }); }; reducers[types.USER_EMAIL_NEW_EXISTS] = function(state, action) { - let user = Object.assign({}, state.user); + const user = Object.assign({}, state.user); return Object.assign({}, state, { emailToVerify: action.data.email, emailNewIsPending: false, @@ -101,12 +101,12 @@ reducers[types.USER_EMAIL_VERIFY_STARTED] = function(state, action) { }; reducers[types.USER_EMAIL_VERIFY_SUCCESS] = function(state, action) { - let user = Object.assign({}, state.user); + const user = Object.assign({}, state.user); user.primary_email = action.data.email; return Object.assign({}, state, { emailToVerify: "", emailVerifyIsPending: false, - user: user, + user, }); }; diff --git a/src/renderer/redux/reducers/wallet.js b/src/renderer/redux/reducers/wallet.js index a4e25b964..233bcea25 100644 --- a/src/renderer/redux/reducers/wallet.js +++ b/src/renderer/redux/reducers/wallet.js @@ -25,7 +25,7 @@ reducers[types.FETCH_TRANSACTIONS_STARTED] = function(state, action) { }; reducers[types.FETCH_TRANSACTIONS_COMPLETED] = function(state, action) { - let byId = Object.assign({}, state.transactions); + const byId = Object.assign({}, state.transactions); const { transactions } = action.data; diff --git a/src/renderer/redux/selectors/availability.js b/src/renderer/redux/selectors/availability.js index 99bf63ad9..679f25ca0 100644 --- a/src/renderer/redux/selectors/availability.js +++ b/src/renderer/redux/selectors/availability.js @@ -7,21 +7,16 @@ export const selectAvailabilityByUri = createSelector( state => state.byUri || {} ); -export const makeSelectIsAvailableForUri = uri => { - return createSelector( +export const makeSelectIsAvailableForUri = uri => + createSelector( selectAvailabilityByUri, byUri => (!byUri || byUri[uri] === undefined ? undefined : byUri[uri] > 0) ); -}; export const selectFetchingAvailability = createSelector( _selectState, state => state.fetching || {} ); -export const makeSelectFetchingAvailabilityForUri = uri => { - return createSelector( - selectFetchingAvailability, - byUri => byUri && byUri[uri] - ); -}; +export const makeSelectFetchingAvailabilityForUri = uri => + createSelector(selectFetchingAvailability, byUri => byUri && byUri[uri]); diff --git a/src/renderer/redux/selectors/claims.js b/src/renderer/redux/selectors/claims.js index 5b1c7bbc0..3fc571aa0 100644 --- a/src/renderer/redux/selectors/claims.js +++ b/src/renderer/redux/selectors/claims.js @@ -40,12 +40,11 @@ export const selectAllClaimsByChannel = createSelector( state => state.claimsByChannel || {} ); -export const makeSelectClaimForUri = uri => { - return createSelector( +export const makeSelectClaimForUri = uri => + createSelector( selectClaimsByUri, claims => claims && claims[lbryuri.normalize(uri)] ); -}; export const makeSelectClaimIsMine = rawUri => { const uri = lbryuri.normalize(rawUri); @@ -65,12 +64,11 @@ export const selectAllFetchingChannelClaims = createSelector( state => state.fetchingChannelClaims || {} ); -export const makeSelectFetchingChannelClaims = uri => { - return createSelector( +export const makeSelectFetchingChannelClaims = uri => + createSelector( selectAllFetchingChannelClaims, fetching => fetching && fetching[uri] ); -}; export const makeSelectClaimsInChannelForCurrentPage = uri => { const pageSelector = makeSelectCurrentParam("page"); @@ -90,30 +88,27 @@ export const makeSelectClaimsInChannelForCurrentPage = uri => { ); }; -export const makeSelectMetadataForUri = uri => { - return createSelector(makeSelectClaimForUri(uri), claim => { +export const makeSelectMetadataForUri = uri => + createSelector(makeSelectClaimForUri(uri), claim => { const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; - const value = metadata ? metadata : claim === undefined ? undefined : null; + const value = metadata || (claim === undefined ? undefined : null); return value; }); -}; -export const makeSelectTitleForUri = uri => { - return createSelector( +export const makeSelectTitleForUri = uri => + createSelector( makeSelectMetadataForUri(uri), metadata => metadata && metadata.title ); -}; -export const makeSelectContentTypeForUri = uri => { - return createSelector(makeSelectClaimForUri(uri), claim => { +export const makeSelectContentTypeForUri = uri => + createSelector(makeSelectClaimForUri(uri), claim => { const source = claim && claim.value && claim.value.stream && claim.value.stream.source; return source ? source.contentType : undefined; }); -}; export const selectIsFetchingClaimListMine = createSelector( _selectState, @@ -203,7 +198,7 @@ export const selectMyChannelClaims = createSelector( ids.forEach(id => { if (byId[id]) { - //I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-app/issues/544 + // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-app/issues/544 claims.push(byId[id]); } }); diff --git a/src/renderer/redux/selectors/content.js b/src/renderer/redux/selectors/content.js index a1c98f049..7d7f01ef9 100644 --- a/src/renderer/redux/selectors/content.js +++ b/src/renderer/redux/selectors/content.js @@ -22,28 +22,25 @@ export const selectPlayingUri = createSelector( state => state.playingUri ); -export const makeSelectIsUriResolving = uri => { - return createSelector( +export const makeSelectIsUriResolving = uri => + createSelector( selectResolvingUris, resolvingUris => resolvingUris && resolvingUris.indexOf(uri) != -1 ); -}; export const selectChannelClaimCounts = createSelector( _selectState, state => state.channelClaimCounts || {} ); -export const makeSelectTotalItemsForChannel = uri => { - return createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]); -}; +export const makeSelectTotalItemsForChannel = uri => + createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]); -export const makeSelectTotalPagesForChannel = uri => { - return createSelector( +export const makeSelectTotalPagesForChannel = uri => + createSelector( selectChannelClaimCounts, byUri => byUri && byUri[uri] && Math.ceil(byUri[uri] / 10) ); -}; export const selectRewardContentClaimIds = createSelector( _selectState, diff --git a/src/renderer/redux/selectors/cost_info.js b/src/renderer/redux/selectors/cost_info.js index 1bf6c1fe7..20eae1a69 100644 --- a/src/renderer/redux/selectors/cost_info.js +++ b/src/renderer/redux/selectors/cost_info.js @@ -8,12 +8,11 @@ export const selectAllCostInfoByUri = createSelector( state => state.byUri || {} ); -export const makeSelectCostInfoForUri = uri => { - return createSelector( +export const makeSelectCostInfoForUri = uri => + createSelector( selectAllCostInfoByUri, costInfos => costInfos && costInfos[uri] ); -}; export const selectCostForCurrentPageUri = createSelector( selectAllCostInfoByUri, @@ -27,9 +26,8 @@ export const selectFetchingCostInfo = createSelector( state => state.fetching || {} ); -export const makeSelectFetchingCostInfoForUri = uri => { - return createSelector( +export const makeSelectFetchingCostInfoForUri = uri => + createSelector( selectFetchingCostInfo, fetchingByUri => fetchingByUri && fetchingByUri[uri] ); -}; diff --git a/src/renderer/redux/selectors/file_info.js b/src/renderer/redux/selectors/file_info.js index 0bf76ef2f..74482abf0 100644 --- a/src/renderer/redux/selectors/file_info.js +++ b/src/renderer/redux/selectors/file_info.js @@ -26,8 +26,8 @@ export const selectIsFetchingFileListDownloadedOrPublished = createSelector( isFetchingFileList || isFetchingClaimListMine ); -export const makeSelectFileInfoForUri = uri => { - return createSelector( +export const makeSelectFileInfoForUri = uri => + createSelector( selectClaimsByUri, selectFileInfosByOutpoint, (claims, byOutpoint) => { @@ -37,15 +37,14 @@ export const makeSelectFileInfoForUri = uri => { return outpoint ? byOutpoint[outpoint] : undefined; } ); -}; export const selectDownloadingByOutpoint = createSelector( _selectState, state => state.downloadingByOutpoint || {} ); -export const makeSelectDownloadingForUri = uri => { - return createSelector( +export const makeSelectDownloadingForUri = uri => + createSelector( selectDownloadingByOutpoint, makeSelectFileInfoForUri(uri), (byOutpoint, fileInfo) => { @@ -53,16 +52,14 @@ export const makeSelectDownloadingForUri = uri => { return byOutpoint[fileInfo.outpoint]; } ); -}; export const selectUrisLoading = createSelector( _selectState, state => state.urisLoading || {} ); -export const makeSelectLoadingForUri = uri => { - return createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); -}; +export const makeSelectLoadingForUri = uri => + createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); export const selectFileInfosPendingPublish = createSelector( _selectState, @@ -72,8 +69,8 @@ export const selectFileInfosPendingPublish = createSelector( export const selectFileInfosDownloaded = createSelector( selectFileInfosByOutpoint, selectMyClaims, - (byOutpoint, myClaims) => { - return Object.values(byOutpoint).filter(fileInfo => { + (byOutpoint, myClaims) => + Object.values(byOutpoint).filter(fileInfo => { const myClaimIds = myClaims.map(claim => claim.claim_id); return ( @@ -81,8 +78,7 @@ export const selectFileInfosDownloaded = createSelector( myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes) ); - }); - } + }) ); export const selectFileInfosPublished = createSelector( @@ -157,6 +153,6 @@ export const selectTotalDownloadProgress = createSelector( const totalProgress = progress.reduce((a, b) => a + b, 0); if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; - else return -1; + return -1; } ); diff --git a/src/renderer/redux/selectors/navigation.js b/src/renderer/redux/selectors/navigation.js index 2b1b384c9..7d401127a 100644 --- a/src/renderer/redux/selectors/navigation.js +++ b/src/renderer/redux/selectors/navigation.js @@ -13,9 +13,9 @@ export const selectCurrentPath = createSelector( export const computePageFromPath = path => path.replace(/^\//, "").split("?")[0]; -export const selectCurrentPage = createSelector(selectCurrentPath, path => { - return computePageFromPath(path); -}); +export const selectCurrentPage = createSelector(selectCurrentPath, path => + computePageFromPath(path) +); export const selectCurrentParams = createSelector(selectCurrentPath, path => { if (path === undefined) return {}; @@ -24,12 +24,11 @@ export const selectCurrentParams = createSelector(selectCurrentPath, path => { return parseQueryParams(path.split("?")[1]); }); -export const makeSelectCurrentParam = param => { - return createSelector( +export const makeSelectCurrentParam = param => + createSelector( selectCurrentParams, params => (params ? params[param] : undefined) ); -}; export const selectHeaderLinks = createSelector(selectCurrentPage, page => { // This contains intentional fall throughs diff --git a/src/renderer/redux/selectors/rewards.js b/src/renderer/redux/selectors/rewards.js index c481a1977..ed6ef4605 100644 --- a/src/renderer/redux/selectors/rewards.js +++ b/src/renderer/redux/selectors/rewards.js @@ -31,12 +31,13 @@ export const selectClaimedRewardsByTransactionId = createSelector( export const selectUnclaimedRewards = createSelector( selectUnclaimedRewardsByType, byType => - Object.values(byType).sort(function(a, b) { - return rewards.SORT_ORDER.indexOf(a.reward_type) < + Object.values(byType).sort( + (a, b) => + rewards.SORT_ORDER.indexOf(a.reward_type) < rewards.SORT_ORDER.indexOf(b.reward_type) - ? -1 - : 1; - }) || [] + ? -1 + : 1 + ) || [] ); export const selectIsRewardEligible = createSelector( @@ -51,10 +52,7 @@ export const selectFetchingRewards = createSelector( export const selectUnclaimedRewardValue = createSelector( selectUnclaimedRewards, - rewards => - rewards.reduce((sum, reward) => { - return sum + reward.reward_amount; - }, 0) + rewards => rewards.reduce((sum, reward) => sum + reward.reward_amount, 0) ); export const selectHasClaimedReward = (state, props) => { @@ -62,47 +60,39 @@ export const selectHasClaimedReward = (state, props) => { return reward && reward.transaction_id !== ""; }; -export const makeSelectHasClaimedReward = () => { - return createSelector(selectHasClaimedReward, claimed => claimed); -}; +export const makeSelectHasClaimedReward = () => + createSelector(selectHasClaimedReward, claimed => claimed); export const selectClaimsPendingByType = createSelector( _selectState, state => state.claimPendingByType ); -const selectIsClaimRewardPending = (state, props) => { - return selectClaimsPendingByType(state, props)[props.reward_type]; -}; +const selectIsClaimRewardPending = (state, props) => + selectClaimsPendingByType(state, props)[props.reward_type]; -export const makeSelectIsRewardClaimPending = () => { - return createSelector(selectIsClaimRewardPending, isClaiming => isClaiming); -}; +export const makeSelectIsRewardClaimPending = () => + createSelector(selectIsClaimRewardPending, isClaiming => isClaiming); export const selectClaimErrorsByType = createSelector( _selectState, state => state.claimErrorsByType ); -const selectClaimRewardError = (state, props) => { - return selectClaimErrorsByType(state, props)[props.reward_type]; -}; +const selectClaimRewardError = (state, props) => + selectClaimErrorsByType(state, props)[props.reward_type]; -export const makeSelectClaimRewardError = () => { - return createSelector(selectClaimRewardError, errorMessage => errorMessage); -}; +export const makeSelectClaimRewardError = () => + createSelector(selectClaimRewardError, errorMessage => errorMessage); -const selectRewardByType = (state, props) => { - return selectUnclaimedRewardsByType(state)[props.reward_type]; -}; +const selectRewardByType = (state, props) => + selectUnclaimedRewardsByType(state)[props.reward_type]; -export const makeSelectRewardByType = () => { - return createSelector(selectRewardByType, reward => reward); -}; +export const makeSelectRewardByType = () => + createSelector(selectRewardByType, reward => reward); -export const makeSelectRewardAmountByType = () => { - return createSelector( +export const makeSelectRewardAmountByType = () => + createSelector( selectRewardByType, reward => (reward ? reward.reward_amount : 0) ); -}; diff --git a/src/renderer/redux/selectors/search.js b/src/renderer/redux/selectors/search.js index ad522ec19..8faf0a307 100644 --- a/src/renderer/redux/selectors/search.js +++ b/src/renderer/redux/selectors/search.js @@ -23,19 +23,18 @@ export const selectSearchUrisByQuery = createSelector( state => state.urisByQuery ); -export const makeSelectSearchUris = query => { - //replace statement below is kind of ugly, and repeated in doSearch action - return createSelector( +export const makeSelectSearchUris = query => + // replace statement below is kind of ugly, and repeated in doSearch action + createSelector( selectSearchUrisByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, "") : query] ); -}; export const selectWunderBarAddress = createSelector( selectCurrentPage, selectPageTitle, selectSearchQuery, - (page, title, query) => (page != "search" ? title : query ? query : title) + (page, title, query) => (page != "search" ? title : query || title) ); export const selectWunderBarIcon = createSelector( diff --git a/src/renderer/redux/selectors/settings.js b/src/renderer/redux/selectors/settings.js index a504e0df6..b0a7325dd 100644 --- a/src/renderer/redux/selectors/settings.js +++ b/src/renderer/redux/selectors/settings.js @@ -14,19 +14,18 @@ export const selectClientSettings = createSelector( state => state.clientSettings || {} ); -export const makeSelectClientSetting = setting => { - return createSelector( +export const makeSelectClientSetting = setting => + createSelector( selectClientSettings, settings => (settings ? settings[setting] : undefined) ); -}; export const selectSettingsIsGenerous = createSelector( selectDaemonSettings, settings => settings && settings.is_generous_host ); -//refactor me +// refactor me export const selectShowNsfw = makeSelectClientSetting(settings.SHOW_NSFW); export const selectLanguages = createSelector( @@ -36,5 +35,5 @@ export const selectLanguages = createSelector( export const selectThemePath = createSelector( makeSelectClientSetting(settings.THEME), - theme => staticResourcesPath + "/themes/" + (theme || "light") + ".css" + theme => `${staticResourcesPath}/themes/${theme || "light"}.css` ); diff --git a/src/renderer/redux/selectors/subscriptions.js b/src/renderer/redux/selectors/subscriptions.js index 5694c8f47..f3eb78a6e 100644 --- a/src/renderer/redux/selectors/subscriptions.js +++ b/src/renderer/redux/selectors/subscriptions.js @@ -21,7 +21,7 @@ export const selectSubscriptionsFromClaims = createSelector( return []; } - let fetchedSubscriptions = []; + const fetchedSubscriptions = []; savedSubscriptions.forEach(subscription => { let channelClaims = []; @@ -40,9 +40,9 @@ export const selectSubscriptionsFromClaims = createSelector( } // all we really need is a uri for each claim - channelClaims = channelClaims.map(claim => { - return `${claim.name}#${claim.claim_id}`; - }) + channelClaims = channelClaims.map( + claim => `${claim.name}#${claim.claim_id}` + ); fetchedSubscriptions.push({ claims: channelClaims, diff --git a/src/renderer/redux/selectors/wallet.js b/src/renderer/redux/selectors/wallet.js index 15182b743..dca790e5b 100644 --- a/src/renderer/redux/selectors/wallet.js +++ b/src/renderer/redux/selectors/wallet.js @@ -20,7 +20,7 @@ export const selectTransactionItems = createSelector( Object.keys(byId).forEach(txid => { const tx = byId[txid]; - //ignore dust/fees + // ignore dust/fees // it is fee only txn if all infos are also empty if ( Math.abs(tx.value) === Math.abs(tx.fee) && @@ -31,7 +31,7 @@ export const selectTransactionItems = createSelector( return; } - let append = []; + const append = []; append.push( ...tx.claim_info.map(item => @@ -63,16 +63,16 @@ export const selectTransactionItems = createSelector( items.push( ...append.map(item => { - //value on transaction, amount on outpoint - //amount is always positive, but should match sign of value + // value on transaction, amount on outpoint + // amount is always positive, but should match sign of value const amount = parseFloat( item.balance_delta ? item.balance_delta : item.value ); return { - txid: txid, + txid, date: tx.timestamp ? new Date(parseInt(tx.timestamp) * 1000) : null, - amount: amount, + amount, fee: amount < 0 ? -1 * tx.fee / append.length : 0, claim_id: item.claim_id, claim_name: item.claim_name, @@ -89,19 +89,15 @@ export const selectTransactionItems = createSelector( export const selectRecentTransactions = createSelector( selectTransactionItems, transactions => { - let threshold = new Date(); + const threshold = new Date(); threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => { - return transaction.date > threshold; - }); + return transactions.filter(transaction => transaction.date > threshold); } ); export const selectHasTransactions = createSelector( selectTransactionItems, - transactions => { - return transactions && transactions.length > 0; - } + transactions => transactions && transactions.length > 0 ); export const selectIsFetchingTransactions = createSelector( @@ -146,10 +142,9 @@ export const selectDraftTransactionError = createSelector( export const selectBlocks = createSelector(_selectState, state => state.blocks); -export const makeSelectBlockDate = block => { - return createSelector( +export const makeSelectBlockDate = block => + createSelector( selectBlocks, blocks => blocks && blocks[block] ? new Date(blocks[block].time * 1000) : undefined ); -}; diff --git a/src/renderer/rewards.js b/src/renderer/rewards.js index 0fe0121e0..72ca1fb44 100644 --- a/src/renderer/rewards.js +++ b/src/renderer/rewards.js @@ -95,15 +95,16 @@ rewards.claimReward = function(type) { case rewards.TYPE_FIRST_CHANNEL: lbry .claim_list_mine() - .then(function(claims) { - let claim = claims.reverse().find(function(claim) { - return ( - claim.name.length && - claim.name[0] == "@" && - claim.txid.length && - claim.category == "claim" + .then(claims => { + const claim = claims + .reverse() + .find( + claim => + claim.name.length && + claim.name[0] == "@" && + claim.txid.length && + claim.category == "claim" ); - }); if (claim) { params.transaction_id = claim.txid; requestReward(resolve, reject, params); @@ -120,14 +121,15 @@ rewards.claimReward = function(type) { lbry .claim_list_mine() .then(claims => { - let claim = claims.reverse().find(function(claim) { - return ( - claim.name.length && - claim.name[0] != "@" && - claim.txid.length && - claim.category == "claim" + const claim = claims + .reverse() + .find( + claim => + claim.name.length && + claim.name[0] != "@" && + claim.txid.length && + claim.category == "claim" ); - }); if (claim) { params.transaction_id = claim.txid; requestReward(resolve, reject, params); diff --git a/src/renderer/util/batchActions.js b/src/renderer/util/batchActions.js index 19c7ade28..d8cb486a5 100644 --- a/src/renderer/util/batchActions.js +++ b/src/renderer/util/batchActions.js @@ -2,7 +2,7 @@ function batchActions(...actions) { return { type: "BATCH_ACTIONS", - actions: actions, + actions, }; } diff --git a/src/renderer/util/formatCredits.js b/src/renderer/util/formatCredits.js index 30d36ce98..fea63a00a 100644 --- a/src/renderer/util/formatCredits.js +++ b/src/renderer/util/formatCredits.js @@ -17,7 +17,7 @@ export function formatFullPrice(amount, precision) { const index = decimals.indexOf(first); // Set format fraction - formated = "." + fraction.substring(0, index + precision); + formated = `.${fraction.substring(0, index + precision)}`; } return parseFloat(quantity[0] + formated); diff --git a/src/renderer/util/query_params.js b/src/renderer/util/query_params.js index 51987755b..76ed1c754 100644 --- a/src/renderer/util/query_params.js +++ b/src/renderer/util/query_params.js @@ -4,12 +4,10 @@ export function parseQueryParams(queryString) { .split("?") .pop() .split("&") - .map(function(p) { - return p.split("="); - }); + .map(p => p.split("=")); const params = {}; - parts.forEach(function(arr) { + parts.forEach(arr => { params[arr[0]] = arr[1]; }); return params; @@ -21,7 +19,7 @@ export function toQueryString(params) { const parts = []; for (const key in params) { if (params.hasOwnProperty(key) && params[key]) { - parts.push(key + "=" + params[key]); + parts.push(`${key}=${params[key]}`); } } return parts.join("&"); diff --git a/src/renderer/util/redux-utils.js b/src/renderer/util/redux-utils.js index 04aa0c3cc..b50e55812 100644 --- a/src/renderer/util/redux-utils.js +++ b/src/renderer/util/redux-utils.js @@ -1,17 +1,18 @@ // util for creating reducers // based off of redux-actions // https://redux-actions.js.org/docs/api/handleAction.html#handleactions -export const handleActions = (actionMap, defaultState) => { - return (state = defaultState, action) => { - const handler = actionMap[action.type]; +export const handleActions = (actionMap, defaultState) => ( + state = defaultState, + action +) => { + const handler = actionMap[action.type]; - if (handler) { - const newState = handler(state, action); - return Object.assign({}, state, newState); - } + if (handler) { + const newState = handler(state, action); + return Object.assign({}, state, newState); + } - // just return the original state if no handler - // returning a copy here breaks redux-persist - return state; - }; + // just return the original state if no handler + // returning a copy here breaks redux-persist + return state; }; diff --git a/src/renderer/util/setBadge.js b/src/renderer/util/setBadge.js index 5d564c434..372b8d4e1 100644 --- a/src/renderer/util/setBadge.js +++ b/src/renderer/util/setBadge.js @@ -1,4 +1,5 @@ const { remote } = require("electron"); + const application = remote.app; const dock = application.dock; const win = remote.BrowserWindow.getFocusedWindow(); diff --git a/src/renderer/util/setProgressBar.js b/src/renderer/util/setProgressBar.js index b5d869f3d..942d4288c 100644 --- a/src/renderer/util/setProgressBar.js +++ b/src/renderer/util/setProgressBar.js @@ -1,4 +1,5 @@ const { remote } = require("electron"); + const application = remote.app; const win = remote.getCurrentWindow(); diff --git a/src/renderer/util/shape_shift.js b/src/renderer/util/shape_shift.js index 7adfc1abc..5b04100e3 100644 --- a/src/renderer/util/shape_shift.js +++ b/src/renderer/util/shape_shift.js @@ -20,7 +20,7 @@ const validateAddress = (coinType, address) => { }; export const validateShapeShiftForm = (vals, props) => { - let errors = {}; + const errors = {}; if (!vals.returnAddress) { return errors; @@ -45,6 +45,4 @@ const exampleCoinAddresses = { "466XMeJEcowYGx7RzUJj3VDWBZgRWErVQQX6tHYbsacS5QF6v3tidE6LZZnTJgzeEh6bKEEJ6GC9jHirrUKvJwVKVj9e7jm", }; -export const getExampleAddress = coin => { - return exampleCoinAddresses[coin]; -}; +export const getExampleAddress = coin => exampleCoinAddresses[coin]; From 29eb306934a4c548966a7eace524073e782f6cc2 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 18:50:17 -0300 Subject: [PATCH 05/66] Add electron as a core module for ESLint --- .eslintrc.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 39d1f5f24..8101e35be 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -12,7 +12,10 @@ "webpack": { "config": "webpack.renderer.additions.js" } - } + }, + "import/core-modules": [ + "electron" + ] }, "parser": "babel-eslint", "env": { From 93d63865be4ef48afacfcb204b01425af11d4c15 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 14 Dec 2017 09:58:07 -0300 Subject: [PATCH 06/66] Fix locales path --- .gitignore | 1 + src/renderer/app.js | 7 +++++-- src/renderer/extractLocals.js | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index e20de7b15..023767f02 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ /lbry-app /lbry-venv /static/daemon/lbrynet* +/static/locales /daemon/build /daemon/venv /daemon/requirements.txt diff --git a/src/renderer/app.js b/src/renderer/app.js index fb64e5a77..ef3f24ce9 100644 --- a/src/renderer/app.js +++ b/src/renderer/app.js @@ -1,12 +1,15 @@ -import store from "store.js"; +import store from "store"; import { remote } from "electron"; +import path from "path"; const env = process.env.NODE_ENV || "production"; const config = { ...require(`./config/${env}`), }; const i18n = require("y18n")({ - directory: `${remote.app.getAppPath()}/locales`, + directory: path + .join(remote.app.getAppPath(), "/../static/locales") + .replace(/\\/g, "\\\\"), updateFiles: false, locale: "en", }); diff --git a/src/renderer/extractLocals.js b/src/renderer/extractLocals.js index 328e53294..9e4746d3e 100644 --- a/src/renderer/extractLocals.js +++ b/src/renderer/extractLocals.js @@ -1,7 +1,7 @@ const extract = require("i18n-extract"); const fs = require("fs"); -const dir = `${__dirname}/../../dist/locales`; +const dir = `${__dirname}/../../static/locales`; const path = `${dir}/en.json`; if (!fs.existsSync(dir)) { From c4c43e1219d862b00658c6c704713aab7cd46399 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Fri, 15 Dec 2017 17:33:01 -0300 Subject: [PATCH 07/66] Add linux app category --- electron-builder.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/electron-builder.json b/electron-builder.json index acf8e77a2..9e0a8f86b 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -1,7 +1,7 @@ { "appId": "io.lbry.LBRY", "mac": { - "category": "public.app-category.entertainment", + "category": "public.app-category.entertainment" }, "dmg": { "iconSize": 128, @@ -34,6 +34,7 @@ ], "linux": { "target": "deb", + "category": "Video", "desktop": { "MimeType": "x-scheme-handler/lbry", "Exec": "/opt/LBRY/lbry %U" From 1d67f8df9cb36f66deed9a5522266c34193103f2 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Fri, 15 Dec 2017 15:46:50 -0500 Subject: [PATCH 08/66] add copy button to wallet address, fixes #875 --- CHANGELOG.md | 2 +- src/renderer/component/walletAddress/view.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e66e97c3e..7a57edac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added - * + * Added copy address button to the Wallet Address component on Send / Receive (#875) * ### Changed diff --git a/src/renderer/component/walletAddress/view.jsx b/src/renderer/component/walletAddress/view.jsx index 829955fa6..72bb91a46 100644 --- a/src/renderer/component/walletAddress/view.jsx +++ b/src/renderer/component/walletAddress/view.jsx @@ -21,7 +21,7 @@ class WalletAddress extends React.PureComponent { "Use this wallet address to receive credits sent by another user (or yourself)." )}

-
+
Date: Fri, 15 Dec 2017 21:12:59 -0800 Subject: [PATCH 09/66] Updated contribution process --- CONTRIBUTING.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e7d0dce20..a64256fb0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,37 @@ ## Contributing to LBRY -https://lbry.io/faq/contributing +You found this page! That means you are well on your way to contributing to the LBRY app. This application is primarily written in JavaScript and is built on [Electron](https://electronjs.org) while utilizing [React](https://reactjs.org) and [Redux](https://redux.js.org) for UI and application state. + +LBRY is an open source project, and therefore is developed out in the open for everyone to see. What you see here are the latest source code changes and the issues. + +Since LBRY is an based around a decentralized community, we believe that the app will be strongest if it receives contributions from individuals outside the core team -- such as yourself! + +In order to make contributing as easy and rewarding of possible, we have instituted the following system: + +* Anyone can view all issues in the system by clicking on the [Issues](https://github.com/lbryio/lbry-app/issues) button at the top of the page. +...Feel free to add an issue if you think we have missed something (and you might earn some LBC in the process because we do tip people for reporting bugs). +* Once on the [Issues](https://github.com/lbryio/lbry-app/issues) page, a user can filter issues by the [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label to see a curated list of suggested issues with which community members can help. +* Every [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issue is ranked on a scale from zero to four. +...--- | --- +...[**level 0**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+0%22) | Typos and text edit -- a tech savvy non-programmer can fix these +...[**level 1**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+1%22) | Programming issues that require little knowledge of how the LBRY app works +...[**level 2**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+2%22) | Issues of average difficulty that require the developer to dig into how the app works a little bit +...[**level 3**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+3%22) | Issues that are likely too tricky to be level 2 or require more thinking outside of the box +...[**level 4**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+4%22) | Big features or really hard issues +...The process of ranking issues is highly subjective. The purpose of sorting issues like this is to give contributors a general idea of the type of issues at which they are looking. It could very well be the case that a level 1 issue is more difficult than a level 2, for instance. This system is meant to help you find relevant issues, not to prevent you from working on issues that you otherwise would. If these rankings don't work for you, feel free to ignore them. +* After deciding what to work on, [fork](https://help.github.com/articles/fork-a-repo/) this repository, make your changes, and submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). +* Once your pull request is visible in the LBRY repo, a LBRY team member will review it and make sure it is up to our standards. At this point, you may have to change your code based on our suggestions and comments. +* Then, upon a satisfactory review your code, we will merge it and send you a tip (in LBC) for your contribution. + +We are dedicated to be fair and friendly in this process. In __general__, level 4 issues will be paid more than level 3 issues which will be paid more than level 2, and so on. However, this is not due to their labels, but rather how difficult they ended up being. Maybe an issue was labeled level 1 but was actually very difficult-- in this case we would be **more than happy** to tip accordingly. If you do good work, we want you to be rewarded for it. + +Also, we are here to enable you. We want you to succeed, so do not hesitate to ask questions. If you need some information or assistance in completely an issue, please let us know! This is what we are here for-- pushing development forward. + +Lastly, don't feel limited by this list. Should LBRY have built in VPN/proxy support? Add it! It's not in the issue tracker but maybe it's a good idea. Do you think the search layout is unintuitive? Change it! We welcome all feedback and suggestions. That said, it may be the case that we do not wish to incorporate your change, if you don't check with us first. If you want to add a feature that is not listed in the issue tracker, go ahead and [create an issue](https://github.com/lbryio/lbry-app/issues/new), and say in the description that you would like to try to implement it yourself. This way we can tell you in advance if we will accept your changes and we can point you in the right direction. + +## Get In Touch +[Liam](https://github.com/liamcardenas) is the application engineer in charge of community development. He is the person to contact with any development/contribution related questions. Discord: liamsdouble, Email: liam@lbry.io +[Tom](https://github.com/tzarebczan) is the community manager. He knows more than anyone about the app and all of its flaws. Reach out to him with any questions about how the app works, if a bug has been reported, or if a feature should be requested. Discord: jigglytom, Email: tom@lbry.io +[Sean](https://github.com/seanyesmunt) is an application engineer who focuses largely on UI/UX. If you have a design or implementation question, feel free to reach out to him. Discord: sean, Email: sean@lbry.io + +More information about contributing to LBRY [here](https://lbry.io/faq/contributing). From 8d28babaf1fa5d1a8722cf52442f1f2f67201573 Mon Sep 17 00:00:00 2001 From: Liam Cardenas Date: Fri, 15 Dec 2017 21:42:55 -0800 Subject: [PATCH 10/66] Fixed typos and formatting issues --- CONTRIBUTING.md | 53 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a64256fb0..e9d7c9811 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,37 +1,46 @@ -## Contributing to LBRY +# Contributing to LBRY You found this page! That means you are well on your way to contributing to the LBRY app. This application is primarily written in JavaScript and is built on [Electron](https://electronjs.org) while utilizing [React](https://reactjs.org) and [Redux](https://redux.js.org) for UI and application state. -LBRY is an open source project, and therefore is developed out in the open for everyone to see. What you see here are the latest source code changes and the issues. +LBRY is an open source project, and therefore is developed out in the open for everyone to see. What you see here are the latest source code changes and issues. Since LBRY is an based around a decentralized community, we believe that the app will be strongest if it receives contributions from individuals outside the core team -- such as yourself! In order to make contributing as easy and rewarding of possible, we have instituted the following system: -* Anyone can view all issues in the system by clicking on the [Issues](https://github.com/lbryio/lbry-app/issues) button at the top of the page. -...Feel free to add an issue if you think we have missed something (and you might earn some LBC in the process because we do tip people for reporting bugs). -* Once on the [Issues](https://github.com/lbryio/lbry-app/issues) page, a user can filter issues by the [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label to see a curated list of suggested issues with which community members can help. +* Anyone can view all issues in the system by clicking on the [Issues](https://github.com/lbryio/lbry-app/issues) button at the top of the page. Feel free to add an issue if you think we have missed something (and you might earn some LBC in the process because we do tip people for reporting bugs). +* Once on the [Issues](https://github.com/lbryio/lbry-app/issues) page, a potential contributor can filter issues by the [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label to see a curated list of suggested issues with which community members can help. * Every [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issue is ranked on a scale from zero to four. -...--- | --- -...[**level 0**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+0%22) | Typos and text edit -- a tech savvy non-programmer can fix these -...[**level 1**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+1%22) | Programming issues that require little knowledge of how the LBRY app works -...[**level 2**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+2%22) | Issues of average difficulty that require the developer to dig into how the app works a little bit -...[**level 3**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+3%22) | Issues that are likely too tricky to be level 2 or require more thinking outside of the box -...[**level 4**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+4%22) | Big features or really hard issues -...The process of ranking issues is highly subjective. The purpose of sorting issues like this is to give contributors a general idea of the type of issues at which they are looking. It could very well be the case that a level 1 issue is more difficult than a level 2, for instance. This system is meant to help you find relevant issues, not to prevent you from working on issues that you otherwise would. If these rankings don't work for you, feel free to ignore them. -* After deciding what to work on, [fork](https://help.github.com/articles/fork-a-repo/) this repository, make your changes, and submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). -* Once your pull request is visible in the LBRY repo, a LBRY team member will review it and make sure it is up to our standards. At this point, you may have to change your code based on our suggestions and comments. -* Then, upon a satisfactory review your code, we will merge it and send you a tip (in LBC) for your contribution. -We are dedicated to be fair and friendly in this process. In __general__, level 4 issues will be paid more than level 3 issues which will be paid more than level 2, and so on. However, this is not due to their labels, but rather how difficult they ended up being. Maybe an issue was labeled level 1 but was actually very difficult-- in this case we would be **more than happy** to tip accordingly. If you do good work, we want you to be rewarded for it. +Level | Description +--- | --- +[**level 0**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+0%22) | Typos and text edits -- a tech savvy non-programmer can fix these +[**level 1**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+1%22) | Programming issues that require little knowledge of how the LBRY app works +[**level 2**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+2%22) | Issues of average difficulty that require the developer to dig into how the app works a little bit +[**level 3**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+3%22) | Issues that are likely too tricky to be level 2 or require more thinking outside of the box +[**level 4**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+4%22) | Big features or really hard issues -Also, we are here to enable you. We want you to succeed, so do not hesitate to ask questions. If you need some information or assistance in completely an issue, please let us know! This is what we are here for-- pushing development forward. +The process of ranking issues is highly subjective. The purpose of sorting issues like this is to give contributors a general idea of the type of issues at which they are looking. It could very well be the case that a level 1 issue is more difficult than a level 2, for instance. This system is meant to help you find relevant issues, not to prevent you from working on issues that you otherwise would. If these rankings don't work for you, feel free to ignore them. -Lastly, don't feel limited by this list. Should LBRY have built in VPN/proxy support? Add it! It's not in the issue tracker but maybe it's a good idea. Do you think the search layout is unintuitive? Change it! We welcome all feedback and suggestions. That said, it may be the case that we do not wish to incorporate your change, if you don't check with us first. If you want to add a feature that is not listed in the issue tracker, go ahead and [create an issue](https://github.com/lbryio/lbry-app/issues/new), and say in the description that you would like to try to implement it yourself. This way we can tell you in advance if we will accept your changes and we can point you in the right direction. +* After deciding what to work on, a potential contributor can [fork](https://help.github.com/articles/fork-a-repo/) this repository, make his or her changes, and submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). +* Once the pull request is visible in the LBRY repo, a LBRY team member will review it and make sure it is up to our standards. At this point, the contributor may have to change his or her code based on our suggestions and comments. +* Then, upon a satisfactory review of the code, we will merge it and send the contributor a tip (in LBC) for the contribution. -## Get In Touch -[Liam](https://github.com/liamcardenas) is the application engineer in charge of community development. He is the person to contact with any development/contribution related questions. Discord: liamsdouble, Email: liam@lbry.io -[Tom](https://github.com/tzarebczan) is the community manager. He knows more than anyone about the app and all of its flaws. Reach out to him with any questions about how the app works, if a bug has been reported, or if a feature should be requested. Discord: jigglytom, Email: tom@lbry.io -[Sean](https://github.com/seanyesmunt) is an application engineer who focuses largely on UI/UX. If you have a design or implementation question, feel free to reach out to him. Discord: sean, Email: sean@lbry.io +We are dedicated to being fair and friendly in this process. In __general__, level 4 issues will be paid more than level 3 issues which will be paid more than level 2, and so on. However, this is not due to their labels, but rather how difficult they ended up being. Maybe an issue labeled "level 1" turned out to be very difficult. In this case we would be **more than happy** to tip accordingly. If you do good work, we want you to be rewarded for it. + +Also, we are here to enable you. We want you to succeed, so do not hesitate to ask questions. If you need some information or assistance in completing an issue, please let us know! That is what we are here for-- pushing development forward. + +Lastly, don't feel limited by this list. Should LBRY have built-in Tor support? Add it! It's not in the issue tracker but maybe it's a good idea. Do you think the search layout is unintuitive? Change it! We welcome all feedback and suggestions. That said, it may be the case that we do not wish to incorporate your change if you don't check with us first (also, please check with us especially if you are planning on adding Tor support :P). If you want to add a feature that is not listed in the issue tracker, go ahead and [create an issue](https://github.com/lbryio/lbry-app/issues/new), and say in the description that you would like to try to implement it yourself. This way we can tell you in advance if we will accept your changes and we can point you in the right direction. + +# Get In Touch +Name | Role | Discord | Email +--- | --- | --- | --- +[Liam](https://github.com/liamcardenas) | The application engineer in charge of community development. He is the person to contact with any development/contribution related questions. | liamsdouble | liam@lbry.io +[Tom](https://github.com/tzarebczan) | Community manager. He knows more than anyone about the app and all of its flaws. Reach out to him with any questions about how the app works, if a bug has been reported, or if a feature should be requested. | jigglytom | tom@lbry.io +[Sean](https://github.com/seanyesmunt) | An application engineer who focuses largely on UI/UX. If you have a design or implementation question, feel free to reach out to him. | sean | sean@lbry.io + +Join our discord [here](https://chat.lbry.io/). + +# More Information More information about contributing to LBRY [here](https://lbry.io/faq/contributing). From f407cd91a13f5b5ca2f625434824480abcf36936 Mon Sep 17 00:00:00 2001 From: Liam Cardenas Date: Mon, 18 Dec 2017 21:53:01 -0800 Subject: [PATCH 11/66] Move analytics out of redux folder --- src/renderer/index.js | 20 ++++++++++++++++---- src/renderer/redux/actions/navigation.js | 3 --- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/renderer/index.js b/src/renderer/index.js index 155278bda..d5154b084 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -19,8 +19,10 @@ const contextMenu = remote.require("./main.js").contextMenu; const app = require("./app"); // Workaround for https://github.com/electron-userland/electron-webpack/issues/52 -if (process.env.NODE_ENV !== 'development') { - window.staticResourcesPath = require("path").join(remote.app.getAppPath(), "../static").replace(/\\/g, "\\\\"); +if (process.env.NODE_ENV !== "development") { + window.staticResourcesPath = require("path") + .join(remote.app.getAppPath(), "../static") + .replace(/\\/g, "\\\\"); } else { window.staticResourcesPath = ""; } @@ -55,6 +57,16 @@ ipcRenderer.on("window-is-focused", (event, data) => { dock.setBadge(""); }); +(function(history) { + var replaceState = history.replaceState; + history.replaceState = function(_, __, path) { + amplitude + .getInstance() + .logEvent("NAVIGATION", { destination: path ? path.slice(1) : path }); + return replaceState.apply(history, arguments); + }; +})(window.history); + document.addEventListener("click", event => { var target = event.target; while (target && target !== document) { @@ -110,7 +122,7 @@ var init = function() {
, - document.getElementById('app') + document.getElementById("app") ); } ); @@ -124,7 +136,7 @@ var init = function() { , - document.getElementById('app') + document.getElementById("app") ); } }; diff --git a/src/renderer/redux/actions/navigation.js b/src/renderer/redux/actions/navigation.js index a4cbca615..b718936aa 100644 --- a/src/renderer/redux/actions/navigation.js +++ b/src/renderer/redux/actions/navigation.js @@ -9,7 +9,6 @@ import { } from "redux/selectors/navigation"; import { doSearch } from "redux/actions/search"; import { toQueryString } from "util/query_params"; -import amplitude from "amplitude-js"; export function doNavigate(path, params = {}, options = {}) { return function(dispatch, getState) { @@ -24,8 +23,6 @@ export function doNavigate(path, params = {}, options = {}) { const scrollY = options.scrollY; - amplitude.getInstance().logEvent("NAVIGATION", { destination: url }); - dispatch({ type: types.HISTORY_NAVIGATE, data: { url, index: options.index, scrollY }, From a9863b90820930f0b8aaffbdf4ef294397efb6b3 Mon Sep 17 00:00:00 2001 From: Liam Cardenas Date: Mon, 18 Dec 2017 22:34:03 -0800 Subject: [PATCH 12/66] Improve click analytics --- src/renderer/component/header/view.jsx | 1 + src/renderer/index.js | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/renderer/component/header/view.jsx b/src/renderer/component/header/view.jsx index 1e83abbe7..b3b6cdc51 100644 --- a/src/renderer/component/header/view.jsx +++ b/src/renderer/component/header/view.jsx @@ -46,6 +46,7 @@ export const Header = props => { onClick={() => navigate("/subscriptions")} button="alt button--flat" icon="icon-at" + title={__("My Subscriptions")} />
diff --git a/src/renderer/index.js b/src/renderer/index.js index d5154b084..e3ed7836b 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -73,7 +73,8 @@ document.addEventListener("click", event => { if (target.matches("a") || target.matches("button")) { // TODO: Look into using accessiblity labels (this would also make the app more accessible) let hrefParts = window.location.href.split("#"); - let element = target.title || (target.text && target.text.trim()); + let element = + target.title || (target.textContent && target.textContent.trim()); if (element) { amplitude.getInstance().logEvent("CLICK", { target: element, @@ -84,6 +85,7 @@ document.addEventListener("click", event => { amplitude.getInstance().logEvent("UNMARKED_CLICK", { location: hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : "/", + source: target.outerHTML, }); } } From 3f067f13cfdd011f04db196cfbc83c8ccc26fa2e Mon Sep 17 00:00:00 2001 From: Liam Cardenas Date: Mon, 18 Dec 2017 23:25:58 -0800 Subject: [PATCH 13/66] Update CONTRIBUTING.md --- CONTRIBUTING.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9d7c9811..3724771ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,29 +9,33 @@ Since LBRY is an based around a decentralized community, we believe that the app In order to make contributing as easy and rewarding of possible, we have instituted the following system: * Anyone can view all issues in the system by clicking on the [Issues](https://github.com/lbryio/lbry-app/issues) button at the top of the page. Feel free to add an issue if you think we have missed something (and you might earn some LBC in the process because we do tip people for reporting bugs). -* Once on the [Issues](https://github.com/lbryio/lbry-app/issues) page, a potential contributor can filter issues by the [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) label to see a curated list of suggested issues with which community members can help. -* Every [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) issue is ranked on a scale from zero to four. +* Once on the [Issues](https://github.com/lbryio/lbry-app/issues) page, a potential contributor can filter issues by the [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+no%3Aassignee) label to see a curated list of suggested issues with which community members can help. +* Every [Help Wanted](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+no%3Aassignee) issue is ranked on a scale from zero to four. Level | Description --- | --- -[**level 0**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+0%22) | Typos and text edits -- a tech savvy non-programmer can fix these -[**level 1**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+1%22) | Programming issues that require little knowledge of how the LBRY app works -[**level 2**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+2%22) | Issues of average difficulty that require the developer to dig into how the app works a little bit -[**level 3**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+3%22) | Issues that are likely too tricky to be level 2 or require more thinking outside of the box -[**level 4**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+4%22) | Big features or really hard issues +[**level 0**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+0%22+no%3Aassignee) | Typos and text edits -- a tech savvy non-programmer can fix these +[**level 1**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+1%22+no%3Aassignee) | Programming issues that require little knowledge of how the LBRY app works +[**level 2**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+2%22+no%3Aassignee) | Issues of average difficulty that require the developer to dig into how the app works a little bit +[**level 3**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+3%22+no%3Aassignee) | Issues that are likely too tricky to be level 2 or require more thinking outside of the box +[**level 4**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+4%22+no%3Aassignee) | Big features or really hard issues The process of ranking issues is highly subjective. The purpose of sorting issues like this is to give contributors a general idea of the type of issues at which they are looking. It could very well be the case that a level 1 issue is more difficult than a level 2, for instance. This system is meant to help you find relevant issues, not to prevent you from working on issues that you otherwise would. If these rankings don't work for you, feel free to ignore them. -* After deciding what to work on, a potential contributor can [fork](https://help.github.com/articles/fork-a-repo/) this repository, make his or her changes, and submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). +* After deciding what to work on, a potential contributor can [fork](https://help.github.com/articles/fork-a-repo/) this repository, make his or her changes, and submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). A contributor wanting to reserve an issue in advance can leave a comment saying that he or she is working on it. Contributors should respect other people's efforts to complete issues in a timely manner and, therefore, not begin working on anything reserved (or updated) within the last 3 days. If someone has been officially assigned an issue via Github's assignment system, it is also not available. Contributors are encouraged to ask if they have any questions about issue availability. * Once the pull request is visible in the LBRY repo, a LBRY team member will review it and make sure it is up to our standards. At this point, the contributor may have to change his or her code based on our suggestions and comments. * Then, upon a satisfactory review of the code, we will merge it and send the contributor a tip (in LBC) for the contribution. -We are dedicated to being fair and friendly in this process. In __general__, level 4 issues will be paid more than level 3 issues which will be paid more than level 2, and so on. However, this is not due to their labels, but rather how difficult they ended up being. Maybe an issue labeled "level 1" turned out to be very difficult. In this case we would be **more than happy** to tip accordingly. If you do good work, we want you to be rewarded for it. +We are dedicated to being fair and friendly in this process. In __general__, level 4 issues will be paid more than level 3 issues which will be paid more than level 2, and so on. However, this is not due to their labeling, but rather how difficult they end up being. Maybe an issue labeled "level 1" turns out to be very difficult. In this case we would be **more than happy** to tip accordingly. If you do good work, we want you to be rewarded for it. Also, we are here to enable you. We want you to succeed, so do not hesitate to ask questions. If you need some information or assistance in completing an issue, please let us know! That is what we are here for-- pushing development forward. Lastly, don't feel limited by this list. Should LBRY have built-in Tor support? Add it! It's not in the issue tracker but maybe it's a good idea. Do you think the search layout is unintuitive? Change it! We welcome all feedback and suggestions. That said, it may be the case that we do not wish to incorporate your change if you don't check with us first (also, please check with us especially if you are planning on adding Tor support :P). If you want to add a feature that is not listed in the issue tracker, go ahead and [create an issue](https://github.com/lbryio/lbry-app/issues/new), and say in the description that you would like to try to implement it yourself. This way we can tell you in advance if we will accept your changes and we can point you in the right direction. +# Tom's "Voice of the User" Wishlist + +[Anything marked with **both** "Help Wanted" and "Tom's 'Voice of the User' Wishlist"](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22Tom%27s+%5C%22Voice+of+the+User%5C%22+Wishlist%22+label%3A%22help+wanted%22+no%3Aassignee) will earn you an extra 50 LBC on top of what we would otherwise tip you. + # Get In Touch Name | Role | Discord | Email --- | --- | --- | --- From 1325b940318c27e0fbd51085ce760c76eeabaa2a Mon Sep 17 00:00:00 2001 From: Liam Cardenas Date: Mon, 18 Dec 2017 23:30:49 -0800 Subject: [PATCH 14/66] Added TL;DR --- CONTRIBUTING.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3724771ff..b6a4d8676 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,14 @@ You found this page! That means you are well on your way to contributing to the LBRY app. This application is primarily written in JavaScript and is built on [Electron](https://electronjs.org) while utilizing [React](https://reactjs.org) and [Redux](https://redux.js.org) for UI and application state. +## TL;DR? +* [Here](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+no%3Aassignee) is a list of help wanted issues. +* Comment on an issue to let us know if you are going to work on it, don't take an issue that someone has reserved less than 3 days ago +* Submit a pull request and get paid in LBC +* Don't hesitate to contact us with any questions or comments + +## Longer Version + LBRY is an open source project, and therefore is developed out in the open for everyone to see. What you see here are the latest source code changes and issues. Since LBRY is an based around a decentralized community, we believe that the app will be strongest if it receives contributions from individuals outside the core team -- such as yourself! From 6175a464937ae1a587584c914018c9ef2110df90 Mon Sep 17 00:00:00 2001 From: Liam Cardenas Date: Tue, 19 Dec 2017 08:54:06 -0800 Subject: [PATCH 15/66] Reworded sentence --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6a4d8676..10d01b548 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ Level | Description [**level 3**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+3%22+no%3Aassignee) | Issues that are likely too tricky to be level 2 or require more thinking outside of the box [**level 4**](https://github.com/lbryio/lbry-app/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22+label%3A%22level+4%22+no%3Aassignee) | Big features or really hard issues -The process of ranking issues is highly subjective. The purpose of sorting issues like this is to give contributors a general idea of the type of issues at which they are looking. It could very well be the case that a level 1 issue is more difficult than a level 2, for instance. This system is meant to help you find relevant issues, not to prevent you from working on issues that you otherwise would. If these rankings don't work for you, feel free to ignore them. +The process of ranking issues is highly subjective. The purpose of sorting issues like this is to give contributors a general idea about the type of issues they are looking at. It could very well be the case that a level 1 issue is more difficult than a level 2, for instance. This system is meant to help you find relevant issues, not to prevent you from working on issues that you otherwise would. If these rankings don't work for you, feel free to ignore them. * After deciding what to work on, a potential contributor can [fork](https://help.github.com/articles/fork-a-repo/) this repository, make his or her changes, and submit a [pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/). A contributor wanting to reserve an issue in advance can leave a comment saying that he or she is working on it. Contributors should respect other people's efforts to complete issues in a timely manner and, therefore, not begin working on anything reserved (or updated) within the last 3 days. If someone has been officially assigned an issue via Github's assignment system, it is also not available. Contributors are encouraged to ask if they have any questions about issue availability. * Once the pull request is visible in the LBRY repo, a LBRY team member will review it and make sure it is up to our standards. At this point, the contributor may have to change his or her code based on our suggestions and comments. From 6cfe724f55b19d86ff2e359fc630688344381a13 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 19 Dec 2017 13:44:48 -0500 Subject: [PATCH 16/66] update discord username jigglytom > jiggytom --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 10d01b548..9f8c64645 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ Lastly, don't feel limited by this list. Should LBRY have built-in Tor support? Name | Role | Discord | Email --- | --- | --- | --- [Liam](https://github.com/liamcardenas) | The application engineer in charge of community development. He is the person to contact with any development/contribution related questions. | liamsdouble | liam@lbry.io -[Tom](https://github.com/tzarebczan) | Community manager. He knows more than anyone about the app and all of its flaws. Reach out to him with any questions about how the app works, if a bug has been reported, or if a feature should be requested. | jigglytom | tom@lbry.io +[Tom](https://github.com/tzarebczan) | Community manager. He knows more than anyone about the app and all of its flaws. Reach out to him with any questions about how the app works, if a bug has been reported, or if a feature should be requested. | jiggytom | tom@lbry.io [Sean](https://github.com/seanyesmunt) | An application engineer who focuses largely on UI/UX. If you have a design or implementation question, feel free to reach out to him. | sean | sean@lbry.io Join our discord [here](https://chat.lbry.io/). From 01dd124d6009da7f61fd71e6d996e3b80b0a4b18 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 11:48:38 -0300 Subject: [PATCH 17/66] Update electron-builder --- README.md | 14 +-- build/build.ps1 | 2 +- build/build.sh | 2 +- electron-builder.json | 2 +- package.json | 17 ++-- yarn.lock | 213 ++++++++++++++++++++++++------------------ 6 files changed, 140 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index aed0caca0..9cb673480 100644 --- a/README.md +++ b/README.md @@ -32,9 +32,9 @@ Run `yarn dev` This will set up a server that will automatically compile any changes made inside `src\` folder and automatically reload the app without losing the state. -### Packaging +### Build -Run `yarn dist` +Run `yarn build` We use [electron-builder](https://github.com/electron-userland/electron-builder) to create distributable packages. @@ -60,16 +60,16 @@ exit python -m pip install -r build\requirements.txt npm install -g yarn yarn install -yarn dist +yarn build ``` -3. Download the lbry daemon and cli [binaries](https://github.com/lbryio/lbry/releases) and place them in `dist\` - -### Building lbry-app -Run `yarn dist` +3. Download the lbry daemon and cli [binaries](https://github.com/lbryio/lbry/releases) and place them in `static\daemon` ### Ongoing Development Run `yarn dev` +### Build +Run `yarn build` + This will set up a server that will automatically compile any changes made inside `src\` folder and automatically reload the app without losing the state. ## Internationalization diff --git a/build/build.ps1 b/build/build.ps1 index 3fb9d90b8..730fd80af 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -26,7 +26,7 @@ dir static\daemon\ # verify that daemon binary is there rm daemon.zip # build electron app -yarn dist +yarn build dir dist # verify that binary was built/named correctly python build\upload_assets.py diff --git a/build/build.sh b/build/build.sh index 37a26b0a1..2273eff00 100755 --- a/build/build.sh +++ b/build/build.sh @@ -77,7 +77,7 @@ if [ "$FULL_BUILD" == "true" ]; then security unlock-keychain -p ${KEYCHAIN_PASSWORD} osx-build.keychain fi - yarn dist + yarn build # 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 diff --git a/electron-builder.json b/electron-builder.json index acf8e77a2..4b0ee92f1 100644 --- a/electron-builder.json +++ b/electron-builder.json @@ -1,7 +1,7 @@ { "appId": "io.lbry.LBRY", "mac": { - "category": "public.app-category.entertainment", + "category": "public.app-category.entertainment" }, "dmg": { "iconSize": 128, diff --git a/package.json b/package.json index 60b51013a..878a56108 100644 --- a/package.json +++ b/package.json @@ -14,17 +14,17 @@ "name": "LBRY Inc.", "email": "hello@lbry.io" }, + "main": "src/main/index.js", "scripts": { - "extract-langs": "node src/renderer/extractLocals.js", + "extract-langs": "node build/extractLocals.js", "dev": "electron-webpack dev", "compile": "electron-webpack && yarn extract-langs", - "dist": "yarn compile && electron-builder", - "dist:dir": "yarn dist -- --dir -c.compression=store -c.mac.identity=null", + "build": "yarn compile && electron-builder build", "postinstall": "electron-builder install-app-deps", "precommit": "lint-staged", - "lint": "eslint src/" + "lint": "eslint src/", + "pretty": "prettier src/ --write" }, - "main": "src/main/index.js", "keywords": [ "lbry" ], @@ -65,6 +65,7 @@ "y18n": "^4.0.0" }, "devDependencies": { + "babel-eslint": "^8.0.3", "babel-plugin-module-resolver": "^3.0.0", "babel-plugin-react-require": "^3.0.0", "babel-polyfill": "^6.20.0", @@ -74,10 +75,10 @@ "bluebird": "^3.5.1", "devtron": "^1.4.0", "electron": "^1.7.9", - "electron-builder": "^19.48.2", + "electron-builder": "^19.49.0", "electron-devtools-installer": "^2.2.1", "electron-webpack": "^1.11.0", - "electron-webpack-eslint": "^1.2.0", + "eslint": "^4.13.1", "eslint-config-airbnb": "^16.1.0", "eslint-config-prettier": "^2.9.0", "eslint-import-resolver-webpack": "^0.8.3", @@ -109,7 +110,7 @@ "license": "MIT", "lint-staged": { "src/**/*.{js,jsx}": [ - "prettier --trailing-comma es5 --write", + "prettier --write", "git add" ] }, diff --git a/yarn.lock b/yarn.lock index c66b37252..2a9d3095c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,7 +171,7 @@ agentkeepalive@^3.3.0: dependencies: humanize-ms "^1.2.1" -ajv-keywords@^2.0.0, ajv-keywords@^2.1.0: +ajv-keywords@^2.0.0, ajv-keywords@^2.1.0, ajv-keywords@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" @@ -200,6 +200,15 @@ ajv@^5.3.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^5.5.1: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -281,14 +290,14 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" -app-package-builder@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/app-package-builder/-/app-package-builder-1.5.3.tgz#a24776370dae3b7c35e7aedfbc77b93137d2ab4c" +app-package-builder@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/app-package-builder/-/app-package-builder-2.0.0.tgz#f0a6cbd2010e68fc79a44e9844c4a512e33ae55e" dependencies: bluebird-lst "^1.0.5" - builder-util "^3.4.3" - builder-util-runtime "^3.3.0" - fs-extra-p "^4.4.4" + builder-util "^3.4.4" + builder-util-runtime "^3.4.0" + fs-extra-p "^4.5.0" int64-buffer "^0.1.10" rabin-bindings "~1.7.4" @@ -510,7 +519,7 @@ babel-core@^6.24.1, babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" -babel-eslint@^8.0.1: +babel-eslint@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.0.3.tgz#f29ecf02336be438195325cd47c468da81ee4e98" dependencies: @@ -1579,7 +1588,16 @@ buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" -builder-util-runtime@3.3.0, builder-util-runtime@^3.3.0: +builder-util-runtime@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-3.4.0.tgz#34883f50a3bbf6502abc40902926a1a8dfef5d43" + dependencies: + bluebird-lst "^1.0.5" + debug "^3.1.0" + fs-extra-p "^4.5.0" + sax "^1.2.4" + +builder-util-runtime@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-3.3.0.tgz#6374029211544f1a380fc7275658b0616b0e9ae1" dependencies: @@ -1588,7 +1606,37 @@ builder-util-runtime@3.3.0, builder-util-runtime@^3.3.0: fs-extra-p "^4.4.4" sax "^1.2.4" -builder-util@3.4.3, builder-util@^3.4.2, builder-util@^3.4.3: +builder-util-runtime@^3.3.1, builder-util-runtime@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-3.4.1.tgz#5fb4cea5bb2bdfae1262aba099c21b2bdcecd742" + dependencies: + bluebird-lst "^1.0.5" + debug "^3.1.0" + fs-extra-p "^4.5.0" + sax "^1.2.4" + +builder-util@3.4.4, builder-util@^3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-3.4.4.tgz#cab30f37c1ee4fb23d33b20ac71e76e3c8451d28" + dependencies: + "7zip-bin" "^2.3.4" + bluebird-lst "^1.0.5" + builder-util-runtime "^3.3.1" + chalk "^2.3.0" + debug "^3.1.0" + fs-extra-p "^4.4.5" + ini "^1.3.5" + is-ci "^1.0.10" + js-yaml "^3.10.0" + lazy-val "^1.0.3" + node-emoji "^1.8.1" + semver "^5.4.1" + source-map-support "^0.5.0" + stat-mode "^0.2.2" + temp-file "^3.0.0" + tunnel-agent "^0.6.0" + +builder-util@^3.4.2: version "3.4.3" resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-3.4.3.tgz#c7d6908ffc56fa3c4de0ec804dbcb9bbf6aa2ab4" dependencies: @@ -1917,10 +1965,6 @@ coa@~1.0.1: dependencies: q "^1.1.2" -coalescy@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/coalescy/-/coalescy-1.0.0.tgz#4b065846b836361ada6c4b4a4abf4bc1cac31bf1" - code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -2704,51 +2748,51 @@ ejs@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" -electron-builder-lib@19.48.2: - version "19.48.2" - resolved "https://registry.yarnpkg.com/electron-builder-lib/-/electron-builder-lib-19.48.2.tgz#1b088d219937c0acdcefdd68c4933074cfa2e309" +electron-builder-lib@19.49.0: + version "19.49.0" + resolved "https://registry.yarnpkg.com/electron-builder-lib/-/electron-builder-lib-19.49.0.tgz#352e334dfcbb4073bb5e78e28a32acb723789895" dependencies: "7zip-bin" "^2.3.4" - app-package-builder "1.5.3" + app-package-builder "2.0.0" asar-integrity "0.2.3" async-exit-hook "^2.0.1" bluebird-lst "^1.0.5" - builder-util "3.4.3" - builder-util-runtime "3.3.0" + builder-util "3.4.4" + builder-util-runtime "3.4.0" chromium-pickle-js "^0.2.0" debug "^3.1.0" dmg-builder "2.1.8" ejs "^2.5.7" electron-osx-sign "0.4.7" - electron-publish "19.46.5" - fs-extra-p "^4.4.4" + electron-publish "19.49.0" + fs-extra-p "^4.5.0" hosted-git-info "^2.5.0" is-ci "^1.0.10" isbinaryfile "^3.0.2" js-yaml "^3.10.0" - lazy-val "^1.0.2" + lazy-val "^1.0.3" minimatch "^3.0.4" normalize-package-data "^2.4.0" plist "^2.1.0" - read-config-file "1.2.0" + read-config-file "1.2.1" sanitize-filename "^1.6.1" semver "^5.4.1" temp-file "^3.0.0" -electron-builder@^19.48.2: - version "19.48.2" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-19.48.2.tgz#3de27d1e53ffbe715725d461add287f201d056e4" +electron-builder@^19.49.0: + version "19.49.0" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-19.49.0.tgz#f7a2754353ffd5dfe26e0cbe5dfe92d89e5cea0c" dependencies: bluebird-lst "^1.0.5" - builder-util "3.4.3" - builder-util-runtime "3.3.0" + builder-util "3.4.4" + builder-util-runtime "3.4.0" chalk "^2.3.0" - electron-builder-lib "19.48.2" + electron-builder-lib "19.49.0" electron-download-tf "4.3.4" - fs-extra-p "^4.4.4" + fs-extra-p "^4.5.0" is-ci "^1.0.10" - lazy-val "^1.0.2" - read-config-file "1.2.0" + lazy-val "^1.0.3" + read-config-file "1.2.1" sanitize-filename "^1.6.1" update-notifier "^2.3.0" yargs "^10.0.3" @@ -2809,30 +2853,21 @@ electron-osx-sign@0.4.7: minimist "^1.2.0" plist "^2.1.0" -electron-publish@19.46.5: - version "19.46.5" - resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-19.46.5.tgz#eb545af247edc78297a9ace6ebb2bad7c0fcc2a4" +electron-publish@19.49.0: + version "19.49.0" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-19.49.0.tgz#ca75482f7767683f14428d47344f34e9bf78c2d4" dependencies: bluebird-lst "^1.0.5" - builder-util "^3.4.2" - builder-util-runtime "^3.3.0" + builder-util "^3.4.4" + builder-util-runtime "^3.4.0" chalk "^2.3.0" - fs-extra-p "^4.4.4" + fs-extra-p "^4.5.0" mime "^2.0.3" electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.27: version "1.3.27" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.27.tgz#78ecb8a399066187bb374eede35d9c70565a803d" -electron-webpack-eslint@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/electron-webpack-eslint/-/electron-webpack-eslint-1.2.0.tgz#34772534e3941273ce6dcae7f26366c28bd7dfa1" - dependencies: - babel-eslint "^8.0.1" - eslint "^4.9.0" - eslint-friendly-formatter "^3.0.0" - eslint-loader "^1.9.0" - electron-webpack-js@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/electron-webpack-js/-/electron-webpack-js-1.1.0.tgz#c7c1cf375f6d32638ba62f46e1bd31445b7f1018" @@ -3111,16 +3146,6 @@ eslint-config-prettier@^2.9.0: dependencies: get-stdin "^5.0.1" -eslint-friendly-formatter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-friendly-formatter/-/eslint-friendly-formatter-3.0.0.tgz#278874435a6c46ec1d94fa0b1ff494e30ef04290" - dependencies: - chalk "^1.0.0" - coalescy "1.0.0" - extend "^3.0.0" - minimist "^1.2.0" - text-table "^0.2.0" - eslint-import-resolver-node@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" @@ -3144,16 +3169,6 @@ eslint-import-resolver-webpack@^0.8.3: resolve "^1.2.0" semver "^5.3.0" -eslint-loader@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-1.9.0.tgz#7e1be9feddca328d3dcfaef1ad49d5beffe83a13" - dependencies: - loader-fs-cache "^1.0.0" - loader-utils "^1.0.2" - object-assign "^4.0.1" - object-hash "^1.1.4" - rimraf "^2.6.1" - eslint-module-utils@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" @@ -3214,7 +3229,7 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@^4.9.0: +eslint@^4.13.1: version "4.13.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.13.1.tgz#0055e0014464c7eb7878caf549ef2941992b444f" dependencies: @@ -3440,7 +3455,7 @@ ext-name@^5.0.0: ext-list "^2.0.0" sort-keys-length "^1.0.0" -extend@^3.0.0, extend@~3.0.0, extend@~3.0.1: +extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -3609,14 +3624,6 @@ find-babel-config@^1.1.0: json5 "^0.5.1" path-exists "^3.0.0" -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" @@ -3786,6 +3793,13 @@ fs-extra-p@^4.4.4: bluebird-lst "^1.0.4" fs-extra "^4.0.2" +fs-extra-p@^4.4.5, fs-extra-p@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.5.0.tgz#b79f3f3fcc0b5e57b7e7caeb06159f958ef15fe8" + dependencies: + bluebird-lst "^1.0.5" + fs-extra "^5.0.0" + fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -3804,6 +3818,14 @@ fs-extra@^4.0.0, fs-extra@^4.0.1, fs-extra@^4.0.2: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-vacuum@~1.2.10: version "1.2.10" resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" @@ -5104,6 +5126,10 @@ lazy-val@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.2.tgz#d9b07fb1fce54cbc99b3c611de431b83249369b6" +lazy-val@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.3.tgz#bb97b200ef00801d94c317e29dc6ed39e31c5edc" + lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" @@ -5235,13 +5261,6 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" -loader-fs-cache@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc" - dependencies: - find-cache-dir "^0.1.1" - mkdirp "0.5.1" - loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -5716,7 +5735,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5, mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -6272,10 +6291,6 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -object-hash@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.2.0.tgz#e96af0e96981996a1d47f88ead8f74f1ebc4422b" - object-keys@^1.0.6, object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -7303,7 +7318,21 @@ read-cmd-shim@~1.0.1: dependencies: graceful-fs "^4.1.2" -read-config-file@1.2.0, read-config-file@^1.2.0: +read-config-file@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-1.2.1.tgz#f889ea5c13372319433f5df09d7a9742c72d0b25" + dependencies: + ajv "^5.5.1" + ajv-keywords "^2.1.1" + bluebird-lst "^1.0.5" + dotenv "^4.0.0" + dotenv-expand "^4.0.1" + fs-extra-p "^4.4.4" + js-yaml "^3.10.0" + json5 "^0.5.1" + lazy-val "^1.0.2" + +read-config-file@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/read-config-file/-/read-config-file-1.2.0.tgz#1fd7dc8ccdad838cac9f686182625290fc94f456" dependencies: @@ -8533,7 +8562,7 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -text-table@^0.2.0, text-table@~0.2.0: +text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" From ac821a5e4db0b846ada440a0d87134f0285ec39a Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:32:59 -0300 Subject: [PATCH 18/66] Update electron configuration for ESLint import plugin --- .eslintrc.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 8101e35be..8d37b5407 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,6 +4,7 @@ ], "extends": [ "airbnb", + "plugin:import/electron", "plugin:flowtype/recommended", "prettier" ], @@ -12,10 +13,7 @@ "webpack": { "config": "webpack.renderer.additions.js" } - }, - "import/core-modules": [ - "electron" - ] + } }, "parser": "babel-eslint", "env": { From 11609780959a9f9aafb0137c2d6c2eead5feb610 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:34:18 -0300 Subject: [PATCH 19/66] Add missing global vars to ESLint configuration --- .eslintrc.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 8d37b5407..8eff1a76e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -22,6 +22,9 @@ }, "globals": { "__static": true, - "__": true + "staticResourcesPath": true, + "__": true, + "__n": true, + "app": true } } \ No newline at end of file From 97fe53d647a4997a14be2c1f521d62bb9db07bbc Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:35:13 -0300 Subject: [PATCH 20/66] Warn if not using ES6 imports/exports --- .eslintrc.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.eslintrc.json b/.eslintrc.json index 8eff1a76e..bc69f279c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -26,5 +26,9 @@ "__": true, "__n": true, "app": true + }, + "rules": { + "import/no-commonjs": 1, + "import/no-amd": 1 } } \ No newline at end of file From b0255f468a043a98d9944a2619804591641edf2f Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:36:03 -0300 Subject: [PATCH 21/66] Add Prettier config file --- .prettierrc.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .prettierrc.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..5d5281c52 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "trailing-comma": "es5", + "printWidth": 100 +} \ No newline at end of file From 3b26f0621019392f95a027e116a299b0eeefea39 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:37:19 -0300 Subject: [PATCH 22/66] Update extractLocals.js location --- {src/renderer => build}/extractLocals.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) rename {src/renderer => build}/extractLocals.js (66%) diff --git a/src/renderer/extractLocals.js b/build/extractLocals.js similarity index 66% rename from src/renderer/extractLocals.js rename to build/extractLocals.js index 9e4746d3e..8f48b1492 100644 --- a/src/renderer/extractLocals.js +++ b/build/extractLocals.js @@ -1,20 +1,21 @@ const extract = require("i18n-extract"); const fs = require("fs"); +const path = require("path"); -const dir = `${__dirname}/../../static/locales`; -const path = `${dir}/en.json`; +const outputDir = `${__dirname}/../static/locales`; +const outputPath = `${outputDir}/en.json`; -if (!fs.existsSync(dir)) { - fs.mkdirSync(dir); +if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir); } -fs.writeFile(path, "{}", "utf8", err => { +fs.writeFile(outputPath, "{}", "utf8", err => { if (err) { return console.log(err); } - const enLocale = require(path); + const enLocale = require(outputPath); - const keys = extract.extractFromFiles(["js/**/*.{js,jsx}"], { + const keys = extract.extractFromFiles("src/**/*.{js,jsx}", { marker: "__", }); @@ -22,7 +23,7 @@ fs.writeFile(path, "{}", "utf8", err => { reports = reports.concat(extract.findMissing(enLocale, keys)); if (reports.length > 0) { - fs.readFile(path, "utf8", (err, data) => { + fs.readFile(outputPath, "utf8", (err, data) => { if (err) { console.log(err); } else { @@ -36,7 +37,7 @@ fs.writeFile(path, "{}", "utf8", err => { } const json = JSON.stringify(localeObj, null, "\t"); // convert it back to json-string - fs.writeFile(path, json, "utf8", err => { + fs.writeFile(outputPath, json, "utf8", err => { if (err) { throw err; } From a9d386e5dde739466612fa447e27c1e1b5170434 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:38:52 -0300 Subject: [PATCH 23/66] Pretty print and lint Webpack configuration file --- webpack.renderer.additions.js | 38 ++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/webpack.renderer.additions.js b/webpack.renderer.additions.js index 20466b4d8..d3465623a 100644 --- a/webpack.renderer.additions.js +++ b/webpack.renderer.additions.js @@ -1,6 +1,7 @@ -const path = require('path'); +const Path = require("path"); +const FlowFlowPlugin = require("./flowtype-plugin"); -const ELECTRON_RENDERER_PROCESS_ROOT = path.resolve(__dirname, 'src/renderer/'); +const ELECTRON_RENDERER_PROCESS_ROOT = Path.resolve(__dirname, "src/renderer/"); module.exports = { // This rule is temporarily necessary until https://github.com/electron-userland/electron-webpack/issues/60 is fixed. @@ -8,26 +9,27 @@ module.exports = { rules: [ { test: /\.jsx?$/, - loader: 'babel-loader', + loader: "babel-loader", options: { - presets: ['env', 'react', 'stage-2'] - } - } - ] + presets: ["env", "react", "stage-2"], + }, + }, + ], }, // This allows imports to be made from the renderer process root (https://moduscreate.com/blog/es6-es2015-import-no-relative-path-webpack/). resolve: { - modules: [ELECTRON_RENDERER_PROCESS_ROOT, 'node_modules', __dirname], - extensions: ['.js', '.jsx', '.scss'] - } + modules: [ELECTRON_RENDERER_PROCESS_ROOT, "node_modules", __dirname], + extensions: [".js", ".jsx", ".scss"], + }, }; -if (process.env.NODE_ENV === 'development') { - const FLOW_BABEL_WEBPACK_PLUGIN = require('./flowtype-plugin'); - - module.exports.plugins = [ - new FLOW_BABEL_WEBPACK_PLUGIN({ - warn: true - }) - ] +if (process.env.NODE_ENV === "development") { + module.exports = { + ...module.exports, + plugins: [ + new FlowFlowPlugin({ + warn: true, + }), + ] + }; } From 57b8cb82ea1fd6b1da4063535fc83b87d80ee0c8 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 16:06:59 -0300 Subject: [PATCH 24/66] Move bluebird from devDependencies to dependencies --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 878a56108..7eb2ebffe 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ ], "dependencies": { "amplitude-js": "^4.0.0", + "bluebird": "^3.5.1", "classnames": "^2.2.5", "electron-dl": "^1.6.0", "formik": "^0.10.4", @@ -72,7 +73,6 @@ "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.18.0", - "bluebird": "^3.5.1", "devtron": "^1.4.0", "electron": "^1.7.9", "electron-builder": "^19.49.0", From c1a6b5a9405dbdb372c2fbabdc20c5ed4e4e2cae Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 17:05:00 -0300 Subject: [PATCH 25/66] Fix and update Prettier and ESLint scripts --- .lintstagedrc | 12 ++++++++++++ package.json | 10 ++-------- 2 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 .lintstagedrc diff --git a/.lintstagedrc b/.lintstagedrc new file mode 100644 index 000000000..bd9f228ce --- /dev/null +++ b/.lintstagedrc @@ -0,0 +1,12 @@ +{ + "linters": { + "src/**/*.{js,jsx,scss,json}": [ + "prettier --write", + "git add" + ], + "src/**/*.{js,jsx}": [ + "eslint --fix", + "git add" + ] + } +} diff --git a/package.json b/package.json index 7eb2ebffe..5c0a7acd9 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "build": "yarn compile && electron-builder build", "postinstall": "electron-builder install-app-deps", "precommit": "lint-staged", - "lint": "eslint src/", - "pretty": "prettier src/ --write" + "lint": "eslint src/**/*.{js,jsx} --fix", + "pretty": "prettier src/**/*.{js,jsx,scss,json} --write" }, "keywords": [ "lbry" @@ -108,12 +108,6 @@ "yarn": "^1.3" }, "license": "MIT", - "lint-staged": { - "src/**/*.{js,jsx}": [ - "prettier --write", - "git add" - ] - }, "lbrySettings": { "lbrynetDaemonVersion": "0.18.0", "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip" From 4a48d0a52137bb13f2050bb9684a53abda9e2005 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 21 Dec 2017 12:17:33 -0300 Subject: [PATCH 26/66] Ajust Prettier and ESLint to respect Airbnb JavaScript formating rules --- .eslintrc.json | 2 +- .prettierrc.json | 5 +++-- package.json | 1 + yarn.lock | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index bc69f279c..2fbd88746 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,7 +6,7 @@ "airbnb", "plugin:import/electron", "plugin:flowtype/recommended", - "prettier" + "plugin:prettier/recommended" ], "settings": { "import/resolver": { diff --git a/.prettierrc.json b/.prettierrc.json index 5d5281c52..1d3fce725 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,5 @@ { - "trailing-comma": "es5", - "printWidth": 100 + "trailingComma": "es5", + "printWidth": 100, + "singleQuote": true } \ No newline at end of file diff --git a/package.json b/package.json index 5c0a7acd9..178dc84df 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "eslint-plugin-flowtype": "^2.40.1", "eslint-plugin-import": "^2.8.0", "eslint-plugin-jsx-a11y": "^6.0.3", + "eslint-plugin-prettier": "^2.4.0", "eslint-plugin-react": "^7.5.1", "flow-babel-webpack-plugin": "^1.1.0", "flow-bin": "^0.61.0", diff --git a/yarn.lock b/yarn.lock index 2a9d3095c..690ed20b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3209,6 +3209,13 @@ eslint-plugin-jsx-a11y@^6.0.3: emoji-regex "^6.1.0" jsx-ast-utils "^2.0.0" +eslint-plugin-prettier@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.4.0.tgz#85cab0775c6d5e3344ef01e78d960f166fb93aae" + dependencies: + fast-diff "^1.1.1" + jest-docblock "^21.0.0" + eslint-plugin-react@^7.5.1: version "7.5.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz#52e56e8d80c810de158859ef07b880d2f56ee30b" @@ -3512,6 +3519,10 @@ fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" +fast-diff@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -4916,6 +4927,10 @@ jayson@^2.0.2: json-stringify-safe "5.0.1" lodash "3.6.0" +jest-docblock@^21.0.0: + version "21.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" + jest-get-type@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.2.0.tgz#f6376ab9db4b60d81e39f30749c6c466f40d4a23" From 7cd25e777aded97a7609e084ccff4ae0c8240a94 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 21 Dec 2017 14:32:51 -0300 Subject: [PATCH 27/66] Pretty print and lint non-component sources --- package.json | 4 +- src/main/index.js | 796 ++++++------- src/main/menu/context-menu.js | 35 - src/main/menu/contextMenu.js | 30 + src/main/menu/main-menu.js | 136 --- src/main/menu/mainMenu.js | 138 +++ src/renderer/app.js | 36 +- src/renderer/constants/action_types.js | 274 +++-- src/renderer/constants/icons.js | 10 +- src/renderer/constants/languages.js | 366 +++--- src/renderer/constants/modal_types.js | 30 +- src/renderer/constants/settings.js | 24 +- src/renderer/constants/shape_shift.js | 6 +- src/renderer/constants/transaction_types.js | 3 +- src/renderer/flow-typed/reselect.js | 2 + src/renderer/index.js | 106 +- src/renderer/jsonrpc.js | 67 +- src/renderer/lbry.js | 269 ++--- src/renderer/lbryio.js | 141 ++- src/renderer/lbryuri.js | 119 +- src/renderer/redux/actions/app.js | 133 +-- src/renderer/redux/actions/availability.js | 49 +- src/renderer/redux/actions/content.js | 401 +++---- src/renderer/redux/actions/cost_info.js | 70 +- src/renderer/redux/actions/file_info.js | 65 +- src/renderer/redux/actions/navigation.js | 42 +- src/renderer/redux/actions/rewards.js | 78 +- src/renderer/redux/actions/search.js | 34 +- src/renderer/redux/actions/settings.js | 132 +-- src/renderer/redux/actions/shape_shift.js | 91 +- src/renderer/redux/actions/subscriptions.js | 23 +- src/renderer/redux/actions/user.js | 188 ++- src/renderer/redux/actions/wallet.js | 130 +- src/renderer/redux/reducers/app.js | 53 +- src/renderer/redux/reducers/availability.js | 6 +- src/renderer/redux/reducers/claims.js | 53 +- src/renderer/redux/reducers/content.js | 32 +- src/renderer/redux/reducers/cost_info.js | 6 +- src/renderer/redux/reducers/file_info.js | 30 +- src/renderer/redux/reducers/navigation.js | 29 +- src/renderer/redux/reducers/rewards.js | 39 +- src/renderer/redux/reducers/search.js | 10 +- src/renderer/redux/reducers/settings.js | 48 +- src/renderer/redux/reducers/shape_shift.js | 119 +- src/renderer/redux/reducers/subscriptions.js | 39 +- src/renderer/redux/reducers/user.js | 69 +- src/renderer/redux/reducers/wallet.js | 44 +- src/renderer/redux/selectors/app.js | 93 +- src/renderer/redux/selectors/availability.js | 23 +- src/renderer/redux/selectors/claims.js | 158 +-- src/renderer/redux/selectors/content.js | 27 +- src/renderer/redux/selectors/cost_info.js | 29 +- src/renderer/redux/selectors/file_info.js | 63 +- src/renderer/redux/selectors/navigation.js | 178 ++- src/renderer/redux/selectors/rewards.js | 67 +- src/renderer/redux/selectors/search.js | 96 +- src/renderer/redux/selectors/settings.js | 30 +- src/renderer/redux/selectors/shape_shift.js | 8 +- src/renderer/redux/selectors/subscriptions.js | 18 +- src/renderer/redux/selectors/user.js | 47 +- src/renderer/redux/selectors/wallet.js | 171 ++- src/renderer/rewards.js | 111 +- src/renderer/scss/_gui.scss | 78 +- src/renderer/scss/_icons.scss | 1055 +++++++++-------- src/renderer/scss/_reset.scss | 86 +- src/renderer/scss/_vars.scss | 47 +- src/renderer/scss/all.scss | 60 +- src/renderer/scss/component/_button.scss | 46 +- src/renderer/scss/component/_card.scss | 63 +- .../scss/component/_channel-indicator.scss | 1 - src/renderer/scss/component/_checkbox.scss | 24 +- .../scss/component/_file-download.scss | 15 +- src/renderer/scss/component/_file-tile.scss | 1 - src/renderer/scss/component/_form-field.scss | 67 +- src/renderer/scss/component/_header.scss | 19 +- src/renderer/scss/component/_load-screen.scss | 1 - .../scss/component/_markdown-editor.scss | 72 +- src/renderer/scss/component/_menu.scss | 1 - src/renderer/scss/component/_modal.scss | 9 +- src/renderer/scss/component/_notice.scss | 21 +- src/renderer/scss/component/_pagination.scss | 10 +- src/renderer/scss/component/_radio.scss | 82 +- src/renderer/scss/component/_scrollbar.scss | 20 +- src/renderer/scss/component/_shapeshift.scss | 1 - src/renderer/scss/component/_snack-bar.scss | 3 +- src/renderer/scss/component/_spinner.scss | 2 +- src/renderer/scss/component/_table.scss | 29 +- src/renderer/scss/component/_tabs.scss | 27 +- src/renderer/scss/component/_tooltip.scss | 4 +- src/renderer/scss/component/_video.scss | 5 +- src/renderer/scss/mixin/link.scss | 10 +- src/renderer/store.js | 71 +- src/renderer/types/common.js | 2 + src/renderer/util/batchActions.js | 2 +- src/renderer/util/formatCredits.js | 15 +- src/renderer/util/query_params.js | 24 +- src/renderer/util/redux-utils.js | 7 +- src/renderer/util/setBadge.js | 4 +- src/renderer/util/setProgressBar.js | 3 +- src/renderer/util/shape_shift.js | 14 +- src/renderer/util/throttle.js | 27 +- webpack.renderer.additions.js | 29 +- yarn.lock | 6 +- 103 files changed, 3577 insertions(+), 4210 deletions(-) delete mode 100644 src/main/menu/context-menu.js create mode 100644 src/main/menu/contextMenu.js delete mode 100644 src/main/menu/main-menu.js create mode 100644 src/main/menu/mainMenu.js diff --git a/package.json b/package.json index 178dc84df..dc656400d 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "build": "yarn compile && electron-builder build", "postinstall": "electron-builder install-app-deps", "precommit": "lint-staged", - "lint": "eslint src/**/*.{js,jsx} --fix", - "pretty": "prettier src/**/*.{js,jsx,scss,json} --write" + "lint": "eslint 'src/**/*.{js,jsx}' --fix", + "pretty-print": "prettier 'src/**/*.{js,jsx,scss,json}' --write" }, "keywords": [ "lbry" diff --git a/src/main/index.js b/src/main/index.js index 67e16acca..6c83391ff 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,68 +1,39 @@ +/* eslint-disable no-console */ // Module imports -const { - app, - BrowserWindow, - ipcMain, - Menu, - Tray, - globalShortcut, -} = require("electron"); -const path = require("path"); -const url = require("url"); -const jayson = require("jayson"); -const semver = require("semver"); -const https = require("https"); -const keytar = require("keytar"); -// tree-kill has better cross-platform handling of -// killing a process. child-process.kill was unreliable -const kill = require("tree-kill"); -const child_process = require("child_process"); -const assert = require("assert"); +import Path from 'path'; +import Url from 'url'; +import Jayson from 'jayson'; +import Semver from 'semver'; +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 mainMenu from './menu/mainMenu'; const localVersion = app.getVersion(); -const setMenu = require("./menu/main-menu.js"); -export const contextMenu = require("./menu/context-menu"); +export { contextMenu as Default } from './menu/contextMenu'; // Debug configs -const isDevelopment = process.env.NODE_ENV === "development"; -if (isDevelopment) { - try { - const { - default: installExtension, - REACT_DEVELOPER_TOOLS, - REDUX_DEVTOOLS, - } = require("electron-devtools-installer"); - app.on("ready", () => { - [REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS].forEach(extension => { - installExtension(extension) - .then(name => console.log(`Added Extension: ${name}`)) - .catch(err => console.log("An error occurred: ", err)); - }); - }); - } catch (err) { - console.error(err); - } -} +const isDevelopment = process.env.NODE_ENV === 'development'; // 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"); +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'); const rendererUrl = isDevelopment ? `http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}` : `file://${__dirname}/index.html`; -const client = jayson.client.http({ - host: "localhost", +const client = Jayson.client.http({ + host: 'localhost', port: 5279, - path: "/", + path: '/', timeout: 1000, }); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. -let win; +let rendererWindow; // Also keep the daemon subprocess alive let daemonSubprocess; @@ -95,8 +66,8 @@ function processRequestedUri(uri) { // lbry://channel/#claimid. We remove the slash here as well. // On Linux and Mac, we just return the URI as given. - if (process.platform === "win32") { - return uri.replace(/\/$/, "").replace("/#", "#"); + if (process.platform === 'win32') { + return uri.replace(/\/$/, '').replace('/#', '#'); } return uri; } @@ -109,223 +80,22 @@ function processRequestedUri(uri) { function openItem(fullPath) { const subprocOptions = { detached: true, - stdio: "ignore", + stdio: 'ignore', }; let child; - if (process.platform === "darwin") { - child = child_process.spawn("open", [fullPath], subprocOptions); - } else if (process.platform === "linux") { - child = child_process.spawn("xdg-open", [fullPath], subprocOptions); - } else if (process.platform === "win32") { - child = child_process.spawn( - fullPath, - Object.assign({}, subprocOptions, { shell: true }) - ); + if (process.platform === 'darwin') { + child = ChildProcess.spawn('open', [fullPath], subprocOptions); + } else if (process.platform === 'linux') { + child = ChildProcess.spawn('xdg-open', [fullPath], subprocOptions); + } else if (process.platform === 'win32') { + child = ChildProcess.spawn(fullPath, Object.assign({}, subprocOptions, { shell: true })); } // Causes child process reference to be garbage collected, allowing main process to exit child.unref(); } -function getPidsForProcessName(name) { - if (process.platform === "win32") { - const tasklistOut = child_process.execSync( - `tasklist /fi "Imagename eq ${name}.exe" /nh`, - { encoding: "utf8" } - ); - if (tasklistOut.startsWith("INFO")) { - return []; - } - return tasklistOut.match(/[^\r\n]+/g).map(line => line.split(/\s+/)[1]); // Second column of every non-empty line - } - const pgrepOut = child_process.spawnSync("pgrep", ["-x", name], { - encoding: "utf8", - }).stdout; - return pgrepOut.match(/\d+/g); -} - -function createWindow() { - // Disable renderer process's webSecurity on development to enable CORS. - win = isDevelopment - ? new BrowserWindow({ - backgroundColor: "#155B4A", - minWidth: 800, - minHeight: 600, - webPreferences: { webSecurity: false }, - }) - : new BrowserWindow({ - backgroundColor: "#155B4A", - minWidth: 800, - minHeight: 600, - }); - - win.webContents.session.setUserAgent(`LBRY/${localVersion}`); - - win.maximize(); - if (isDevelopment) { - win.webContents.openDevTools(); - } - win.loadURL(rendererUrl); - if (openUri) { - // We stored and received a URI that an external app requested before we had a window object - win.webContents.on("did-finish-load", () => { - win.webContents.send("open-uri-requested", openUri); - }); - } - - win.removeAllListeners(); - - win.on("close", event => { - if (minimize) { - event.preventDefault(); - win.hide(); - } - }); - - win.on("closed", () => { - win = null; - }); - - win.on("hide", () => { - // Checks what to show in the tray icon menu - if (minimize) updateTray(); - }); - - win.on("show", () => { - // Checks what to show in the tray icon menu - if (minimize) updateTray(); - }); - - win.on("blur", () => { - // Checks what to show in the tray icon menu - if (minimize) updateTray(); - - // Unregisters Alt+F4 shortcut - globalShortcut.unregister("Alt+F4"); - }); - - win.on("focus", () => { - // Checks what to show in the tray icon menu - if (minimize) updateTray(); - - // Registers shortcut for closing(quitting) the app - globalShortcut.register("Alt+F4", () => safeQuit()); - - win.webContents.send("window-is-focused", null); - }); - - // Menu bar - win.setAutoHideMenuBar(true); - win.setMenuBarVisibility(isDevelopment); - setMenu(); -} - -function createTray() { - // Minimize to tray logic follows: - // Set the tray icon - let iconPath; - if (process.platform === "darwin") { - // Using @2x for mac retina screens so the icon isn't blurry - // file name needs to include "Template" at the end for dark menu bar - iconPath = path.join(__static, "/img/fav/macTemplate@2x.png"); - } else { - iconPath = path.join(__static, "/img/fav/32x32.png"); - } - - tray = new Tray(iconPath); - tray.setToolTip("LBRY App"); - tray.setTitle("LBRY"); - tray.on("double-click", () => { - win.show(); - }); -} - -// This needs to be done as for linux the context menu doesn't update automatically(docs) -function updateTray() { - const contextMenu = Menu.buildFromTemplate(getMenuTemplate()); - if (tray) { - tray.setContextMenu(contextMenu); - } else { - console.log("How did update tray get called without a tray?"); - } -} - -function getMenuTemplate() { - return [ - getToggleItem(), - { - label: "Quit", - click: () => safeQuit(), - }, - ]; - - function getToggleItem() { - if (win.isVisible() && win.isFocused()) { - return { - label: "Hide LBRY App", - click: () => win.hide(), - }; - } - return { - label: "Show LBRY App", - click: () => win.show(), - }; - } -} - -function handleOpenUriRequested(uri) { - if (!win) { - // Window not created yet, so store up requested URI for when it is - openUri = processRequestedUri(uri); - } else { - if (win.isMinimized()) { - win.restore(); - } else if (!win.isVisible()) { - win.show(); - } - - win.focus(); - win.webContents.send("open-uri-requested", processRequestedUri(uri)); - } -} - -function handleDaemonSubprocessExited() { - console.log("The daemon has exited."); - daemonSubprocess = null; - if (!daemonStopRequested) { - // We didn't request to stop the daemon, so display a - // warning and schedule a quit. - // - // TODO: maybe it would be better to restart the daemon? - if (win) { - console.log("Did not request daemon stop, so quitting in 5 seconds."); - win.loadURL(`file://${__static}/warning.html`); - setTimeout(quitNow, 5000); - } else { - console.log("Did not request daemon stop, so quitting."); - quitNow(); - } - } -} - -function launchDaemon() { - assert(!daemonSubprocess, "Tried to launch daemon twice"); - - console.log("Launching daemon:", DAEMON_PATH); - daemonSubprocess = child_process.spawn(DAEMON_PATH); - // Need to handle the data event instead of attaching to - // process.stdout because the latter doesn't work. I believe on - // windows it buffers stdout and we don't get any meaningful output - daemonSubprocess.stdout.on("data", buf => { - console.log(String(buf).trim()); - }); - daemonSubprocess.stderr.on("data", buf => { - console.log(String(buf).trim()); - }); - daemonSubprocess.on("exit", handleDaemonSubprocessExited); -} - /* * Quits by first killing the daemon, the calling quitting for real. */ @@ -334,6 +104,155 @@ export function safeQuit() { app.quit(); } +function getMenuTemplate() { + function getToggleItem() { + if (rendererWindow.isVisible() && rendererWindow.isFocused()) { + return { + label: 'Hide LBRY App', + click: () => rendererWindow.hide(), + }; + } + return { + label: 'Show LBRY App', + click: () => rendererWindow.show(), + }; + } + + return [ + getToggleItem(), + { + label: 'Quit', + click: () => safeQuit(), + }, + ]; +} + +// This needs to be done as for linux the context menu doesn't update automatically(docs) +function updateTray() { + const trayContextMenu = Menu.buildFromTemplate(getMenuTemplate()); + if (tray) { + tray.setContextMenu(trayContextMenu); + } else { + console.log('How did update tray get called without a tray?'); + } +} + +function createWindow() { + // Disable renderer process's webSecurity on development to enable CORS. + let windowConfiguration = { + backgroundColor: '#155B4A', + minWidth: 800, + minHeight: 600, + autoHideMenuBar: true, + }; + + windowConfiguration = isDevelopment + ? { + ...windowConfiguration, + webPreferences: { + webSecurity: false, + }, + } + : windowConfiguration; + + let window = new BrowserWindow(windowConfiguration); + + window.webContents.session.setUserAgent(`LBRY/${localVersion}`); + + window.maximize(); + if (isDevelopment) { + window.webContents.openDevTools(); + } + window.loadURL(rendererUrl); + if (openUri) { + // We stored and received a URI that an external app requested before we had a window object + window.webContents.on('did-finish-load', () => { + window.webContents.send('open-uri-requested', openUri); + }); + } + + window.removeAllListeners(); + + window.on('close', event => { + if (minimize) { + event.preventDefault(); + window.hide(); + } + }); + + window.on('closed', () => { + window = null; + }); + + window.on('hide', () => { + // Checks what to show in the tray icon menu + if (minimize) updateTray(); + }); + + window.on('show', () => { + // Checks what to show in the tray icon menu + if (minimize) updateTray(); + }); + + window.on('blur', () => { + // Checks what to show in the tray icon menu + if (minimize) updateTray(); + + // Unregisters Alt+F4 shortcut + globalShortcut.unregister('Alt+F4'); + }); + + window.on('focus', () => { + // Checks what to show in the tray icon menu + if (minimize) updateTray(); + + // Registers shortcut for closing(quitting) the app + globalShortcut.register('Alt+F4', () => safeQuit()); + + window.webContents.send('window-is-focused', null); + }); + + mainMenu(); + + return window; +} + +function createTray() { + // Minimize to tray logic follows: + // Set the tray icon + let iconPath; + if (process.platform === 'darwin') { + // Using @2x for mac retina screens so the icon isn't blurry + // file name needs to include "Template" at the end for dark menu bar + iconPath = Path.join(__static, '/img/fav/macTemplate@2x.png'); + } else { + iconPath = Path.join(__static, '/img/fav/32x32.png'); + } + + tray = new Tray(iconPath); + tray.setToolTip('LBRY App'); + tray.setTitle('LBRY'); + tray.on('double-click', () => { + rendererWindow.show(); + }); +} + +function handleOpenUriRequested(uri) { + if (!rendererWindow) { + // Window not created yet, so store up requested URI for when it is + openUri = processRequestedUri(uri); + } else { + if (rendererWindow.isMinimized()) { + rendererWindow.restore(); + } else if (!rendererWindow.isVisible()) { + rendererWindow.show(); + } + + rendererWindow.focus(); + rendererWindow.webContents.send('open-uri-requested', processRequestedUri(uri)); + } +} + /* * Quits without any preparation. When a quit is requested (either through the * interface or through app.quit()), we abort the quit, try to shut down the daemon, @@ -344,16 +263,52 @@ function quitNow() { safeQuit(); } +function handleDaemonSubprocessExited() { + console.log('The daemon has exited.'); + daemonSubprocess = null; + if (!daemonStopRequested) { + // We didn't request to stop the daemon, so display a + // warning and schedule a quit. + // + // TODO: maybe it would be better to restart the daemon? + if (rendererWindow) { + console.log('Did not request daemon stop, so quitting in 5 seconds.'); + rendererWindow.loadURL(`file://${__static}/warning.html`); + setTimeout(quitNow, 5000); + } else { + console.log('Did not request daemon stop, so quitting.'); + quitNow(); + } + } +} + +function launchDaemon() { + Assert(!daemonSubprocess, 'Tried to launch daemon twice'); + + console.log('Launching daemon:', DAEMON_PATH); + daemonSubprocess = ChildProcess.spawn(DAEMON_PATH); + // Need to handle the data event instead of attaching to + // process.stdout because the latter doesn't work. I believe on + // windows it buffers stdout and we don't get any meaningful output + daemonSubprocess.stdout.on('data', buf => { + console.log(String(buf).trim()); + }); + daemonSubprocess.stderr.on('data', buf => { + console.log(String(buf).trim()); + }); + daemonSubprocess.on('exit', handleDaemonSubprocessExited); +} + const isSecondaryInstance = app.makeSingleInstance(argv => { if (argv.length >= 2) { handleOpenUriRequested(argv[1]); // This will handle restoring and focusing the window - } else if (win) { - if (win.isMinimized()) { - win.restore(); - } else if (!win.isVisible()) { - win.show(); + } else if (rendererWindow) { + if (rendererWindow.isMinimized()) { + rendererWindow.restore(); + } else if (!rendererWindow.isVisible()) { + rendererWindow.show(); } - win.focus(); + rendererWindow.focus(); } }); @@ -365,126 +320,44 @@ if (isSecondaryInstance) { function launchDaemonIfNotRunning() { // Check if the daemon is already running. If we get // an error its because its not running - console.log("Checking for lbrynet daemon"); - client.request("status", [], (err, res) => { + console.log('Checking for lbrynet daemon'); + client.request('status', [], err => { if (err) { - console.log("lbrynet daemon needs to be launched"); + console.log('lbrynet daemon needs to be launched'); launchDaemon(); } else { - console.log("lbrynet daemon is already running"); + console.log('lbrynet daemon is already running'); } }); } -/* - * Last resort for killing unresponsive daemon instances. - * Looks for any processes called "lbrynet-daemon" and - * tries to force kill them. - */ -function forceKillAllDaemonsAndQuit() { - console.log( - "Attempting to force kill any running lbrynet-daemon instances..." - ); - - const daemonPids = getPidsForProcessName("lbrynet-daemon"); - if (!daemonPids) { - console.log("No lbrynet-daemon found running."); - quitNow(); - } else { - console.log( - `Found ${ - daemonPids.length - } running daemon instances. Attempting to force kill...` - ); - - for (const pid of daemonPids) { - let daemonKillAttemptsComplete = 0; - kill(pid, "SIGKILL", err => { - daemonKillAttemptsComplete++; - if (err) { - console.log( - `Failed to force kill daemon task with pid ${pid}. Error message: ${ - err.message - }` - ); - } else { - console.log(`Force killed daemon task with pid ${pid}.`); - } - if (daemonKillAttemptsComplete >= daemonPids.length - 1) { - quitNow(); - } - }); +// Taken from webtorrent-desktop +function checkLinuxTraySupport(cb) { + // Check that we're on Ubuntu (or another debian system) and that we have + // libappindicator1. + ChildProcess.exec('dpkg --get-selections libappindicator1', (err, stdout) => { + if (err) return cb(err); + // Unfortunately there's no cleaner way, as far as I can tell, to check + // whether a debian package is installed: + if (stdout.endsWith('\tinstall\n')) { + return cb(null); } - } -} - -app.setAsDefaultProtocolClient("lbry"); - -app.on("ready", () => { - launchDaemonIfNotRunning(); - if (process.platform === "linux") { - checkLinuxTraySupport(err => { - if (!err) createTray(); - else minimize = false; - }); - } else { - createTray(); - } - createWindow(); -}); - -// Quit when all windows are closed. -app.on("window-all-closed", () => { - // On macOS it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - if (process.platform !== "darwin") { - app.quit(); - } -}); - -app.on("before-quit", event => { - 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."); - } -}); - -app.on("activate", () => { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (win === null) { - createWindow(); - } -}); - -if (process.platform === "darwin") { - app.on("open-url", (event, uri) => { - handleOpenUriRequested(uri); + return cb(new Error('debian package not installed')); }); -} else if (process.argv.length >= 2) { - handleOpenUriRequested(process.argv[1]); } // When a quit is attempted, this is called. It attempts to shutdown the daemon, // then calls quitNow() to quit for real. function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) { function doShutdown() { - console.log("Shutting down daemon"); + console.log('Shutting down daemon'); daemonStopRequested = true; - client.request("daemon_stop", [], (err, res) => { + client.request('daemon_stop', [], err => { if (err) { - console.log( - `received error when stopping lbrynet-daemon. Error message: ${ - err.message - }\n` - ); - console.log("You will need to manually kill the daemon."); + console.log(`received error when stopping lbrynet-daemon. Error message: ${err.message}\n`); + console.log('You will need to manually kill the daemon.'); } else { - console.log("Successfully stopped daemon via RPC call."); + console.log('Successfully stopped daemon via RPC call.'); quitNow(); } }); @@ -493,7 +366,7 @@ function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) { if (daemonSubprocess) { doShutdown(); } else if (!evenIfNotStartedByApp) { - console.log("Not killing lbrynet-daemon because app did not start it"); + console.log('Not killing lbrynet-daemon because app did not start it'); quitNow(); } else { doShutdown(); @@ -503,111 +376,154 @@ function shutdownDaemonAndQuit(evenIfNotStartedByApp = false) { // If not, we should wait until the daemon is closed before we start the install. } -// Taken from webtorrent-desktop -function checkLinuxTraySupport(cb) { - // Check that we're on Ubuntu (or another debian system) and that we have - // libappindicator1. - child_process.exec( - "dpkg --get-selections libappindicator1", - (err, stdout) => { - if (err) return cb(err); - // Unfortunately there's no cleaner way, as far as I can tell, to check - // whether a debian package is installed: - if (stdout.endsWith("\tinstall\n")) { - cb(null); - } else { - cb(new Error("debian package not installed")); - } - } - ); +if (isDevelopment) { + import('devtron') + .then(({ install }) => { + install(); + console.log('Added Extension: Devtron'); + }) + .catch(error => { + console.error(error); + }); + import('electron-devtools-installer') + .then(({ default: installExtension, REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS }) => { + app.on('ready', () => { + [REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS].forEach(extension => { + installExtension(extension) + .then(name => console.log(`Added Extension: ${name}`)) + .catch(err => console.log('An error occurred: ', err)); + }); + }); + }) + .catch(error => { + console.error(error); + }); } -ipcMain.on("upgrade", (event, installerPath) => { - app.on("quit", () => { - console.log("Launching upgrade installer at", installerPath); +app.setAsDefaultProtocolClient('lbry'); + +app.on('ready', () => { + launchDaemonIfNotRunning(); + if (process.platform === 'linux') { + checkLinuxTraySupport(err => { + if (!err) createTray(); + else minimize = false; + }); + } else { + createTray(); + } + rendererWindow = createWindow(); +}); + +// Quit when all windows are closed. +app.on('window-all-closed', () => { + // On macOS it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('before-quit', event => { + 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.'); + } +}); + +app.on('activate', () => { + // On macOS it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (rendererWindow === null) { + createWindow(); + } +}); + +if (process.platform === 'darwin') { + app.on('open-url', (event, uri) => { + handleOpenUriRequested(uri); + }); +} else if (process.argv.length >= 2) { + handleOpenUriRequested(process.argv[1]); +} + +ipcMain.on('upgrade', (event, installerPath) => { + app.on('quit', () => { + console.log('Launching upgrade installer at', installerPath); // This gets triggered called after *all* other quit-related events, so // we'll only get here if we're fully prepared and quitting for real. openItem(installerPath); }); - if (win) { - win.loadURL(`file://${__static}/upgrade.html`); + if (rendererWindow) { + rendererWindow.loadURL(`file://${__static}/upgrade.html`); } shutdownDaemonAndQuit(true); // wait for daemon to shut down before upgrading // what to do if no shutdown in a long time? - console.log("Update downloaded to", installerPath); + console.log('Update downloaded to', installerPath); console.log( - "The app will close, and you will be prompted to install the latest version of LBRY." + 'The app will close, and you will be prompted to install the latest version of LBRY.' ); - console.log("After the install is complete, please reopen the app."); + console.log('After the install is complete, please reopen the app.'); }); -ipcMain.on("version-info-requested", () => { +ipcMain.on('version-info-requested', () => { function formatRc(ver) { // Adds dash if needed to make RC suffix semver friendly - return ver.replace(/([^-])rc/, "$1-rc"); + return ver.replace(/([^-])rc/, '$1-rc'); } - let result = ""; + let result = ''; const opts = { headers: { - "User-Agent": `LBRY/${localVersion}`, + 'User-Agent': `LBRY/${localVersion}`, }, }; - const req = https.get( - Object.assign(opts, url.parse(LATEST_RELEASE_API_URL)), - res => { - res.on("data", data => { - result += data; - }); - res.on("end", () => { - const tagName = JSON.parse(result).tag_name; - const [_, remoteVersion] = tagName.match(/^v([\d.]+(?:-?rc\d+)?)$/); - if (!remoteVersion) { - if (win) { - win.webContents.send("version-info-received", null); - } - } else { - const upgradeAvailable = semver.gt( - formatRc(remoteVersion), - formatRc(localVersion) - ); - if (win) { - win.webContents.send("version-info-received", { - remoteVersion, - localVersion, - upgradeAvailable, - }); - } + const req = Https.get(Object.assign(opts, Url.parse(LATEST_RELEASE_API_URL)), res => { + res.on('data', data => { + result += data; + }); + res.on('end', () => { + const tagName = JSON.parse(result).tag_name; + const [, remoteVersion] = tagName.match(/^v([\d.]+(?:-?rc\d+)?)$/); + if (!remoteVersion) { + if (rendererWindow) { + rendererWindow.webContents.send('version-info-received', null); } - }); - } - ); + } else { + const upgradeAvailable = Semver.gt(formatRc(remoteVersion), formatRc(localVersion)); + if (rendererWindow) { + rendererWindow.webContents.send('version-info-received', { + remoteVersion, + localVersion, + upgradeAvailable, + }); + } + } + }); + }); - req.on("error", err => { - console.log("Failed to get current version from GitHub. Error:", err); - if (win) { - win.webContents.send("version-info-received", null); + req.on('error', err => { + console.log('Failed to get current version from GitHub. Error:', err); + if (rendererWindow) { + rendererWindow.webContents.send('version-info-received', null); } }); }); -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('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 - ); +ipcMain.on('set-auth-token', (event, token) => { + Keytar.setPassword('LBRY', 'auth_token', token ? token.toString().trim() : null); }); diff --git a/src/main/menu/context-menu.js b/src/main/menu/context-menu.js deleted file mode 100644 index 26ed0f7de..000000000 --- a/src/main/menu/context-menu.js +++ /dev/null @@ -1,35 +0,0 @@ -const { Menu } = require("electron"); -const electron = require("electron"); - -const app = electron.app; - -const contextMenuTemplate = [ - { - role: "cut", - }, - { - role: "copy", - }, - { - role: "paste", - }, -]; - -module.exports = { - showContextMenu(win, posX, posY, showDevItems) { - const template = contextMenuTemplate.slice(); - if (showDevItems) { - template.push({ - type: "separator", - }); - template.push({ - label: "Inspect Element", - click() { - win.inspectElement(posX, posY); - }, - }); - } - - Menu.buildFromTemplate(template).popup(win); - }, -}; diff --git a/src/main/menu/contextMenu.js b/src/main/menu/contextMenu.js new file mode 100644 index 000000000..ad33c6bc2 --- /dev/null +++ b/src/main/menu/contextMenu.js @@ -0,0 +1,30 @@ +import { Menu } from 'electron'; + +const contextMenuTemplate = [ + { + role: 'cut', + }, + { + role: 'copy', + }, + { + role: 'paste', + }, +]; + +export default function contextMenu(win, posX, posY, showDevItems) { + const template = contextMenuTemplate.slice(); + if (showDevItems) { + template.push({ + type: 'separator', + }); + template.push({ + label: 'Inspect Element', + click() { + win.inspectElement(posX, posY); + }, + }); + } + + Menu.buildFromTemplate(template).popup(win); +} diff --git a/src/main/menu/main-menu.js b/src/main/menu/main-menu.js deleted file mode 100644 index c26bfd118..000000000 --- a/src/main/menu/main-menu.js +++ /dev/null @@ -1,136 +0,0 @@ -const { app, shell, Menu } = require("electron"); -const { safeQuit } = require("../index.js"); - -const baseTemplate = [ - { - label: "File", - submenu: [ - { - label: "Quit", - accelerator: "CommandOrControl+Q", - click: () => safeQuit(), - }, - ], - }, - { - label: "Edit", - submenu: [ - { - role: "undo", - }, - { - role: "redo", - }, - { - type: "separator", - }, - { - role: "cut", - }, - { - role: "copy", - }, - { - role: "paste", - }, - { - role: "selectall", - }, - ], - }, - { - label: "View", - submenu: [ - { - role: "reload", - }, - { - label: "Developer", - submenu: [ - { - role: "forcereload", - }, - { - role: "toggledevtools", - }, - ], - }, - { - type: "separator", - }, - { - role: "togglefullscreen", - }, - ], - }, - { - role: "help", - submenu: [ - { - label: "Learn More", - click(item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.send("open-menu", "/help"); - } - }, - }, - { - label: "Frequently Asked Questions", - click(item, focusedWindow) { - shell.openExternal("https://lbry.io/faq"); - }, - }, - { - type: "separator", - }, - { - label: "Report Issue", - click(item, focusedWindow) { - shell.openExternal("https://lbry.io/faq/contributing#report-a-bug"); - }, - }, - { - type: "separator", - }, - { - label: "Developer API Guide", - click(item, focusedWindow) { - shell.openExternal("https://lbry.io/quickstart"); - }, - }, - ], - }, -]; - -const macOSAppMenuTemplate = { - label: app.getName(), - submenu: [ - { - role: "about", - }, - { - type: "separator", - }, - { - role: "hide", - }, - { - role: "hideothers", - }, - { - role: "unhide", - }, - { - type: "separator", - }, - { - role: "quit", - }, - ], -}; - -module.exports = () => { - const template = baseTemplate.slice(); - process.platform === "darwin" && template.unshift(macOSAppMenuTemplate); - Menu.setApplicationMenu(Menu.buildFromTemplate(template)); -}; diff --git a/src/main/menu/mainMenu.js b/src/main/menu/mainMenu.js new file mode 100644 index 000000000..879ce8206 --- /dev/null +++ b/src/main/menu/mainMenu.js @@ -0,0 +1,138 @@ +import { app, Menu, shell } from 'electron'; +import { safeQuit } from '../index'; + +const baseTemplate = [ + { + label: 'File', + submenu: [ + { + label: 'Quit', + accelerator: 'CommandOrControl+Q', + click: () => safeQuit(), + }, + ], + }, + { + label: 'Edit', + submenu: [ + { + role: 'undo', + }, + { + role: 'redo', + }, + { + type: 'separator', + }, + { + role: 'cut', + }, + { + role: 'copy', + }, + { + role: 'paste', + }, + { + role: 'selectall', + }, + ], + }, + { + label: 'View', + submenu: [ + { + role: 'reload', + }, + { + label: 'Developer', + submenu: [ + { + role: 'forcereload', + }, + { + role: 'toggledevtools', + }, + ], + }, + { + type: 'separator', + }, + { + role: 'togglefullscreen', + }, + ], + }, + { + role: 'help', + submenu: [ + { + label: 'Learn More', + click(item, focusedWindow) { + if (focusedWindow) { + focusedWindow.webContents.send('open-menu', '/help'); + } + }, + }, + { + label: 'Frequently Asked Questions', + click() { + shell.openExternal('https://lbry.io/faq'); + }, + }, + { + type: 'separator', + }, + { + label: 'Report Issue', + click() { + shell.openExternal('https://lbry.io/faq/contributing#report-a-bug'); + }, + }, + { + type: 'separator', + }, + { + label: 'Developer API Guide', + click() { + shell.openExternal('https://lbry.io/quickstart'); + }, + }, + ], + }, +]; + +const macOSAppMenuTemplate = { + label: app.getName(), + submenu: [ + { + role: 'about', + }, + { + type: 'separator', + }, + { + role: 'hide', + }, + { + role: 'hideothers', + }, + { + role: 'unhide', + }, + { + type: 'separator', + }, + { + role: 'quit', + }, + ], +}; + +export default () => { + const template = baseTemplate.slice(); + if (process.platform === 'darwin') { + template.unshift(macOSAppMenuTemplate); + } + Menu.setApplicationMenu(Menu.buildFromTemplate(template)); +}; diff --git a/src/renderer/app.js b/src/renderer/app.js index ef3f24ce9..1e979db9e 100644 --- a/src/renderer/app.js +++ b/src/renderer/app.js @@ -1,17 +1,16 @@ -import store from "store"; -import { remote } from "electron"; -import path from "path"; +import store from 'store'; +import { remote } from 'electron'; +import path from 'path'; +import y18n from 'y18n'; -const env = process.env.NODE_ENV || "production"; +const env = process.env.NODE_ENV || 'production'; const config = { - ...require(`./config/${env}`), + ...import(`./config/${env}`), }; -const i18n = require("y18n")({ - directory: path - .join(remote.app.getAppPath(), "/../static/locales") - .replace(/\\/g, "\\\\"), +const i18n = y18n({ + directory: path.join(remote.app.getAppPath(), '/../static/locales').replace(/\\/g, '\\\\'), updateFiles: false, - locale: "en", + locale: 'en', }); const logs = []; @@ -26,8 +25,17 @@ const app = { }, }; -window.__ = i18n.__; -window.__n = i18n.__n; +// Workaround for https://github.com/electron-userland/electron-webpack/issues/52 +if (env !== 'development') { + window.staticResourcesPath = path + .join(remote.app.getAppPath(), '../static') + .replace(/\\/g, '\\\\'); +} else { + window.staticResourcesPath = ''; +} -global.app = app; -module.exports = app; +// eslint-disable-next-line no-underscore-dangle +window.__ = i18n.__; +// eslint-disable-next-line no-underscore-dangle +window.__n = i18n.__n; +window.app = app; diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js index 594aa716a..1159d256b 100644 --- a/src/renderer/constants/action_types.js +++ b/src/renderer/constants/action_types.js @@ -1,166 +1,156 @@ -export const OPEN_MODAL = "OPEN_MODAL"; -export const CLOSE_MODAL = "CLOSE_MODAL"; -export const SHOW_SNACKBAR = "SHOW_SNACKBAR"; -export const REMOVE_SNACKBAR_SNACK = "REMOVE_SNACKBAR_SNACK"; -export const WINDOW_FOCUSED = "WINDOW_FOCUSED"; -export const DAEMON_READY = "DAEMON_READY"; -export const DAEMON_VERSION_MATCH = "DAEMON_VERSION_MATCH"; -export const DAEMON_VERSION_MISMATCH = "DAEMON_VERSION_MISMATCH"; -export const VOLUME_CHANGED = "VOLUME_CHANGED"; +export const OPEN_MODAL = 'OPEN_MODAL'; +export const CLOSE_MODAL = 'CLOSE_MODAL'; +export const SHOW_SNACKBAR = 'SHOW_SNACKBAR'; +export const REMOVE_SNACKBAR_SNACK = 'REMOVE_SNACKBAR_SNACK'; +export const WINDOW_FOCUSED = 'WINDOW_FOCUSED'; +export const DAEMON_READY = 'DAEMON_READY'; +export const DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; +export const DAEMON_VERSION_MISMATCH = 'DAEMON_VERSION_MISMATCH'; +export const VOLUME_CHANGED = 'VOLUME_CHANGED'; // Navigation -export const CHANGE_AFTER_AUTH_PATH = "CHANGE_AFTER_AUTH_PATH"; -export const WINDOW_SCROLLED = "WINDOW_SCROLLED"; -export const HISTORY_NAVIGATE = "HISTORY_NAVIGATE"; +export const CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; +export const WINDOW_SCROLLED = 'WINDOW_SCROLLED'; +export const HISTORY_NAVIGATE = 'HISTORY_NAVIGATE'; // Upgrades -export const UPGRADE_CANCELLED = "UPGRADE_CANCELLED"; -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 CHECK_UPGRADE_AVAILABLE = "CHECK_UPGRADE_AVAILABLE"; -export const CHECK_UPGRADE_START = "CHECK_UPGRADE_START"; -export const CHECK_UPGRADE_SUCCESS = "CHECK_UPGRADE_SUCCESS"; -export const CHECK_UPGRADE_FAIL = "CHECK_UPGRADE_FAIL"; -export const CHECK_UPGRADE_SUBSCRIBE = "CHECK_UPGRADE_SUBSCRIBE"; -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 UPGRADE_CANCELLED = 'UPGRADE_CANCELLED'; +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 CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE'; +export const CHECK_UPGRADE_START = 'CHECK_UPGRADE_START'; +export const CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS'; +export const CHECK_UPGRADE_FAIL = 'CHECK_UPGRADE_FAIL'; +export const CHECK_UPGRADE_SUBSCRIBE = 'CHECK_UPGRADE_SUBSCRIBE'; +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'; // Wallet -export const GET_NEW_ADDRESS_STARTED = "GET_NEW_ADDRESS_STARTED"; -export const GET_NEW_ADDRESS_COMPLETED = "GET_NEW_ADDRESS_COMPLETED"; -export const FETCH_TRANSACTIONS_STARTED = "FETCH_TRANSACTIONS_STARTED"; -export const FETCH_TRANSACTIONS_COMPLETED = "FETCH_TRANSACTIONS_COMPLETED"; -export const UPDATE_BALANCE = "UPDATE_BALANCE"; -export const CHECK_ADDRESS_IS_MINE_STARTED = "CHECK_ADDRESS_IS_MINE_STARTED"; -export const CHECK_ADDRESS_IS_MINE_COMPLETED = - "CHECK_ADDRESS_IS_MINE_COMPLETED"; -export const SET_DRAFT_TRANSACTION_AMOUNT = "SET_DRAFT_TRANSACTION_AMOUNT"; -export const SET_DRAFT_TRANSACTION_ADDRESS = "SET_DRAFT_TRANSACTION_ADDRESS"; -export const SEND_TRANSACTION_STARTED = "SEND_TRANSACTION_STARTED"; -export const SEND_TRANSACTION_COMPLETED = "SEND_TRANSACTION_COMPLETED"; -export const SEND_TRANSACTION_FAILED = "SEND_TRANSACTION_FAILED"; -export const FETCH_BLOCK_SUCCESS = "FETCH_BLOCK_SUCCESS"; -export const SUPPORT_TRANSACTION_STARTED = "SUPPORT_TRANSACTION_STARTED"; -export const SUPPORT_TRANSACTION_COMPLETED = "SUPPORT_TRANSACTION_COMPLETED"; -export const SUPPORT_TRANSACTION_FAILED = "SUPPORT_TRANSACTION_FAILED"; +export const GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; +export const GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; +export const FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; +export const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; +export const UPDATE_BALANCE = 'UPDATE_BALANCE'; +export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; +export const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'; +export const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; +export const SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'; +export const SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'; +export const SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'; +export const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; +export const FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS'; +export const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; +export const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; +export const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; // Claims -export const FETCH_FEATURED_CONTENT_STARTED = "FETCH_FEATURED_CONTENT_STARTED"; -export const FETCH_FEATURED_CONTENT_COMPLETED = - "FETCH_FEATURED_CONTENT_COMPLETED"; -export const RESOLVE_URIS_STARTED = "RESOLVE_URIS_STARTED"; -export const RESOLVE_URIS_COMPLETED = "RESOLVE_URIS_COMPLETED"; -export const FETCH_CHANNEL_CLAIMS_STARTED = "FETCH_CHANNEL_CLAIMS_STARTED"; -export const FETCH_CHANNEL_CLAIMS_COMPLETED = "FETCH_CHANNEL_CLAIMS_COMPLETED"; -export const FETCH_CHANNEL_CLAIM_COUNT_STARTED = - "FETCH_CHANNEL_CLAIM_COUNT_STARTED"; -export const FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = - "FETCH_CHANNEL_CLAIM_COUNT_COMPLETED"; -export const FETCH_CLAIM_LIST_MINE_STARTED = "FETCH_CLAIM_LIST_MINE_STARTED"; -export const FETCH_CLAIM_LIST_MINE_COMPLETED = - "FETCH_CLAIM_LIST_MINE_COMPLETED"; -export const ABANDON_CLAIM_STARTED = "ABANDON_CLAIM_STARTED"; -export const ABANDON_CLAIM_SUCCEEDED = "ABANDON_CLAIM_SUCCEEDED"; -export const FETCH_CHANNEL_LIST_MINE_STARTED = - "FETCH_CHANNEL_LIST_MINE_STARTED"; -export const FETCH_CHANNEL_LIST_MINE_COMPLETED = - "FETCH_CHANNEL_LIST_MINE_COMPLETED"; -export const CREATE_CHANNEL_STARTED = "CREATE_CHANNEL_STARTED"; -export const CREATE_CHANNEL_COMPLETED = "CREATE_CHANNEL_COMPLETED"; -export const PUBLISH_STARTED = "PUBLISH_STARTED"; -export const PUBLISH_COMPLETED = "PUBLISH_COMPLETED"; -export const PUBLISH_FAILED = "PUBLISH_FAILED"; -export const SET_PLAYING_URI = "PLAY_URI"; +export const FETCH_FEATURED_CONTENT_STARTED = 'FETCH_FEATURED_CONTENT_STARTED'; +export const FETCH_FEATURED_CONTENT_COMPLETED = 'FETCH_FEATURED_CONTENT_COMPLETED'; +export const RESOLVE_URIS_STARTED = 'RESOLVE_URIS_STARTED'; +export const RESOLVE_URIS_COMPLETED = 'RESOLVE_URIS_COMPLETED'; +export const FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'; +export const FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'; +export const FETCH_CHANNEL_CLAIM_COUNT_STARTED = 'FETCH_CHANNEL_CLAIM_COUNT_STARTED'; +export const FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = 'FETCH_CHANNEL_CLAIM_COUNT_COMPLETED'; +export const FETCH_CLAIM_LIST_MINE_STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED'; +export const FETCH_CLAIM_LIST_MINE_COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED'; +export const ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED'; +export const ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED'; +export const FETCH_CHANNEL_LIST_MINE_STARTED = 'FETCH_CHANNEL_LIST_MINE_STARTED'; +export const FETCH_CHANNEL_LIST_MINE_COMPLETED = 'FETCH_CHANNEL_LIST_MINE_COMPLETED'; +export const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; +export const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; +export const PUBLISH_STARTED = 'PUBLISH_STARTED'; +export const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; +export const PUBLISH_FAILED = 'PUBLISH_FAILED'; +export const SET_PLAYING_URI = 'PLAY_URI'; // Files -export const FILE_LIST_STARTED = "FILE_LIST_STARTED"; -export const FILE_LIST_SUCCEEDED = "FILE_LIST_SUCCEEDED"; -export const FETCH_FILE_INFO_STARTED = "FETCH_FILE_INFO_STARTED"; -export const FETCH_FILE_INFO_COMPLETED = "FETCH_FILE_INFO_COMPLETED"; -export const FETCH_COST_INFO_STARTED = "FETCH_COST_INFO_STARTED"; -export const FETCH_COST_INFO_COMPLETED = "FETCH_COST_INFO_COMPLETED"; -export const LOADING_VIDEO_STARTED = "LOADING_VIDEO_STARTED"; -export const LOADING_VIDEO_COMPLETED = "LOADING_VIDEO_COMPLETED"; -export const LOADING_VIDEO_FAILED = "LOADING_VIDEO_FAILED"; -export const DOWNLOADING_STARTED = "DOWNLOADING_STARTED"; -export const DOWNLOADING_PROGRESSED = "DOWNLOADING_PROGRESSED"; -export const DOWNLOADING_COMPLETED = "DOWNLOADING_COMPLETED"; -export const PLAY_VIDEO_STARTED = "PLAY_VIDEO_STARTED"; -export const FETCH_AVAILABILITY_STARTED = "FETCH_AVAILABILITY_STARTED"; -export const FETCH_AVAILABILITY_COMPLETED = "FETCH_AVAILABILITY_COMPLETED"; -export const FILE_DELETE = "FILE_DELETE"; +export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; +export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; +export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; +export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'; +export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; +export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; +export const LOADING_VIDEO_STARTED = 'LOADING_VIDEO_STARTED'; +export const LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; +export const LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; +export const DOWNLOADING_STARTED = 'DOWNLOADING_STARTED'; +export const DOWNLOADING_PROGRESSED = 'DOWNLOADING_PROGRESSED'; +export const DOWNLOADING_COMPLETED = 'DOWNLOADING_COMPLETED'; +export const PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED'; +export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; +export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; +export const FILE_DELETE = 'FILE_DELETE'; // Search -export const SEARCH_STARTED = "SEARCH_STARTED"; -export const SEARCH_COMPLETED = "SEARCH_COMPLETED"; -export const SEARCH_CANCELLED = "SEARCH_CANCELLED"; +export const SEARCH_STARTED = 'SEARCH_STARTED'; +export const SEARCH_COMPLETED = 'SEARCH_COMPLETED'; +export const SEARCH_CANCELLED = 'SEARCH_CANCELLED'; // Settings -export const DAEMON_SETTINGS_RECEIVED = "DAEMON_SETTINGS_RECEIVED"; -export const CLIENT_SETTING_CHANGED = "CLIENT_SETTING_CHANGED"; +export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; +export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; // User -export const AUTHENTICATION_STARTED = "AUTHENTICATION_STARTED"; -export const AUTHENTICATION_SUCCESS = "AUTHENTICATION_SUCCESS"; -export const AUTHENTICATION_FAILURE = "AUTHENTICATION_FAILURE"; -export const USER_EMAIL_DECLINE = "USER_EMAIL_DECLINE"; -export const USER_EMAIL_NEW_STARTED = "USER_EMAIL_NEW_STARTED"; -export const USER_EMAIL_NEW_SUCCESS = "USER_EMAIL_NEW_SUCCESS"; -export const USER_EMAIL_NEW_EXISTS = "USER_EMAIL_NEW_EXISTS"; -export const USER_EMAIL_NEW_FAILURE = "USER_EMAIL_NEW_FAILURE"; -export const USER_EMAIL_VERIFY_STARTED = "USER_EMAIL_VERIFY_STARTED"; -export const USER_EMAIL_VERIFY_SUCCESS = "USER_EMAIL_VERIFY_SUCCESS"; -export const USER_EMAIL_VERIFY_FAILURE = "USER_EMAIL_VERIFY_FAILURE"; -export const USER_IDENTITY_VERIFY_STARTED = "USER_IDENTITY_VERIFY_STARTED"; -export const USER_IDENTITY_VERIFY_SUCCESS = "USER_IDENTITY_VERIFY_SUCCESS"; -export const USER_IDENTITY_VERIFY_FAILURE = "USER_IDENTITY_VERIFY_FAILURE"; -export const USER_FETCH_STARTED = "USER_FETCH_STARTED"; -export const USER_FETCH_SUCCESS = "USER_FETCH_SUCCESS"; -export const USER_FETCH_FAILURE = "USER_FETCH_FAILURE"; -export const USER_INVITE_STATUS_FETCH_STARTED = - "USER_INVITE_STATUS_FETCH_STARTED"; -export const USER_INVITE_STATUS_FETCH_SUCCESS = - "USER_INVITE_STATUS_FETCH_SUCCESS"; -export const USER_INVITE_STATUS_FETCH_FAILURE = - "USER_INVITE_STATUS_FETCH_FAILURE"; -export const USER_INVITE_NEW_STARTED = "USER_INVITE_NEW_STARTED"; -export const USER_INVITE_NEW_SUCCESS = "USER_INVITE_NEW_SUCCESS"; -export const USER_INVITE_NEW_FAILURE = "USER_INVITE_NEW_FAILURE"; -export const FETCH_ACCESS_TOKEN_SUCCESS = "FETCH_ACCESS_TOKEN_SUCCESS"; +export const AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED'; +export const AUTHENTICATION_SUCCESS = 'AUTHENTICATION_SUCCESS'; +export const AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE'; +export const USER_EMAIL_DECLINE = 'USER_EMAIL_DECLINE'; +export const USER_EMAIL_NEW_STARTED = 'USER_EMAIL_NEW_STARTED'; +export const USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'; +export const USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'; +export const USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'; +export const USER_EMAIL_VERIFY_STARTED = 'USER_EMAIL_VERIFY_STARTED'; +export const USER_EMAIL_VERIFY_SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS'; +export const USER_EMAIL_VERIFY_FAILURE = 'USER_EMAIL_VERIFY_FAILURE'; +export const USER_IDENTITY_VERIFY_STARTED = 'USER_IDENTITY_VERIFY_STARTED'; +export const USER_IDENTITY_VERIFY_SUCCESS = 'USER_IDENTITY_VERIFY_SUCCESS'; +export const USER_IDENTITY_VERIFY_FAILURE = 'USER_IDENTITY_VERIFY_FAILURE'; +export const USER_FETCH_STARTED = 'USER_FETCH_STARTED'; +export const USER_FETCH_SUCCESS = 'USER_FETCH_SUCCESS'; +export const USER_FETCH_FAILURE = 'USER_FETCH_FAILURE'; +export const USER_INVITE_STATUS_FETCH_STARTED = 'USER_INVITE_STATUS_FETCH_STARTED'; +export const USER_INVITE_STATUS_FETCH_SUCCESS = 'USER_INVITE_STATUS_FETCH_SUCCESS'; +export const USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE'; +export const USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; +export const USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; +export const USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; +export const FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; // Rewards -export const FETCH_REWARDS_STARTED = "FETCH_REWARDS_STARTED"; -export const FETCH_REWARDS_COMPLETED = "FETCH_REWARDS_COMPLETED"; -export const CLAIM_REWARD_STARTED = "CLAIM_REWARD_STARTED"; -export const CLAIM_REWARD_SUCCESS = "CLAIM_REWARD_SUCCESS"; -export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE"; -export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR"; -export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED"; +export const FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'; +export const FETCH_REWARDS_COMPLETED = 'FETCH_REWARDS_COMPLETED'; +export const CLAIM_REWARD_STARTED = 'CLAIM_REWARD_STARTED'; +export const CLAIM_REWARD_SUCCESS = 'CLAIM_REWARD_SUCCESS'; +export const CLAIM_REWARD_FAILURE = 'CLAIM_REWARD_FAILURE'; +export const CLAIM_REWARD_CLEAR_ERROR = 'CLAIM_REWARD_CLEAR_ERROR'; +export const FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED'; // Language -export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED"; -export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED"; +export const DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED'; +export const DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED'; // ShapeShift -export const GET_SUPPORTED_COINS_START = "GET_SUPPORTED_COINS_START"; -export const GET_SUPPORTED_COINS_SUCCESS = "GET_SUPPORTED_COINS_SUCCESS"; -export const GET_SUPPORTED_COINS_FAIL = "GET_SUPPORTED_COINS_FAIL"; -export const GET_COIN_STATS_START = "GET_COIN_STATS_START"; -export const GET_COIN_STATS_SUCCESS = "GET_COIN_STATS_SUCCESS"; -export const GET_COIN_STATS_FAIL = "GET_COIN_STATS_FAIL"; -export const PREPARE_SHAPE_SHIFT_START = "PREPARE_SHAPE_SHIFT_START"; -export const PREPARE_SHAPE_SHIFT_SUCCESS = "PREPARE_SHAPE_SHIFT_SUCCESS"; -export const PREPARE_SHAPE_SHIFT_FAIL = "PREPARE_SHAPE_SHIFT_FAIL"; -export const GET_ACTIVE_SHIFT_START = "GET_ACTIVE_SHIFT_START"; -export const GET_ACTIVE_SHIFT_SUCCESS = "GET_ACTIVE_SHIFT_SUCCESS"; -export const GET_ACTIVE_SHIFT_FAIL = "GET_ACTIVE_SHIFT_FAIL"; -export const CLEAR_SHAPE_SHIFT = "CLEAR_SHAPE_SHIFT"; +export const GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START'; +export const GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS'; +export const GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL'; +export const GET_COIN_STATS_START = 'GET_COIN_STATS_START'; +export const GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS'; +export const GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL'; +export const PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START'; +export const PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS'; +export const PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL'; +export const GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START'; +export const GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS'; +export const GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL'; +export const CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; // Subscriptions -export const CHANNEL_SUBSCRIBE = "CHANNEL_SUBSCRIBE"; -export const CHANNEL_UNSUBSCRIBE = "CHANNEL_UNSUBSCRIBE"; -export const HAS_FETCHED_SUBSCRIPTIONS = "HAS_FETCHED_SUBSCRIPTIONS"; +export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; +export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; +export const HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS'; diff --git a/src/renderer/constants/icons.js b/src/renderer/constants/icons.js index d28d7591e..728a8f196 100644 --- a/src/renderer/constants/icons.js +++ b/src/renderer/constants/icons.js @@ -1,5 +1,5 @@ -export const FEATURED = "rocket"; -export const LOCAL = "folder"; -export const FILE = "file"; -export const HISTORY = "history"; -export const HELP_CIRCLE = "question-circle"; +export const FEATURED = 'rocket'; +export const LOCAL = 'folder'; +export const FILE = 'file'; +export const HISTORY = 'history'; +export const HELP_CIRCLE = 'question-circle'; diff --git a/src/renderer/constants/languages.js b/src/renderer/constants/languages.js index f1879e904..8ae7c12cc 100644 --- a/src/renderer/constants/languages.js +++ b/src/renderer/constants/languages.js @@ -1,187 +1,187 @@ const LANGUAGES = { - aa: ["Afar", "Afar"], - ab: ["Abkhazian", "Аҧсуа"], - af: ["Afrikaans", "Afrikaans"], - ak: ["Akan", "Akana"], - am: ["Amharic", "አማርኛ"], - an: ["Aragonese", "Aragonés"], - ar: ["Arabic", "العربية"], - as: ["Assamese", "অসমীয়া"], - av: ["Avar", "Авар"], - ay: ["Aymara", "Aymar"], - az: ["Azerbaijani", "Azərbaycanca / آذربايجان"], - ba: ["Bashkir", "Башҡорт"], - be: ["Belarusian", "Беларуская"], - bg: ["Bulgarian", "Български"], - bh: ["Bihari", "भोजपुरी"], - bi: ["Bislama", "Bislama"], - bm: ["Bambara", "Bamanankan"], - bn: ["Bengali", "বাংলা"], - bo: ["Tibetan", "བོད་ཡིག / Bod skad"], - br: ["Breton", "Brezhoneg"], - bs: ["Bosnian", "Bosanski"], - ca: ["Catalan", "Català"], - ce: ["Chechen", "Нохчийн"], - ch: ["Chamorro", "Chamoru"], - co: ["Corsican", "Corsu"], - cr: ["Cree", "Nehiyaw"], - cs: ["Czech", "Česky"], - cu: ["Old Church Slavonic / Old Bulgarian", "словѣньскъ / slověnĭskŭ"], - cv: ["Chuvash", "Чăваш"], - cy: ["Welsh", "Cymraeg"], - da: ["Danish", "Dansk"], - de: ["German", "Deutsch"], - dv: ["Divehi", "ދިވެހިބަސް"], - dz: ["Dzongkha", "ཇོང་ཁ"], - ee: ["Ewe", "Ɛʋɛ"], - el: ["Greek", "Ελληνικά"], - en: ["English", "English"], - eo: ["Esperanto", "Esperanto"], - es: ["Spanish", "Español"], - et: ["Estonian", "Eesti"], - eu: ["Basque", "Euskara"], - fa: ["Persian", "فارسی"], - ff: ["Peul", "Fulfulde"], - fi: ["Finnish", "Suomi"], - fj: ["Fijian", "Na Vosa Vakaviti"], - fo: ["Faroese", "Føroyskt"], - fr: ["French", "Français"], - fy: ["West Frisian", "Frysk"], - ga: ["Irish", "Gaeilge"], - gd: ["Scottish Gaelic", "Gàidhlig"], - gl: ["Galician", "Galego"], - gn: ["Guarani", "Avañe'ẽ"], - gu: ["Gujarati", "ગુજરાતી"], - gv: ["Manx", "Gaelg"], - ha: ["Hausa", "هَوُسَ"], - he: ["Hebrew", "עברית"], - hi: ["Hindi", "हिन्दी"], - ho: ["Hiri Motu", "Hiri Motu"], - hr: ["Croatian", "Hrvatski"], - ht: ["Haitian", "Krèyol ayisyen"], - hu: ["Hungarian", "Magyar"], - hy: ["Armenian", "Հայերեն"], - hz: ["Herero", "Otsiherero"], - ia: ["Interlingua", "Interlingua"], - id: ["Indonesian", "Bahasa Indonesia"], - ie: ["Interlingue", "Interlingue"], - ig: ["Igbo", "Igbo"], - ii: ["Sichuan Yi", "ꆇꉙ / 四川彝语"], - ik: ["Inupiak", "Iñupiak"], - io: ["Ido", "Ido"], - is: ["Icelandic", "Íslenska"], - it: ["Italian", "Italiano"], - iu: ["Inuktitut", "ᐃᓄᒃᑎᑐᑦ"], - ja: ["Japanese", "日本語"], - jv: ["Javanese", "Basa Jawa"], - ka: ["Georgian", "ქართული"], - kg: ["Kongo", "KiKongo"], - ki: ["Kikuyu", "Gĩkũyũ"], - kj: ["Kuanyama", "Kuanyama"], - kk: ["Kazakh", "Қазақша"], - kl: ["Greenlandic", "Kalaallisut"], - km: ["Cambodian", "ភាសាខ្មែរ"], - kn: ["Kannada", "ಕನ್ನಡ"], - ko: ["Korean", "한국어"], - kr: ["Kanuri", "Kanuri"], - ks: ["Kashmiri", "कश्मीरी / كشميري"], - ku: ["Kurdish", "Kurdî / كوردی"], - kv: ["Komi", "Коми"], - kw: ["Cornish", "Kernewek"], - ky: ["Kirghiz", "Kırgızca / Кыргызча"], - la: ["Latin", "Latina"], - lb: ["Luxembourgish", "Lëtzebuergesch"], - lg: ["Ganda", "Luganda"], - li: ["Limburgian", "Limburgs"], - ln: ["Lingala", "Lingála"], - lo: ["Laotian", "ລາວ / Pha xa lao"], - lt: ["Lithuanian", "Lietuvių"], - lv: ["Latvian", "Latviešu"], - mg: ["Malagasy", "Malagasy"], - mh: ["Marshallese", "Kajin Majel / Ebon"], - mi: ["Maori", "Māori"], - mk: ["Macedonian", "Македонски"], - ml: ["Malayalam", "മലയാളം"], - mn: ["Mongolian", "Монгол"], - mo: ["Moldovan", "Moldovenească"], - mr: ["Marathi", "मराठी"], - ms: ["Malay", "Bahasa Melayu"], - mt: ["Maltese", "bil-Malti"], - my: ["Burmese", "Myanmasa"], - na: ["Nauruan", "Dorerin Naoero"], - nd: ["North Ndebele", "Sindebele"], - ne: ["Nepali", "नेपाली"], - ng: ["Ndonga", "Oshiwambo"], - nl: ["Dutch", "Nederlands"], - nn: ["Norwegian Nynorsk", "Norsk (nynorsk)"], - no: ["Norwegian", "Norsk (bokmål / riksmål)"], - nr: ["South Ndebele", "isiNdebele"], - nv: ["Navajo", "Diné bizaad"], - ny: ["Chichewa", "Chi-Chewa"], - oc: ["Occitan", "Occitan"], - oj: ["Ojibwa", "ᐊᓂᔑᓈᐯᒧᐎᓐ / Anishinaabemowin"], - om: ["Oromo", "Oromoo"], - or: ["Oriya", "ଓଡ଼ିଆ"], - os: ["Ossetian / Ossetic", "Иронау"], - pa: ["Panjabi / Punjabi", "ਪੰਜਾਬੀ / पंजाबी / پنجابي"], - pi: ["Pali", "Pāli / पाऴि"], - pl: ["Polish", "Polski"], - ps: ["Pashto", "پښتو"], - pt: ["Portuguese", "Português"], - qu: ["Quechua", "Runa Simi"], - rm: ["Raeto Romance", "Rumantsch"], - rn: ["Kirundi", "Kirundi"], - ro: ["Romanian", "Română"], - ru: ["Russian", "Русский"], - rw: ["Rwandi", "Kinyarwandi"], - sa: ["Sanskrit", "संस्कृतम्"], - sc: ["Sardinian", "Sardu"], - sd: ["Sindhi", "सिनधि"], - se: ["Northern Sami", "Sámegiella"], - sg: ["Sango", "Sängö"], - sh: ["Serbo-Croatian", "Srpskohrvatski / Српскохрватски"], - si: ["Sinhalese", "සිංහල"], - sk: ["Slovak", "Slovenčina"], - sl: ["Slovenian", "Slovenščina"], - sm: ["Samoan", "Gagana Samoa"], - sn: ["Shona", "chiShona"], - so: ["Somalia", "Soomaaliga"], - sq: ["Albanian", "Shqip"], - sr: ["Serbian", "Српски"], - ss: ["Swati", "SiSwati"], - st: ["Southern Sotho", "Sesotho"], - su: ["Sundanese", "Basa Sunda"], - sv: ["Swedish", "Svenska"], - sw: ["Swahili", "Kiswahili"], - ta: ["Tamil", "தமிழ்"], - te: ["Telugu", "తెలుగు"], - tg: ["Tajik", "Тоҷикӣ"], - th: ["Thai", "ไทย / Phasa Thai"], - ti: ["Tigrinya", "ትግርኛ"], - tk: ["Turkmen", "Туркмен / تركمن"], - tl: ["Tagalog / Filipino", "Tagalog"], - tn: ["Tswana", "Setswana"], - to: ["Tonga", "Lea Faka-Tonga"], - tr: ["Turkish", "Türkçe"], - ts: ["Tsonga", "Xitsonga"], - tt: ["Tatar", "Tatarça"], - tw: ["Twi", "Twi"], - ty: ["Tahitian", "Reo Mā`ohi"], - ug: ["Uyghur", "Uyƣurqə / ئۇيغۇرچە"], - uk: ["Ukrainian", "Українська"], - ur: ["Urdu", "اردو"], - uz: ["Uzbek", "Ўзбек"], - ve: ["Venda", "Tshivenḓa"], - vi: ["Vietnamese", "Tiếng Việt"], - vo: ["Volapük", "Volapük"], - wa: ["Walloon", "Walon"], - wo: ["Wolof", "Wollof"], - xh: ["Xhosa", "isiXhosa"], - yi: ["Yiddish", "ייִדיש"], - yo: ["Yoruba", "Yorùbá"], - za: ["Zhuang", "Cuengh / Tôô / 壮语"], - zh: ["Chinese", "中文"], - zu: ["Zulu", "isiZulu"], + aa: ['Afar', 'Afar'], + ab: ['Abkhazian', 'Аҧсуа'], + af: ['Afrikaans', 'Afrikaans'], + ak: ['Akan', 'Akana'], + am: ['Amharic', 'አማርኛ'], + an: ['Aragonese', 'Aragonés'], + ar: ['Arabic', 'العربية'], + as: ['Assamese', 'অসমীয়া'], + av: ['Avar', 'Авар'], + ay: ['Aymara', 'Aymar'], + az: ['Azerbaijani', 'Azərbaycanca / آذربايجان'], + ba: ['Bashkir', 'Башҡорт'], + be: ['Belarusian', 'Беларуская'], + bg: ['Bulgarian', 'Български'], + bh: ['Bihari', 'भोजपुरी'], + bi: ['Bislama', 'Bislama'], + bm: ['Bambara', 'Bamanankan'], + bn: ['Bengali', 'বাংলা'], + bo: ['Tibetan', 'བོད་ཡིག / Bod skad'], + br: ['Breton', 'Brezhoneg'], + bs: ['Bosnian', 'Bosanski'], + ca: ['Catalan', 'Català'], + ce: ['Chechen', 'Нохчийн'], + ch: ['Chamorro', 'Chamoru'], + co: ['Corsican', 'Corsu'], + cr: ['Cree', 'Nehiyaw'], + cs: ['Czech', 'Česky'], + cu: ['Old Church Slavonic / Old Bulgarian', 'словѣньскъ / slověnĭskŭ'], + cv: ['Chuvash', 'Чăваш'], + cy: ['Welsh', 'Cymraeg'], + da: ['Danish', 'Dansk'], + de: ['German', 'Deutsch'], + dv: ['Divehi', 'ދިވެހިބަސް'], + dz: ['Dzongkha', 'ཇོང་ཁ'], + ee: ['Ewe', 'Ɛʋɛ'], + el: ['Greek', 'Ελληνικά'], + en: ['English', 'English'], + eo: ['Esperanto', 'Esperanto'], + es: ['Spanish', 'Español'], + et: ['Estonian', 'Eesti'], + eu: ['Basque', 'Euskara'], + fa: ['Persian', 'فارسی'], + ff: ['Peul', 'Fulfulde'], + fi: ['Finnish', 'Suomi'], + fj: ['Fijian', 'Na Vosa Vakaviti'], + fo: ['Faroese', 'Føroyskt'], + fr: ['French', 'Français'], + fy: ['West Frisian', 'Frysk'], + ga: ['Irish', 'Gaeilge'], + gd: ['Scottish Gaelic', 'Gàidhlig'], + gl: ['Galician', 'Galego'], + gn: ['Guarani', "Avañe'ẽ"], + gu: ['Gujarati', 'ગુજરાતી'], + gv: ['Manx', 'Gaelg'], + ha: ['Hausa', 'هَوُسَ'], + he: ['Hebrew', 'עברית'], + hi: ['Hindi', 'हिन्दी'], + ho: ['Hiri Motu', 'Hiri Motu'], + hr: ['Croatian', 'Hrvatski'], + ht: ['Haitian', 'Krèyol ayisyen'], + hu: ['Hungarian', 'Magyar'], + hy: ['Armenian', 'Հայերեն'], + hz: ['Herero', 'Otsiherero'], + ia: ['Interlingua', 'Interlingua'], + id: ['Indonesian', 'Bahasa Indonesia'], + ie: ['Interlingue', 'Interlingue'], + ig: ['Igbo', 'Igbo'], + ii: ['Sichuan Yi', 'ꆇꉙ / 四川彝语'], + ik: ['Inupiak', 'Iñupiak'], + io: ['Ido', 'Ido'], + is: ['Icelandic', 'Íslenska'], + it: ['Italian', 'Italiano'], + iu: ['Inuktitut', 'ᐃᓄᒃᑎᑐᑦ'], + ja: ['Japanese', '日本語'], + jv: ['Javanese', 'Basa Jawa'], + ka: ['Georgian', 'ქართული'], + kg: ['Kongo', 'KiKongo'], + ki: ['Kikuyu', 'Gĩkũyũ'], + kj: ['Kuanyama', 'Kuanyama'], + kk: ['Kazakh', 'Қазақша'], + kl: ['Greenlandic', 'Kalaallisut'], + km: ['Cambodian', 'ភាសាខ្មែរ'], + kn: ['Kannada', 'ಕನ್ನಡ'], + ko: ['Korean', '한국어'], + kr: ['Kanuri', 'Kanuri'], + ks: ['Kashmiri', 'कश्मीरी / كشميري'], + ku: ['Kurdish', 'Kurdî / كوردی'], + kv: ['Komi', 'Коми'], + kw: ['Cornish', 'Kernewek'], + ky: ['Kirghiz', 'Kırgızca / Кыргызча'], + la: ['Latin', 'Latina'], + lb: ['Luxembourgish', 'Lëtzebuergesch'], + lg: ['Ganda', 'Luganda'], + li: ['Limburgian', 'Limburgs'], + ln: ['Lingala', 'Lingála'], + lo: ['Laotian', 'ລາວ / Pha xa lao'], + lt: ['Lithuanian', 'Lietuvių'], + lv: ['Latvian', 'Latviešu'], + mg: ['Malagasy', 'Malagasy'], + mh: ['Marshallese', 'Kajin Majel / Ebon'], + mi: ['Maori', 'Māori'], + mk: ['Macedonian', 'Македонски'], + ml: ['Malayalam', 'മലയാളം'], + mn: ['Mongolian', 'Монгол'], + mo: ['Moldovan', 'Moldovenească'], + mr: ['Marathi', 'मराठी'], + ms: ['Malay', 'Bahasa Melayu'], + mt: ['Maltese', 'bil-Malti'], + my: ['Burmese', 'Myanmasa'], + na: ['Nauruan', 'Dorerin Naoero'], + nd: ['North Ndebele', 'Sindebele'], + ne: ['Nepali', 'नेपाली'], + ng: ['Ndonga', 'Oshiwambo'], + nl: ['Dutch', 'Nederlands'], + nn: ['Norwegian Nynorsk', 'Norsk (nynorsk)'], + no: ['Norwegian', 'Norsk (bokmål / riksmål)'], + nr: ['South Ndebele', 'isiNdebele'], + nv: ['Navajo', 'Diné bizaad'], + ny: ['Chichewa', 'Chi-Chewa'], + oc: ['Occitan', 'Occitan'], + oj: ['Ojibwa', 'ᐊᓂᔑᓈᐯᒧᐎᓐ / Anishinaabemowin'], + om: ['Oromo', 'Oromoo'], + or: ['Oriya', 'ଓଡ଼ିଆ'], + os: ['Ossetian / Ossetic', 'Иронау'], + pa: ['Panjabi / Punjabi', 'ਪੰਜਾਬੀ / पंजाबी / پنجابي'], + pi: ['Pali', 'Pāli / पाऴि'], + pl: ['Polish', 'Polski'], + ps: ['Pashto', 'پښتو'], + pt: ['Portuguese', 'Português'], + qu: ['Quechua', 'Runa Simi'], + rm: ['Raeto Romance', 'Rumantsch'], + rn: ['Kirundi', 'Kirundi'], + ro: ['Romanian', 'Română'], + ru: ['Russian', 'Русский'], + rw: ['Rwandi', 'Kinyarwandi'], + sa: ['Sanskrit', 'संस्कृतम्'], + sc: ['Sardinian', 'Sardu'], + sd: ['Sindhi', 'सिनधि'], + se: ['Northern Sami', 'Sámegiella'], + sg: ['Sango', 'Sängö'], + sh: ['Serbo-Croatian', 'Srpskohrvatski / Српскохрватски'], + si: ['Sinhalese', 'සිංහල'], + sk: ['Slovak', 'Slovenčina'], + sl: ['Slovenian', 'Slovenščina'], + sm: ['Samoan', 'Gagana Samoa'], + sn: ['Shona', 'chiShona'], + so: ['Somalia', 'Soomaaliga'], + sq: ['Albanian', 'Shqip'], + sr: ['Serbian', 'Српски'], + ss: ['Swati', 'SiSwati'], + st: ['Southern Sotho', 'Sesotho'], + su: ['Sundanese', 'Basa Sunda'], + sv: ['Swedish', 'Svenska'], + sw: ['Swahili', 'Kiswahili'], + ta: ['Tamil', 'தமிழ்'], + te: ['Telugu', 'తెలుగు'], + tg: ['Tajik', 'Тоҷикӣ'], + th: ['Thai', 'ไทย / Phasa Thai'], + ti: ['Tigrinya', 'ትግርኛ'], + tk: ['Turkmen', 'Туркмен / تركمن'], + tl: ['Tagalog / Filipino', 'Tagalog'], + tn: ['Tswana', 'Setswana'], + to: ['Tonga', 'Lea Faka-Tonga'], + tr: ['Turkish', 'Türkçe'], + ts: ['Tsonga', 'Xitsonga'], + tt: ['Tatar', 'Tatarça'], + tw: ['Twi', 'Twi'], + ty: ['Tahitian', 'Reo Mā`ohi'], + ug: ['Uyghur', 'Uyƣurqə / ئۇيغۇرچە'], + uk: ['Ukrainian', 'Українська'], + ur: ['Urdu', 'اردو'], + uz: ['Uzbek', 'Ўзбек'], + ve: ['Venda', 'Tshivenḓa'], + vi: ['Vietnamese', 'Tiếng Việt'], + vo: ['Volapük', 'Volapük'], + wa: ['Walloon', 'Walon'], + wo: ['Wolof', 'Wollof'], + xh: ['Xhosa', 'isiXhosa'], + yi: ['Yiddish', 'ייִדיש'], + yo: ['Yoruba', 'Yorùbá'], + za: ['Zhuang', 'Cuengh / Tôô / 壮语'], + zh: ['Chinese', '中文'], + zu: ['Zulu', 'isiZulu'], }; export default LANGUAGES; diff --git a/src/renderer/constants/modal_types.js b/src/renderer/constants/modal_types.js index 3781ca220..9c6d457f9 100644 --- a/src/renderer/constants/modal_types.js +++ b/src/renderer/constants/modal_types.js @@ -1,15 +1,15 @@ -export const CONFIRM_FILE_REMOVE = "confirmFileRemove"; -export const INCOMPATIBLE_DAEMON = "incompatibleDaemon"; -export const FILE_TIMEOUT = "file_timeout"; -export const DOWNLOADING = "downloading"; -export const ERROR = "error"; -export const INSUFFICIENT_CREDITS = "insufficient_credits"; -export const UPGRADE = "upgrade"; -export const WELCOME = "welcome"; -export const EMAIL_COLLECTION = "email_collection"; -export const FIRST_REWARD = "first_reward"; -export const AUTHENTICATION_FAILURE = "auth_failure"; -export const TRANSACTION_FAILED = "transaction_failed"; -export const REWARD_APPROVAL_REQUIRED = "reward_approval_required"; -export const AFFIRM_PURCHASE = "affirm_purchase"; -export const CONFIRM_CLAIM_REVOKE = "confirmClaimRevoke"; +export const CONFIRM_FILE_REMOVE = 'confirmFileRemove'; +export const INCOMPATIBLE_DAEMON = 'incompatibleDaemon'; +export const FILE_TIMEOUT = 'file_timeout'; +export const DOWNLOADING = 'downloading'; +export const ERROR = 'error'; +export const INSUFFICIENT_CREDITS = 'insufficient_credits'; +export const UPGRADE = 'upgrade'; +export const WELCOME = 'welcome'; +export const EMAIL_COLLECTION = 'email_collection'; +export const FIRST_REWARD = 'first_reward'; +export const AUTHENTICATION_FAILURE = 'auth_failure'; +export const TRANSACTION_FAILED = 'transaction_failed'; +export const REWARD_APPROVAL_REQUIRED = 'reward_approval_required'; +export const AFFIRM_PURCHASE = 'affirm_purchase'; +export const CONFIRM_CLAIM_REVOKE = 'confirmClaimRevoke'; diff --git a/src/renderer/constants/settings.js b/src/renderer/constants/settings.js index e8db70e32..dcb90ab07 100644 --- a/src/renderer/constants/settings.js +++ b/src/renderer/constants/settings.js @@ -1,13 +1,13 @@ /* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ -/* Many settings are stored in the localStorage by their name - - be careful about changing the value of a settings constant, as doing so can invalidate existing settings */ -export const CREDIT_REQUIRED_ACKNOWLEDGED = "credit_required_acknowledged"; -export const NEW_USER_ACKNOWLEDGED = "welcome_acknowledged"; -export const EMAIL_COLLECTION_ACKNOWLEDGED = "email_collection_acknowledged"; -export const LANGUAGE = "language"; -export const SHOW_NSFW = "showNsfw"; -export const SHOW_UNAVAILABLE = "showUnavailable"; -export const INSTANT_PURCHASE_ENABLED = "instantPurchaseEnabled"; -export const INSTANT_PURCHASE_MAX = "instantPurchaseMax"; -export const THEME = "theme"; -export const THEMES = "themes"; +/* Many SETTINGS are stored in the localStorage by their name - + be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ +export const CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; +export const NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; +export const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; +export const LANGUAGE = 'language'; +export const SHOW_NSFW = 'showNsfw'; +export const SHOW_UNAVAILABLE = 'showUnavailable'; +export const INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; +export const INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; +export const THEME = 'theme'; +export const THEMES = 'themes'; diff --git a/src/renderer/constants/shape_shift.js b/src/renderer/constants/shape_shift.js index d898f2fc2..1436f50d0 100644 --- a/src/renderer/constants/shape_shift.js +++ b/src/renderer/constants/shape_shift.js @@ -1,3 +1,3 @@ -export const NO_DEPOSITS = "no_deposits"; -export const RECEIVED = "received"; -export const COMPLETE = "complete"; +export const NO_DEPOSITS = 'no_deposits'; +export const RECEIVED = 'received'; +export const COMPLETE = 'complete'; diff --git a/src/renderer/constants/transaction_types.js b/src/renderer/constants/transaction_types.js index 89530f9f0..c12b68c15 100644 --- a/src/renderer/constants/transaction_types.js +++ b/src/renderer/constants/transaction_types.js @@ -1 +1,2 @@ -export const TIP = "tip"; +// eslint-disable-next-line import/prefer-default-export +export const TIP = 'tip'; diff --git a/src/renderer/flow-typed/reselect.js b/src/renderer/flow-typed/reselect.js index 9ee4a6a7f..487f653c5 100644 --- a/src/renderer/flow-typed/reselect.js +++ b/src/renderer/flow-typed/reselect.js @@ -1,3 +1,5 @@ +// @flow + declare module 'reselect' { declare module.exports: any; } diff --git a/src/renderer/index.js b/src/renderer/index.js index 66d5784e8..2506ed051 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -1,87 +1,71 @@ -import React from "react"; -import ReactDOM from "react-dom"; -import App from "component/app/index.js"; -import SnackBar from "component/snackBar"; -import { Provider } from "react-redux"; -import store from "store.js"; -import SplashScreen from "component/splash"; -import { doDaemonReady } from "redux/actions/app"; -import { doNavigate } from "redux/actions/navigation"; -import { doDownloadLanguages } from "redux/actions/settings"; -import * as types from "constants/action_types"; -import amplitude from "amplitude-js"; -import lbry from "lbry"; -import "scss/all.scss"; +/* eslint-disable react/jsx-filename-extension */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from 'component/app'; +import SnackBar from 'component/snackBar'; +import { Provider } from 'react-redux'; +import store from 'store'; +import SplashScreen from 'component/splash'; +import { doDaemonReady } from 'redux/actions/app'; +import { doNavigate } from 'redux/actions/navigation'; +import { doDownloadLanguages } from 'redux/actions/settings'; +import * as ACTIONS from 'constants/action_types'; +import amplitude from 'amplitude-js'; +import lbry from 'lbry'; +import 'scss/all.scss'; +import { ipcRenderer, remote, shell } from 'electron'; -const env = process.env.NODE_ENV || "production"; -const { remote, ipcRenderer, shell } = require("electron"); +const { contextMenu } = remote.require('./main.js'); -const contextMenu = remote.require("./main.js").contextMenu; -const app = require("./app"); - -// Workaround for https://github.com/electron-userland/electron-webpack/issues/52 -if (process.env.NODE_ENV !== "development") { - window.staticResourcesPath = require("path") - .join(remote.app.getAppPath(), "../static") - .replace(/\\/g, "\\\\"); -} else { - window.staticResourcesPath = ""; -} - -window.addEventListener("contextmenu", event => { +window.addEventListener('contextmenu', event => { contextMenu.showContextMenu( remote.getCurrentWindow(), event.x, event.y, - env === "development" + app.env === 'development' ); event.preventDefault(); }); -ipcRenderer.on("open-uri-requested", (event, uri) => { - if (uri && uri.startsWith("lbry://")) { - app.store.dispatch(doNavigate("/show", { uri })); +ipcRenderer.on('open-uri-requested', (event, uri) => { + if (uri && uri.startsWith('lbry://')) { + app.store.dispatch(doNavigate('/show', { uri })); } }); -ipcRenderer.on("open-menu", (event, uri) => { - if (uri && uri.startsWith("/help")) { - app.store.dispatch(doNavigate("/help")); +ipcRenderer.on('open-menu', (event, uri) => { + if (uri && uri.startsWith('/help')) { + app.store.dispatch(doNavigate('/help')); } }); -const dock = remote.app.dock; +const { dock } = remote.app; -ipcRenderer.on("window-is-focused", (event, data) => { +ipcRenderer.on('window-is-focused', () => { if (!dock) return; - app.store.dispatch({ type: types.WINDOW_FOCUSED }); - dock.setBadge(""); + app.store.dispatch({ type: ACTIONS.WINDOW_FOCUSED }); + dock.setBadge(''); }); -document.addEventListener("click", event => { - let target = event.target; +document.addEventListener('click', event => { + let { target } = event; while (target && target !== document) { - if (target.matches("a") || target.matches("button")) { + if (target.matches('a') || target.matches('button')) { // TODO: Look into using accessiblity labels (this would also make the app more accessible) - const hrefParts = window.location.href.split("#"); + const hrefParts = window.location.href.split('#'); const element = target.title || (target.text && target.text.trim()); if (element) { - amplitude.getInstance().logEvent("CLICK", { + amplitude.getInstance().logEvent('CLICK', { target: element, - location: - hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : "/", + location: hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : '/', }); } else { - amplitude.getInstance().logEvent("UNMARKED_CLICK", { - location: - hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : "/", + amplitude.getInstance().logEvent('UNMARKED_CLICK', { + location: hrefParts.length > 1 ? hrefParts[hrefParts.length - 1] : '/', }); } } - if ( - target.matches('a[href^="http"]') || - target.matches('a[href^="mailto"]') - ) { + if (target.matches('a[href^="http"]') || target.matches('a[href^="mailto"]')) { event.preventDefault(); shell.openExternal(target.href); return; @@ -90,20 +74,18 @@ document.addEventListener("click", event => { } }); -const initialState = app.store.getState(); - -const init = function() { +const init = function initializeReactApp() { app.store.dispatch(doDownloadLanguages()); function onDaemonReady() { lbry.status().then(info => { amplitude.getInstance().init( // Amplitude API Key - "0b130efdcbdbf86ec2f7f9eff354033e", + '0b130efdcbdbf86ec2f7f9eff354033e', info.lbry_id, null, () => { - window.sessionStorage.setItem("loaded", "y"); // once we've made it here once per session, we don't need to show splash again + window.sessionStorage.setItem('loaded', 'y'); // once we've made it here once per session, we don't need to show splash again app.store.dispatch(doDaemonReady()); ReactDOM.render( @@ -113,21 +95,21 @@ const init = function() {
, - document.getElementById("app") + document.getElementById('app') ); } ); }); } - if (window.sessionStorage.getItem("loaded") == "y") { + if (window.sessionStorage.getItem('loaded') === 'y') { onDaemonReady(); } else { ReactDOM.render( , - document.getElementById("app") + document.getElementById('app') ); } }; diff --git a/src/renderer/jsonrpc.js b/src/renderer/jsonrpc.js index bf812d7ed..a94ba4fe8 100644 --- a/src/renderer/jsonrpc.js +++ b/src/renderer/jsonrpc.js @@ -1,76 +1,56 @@ const jsonrpc = {}; -jsonrpc.call = function( +jsonrpc.call = function callJsonRpc( connectionString, method, params, callback, errorCallback, - connectFailedCallback, - timeout + connectFailedCallback ) { function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { return response.json(); } - return response - .json() - .then(json => { - let error; - if (json.error) { - error = new Error(json.error); - } else { - error = new Error("Protocol error with unknown response signature"); - } - return Promise.reject(error); - }) - .catch(e => { - console.error(e); - }); - } - - function makeRequest(url, options) { - return new Promise((resolve, reject) => { - fetch(url, options) - .then(resolve) - .catch(reject); - - if (timeout) { - const e = new Error(__("Protocol request timed out")); - setTimeout(() => reject(e), timeout); + return response.json().then(json => { + let error; + if (json.error) { + error = new Error(json.error); + } else { + error = new Error('Protocol error with unknown response signature'); } + return Promise.reject(error); }); } - const counter = parseInt(sessionStorage.getItem("JSONRPCCounter") || 0); + const counter = parseInt(sessionStorage.getItem('JSONRPCCounter') || 0, 10); const url = connectionString; const options = { - method: "POST", + method: 'POST', body: JSON.stringify({ - jsonrpc: "2.0", + jsonrpc: '2.0', method, params, id: counter, }), }; - sessionStorage.setItem("JSONRPCCounter", counter + 1); + sessionStorage.setItem('JSONRPCCounter', counter + 1); return fetch(url, options) .then(checkAndParse) .then(response => { - const error = - response.error || (response.result && response.result.error); + const error = response.error || (response.result && response.result.error); - if (!error && typeof callback === "function") { + if (!error && typeof callback === 'function') { return callback(response.result); } - if (error && typeof errorCallback === "function") { + if (error && typeof errorCallback === 'function') { return errorCallback(error); } - const errorEvent = new CustomEvent("unhandledError", { + const errorEvent = new CustomEvent('unhandledError', { detail: { connectionString, method, @@ -81,22 +61,25 @@ jsonrpc.call = function( }, }); document.dispatchEvent(errorEvent); + + return Promise.resolve(); }) - .catch(e => { + .catch(error => { if (connectFailedCallback) { - return connectFailedCallback(e); + return connectFailedCallback(error); } - const errorEvent = new CustomEvent("unhandledError", { + const errorEvent = new CustomEvent('unhandledError', { detail: { connectionString, method, params, - code: e.response && e.response.status, - message: __("Connection to API server failed"), + code: error.response && error.response.status, + message: __('Connection to API server failed'), }, }); document.dispatchEvent(errorEvent); + return Promise.resolve(); }); }; diff --git a/src/renderer/lbry.js b/src/renderer/lbry.js index 82d701f8a..27cd3ec14 100644 --- a/src/renderer/lbry.js +++ b/src/renderer/lbry.js @@ -1,5 +1,31 @@ -import jsonrpc from "./jsonrpc.js"; -import lbryuri from "./lbryuri.js"; +import jsonrpc from 'jsonrpc'; +import { ipcRenderer } from 'electron'; + +const CHECK_DAEMON_STARTED_TRY_NUMBER = 200; + +const Lbry = { + isConnected: false, + daemonConnectionString: 'http://localhost:5279', + pendingPublishTimeout: 20 * 60 * 1000, +}; + +function apiCall(method, params, resolve, reject) { + return jsonrpc.call(Lbry.daemonConnectionString, method, params, resolve, reject, reject); +} + +const lbryProxy = new Proxy(Lbry, { + get(target, name) { + if (name in target) { + return target[name]; + } + + return function(params = {}) { + return new Promise((resolve, reject) => { + apiCall(name, params, resolve, reject); + }); + }; + }, +}); function getLocal(key, fallback = undefined) { const itemRaw = localStorage.getItem(key); @@ -10,49 +36,24 @@ function setLocal(key, value) { localStorage.setItem(key, JSON.stringify(value)); } -const { remote, ipcRenderer } = require("electron"); - -let lbry = { - isConnected: false, - daemonConnectionString: "http://localhost:5279", - pendingPublishTimeout: 20 * 60 * 1000, -}; - -function apiCall(method, params, resolve, reject) { - return jsonrpc.call( - lbry.daemonConnectionString, - method, - params, - resolve, - reject, - reject - ); -} - /** * Records a publish attempt in local storage. Returns a dictionary with all the data needed to * needed to make a dummy claim or file info object. */ let pendingId = 0; -function savePendingPublish({ name, channel_name }) { - let uri; - if (channel_name) { - uri = lbryuri.build({ name: channel_name, path: name }, false); - } else { - uri = lbryuri.build({ name }, false); - } - ++pendingId; - const pendingPublishes = getLocal("pendingPublishes") || []; +function savePendingPublish({ name, channelName }) { + pendingId += 1; + const pendingPublishes = getLocal('pendingPublishes') || []; const newPendingPublish = { name, - channel_name, + channelName, claim_id: `pending-${pendingId}`, txid: `pending-${pendingId}`, nout: 0, outpoint: `pending-${pendingId}:0`, time: Date.now(), }; - setLocal("pendingPublishes", [...pendingPublishes, newPendingPublish]); + setLocal('pendingPublishes', [...pendingPublishes, newPendingPublish]); return newPendingPublish; } @@ -60,31 +61,27 @@ function savePendingPublish({ name, channel_name }) { * If there is a pending publish with the given name or outpoint, remove it. * A channel name may also be provided along with name. */ -function removePendingPublishIfNeeded({ name, channel_name, outpoint }) { +function removePendingPublishIfNeeded({ name, channelName, outpoint }) { function pubMatches(pub) { return ( pub.outpoint === outpoint || - (pub.name === name && - (!channel_name || pub.channel_name === channel_name)) + (pub.name === name && (!channelName || pub.channel_name === channelName)) ); } - setLocal( - "pendingPublishes", - lbry.getPendingPublishes().filter(pub => !pubMatches(pub)) - ); + setLocal('pendingPublishes', Lbry.getPendingPublishes().filter(pub => !pubMatches(pub))); } /** * Gets the current list of pending publish attempts. Filters out any that have timed out and * removes them from the list. */ -lbry.getPendingPublishes = function() { - const pendingPublishes = getLocal("pendingPublishes") || []; +Lbry.getPendingPublishes = function() { + const pendingPublishes = getLocal('pendingPublishes') || []; const newPendingPublishes = pendingPublishes.filter( - pub => Date.now() - pub.time <= lbry.pendingPublishTimeout + pub => Date.now() - pub.time <= Lbry.pendingPublishTimeout ); - setLocal("pendingPublishes", newPendingPublishes); + setLocal('pendingPublishes', newPendingPublishes); return newPendingPublishes; }; @@ -92,65 +89,52 @@ lbry.getPendingPublishes = function() { * Gets a pending publish attempt by its name or (fake) outpoint. A channel name can also be * provided along withe the name. If no pending publish is found, returns null. */ -function getPendingPublish({ name, channel_name, outpoint }) { - const pendingPublishes = lbry.getPendingPublishes(); +function getPendingPublish({ name, channelName, outpoint }) { + const pendingPublishes = Lbry.getPendingPublishes(); return ( pendingPublishes.find( pub => pub.outpoint === outpoint || - (pub.name === name && - (!channel_name || pub.channel_name === channel_name)) + (pub.name === name && (!channelName || pub.channel_name === channelName)) ) || null ); } -function pendingPublishToDummyClaim({ - channel_name, - name, - outpoint, - claim_id, - txid, - nout, -}) { - return { name, outpoint, claim_id, txid, nout, channel_name }; +function pendingPublishToDummyClaim({ channelName, name, outpoint, claimId, txid, nout }) { + return { name, outpoint, claimId, txid, nout, channelName }; } -function pendingPublishToDummyFileInfo({ name, outpoint, claim_id }) { - return { name, outpoint, claim_id, metadata: null }; +function pendingPublishToDummyFileInfo({ name, outpoint, claimId }) { + return { name, outpoint, claimId, metadata: null }; } // core -lbry._connectPromise = null; -lbry.connect = function() { - if (lbry._connectPromise === null) { - lbry._connectPromise = new Promise((resolve, reject) => { +Lbry.connectPromise = null; +Lbry.connect = function() { + if (Lbry.connectPromise === null) { + Lbry.connectPromise = new Promise((resolve, reject) => { let tryNum = 0; - function checkDaemonStartedFailed() { - if (tryNum <= 200) { - // Move # of tries into constant or config option - setTimeout(() => { - tryNum++; - checkDaemonStarted(); - }, tryNum < 50 ? 400 : 1000); - } else { - reject(new Error("Unable to connect to LBRY")); - } - } - // Check every half second to see if the daemon is accepting connections function checkDaemonStarted() { - lbry + tryNum += 1; + lbryProxy .status() .then(resolve) - .catch(checkDaemonStartedFailed); + .catch(() => { + if (tryNum <= CHECK_DAEMON_STARTED_TRY_NUMBER) { + setTimeout(checkDaemonStarted, tryNum < 50 ? 400 : 1000); + } else { + reject(new Error('Unable to connect to LBRY')); + } + }); } checkDaemonStarted(); }); } - return lbry._connectPromise; + return Lbry.connectPromise; }; /** @@ -160,13 +144,24 @@ lbry.connect = function() { * This currently includes a work-around to cache the file in local storage so that the pending * publish can appear in the UI immediately. */ -lbry.publishDeprecated = function( - params, - fileListedCallback, - publishedCallback, - errorCallback -) { - lbry.publish(params).then( +Lbry.publishDeprecated = function(params, fileListedCallback, publishedCallback, errorCallback) { + // Give a short grace period in case publish() returns right away or (more likely) gives an error + const returnPendingTimeout = setTimeout( + () => { + const { name, channel_name: channelName } = params; + if (publishedCallback || fileListedCallback) { + savePendingPublish({ + name, + channelName, + }); + publishedCallback(true); + } + }, + 2000, + { once: true } + ); + + lbryProxy.publish(params).then( result => { if (returnPendingTimeout) clearTimeout(returnPendingTimeout); publishedCallback(result); @@ -176,66 +171,40 @@ lbry.publishDeprecated = function( errorCallback(err); } ); - - // Give a short grace period in case publish() returns right away or (more likely) gives an error - const returnPendingTimeout = setTimeout( - () => { - if (publishedCallback) { - savePendingPublish({ - name: params.name, - channel_name: params.channel_name, - }); - publishedCallback(true); - } - - if (fileListedCallback) { - const { name, channel_name } = params; - savePendingPublish({ - name: params.name, - channel_name: params.channel_name, - }); - fileListedCallback(true); - } - }, - 2000, - { once: true } - ); }; -lbry.imagePath = function(file) { +Lbry.imagePath = function(file) { return `${staticResourcesPath}/img/${file}`; }; -lbry.getMediaType = function(contentType, fileName) { +Lbry.getMediaType = function(contentType, fileName) { if (contentType) { return /^[^/]+/.exec(contentType)[0]; } else if (fileName) { - const dotIndex = fileName.lastIndexOf("."); - if (dotIndex == -1) { - return "unknown"; + const dotIndex = fileName.lastIndexOf('.'); + if (dotIndex === -1) { + return 'unknown'; } const ext = fileName.substr(dotIndex + 1); if (/^mp4|m4v|webm|flv|f4v|ogv$/i.test(ext)) { - return "video"; + return 'video'; } else if (/^mp3|m4a|aac|wav|flac|ogg|opus$/i.test(ext)) { - return "audio"; - } else if ( - /^html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org$/i.test(ext) - ) { - return "document"; + return 'audio'; + } else if (/^html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org$/i.test(ext)) { + return 'document'; } - return "unknown"; + return 'unknown'; } - return "unknown"; + return 'unknown'; }; -lbry.getAppVersionInfo = function() { - return new Promise((resolve, reject) => { - ipcRenderer.once("version-info-received", (event, versionInfo) => { +Lbry.getAppVersionInfo = function() { + return new Promise(resolve => { + ipcRenderer.once('version-info-received', (event, versionInfo) => { resolve(versionInfo); }); - ipcRenderer.send("version-info-requested"); + ipcRenderer.send('version-info-requested'); }); }; @@ -248,9 +217,9 @@ lbry.getAppVersionInfo = function() { * Returns results from the file_list API method, plus dummy entries for pending publishes. * (If a real publish with the same name is found, the pending publish will be ignored and removed.) */ -lbry.file_list = function(params = {}) { +Lbry.file_list = function(params = {}) { return new Promise((resolve, reject) => { - const { name, channel_name, outpoint } = params; + const { name, channel_name: channelName, outpoint } = params; /** * If we're searching by outpoint, check first to see if there's a matching pending publish. @@ -266,16 +235,14 @@ lbry.file_list = function(params = {}) { } apiCall( - "file_list", + 'file_list', params, fileInfos => { - removePendingPublishIfNeeded({ name, channel_name, outpoint }); + removePendingPublishIfNeeded({ name, channelName, outpoint }); // if a naked file_list call, append the pending file infos - if (!name && !channel_name && !outpoint) { - const dummyFileInfos = lbry - .getPendingPublishes() - .map(pendingPublishToDummyFileInfo); + if (!name && !channelName && !outpoint) { + const dummyFileInfos = Lbry.getPendingPublishes().map(pendingPublishToDummyFileInfo); resolve([...fileInfos, ...dummyFileInfos]); } else { @@ -287,23 +254,21 @@ lbry.file_list = function(params = {}) { }); }; -lbry.claim_list_mine = function(params = {}) { +Lbry.claim_list_mine = function(params = {}) { return new Promise((resolve, reject) => { apiCall( - "claim_list_mine", + 'claim_list_mine', params, claims => { - for (const { name, channel_name, txid, nout } of claims) { + claims.forEach(({ name, channel_name: channelName, txid, nout }) => { removePendingPublishIfNeeded({ name, - channel_name, + channelName, outpoint: `${txid}:${nout}`, }); - } + }); - const dummyClaims = lbry - .getPendingPublishes() - .map(pendingPublishToDummyClaim); + const dummyClaims = Lbry.getPendingPublishes().map(pendingPublishToDummyClaim); resolve([...claims, ...dummyClaims]); }, reject @@ -311,13 +276,13 @@ lbry.claim_list_mine = function(params = {}) { }); }; -lbry.resolve = function(params = {}) { +Lbry.resolve = function(params = {}) { return new Promise((resolve, reject) => { apiCall( - "resolve", + 'resolve', params, data => { - if ("uri" in params) { + if ('uri' in params) { // If only a single URI was requested, don't nest the results in an object resolve(data && data[params.uri] ? data[params.uri] : {}); } else { @@ -329,18 +294,4 @@ lbry.resolve = function(params = {}) { }); }; -lbry = new Proxy(lbry, { - get(target, name) { - if (name in target) { - return target[name]; - } - - return function(params = {}) { - return new Promise((resolve, reject) => { - apiCall(name, params, resolve, reject); - }); - }; - }, -}); - -export default lbry; +export default lbryProxy; diff --git a/src/renderer/lbryio.js b/src/renderer/lbryio.js index 430dd7f36..694f83ed7 100644 --- a/src/renderer/lbryio.js +++ b/src/renderer/lbryio.js @@ -1,48 +1,46 @@ -import lbry from "./lbry.js"; +import Lbry from 'lbry'; +import querystring from 'querystring'; +import { ipcRenderer } from 'electron'; -const querystring = require("querystring"); -const { ipcRenderer } = require("electron"); - -const lbryio = { +const Lbryio = { enabled: true, - _authenticationPromise: null, - _exchangePromise: null, - _exchangeLastFetched: null, + authenticationPromise: null, + exchangePromise: null, + exchangeLastFetched: null, }; const CONNECTION_STRING = process.env.LBRY_APP_API_URL - ? process.env.LBRY_APP_API_URL.replace(/\/*$/, "/") // exactly one slash at the end - : "https://api.lbry.io/"; + ? process.env.LBRY_APP_API_URL.replace(/\/*$/, '/') // exactly one slash at the end + : 'https://api.lbry.io/'; const EXCHANGE_RATE_TIMEOUT = 20 * 60 * 1000; -lbryio.getExchangeRates = function() { +Lbryio.getExchangeRates = function() { if ( - !lbryio._exchangeLastFetched || - Date.now() - lbryio._exchangeLastFetched > EXCHANGE_RATE_TIMEOUT + !Lbryio.exchangeLastFetched || + Date.now() - Lbryio.exchangeLastFetched > EXCHANGE_RATE_TIMEOUT ) { - lbryio._exchangePromise = new Promise((resolve, reject) => { - lbryio - .call("lbc", "exchange_rate", {}, "get", true) - .then(({ lbc_usd, lbc_btc, btc_usd }) => { - const rates = { lbc_usd, lbc_btc, btc_usd }; + Lbryio.exchangePromise = new Promise((resolve, reject) => { + Lbryio.call('lbc', 'exchange_rate', {}, 'get', true) + .then(({ lbc_usd: LBC_USD, lbc_btc: LBC_BTC, btc_usd: BTC_USD }) => { + const rates = { LBC_USD, LBC_BTC, BTC_USD }; resolve(rates); }) .catch(reject); }); - lbryio._exchangeLastFetched = Date.now(); + Lbryio.exchangeLastFetched = Date.now(); } - return lbryio._exchangePromise; + return Lbryio.exchangePromise; }; -lbryio.call = function(resource, action, params = {}, method = "get") { - if (!lbryio.enabled) { - console.log(__("Internal API disabled")); - return Promise.reject(new Error(__("LBRY internal API is disabled"))); +Lbryio.call = function(resource, action, params = {}, method = 'get') { + if (!Lbryio.enabled) { + console.log(__('Internal API disabled')); + return Promise.reject(new Error(__('LBRY internal API is disabled'))); } - if (!(method == "get" || method == "post")) { - return Promise.reject(new Error(__("Invalid method"))); + if (!(method === 'get' || method === 'post')) { + return Promise.reject(new Error(__('Invalid method'))); } function checkAndParse(response) { @@ -54,7 +52,7 @@ lbryio.call = function(resource, action, params = {}, method = "get") { if (json.error) { error = new Error(json.error); } else { - error = new Error("Unknown API error signature"); + error = new Error('Unknown API error signature'); } error.response = response; // this is primarily a hack used in actions/user.js return Promise.reject(error); @@ -65,20 +63,20 @@ lbryio.call = function(resource, action, params = {}, method = "get") { return fetch(url, options).then(checkAndParse); } - return lbryio.getAuthToken().then(token => { + return Lbryio.getAuthToken().then(token => { const fullParams = { auth_token: token, ...params }; const qs = querystring.stringify(fullParams); let url = `${CONNECTION_STRING}${resource}/${action}?${qs}`; let options = { - method: "GET", + method: 'GET', }; - if (method == "post") { + if (method === 'post') { options = { - method: "POST", + method: 'POST', headers: { - "Content-Type": "application/x-www-form-urlencoded", + 'Content-Type': 'application/x-www-form-urlencoded', }, body: qs, }; @@ -89,35 +87,35 @@ lbryio.call = function(resource, action, params = {}, method = "get") { }); }; -lbryio._authToken = null; +Lbryio.authToken = null; -lbryio.getAuthToken = () => - new Promise((resolve, reject) => { - if (lbryio._authToken) { - resolve(lbryio._authToken); +Lbryio.getAuthToken = () => + new Promise(resolve => { + if (Lbryio.authToken) { + resolve(Lbryio.authToken); } else { - ipcRenderer.once("auth-token-response", (event, token) => { - lbryio._authToken = token; + ipcRenderer.once('auth-token-response', (event, token) => { + Lbryio.authToken = token; return resolve(token); }); - ipcRenderer.send("get-auth-token"); + ipcRenderer.send('get-auth-token'); } }); -lbryio.setAuthToken = token => { - lbryio._authToken = token ? token.toString().trim() : null; - ipcRenderer.send("set-auth-token", token); +Lbryio.setAuthToken = token => { + Lbryio.authToken = token ? token.toString().trim() : null; + ipcRenderer.send('set-auth-token', token); }; -lbryio.getCurrentUser = () => lbryio.call("user", "me"); +Lbryio.getCurrentUser = () => Lbryio.call('user', 'me'); -lbryio.authenticate = function() { - if (!lbryio.enabled) { - return new Promise((resolve, reject) => { +Lbryio.authenticate = function() { + if (!Lbryio.enabled) { + return new Promise(resolve => { resolve({ id: 1, - language: "en", - primary_email: "disabled@lbry.io", + language: 'en', + primary_email: 'disabled@lbry.io', has_verified_email: true, is_identity_verified: true, is_reward_approved: false, @@ -125,58 +123,55 @@ lbryio.authenticate = function() { }); } - if (lbryio._authenticationPromise === null) { - lbryio._authenticationPromise = new Promise((resolve, reject) => { - lbryio - .getAuthToken() + if (Lbryio.authenticationPromise === null) { + Lbryio.authenticationPromise = new Promise((resolve, reject) => { + Lbryio.getAuthToken() .then(token => { if (!token || token.length > 60) { return false; } // check that token works - return lbryio - .getCurrentUser() + return Lbryio.getCurrentUser() .then(() => true) .catch(() => false); }) .then(isTokenValid => { if (isTokenValid) { - return; + return reject; } - return lbry - .status() + return Lbry.status() .then(status => - lbryio.call( - "user", - "new", + Lbryio.call( + 'user', + 'new', { - auth_token: "", - language: "en", + auth_token: '', + language: 'en', app_id: status.installation_id, }, - "post" + 'post' ) ) .then(response => { if (!response.auth_token) { - throw new Error(__("auth_token is missing from response")); + throw new Error(__('auth_token is missing from response')); } - return lbryio.setAuthToken(response.auth_token); + return Lbryio.setAuthToken(response.auth_token); }); }) - .then(lbryio.getCurrentUser) + .then(Lbryio.getCurrentUser) .then(resolve, reject); }); } - return lbryio._authenticationPromise; + return Lbryio.authenticationPromise; }; -lbryio.getStripeToken = () => - CONNECTION_STRING.startsWith("http://localhost:") - ? "pk_test_NoL1JWL7i1ipfhVId5KfDZgo" - : "pk_live_e8M4dRNnCCbmpZzduEUZBgJO"; +Lbryio.getStripeToken = () => + CONNECTION_STRING.startsWith('http://localhost:') + ? 'pk_test_NoL1JWL7i1ipfhVId5KfDZgo' + : 'pk_live_e8M4dRNnCCbmpZzduEUZBgJO'; -export default lbryio; +export default Lbryio; diff --git a/src/renderer/lbryuri.js b/src/renderer/lbryuri.js index 7d4be33c0..d9ce508dc 100644 --- a/src/renderer/lbryuri.js +++ b/src/renderer/lbryuri.js @@ -1,10 +1,10 @@ const CHANNEL_NAME_MIN_LEN = 1; const CLAIM_ID_MAX_LEN = 40; -const lbryuri = {}; +const Lbryuri = {}; -lbryuri.REGEXP_INVALID_URI = /[^A-Za-z0-9-]/g; -lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; +Lbryuri.REGEXP_INVALID_URI = /[^A-Za-z0-9-]/g; +Lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; /** * Parses a LBRY name into its component parts. Throws errors with user-friendly @@ -28,13 +28,13 @@ lbryuri.REGEXP_ADDRESS = /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; * - contentName (string): For anon claims, the name; for channel claims, the path * - channelName (string, if present): Channel name without @ */ -lbryuri.parse = function(uri, requireProto = false) { +Lbryuri.parse = function(uri, requireProto = false) { // Break into components. Empty sub-matches are converted to null const componentsRegex = new RegExp( - "^((?:lbry://)?)" + // protocol - "([^:$#/]*)" + // name (stops at the first separator or end) - "([:$#]?)([^/]*)" + // modifier separator, modifier (stops at the first path separator or end) - "(/?)(.*)" // path separator, path + '^((?:lbry://)?)' + // protocol + '([^:$#/]*)' + // name (stops at the first separator or end) + '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) + '(/?)(.*)' // path separator, path ); const [proto, name, modSep, modVal, pathSep, path] = componentsRegex .exec(uri) @@ -45,57 +45,54 @@ lbryuri.parse = function(uri, requireProto = false) { // Validate protocol if (requireProto && !proto) { - throw new Error(__("LBRY URIs must include a protocol prefix (lbry://).")); + throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); } // Validate and process name if (!name) { - throw new Error(__("URI does not include name.")); + throw new Error(__('URI does not include name.')); } - const isChannel = name.startsWith("@"); + const isChannel = name.startsWith('@'); const channelName = isChannel ? name.slice(1) : name; if (isChannel) { if (!channelName) { - throw new Error(__("No channel name after @.")); + throw new Error(__('No channel name after @.')); } if (channelName.length < CHANNEL_NAME_MIN_LEN) { - throw new Error( - __( - `Channel names must be at least %s characters.`, - CHANNEL_NAME_MIN_LEN - ) - ); + throw new Error(__(`Channel names must be at least %s characters.`, CHANNEL_NAME_MIN_LEN)); } contentName = path; } - const nameBadChars = (channelName || name).match(lbryuri.REGEXP_INVALID_URI); + const nameBadChars = (channelName || name).match(Lbryuri.REGEXP_INVALID_URI); if (nameBadChars) { throw new Error( __( `Invalid character %s in name: %s.`, - nameBadChars.length == 1 ? "" : "s", - nameBadChars.join(", ") + nameBadChars.length === 1 ? '' : 's', + nameBadChars.join(', ') ) ); } // Validate and process modifier (claim ID, bid position or claim sequence) - let claimId, claimSequence, bidPosition; + let claimId; + let claimSequence; + let bidPosition; if (modSep) { if (!modVal) { throw new Error(__(`No modifier provided after separator %s.`, modSep)); } - if (modSep == "#") { + if (modSep === '#') { claimId = modVal; - } else if (modSep == ":") { + } else if (modSep === ':') { claimSequence = modVal; - } else if (modSep == "$") { + } else if (modSep === '$') { bidPosition = modVal; } } @@ -109,29 +106,27 @@ lbryuri.parse = function(uri, requireProto = false) { } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__("Claim sequence must be a number.")); + throw new Error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__("Bid position must be a number.")); + throw new Error(__('Bid position must be a number.')); } // Validate and process path if (path) { if (!isChannel) { - throw new Error(__("Only channel URIs may have a path.")); + throw new Error(__('Only channel URIs may have a path.')); } - const pathBadChars = path.match(lbryuri.REGEXP_INVALID_URI); + const pathBadChars = path.match(Lbryuri.REGEXP_INVALID_URI); if (pathBadChars) { - throw new Error( - __(`Invalid character in path: %s`, pathBadChars.join(", ")) - ); + throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); } contentName = path; } else if (pathSep) { - throw new Error(__("No path provided after /")); + throw new Error(__('No path provided after /')); } return { @@ -140,8 +135,8 @@ lbryuri.parse = function(uri, requireProto = false) { isChannel, ...(contentName ? { contentName } : {}), ...(channelName ? { channelName } : {}), - ...(claimSequence ? { claimSequence: parseInt(claimSequence) } : {}), - ...(bidPosition ? { bidPosition: parseInt(bidPosition) } : {}), + ...(claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}), + ...(bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}), ...(claimId ? { claimId } : {}), ...(path ? { path } : {}), }; @@ -152,21 +147,13 @@ lbryuri.parse = function(uri, requireProto = false) { * * The channelName key will accept names with or without the @ prefix. */ -lbryuri.build = function(uriObj, includeProto = true, allowExtraProps = false) { - let { - name, - claimId, - claimSequence, - bidPosition, - path, - contentName, - channelName, - } = uriObj; +Lbryuri.build = function(uriObj, includeProto = true) { + const { claimId, claimSequence, bidPosition, contentName, channelName } = uriObj; + + let { name, path } = uriObj; if (channelName) { - const channelNameFormatted = channelName.startsWith("@") - ? channelName - : `@${channelName}`; + const channelNameFormatted = channelName.startsWith('@') ? channelName : `@${channelName}`; if (!name) { name = channelNameFormatted; } else if (name !== channelNameFormatted) { @@ -187,52 +174,50 @@ lbryuri.build = function(uriObj, includeProto = true, allowExtraProps = false) { if (path && path !== contentName) { throw new Error( __( - "Path and contentName do not match. Only one is required; most likely you wanted contentName." + 'Path and contentName do not match. Only one is required; most likely you wanted contentName.' ) ); } } return ( - (includeProto ? "lbry://" : "") + + (includeProto ? 'lbry://' : '') + name + - (claimId ? `#${claimId}` : "") + - (claimSequence ? `:${claimSequence}` : "") + - (bidPosition ? `\$${bidPosition}` : "") + - (path ? `/${path}` : "") + (claimId ? `#${claimId}` : '') + + (claimSequence ? `:${claimSequence}` : '') + + (bidPosition ? `${bidPosition}` : '') + + (path ? `/${path}` : '') ); }; /* Takes a parseable LBRY URI and converts it to standard, canonical format (currently this just * consists of adding the lbry:// prefix if needed) */ -lbryuri.normalize = function(uri) { +Lbryuri.normalize = function(uri) { if (uri.match(/pending_claim/)) return uri; - const { name, path, bidPosition, claimSequence, claimId } = lbryuri.parse( - uri - ); - return lbryuri.build({ name, path, claimSequence, bidPosition, claimId }); + const { name, path, bidPosition, claimSequence, claimId } = Lbryuri.parse(uri); + return Lbryuri.build({ name, path, claimSequence, bidPosition, claimId }); }; -lbryuri.isValid = function(uri) { +Lbryuri.isValid = function(uri) { let parts; try { - parts = lbryuri.parse(lbryuri.normalize(uri)); + parts = Lbryuri.parse(Lbryuri.normalize(uri)); } catch (error) { return false; } return parts && parts.name; }; -lbryuri.isValidName = function(name, checkCase = true) { - const regexp = new RegExp("^[a-z0-9-]+$", checkCase ? "" : "i"); +Lbryuri.isValidName = function(name, checkCase = true) { + const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); return regexp.test(name); }; -lbryuri.isClaimable = function(uri) { +Lbryuri.isClaimable = function(uri) { let parts; try { - parts = lbryuri.parse(lbryuri.normalize(uri)); + parts = Lbryuri.parse(Lbryuri.normalize(uri)); } catch (error) { return false; } @@ -247,5 +232,5 @@ lbryuri.isClaimable = function(uri) { ); }; -window.lbryuri = lbryuri; -export default lbryuri; +window.lbryuri = Lbryuri; +export default Lbryuri; diff --git a/src/renderer/redux/actions/app.js b/src/renderer/redux/actions/app.js index 031b129f1..b0f8d3811 100644 --- a/src/renderer/redux/actions/app.js +++ b/src/renderer/redux/actions/app.js @@ -1,5 +1,5 @@ -import * as types from "constants/action_types"; -import lbry from "lbry"; +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; import { selectUpdateUrl, selectUpgradeDownloadPath, @@ -7,27 +7,26 @@ import { selectUpgradeFilename, selectIsUpgradeSkipped, selectRemoteVersion, -} from "redux/selectors/app"; -import { doFetchDaemonSettings } from "redux/actions/settings"; -import { doBalanceSubscribe, doFetchTransactions } from "redux/actions/wallet"; -import { doAuthenticate } from "redux/actions/user"; -import { doFetchFileInfosAndPublishedClaims } from "redux/actions/file_info"; -import * as modals from "constants/modal_types"; -import { doFetchRewardedContent } from "redux/actions/content"; -import { selectCurrentModal } from "redux/selectors/app"; + selectCurrentModal, +} from 'redux/selectors/app'; +import { doFetchDaemonSettings } from 'redux/actions/settings'; +import { doBalanceSubscribe, doFetchTransactions } from 'redux/actions/wallet'; +import { doAuthenticate } from 'redux/actions/user'; +import { doFetchFileInfosAndPublishedClaims } from 'redux/actions/file_info'; +import * as MODALS from 'constants/modal_types'; +import { doFetchRewardedContent } from 'redux/actions/content'; +import { ipcRenderer, remote } from 'electron'; +import Path from 'path'; -const { remote, ipcRenderer, shell } = require("electron"); -const path = require("path"); - -const { download } = remote.require("electron-dl"); -const fs = remote.require("fs"); -const { lbrySettings: config } = require("package.json"); +const { download } = remote.require('electron-dl'); +const Fs = remote.require('fs'); +const { lbrySettings: config } = require('package.json'); const CHECK_UPGRADE_INTERVAL = 10 * 60 * 1000; export function doOpenModal(modal, modalProps = {}) { return { - type: types.OPEN_MODAL, + type: ACTIONS.OPEN_MODAL, data: { modal, modalProps, @@ -37,13 +36,13 @@ export function doOpenModal(modal, modalProps = {}) { export function doCloseModal() { return { - type: types.CLOSE_MODAL, + type: ACTIONS.CLOSE_MODAL, }; } export function doUpdateDownloadProgress(percent) { return { - type: types.UPGRADE_DOWNLOAD_PROGRESSED, + type: ACTIONS.UPGRADE_DOWNLOAD_PROGRESSED, data: { percent, }, @@ -52,7 +51,7 @@ export function doUpdateDownloadProgress(percent) { export function doSkipUpgrade() { return { - type: types.SKIP_UPGRADE, + type: ACTIONS.SKIP_UPGRADE, }; } @@ -61,7 +60,7 @@ export function doStartUpgrade() { const state = getState(); const upgradeDownloadPath = selectUpgradeDownloadPath(state); - ipcRenderer.send("upgrade", upgradeDownloadPath); + ipcRenderer.send('upgrade', upgradeDownloadPath); }; } @@ -69,40 +68,36 @@ export function doDownloadUpgrade() { return function(dispatch, getState) { const state = getState(); // Make a new directory within temp directory so the filename is guaranteed to be available - const dir = fs.mkdtempSync( - remote.app.getPath("temp") + require("path").sep - ), - upgradeFilename = selectUpgradeFilename(state); + const dir = Fs.mkdtempSync(remote.app.getPath('temp') + Path.sep); + const upgradeFilename = selectUpgradeFilename(state); const options = { onProgress: p => dispatch(doUpdateDownloadProgress(Math.round(p * 100))), directory: dir, }; - download(remote.getCurrentWindow(), selectUpdateUrl(state), options).then( - downloadItem => { - /** - * TODO: get the download path directly from the download object. It should just be - * downloadItem.getSavePath(), but the copy on the main process is being garbage collected - * too soon. - */ + download(remote.getCurrentWindow(), selectUpdateUrl(state), options).then(downloadItem => { + /** + * TODO: get the download path directly from the download object. It should just be + * downloadItem.getSavePath(), but the copy on the main process is being garbage collected + * too soon. + */ - dispatch({ - type: types.UPGRADE_DOWNLOAD_COMPLETED, - data: { - downloadItem, - path: path.join(dir, upgradeFilename), - }, - }); - } - ); + dispatch({ + type: ACTIONS.UPGRADE_DOWNLOAD_COMPLETED, + data: { + downloadItem, + path: Path.join(dir, upgradeFilename), + }, + }); + }); dispatch({ - type: types.UPGRADE_DOWNLOAD_STARTED, + type: ACTIONS.UPGRADE_DOWNLOAD_STARTED, }); dispatch({ - type: types.OPEN_MODAL, + type: ACTIONS.OPEN_MODAL, data: { - modal: modals.DOWNLOADING, + modal: MODALS.DOWNLOADING, }, }); }; @@ -127,7 +122,7 @@ export function doCancelUpgrade() { } } - dispatch({ type: types.UPGRADE_CANCELLED }); + dispatch({ type: ACTIONS.UPGRADE_CANCELLED }); }; } @@ -135,12 +130,12 @@ export function doCheckUpgradeAvailable() { return function(dispatch, getState) { const state = getState(); dispatch({ - type: types.CHECK_UPGRADE_START, + type: ACTIONS.CHECK_UPGRADE_START, }); const success = ({ remoteVersion, upgradeAvailable }) => { dispatch({ - type: types.CHECK_UPGRADE_SUCCESS, + type: ACTIONS.CHECK_UPGRADE_SUCCESS, data: { upgradeAvailable, remoteVersion, @@ -150,13 +145,12 @@ export function doCheckUpgradeAvailable() { if ( upgradeAvailable && !selectCurrentModal(state) && - (!selectIsUpgradeSkipped(state) || - remoteVersion !== selectRemoteVersion(state)) + (!selectIsUpgradeSkipped(state) || remoteVersion !== selectRemoteVersion(state)) ) { dispatch({ - type: types.OPEN_MODAL, + type: ACTIONS.OPEN_MODAL, data: { - modal: modals.UPGRADE, + modal: MODALS.UPGRADE, }, }); } @@ -164,11 +158,11 @@ export function doCheckUpgradeAvailable() { const fail = () => { dispatch({ - type: types.CHECK_UPGRADE_FAIL, + type: ACTIONS.CHECK_UPGRADE_FAIL, }); }; - lbry.getAppVersionInfo().then(success, fail); + Lbry.getAppVersionInfo().then(success, fail); }; } @@ -182,32 +176,31 @@ export function doCheckUpgradeSubscribe() { CHECK_UPGRADE_INTERVAL ); dispatch({ - type: types.CHECK_UPGRADE_SUBSCRIBE, + type: ACTIONS.CHECK_UPGRADE_SUBSCRIBE, data: { checkUpgradeTimer }, }); }; } export function doCheckDaemonVersion() { - return function(dispatch, getState) { - lbry.version().then(({ lbrynet_version }) => { + return function(dispatch) { + Lbry.version().then(({ lbrynet_version: lbrynetVersion }) => { dispatch({ type: - config.lbrynetDaemonVersion == lbrynet_version - ? types.DAEMON_VERSION_MATCH - : types.DAEMON_VERSION_MISMATCH, + config.lbrynetDaemonVersion === lbrynetVersion + ? ACTIONS.DAEMON_VERSION_MATCH + : ACTIONS.DAEMON_VERSION_MISMATCH, }); }); }; } export function doAlertError(errorList) { - return function(dispatch, getState) { - const state = getState(); + return function(dispatch) { dispatch({ - type: types.OPEN_MODAL, + type: ACTIONS.OPEN_MODAL, data: { - modal: modals.ERROR, + modal: MODALS.ERROR, modalProps: { error: errorList }, }, }); @@ -219,7 +212,7 @@ export function doDaemonReady() { const state = getState(); dispatch(doAuthenticate()); - dispatch({ type: types.DAEMON_READY }); + dispatch({ type: ACTIONS.DAEMON_READY }); dispatch(doFetchDaemonSettings()); dispatch(doBalanceSubscribe()); dispatch(doFetchFileInfosAndPublishedClaims()); @@ -234,19 +227,19 @@ export function doDaemonReady() { export function doShowSnackBar(data) { return { - type: types.SHOW_SNACKBAR, + type: ACTIONS.SHOW_SNACKBAR, data, }; } export function doRemoveSnackBarSnack() { return { - type: types.REMOVE_SNACKBAR_SNACK, + type: ACTIONS.REMOVE_SNACKBAR_SNACK, }; } export function doClearCache() { - return function(dispatch, getState) { + return function() { window.cacheStore.purge(); return Promise.resolve(); @@ -254,15 +247,15 @@ export function doClearCache() { } export function doQuit() { - return function(dispatch, getState) { + return function() { remote.app.quit(); }; } export function doChangeVolume(volume) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.VOLUME_CHANGED, + type: ACTIONS.VOLUME_CHANGED, data: { volume, }, diff --git a/src/renderer/redux/actions/availability.js b/src/renderer/redux/actions/availability.js index 5be5eb760..2382cbbf8 100644 --- a/src/renderer/redux/actions/availability.js +++ b/src/renderer/redux/actions/availability.js @@ -1,32 +1,27 @@ -import * as types from "constants/action_types"; -import lbry from "lbry"; -import { selectFetchingAvailability } from "redux/selectors/availability"; - -export function doFetchAvailability(uri) { - return function(dispatch, getState) { +// eslint-disable-next-line import/prefer-default-export +export function doFetchAvailability() { + return function() { /* this is disabled atm - Jeremy */ - return; - - const state = getState(); - const alreadyFetching = !!selectFetchingAvailability(state)[uri]; - - if (!alreadyFetching) { - dispatch({ - type: types.FETCH_AVAILABILITY_STARTED, - data: { uri }, - }); - - lbry.get_availability({ uri }).then(availability => { - dispatch({ - type: types.FETCH_AVAILABILITY_COMPLETED, - data: { - availability, - uri, - }, - }); - }); - } + // const state = getState(); + // const alreadyFetching = !!selectFetchingAvailability(state)[uri]; + // + // if (!alreadyFetching) { + // dispatch({ + // type: ACTIONS.FETCH_AVAILABILITY_STARTED, + // data: { uri }, + // }); + // + // lbry.get_availability({ uri }).then(availability => { + // dispatch({ + // type: ACTIONS.FETCH_AVAILABILITY_COMPLETED, + // data: { + // availability, + // uri, + // }, + // }); + // }); + // } }; } diff --git a/src/renderer/redux/actions/content.js b/src/renderer/redux/actions/content.js index 10c24791a..0dbab879c 100644 --- a/src/renderer/redux/actions/content.js +++ b/src/renderer/redux/actions/content.js @@ -1,65 +1,63 @@ -import * as types from "constants/action_types"; -import * as settings from "constants/settings"; -import lbry from "lbry"; -import lbryio from "lbryio"; -import lbryuri from "lbryuri"; -import { makeSelectClientSetting } from "redux/selectors/settings"; -import { selectBalance, selectTransactionItems } from "redux/selectors/wallet"; +import { ipcRenderer } from 'electron'; +import * as ACTIONS from 'constants/action_types'; +import * as SETTINGS from 'constants/settings'; +import Lbry from 'lbry'; +import Lbryio from 'lbryio'; +import Lbryuri from 'lbryuri'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; +import { selectBalance, selectTransactionItems } from 'redux/selectors/wallet'; import { makeSelectFileInfoForUri, selectDownloadingByOutpoint, -} from "redux/selectors/file_info"; -import { selectResolvingUris } from "redux/selectors/content"; -import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; -import { doAlertError, doOpenModal } from "redux/actions/app"; -import { doClaimEligiblePurchaseRewards } from "redux/actions/rewards"; -import { selectBadgeNumber } from "redux/selectors/app"; -import { selectTotalDownloadProgress } from "redux/selectors/file_info"; -import setBadge from "util/setBadge"; -import setProgressBar from "util/setProgressBar"; -import batchActions from "util/batchActions"; -import * as modals from "constants/modal_types"; - -const { ipcRenderer } = require("electron"); + selectTotalDownloadProgress, +} from 'redux/selectors/file_info'; +import { selectResolvingUris } from 'redux/selectors/content'; +import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info'; +import { doAlertError, doOpenModal } from 'redux/actions/app'; +import { doClaimEligiblePurchaseRewards } from 'redux/actions/rewards'; +import { selectBadgeNumber } from 'redux/selectors/app'; +import setBadge from 'util/setBadge'; +import setProgressBar from 'util/setProgressBar'; +import batchActions from 'util/batchActions'; +import * as MODALS from 'constants/modal_types'; const DOWNLOAD_POLL_INTERVAL = 250; export function doResolveUris(uris) { return function(dispatch, getState) { - uris = uris.map(lbryuri.normalize); + const normalizedUris = uris.map(Lbryuri.normalize); const state = getState(); // Filter out URIs that are already resolving const resolvingUris = selectResolvingUris(state); - const urisToResolve = uris.filter(uri => !resolvingUris.includes(uri)); + const urisToResolve = normalizedUris.filter(uri => !resolvingUris.includes(uri)); if (urisToResolve.length === 0) { return; } dispatch({ - type: types.RESOLVE_URIS_STARTED, - data: { uris }, + type: ACTIONS.RESOLVE_URIS_STARTED, + data: { uris: normalizedUris }, }); const resolveInfo = {}; - lbry.resolve({ uris: urisToResolve }).then(result => { - for (const [uri, uriResolveInfo] of Object.entries(result)) { + Lbry.resolve({ uris: urisToResolve }).then(result => { + Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { claim: null, - claims_in_channel: null, + claimsInChannel: null, certificate: null, }; - const { claim, certificate, claims_in_channel } = - uriResolveInfo && !uriResolveInfo.error - ? uriResolveInfo - : fallbackResolveInfo; - resolveInfo[uri] = { claim, certificate, claims_in_channel }; - } + const { claim, certificate, claims_in_channel: claimsInChannel } = + uriResolveInfo && !uriResolveInfo.error ? uriResolveInfo : fallbackResolveInfo; + + resolveInfo[uri] = { claim, certificate, claimsInChannel }; + }); dispatch({ - type: types.RESOLVE_URIS_COMPLETED, + type: ACTIONS.RESOLVE_URIS_COMPLETED, data: { resolveInfo }, }); }); @@ -71,23 +69,21 @@ export function doResolveUri(uri) { } export function doFetchFeaturedUris() { - return function(dispatch, getState) { - const state = getState(); - + return function(dispatch) { dispatch({ - type: types.FETCH_FEATURED_CONTENT_STARTED, + type: ACTIONS.FETCH_FEATURED_CONTENT_STARTED, }); const success = ({ Uris }) => { let urisToResolve = []; - for (const category in Uris) { + Object.keys(Uris).forEach(category => { urisToResolve = [...urisToResolve, ...Uris[category]]; - } + }); const actions = [ doResolveUris(urisToResolve), { - type: types.FETCH_FEATURED_CONTENT_COMPLETED, + type: ACTIONS.FETCH_FEATURED_CONTENT_COMPLETED, data: { uris: Uris, success: true, @@ -99,24 +95,22 @@ export function doFetchFeaturedUris() { const failure = () => { dispatch({ - type: types.FETCH_FEATURED_CONTENT_COMPLETED, + type: ACTIONS.FETCH_FEATURED_CONTENT_COMPLETED, data: { uris: {}, }, }); }; - lbryio.call("file", "list_homepage").then(success, failure); + Lbryio.call('file', 'list_homepage').then(success, failure); }; } export function doFetchRewardedContent() { - return function(dispatch, getState) { - const state = getState(); - + return function(dispatch) { const success = nameToClaimId => { dispatch({ - type: types.FETCH_REWARD_CONTENT_COMPLETED, + type: ACTIONS.FETCH_REWARD_CONTENT_COMPLETED, data: { claimIds: Object.values(nameToClaimId), success: true, @@ -126,7 +120,7 @@ export function doFetchRewardedContent() { const failure = () => { dispatch({ - type: types.FETCH_REWARD_CONTENT_COMPLETED, + type: ACTIONS.FETCH_REWARD_CONTENT_COMPLETED, data: { claimIds: [], success: false, @@ -134,73 +128,69 @@ export function doFetchRewardedContent() { }); }; - lbryio.call("reward", "list_featured").then(success, failure); + Lbryio.call('reward', 'list_featured').then(success, failure); }; } export function doUpdateLoadStatus(uri, outpoint) { return function(dispatch, getState) { - const state = getState(); + Lbry.file_list({ + outpoint, + full_status: true, + }).then(([fileInfo]) => { + if (!fileInfo || fileInfo.written_bytes === 0) { + // download hasn't started yet + setTimeout(() => { + dispatch(doUpdateLoadStatus(uri, outpoint)); + }, DOWNLOAD_POLL_INTERVAL); + } else if (fileInfo.completed) { + // TODO this isn't going to get called if they reload the client before + // the download finished + dispatch({ + type: ACTIONS.DOWNLOADING_COMPLETED, + data: { + uri, + outpoint, + fileInfo, + }, + }); - lbry - .file_list({ - outpoint, - full_status: true, - }) - .then(([fileInfo]) => { - if (!fileInfo || fileInfo.written_bytes == 0) { - // download hasn't started yet - setTimeout(() => { - dispatch(doUpdateLoadStatus(uri, outpoint)); - }, DOWNLOAD_POLL_INTERVAL); - } else if (fileInfo.completed) { - // TODO this isn't going to get called if they reload the client before - // the download finished - dispatch({ - type: types.DOWNLOADING_COMPLETED, - data: { - uri, - outpoint, - fileInfo, - }, - }); + const badgeNumber = selectBadgeNumber(getState()); + setBadge(badgeNumber === 0 ? '' : `${badgeNumber}`); - const badgeNumber = selectBadgeNumber(getState()); - setBadge(badgeNumber === 0 ? "" : `${badgeNumber}`); + const totalProgress = selectTotalDownloadProgress(getState()); + setProgressBar(totalProgress); - const totalProgress = selectTotalDownloadProgress(getState()); - setProgressBar(totalProgress); + const notif = new window.Notification('LBRY Download Complete', { + body: fileInfo.metadata.stream.metadata.title, + silent: false, + }); + notif.onclick = () => { + ipcRenderer.send('focusWindow', 'main'); + }; + } else { + // ready to play + const { total_bytes: totalBytes, written_bytes: writtenBytes } = fileInfo; + const progress = writtenBytes / totalBytes * 100; - const notif = new window.Notification("LBRY Download Complete", { - body: fileInfo.metadata.stream.metadata.title, - silent: false, - }); - notif.onclick = () => { - ipcRenderer.send("focusWindow", "main"); - }; - } else { - // ready to play - const { total_bytes, written_bytes } = fileInfo; - const progress = written_bytes / total_bytes * 100; + dispatch({ + type: ACTIONS.DOWNLOADING_PROGRESSED, + data: { + uri, + outpoint, + fileInfo, + progress, + }, + }); - dispatch({ - type: types.DOWNLOADING_PROGRESSED, - data: { - uri, - outpoint, - fileInfo, - progress, - }, - }); + const totalProgress = selectTotalDownloadProgress(getState()); + setProgressBar(totalProgress); - const totalProgress = selectTotalDownloadProgress(getState()); - setProgressBar(totalProgress); - - setTimeout(() => { - dispatch(doUpdateLoadStatus(uri, outpoint)); - }, DOWNLOAD_POLL_INTERVAL); - } - }); + setTimeout(() => { + dispatch(doUpdateLoadStatus(uri, outpoint)); + }, DOWNLOAD_POLL_INTERVAL); + } + }); }; } @@ -209,16 +199,16 @@ export function doStartDownload(uri, outpoint) { const state = getState(); if (!outpoint) { - throw new Error("outpoint is required to begin a download"); + throw new Error('outpoint is required to begin a download'); } const { downloadingByOutpoint = {} } = state.fileInfo; if (downloadingByOutpoint[outpoint]) return; - lbry.file_list({ outpoint, full_status: true }).then(([fileInfo]) => { + Lbry.file_list({ outpoint, full_status: true }).then(([fileInfo]) => { dispatch({ - type: types.DOWNLOADING_STARTED, + type: ACTIONS.DOWNLOADING_STARTED, data: { uri, outpoint, @@ -232,50 +222,50 @@ export function doStartDownload(uri, outpoint) { } export function doDownloadFile(uri, streamInfo) { - return function(dispatch, getState) { - const state = getState(); - + return function(dispatch) { dispatch(doStartDownload(uri, streamInfo.outpoint)); - lbryio - .call("file", "view", { - uri, - outpoint: streamInfo.outpoint, - claim_id: streamInfo.claim_id, - }) - .catch(() => {}); + Lbryio.call('file', 'view', { + uri, + outpoint: streamInfo.outpoint, + claim_id: streamInfo.claim_id, + }).catch(() => {}); dispatch(doClaimEligiblePurchaseRewards()); }; } -export function doLoadVideo(uri) { - return function(dispatch, getState) { - const state = getState(); - +export function doSetPlayingUri(uri) { + return function(dispatch) { dispatch({ - type: types.LOADING_VIDEO_STARTED, + type: ACTIONS.SET_PLAYING_URI, + data: { uri }, + }); + }; +} + +export function doLoadVideo(uri) { + return function(dispatch) { + dispatch({ + type: ACTIONS.LOADING_VIDEO_STARTED, data: { uri, }, }); - lbry - .get({ uri }) + Lbry.get({ uri }) .then(streamInfo => { const timeout = - streamInfo === null || - typeof streamInfo !== "object" || - streamInfo.error == "Timeout"; + streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; if (timeout) { dispatch(doSetPlayingUri(null)); dispatch({ - type: types.LOADING_VIDEO_FAILED, + type: ACTIONS.LOADING_VIDEO_FAILED, data: { uri }, }); - dispatch(doOpenModal(modals.FILE_TIMEOUT, { uri })); + dispatch(doOpenModal(MODALS.FILE_TIMEOUT, { uri })); } else { dispatch(doDownloadFile(uri, streamInfo)); } @@ -283,7 +273,7 @@ export function doLoadVideo(uri) { .catch(() => { dispatch(doSetPlayingUri(null)); dispatch({ - type: types.LOADING_VIDEO_FAILED, + type: ACTIONS.LOADING_VIDEO_FAILED, data: { uri }, }); dispatch( @@ -303,12 +293,11 @@ export function doPurchaseUri(uri) { const balance = selectBalance(state); const fileInfo = makeSelectFileInfoForUri(uri)(state); const downloadingByOutpoint = selectDownloadingByOutpoint(state); - const alreadyDownloading = - fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; + const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; function attemptPlay(cost, instantPurchaseMax = null) { if (cost > 0 && (!instantPurchaseMax || cost > instantPurchaseMax)) { - dispatch(doOpenModal(modals.AFFIRM_PURCHASE, { uri })); + dispatch(doOpenModal(MODALS.AFFIRM_PURCHASE, { uri })); } else { dispatch(doLoadVideo(uri)); } @@ -321,12 +310,14 @@ export function doPurchaseUri(uri) { // doLoadVideo action to reconstruct the file from the blobs if (!fileInfo.written_bytes) dispatch(doLoadVideo(uri)); - return Promise.resolve(); + Promise.resolve(); + return; } // we are already downloading the file if (alreadyDownloading) { - return Promise.resolve(); + Promise.resolve(); + return; } const costInfo = makeSelectCostInfoForUri(uri)(state); @@ -334,25 +325,21 @@ export function doPurchaseUri(uri) { if (cost > balance) { dispatch(doSetPlayingUri(null)); - dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS)); - return Promise.resolve(); + dispatch(doOpenModal(MODALS.INSUFFICIENT_CREDITS)); + Promise.resolve(); + return; } - if ( - cost == 0 || - !makeSelectClientSetting(settings.INSTANT_PURCHASE_ENABLED)(state) - ) { + if (cost === 0 || !makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state)) { attemptPlay(cost); } else { - const instantPurchaseMax = makeSelectClientSetting( - settings.INSTANT_PURCHASE_MAX - )(state); - if (instantPurchaseMax.currency == "LBC") { + const instantPurchaseMax = makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_MAX)(state); + if (instantPurchaseMax.currency === 'LBC') { attemptPlay(cost, instantPurchaseMax.amount); } else { // Need to convert currency of instant purchase maximum before trying to play - lbryio.getExchangeRates().then(({ lbc_usd }) => { - attemptPlay(cost, instantPurchaseMax.amount / lbc_usd); + Lbryio.getExchangeRates().then(({ LBC_USD }) => { + attemptPlay(cost, instantPurchaseMax.amount / LBC_USD); }); } } @@ -360,22 +347,22 @@ export function doPurchaseUri(uri) { } export function doFetchClaimsByChannel(uri, page) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.FETCH_CHANNEL_CLAIMS_STARTED, + type: ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED, data: { uri, page }, }); - lbry.claim_list_by_channel({ uri, page: page || 1 }).then(result => { + Lbry.claim_list_by_channel({ uri, page: page || 1 }).then(result => { const claimResult = result[uri] || {}; - const { claims_in_channel, returned_page } = claimResult; + const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; dispatch({ - type: types.FETCH_CHANNEL_CLAIMS_COMPLETED, + type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, data: { uri, - claims: claims_in_channel || [], - page: returned_page || undefined, + claims: claimsInChannel || [], + page: returnedPage || undefined, }, }); }); @@ -383,18 +370,18 @@ export function doFetchClaimsByChannel(uri, page) { } export function doFetchClaimCountByChannel(uri) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.FETCH_CHANNEL_CLAIM_COUNT_STARTED, + type: ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_STARTED, data: { uri }, }); - lbry.claim_list_by_channel({ uri }).then(result => { - const claimResult = result[uri], - totalClaims = claimResult ? claimResult.claims_in_channel : 0; + Lbry.claim_list_by_channel({ uri }).then(result => { + const claimResult = result[uri]; + const totalClaims = claimResult ? claimResult.claims_in_channel : 0; dispatch({ - type: types.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED, + type: ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED, data: { uri, totalClaims, @@ -405,14 +392,14 @@ export function doFetchClaimCountByChannel(uri) { } export function doFetchClaimListMine() { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.FETCH_CLAIM_LIST_MINE_STARTED, + type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); - lbry.claim_list_mine().then(claims => { + Lbry.claim_list_mine().then(claims => { dispatch({ - type: types.FETCH_CLAIM_LIST_MINE_COMPLETED, + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, data: { claims, }, @@ -422,69 +409,59 @@ export function doFetchClaimListMine() { } export function doPlayUri(uri) { - return function(dispatch, getState) { + return function(dispatch) { dispatch(doSetPlayingUri(uri)); dispatch(doPurchaseUri(uri)); }; } -export function doSetPlayingUri(uri) { - return function(dispatch, getState) { - dispatch({ - type: types.SET_PLAYING_URI, - data: { uri }, - }); - }; -} - export function doFetchChannelListMine() { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.FETCH_CHANNEL_LIST_MINE_STARTED, + type: ACTIONS.FETCH_CHANNEL_LIST_MINE_STARTED, }); const callback = channels => { dispatch({ - type: types.FETCH_CHANNEL_LIST_MINE_COMPLETED, + type: ACTIONS.FETCH_CHANNEL_LIST_MINE_COMPLETED, data: { claims: channels }, }); }; - lbry.channel_list_mine().then(callback); + Lbry.channel_list_mine().then(callback); }; } export function doCreateChannel(name, amount) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.CREATE_CHANNEL_STARTED, + type: ACTIONS.CREATE_CHANNEL_STARTED, }); return new Promise((resolve, reject) => { - lbry - .channel_new({ - channel_name: name, - amount: parseFloat(amount), - }) - .then( - channelClaim => { - channelClaim.name = name; - dispatch({ - type: types.CREATE_CHANNEL_COMPLETED, - data: { channelClaim }, - }); - resolve(channelClaim); - }, - err => { - reject(err); - } - ); + Lbry.channel_new({ + channel_name: name, + amount: parseFloat(amount), + }).then( + channelClaim => { + const newChannelClaim = channelClaim; + newChannelClaim.name = name; + dispatch({ + type: ACTIONS.CREATE_CHANNEL_COMPLETED, + data: { newChannelClaim }, + }); + resolve(newChannelClaim); + }, + error => { + reject(error); + } + ); }); }; } export function doPublish(params) { - return function(dispatch, getState) { + return function(dispatch) { return new Promise((resolve, reject) => { const success = claim => { resolve(claim); @@ -497,7 +474,7 @@ export function doPublish(params) { }; const failure = err => reject(err); - lbry.publishDeprecated(params, null, success, failure); + Lbry.publishDeprecated(params, null, success, failure); }); }; } @@ -507,40 +484,38 @@ export function doAbandonClaim(txid, nout) { const state = getState(); const transactionItems = selectTransactionItems(state); const { claim_id: claimId, claim_name: name } = transactionItems.find( - claim => claim.txid == txid && claim.nout == nout + claim => claim.txid === txid && claim.nout === nout ); dispatch({ - type: types.ABANDON_CLAIM_STARTED, + type: ACTIONS.ABANDON_CLAIM_STARTED, data: { claimId, }, }); - const errorCallback = error => { - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + const errorCallback = () => { + dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); }; const successCallback = results => { if (results.txid) { dispatch({ - type: types.ABANDON_CLAIM_SUCCEEDED, + type: ACTIONS.ABANDON_CLAIM_SUCCEEDED, data: { claimId, }, }); - dispatch(doResolveUri(lbryuri.build({ name, claimId }))); + dispatch(doResolveUri(Lbryuri.build({ name, claimId }))); dispatch(doFetchClaimListMine()); } else { - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); } }; - lbry - .claim_abandon({ - txid, - nout, - }) - .then(successCallback, errorCallback); + Lbry.claim_abandon({ + txid, + nout, + }).then(successCallback, errorCallback); }; } diff --git a/src/renderer/redux/actions/cost_info.js b/src/renderer/redux/actions/cost_info.js index 8420e3cd4..acd0dc8cc 100644 --- a/src/renderer/redux/actions/cost_info.js +++ b/src/renderer/redux/actions/cost_info.js @@ -1,31 +1,18 @@ -import * as types from "constants/action_types"; -import lbry from "lbry"; -import lbryio from "lbryio"; -import { doResolveUri } from "redux/actions/content"; -import { selectResolvingUris } from "redux/selectors/content"; -import { selectClaimsByUri } from "redux/selectors/claims"; -import { selectSettingsIsGenerous } from "redux/selectors/settings"; +import * as ACTIONS from 'constants/action_types'; +import Lbryio from 'lbryio'; +import { selectClaimsByUri } from 'redux/selectors/claims'; +// eslint-disable-next-line import/prefer-default-export export function doFetchCostInfoForUri(uri) { return function(dispatch, getState) { - const state = getState(), - claim = selectClaimsByUri(state)[uri], - isGenerous = selectSettingsIsGenerous(state); + const state = getState(); + const claim = selectClaimsByUri(state)[uri]; - if (!claim) return null; - - function begin() { - dispatch({ - type: types.FETCH_COST_INFO_STARTED, - data: { - uri, - }, - }); - } + if (!claim) return; function resolve(costInfo) { dispatch({ - type: types.FETCH_COST_INFO_COMPLETED, + type: ACTIONS.FETCH_COST_INFO_COMPLETED, data: { uri, costInfo, @@ -33,18 +20,6 @@ export function doFetchCostInfoForUri(uri) { }); } - /** - * "Generous" check below is disabled. We're no longer attempting to include or estimate data fees regardless of settings. - * - * This should be modified when lbry.stream_cost_estimate is reliable and performant. - */ - - /* - lbry.stream_cost_estimate({ uri }).then(cost => { - cacheAndResolve(cost); - }, reject); - */ - const fee = claim.value && claim.value.stream && claim.value.stream.metadata ? claim.value.stream.metadata.fee @@ -52,35 +27,12 @@ export function doFetchCostInfoForUri(uri) { if (fee === undefined) { resolve({ cost: 0, includesData: true }); - } else if (fee.currency == "LBC") { + } else if (fee.currency === 'LBC') { resolve({ cost: fee.amount, includesData: true }); } else { - // begin(); - lbryio.getExchangeRates().then(({ lbc_usd }) => { - resolve({ cost: fee.amount / lbc_usd, includesData: true }); + Lbryio.getExchangeRates().then(({ LBC_USD }) => { + resolve({ cost: fee.amount / LBC_USD, includesData: true }); }); } - - // if (isGenerous && claim) { - // let cost; - // const fee = claim.value && - // claim.value.stream && - // claim.value.stream.metadata - // ? claim.value.stream.metadata.fee - // : undefined; - // if (fee === undefined) { - // resolve({ cost: 0, includesData: true }); - // } else if (fee.currency == "LBC") { - // resolve({ cost: fee.amount, includesData: true }); - // } else { - // // begin(); - // lbryio.getExchangeRates().then(({ lbc_usd }) => { - // resolve({ cost: fee.amount / lbc_usd, includesData: true }); - // }); - // } - // } else { - // begin(); - // lbry.getCostInfo(uri).then(resolve); - // } }; } diff --git a/src/renderer/redux/actions/file_info.js b/src/renderer/redux/actions/file_info.js index 68743bd05..d18bd2533 100644 --- a/src/renderer/redux/actions/file_info.js +++ b/src/renderer/redux/actions/file_info.js @@ -1,23 +1,22 @@ -import * as types from "constants/action_types"; -import lbry from "lbry"; -import { doFetchClaimListMine, doAbandonClaim } from "redux/actions/content"; +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; +import { doFetchClaimListMine, doAbandonClaim } from 'redux/actions/content'; import { selectClaimsByUri, selectIsFetchingClaimListMine, selectMyClaimsOutpoints, -} from "redux/selectors/claims"; +} from 'redux/selectors/claims'; import { selectIsFetchingFileList, selectFileInfosByOutpoint, selectUrisLoading, selectTotalDownloadProgress, -} from "redux/selectors/file_info"; -import { doCloseModal } from "redux/actions/app"; -import { doNavigate, doHistoryBack } from "redux/actions/navigation"; -import setProgressBar from "util/setProgressBar"; -import batchActions from "util/batchActions"; - -const { shell } = require("electron"); +} from 'redux/selectors/file_info'; +import { doCloseModal } from 'redux/actions/app'; +import { doHistoryBack } from 'redux/actions/navigation'; +import setProgressBar from 'util/setProgressBar'; +import batchActions from 'util/batchActions'; +import { shell } from 'electron'; export function doFetchFileInfo(uri) { return function(dispatch, getState) { @@ -28,15 +27,15 @@ export function doFetchFileInfo(uri) { if (!alreadyFetching) { dispatch({ - type: types.FETCH_FILE_INFO_STARTED, + type: ACTIONS.FETCH_FILE_INFO_STARTED, data: { outpoint, }, }); - lbry.file_list({ outpoint, full_status: true }).then(fileInfos => { + Lbry.file_list({ outpoint, full_status: true }).then(fileInfos => { dispatch({ - type: types.FETCH_FILE_INFO_COMPLETED, + type: ACTIONS.FETCH_FILE_INFO_COMPLETED, data: { outpoint, fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null, @@ -54,12 +53,12 @@ export function doFileList() { if (!isFetching) { dispatch({ - type: types.FILE_LIST_STARTED, + type: ACTIONS.FILE_LIST_STARTED, }); - lbry.file_list().then(fileInfos => { + Lbry.file_list().then(fileInfos => { dispatch({ - type: types.FILE_LIST_SUCCEEDED, + type: ACTIONS.FILE_LIST_SUCCEEDED, data: { fileInfos, }, @@ -69,8 +68,14 @@ export function doFileList() { }; } +export function doOpenFileInFolder(path) { + return function() { + shell.showItemInFolder(path); + }; +} + export function doOpenFileInShell(path) { - return function(dispatch, getState) { + return function(dispatch) { const success = shell.openItem(path); if (!success) { dispatch(doOpenFileInFolder(path)); @@ -78,17 +83,11 @@ export function doOpenFileInShell(path) { }; } -export function doOpenFileInFolder(path) { - return function(dispatch, getState) { - shell.showItemInFolder(path); - }; -} - export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) { return function(dispatch, getState) { const state = getState(); - lbry.file_delete({ + Lbry.file_delete({ outpoint, delete_from_download_dir: deleteFromComputer, }); @@ -108,7 +107,7 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) { } dispatch({ - type: types.FILE_DELETE, + type: ACTIONS.FILE_DELETE, data: { outpoint, }, @@ -119,12 +118,8 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) { }; } -export function doDeleteFileAndGoBack( - fileInfo, - deleteFromComputer, - abandonClaim -) { - return function(dispatch, getState) { +export function doDeleteFileAndGoBack(fileInfo, deleteFromComputer, abandonClaim) { + return function(dispatch) { const actions = []; actions.push(doCloseModal()); actions.push(doHistoryBack()); @@ -135,9 +130,9 @@ export function doDeleteFileAndGoBack( export function doFetchFileInfosAndPublishedClaims() { return function(dispatch, getState) { - const state = getState(), - isFetchingClaimListMine = selectIsFetchingClaimListMine(state), - isFetchingFileInfo = selectIsFetchingFileList(state); + const state = getState(); + const isFetchingClaimListMine = selectIsFetchingClaimListMine(state); + const isFetchingFileInfo = selectIsFetchingFileList(state); if (!isFetchingClaimListMine) dispatch(doFetchClaimListMine()); if (!isFetchingFileInfo) dispatch(doFileList()); diff --git a/src/renderer/redux/actions/navigation.js b/src/renderer/redux/actions/navigation.js index 89028458c..57d0ada19 100644 --- a/src/renderer/redux/actions/navigation.js +++ b/src/renderer/redux/actions/navigation.js @@ -1,18 +1,10 @@ -import * as types from "constants/action_types"; -import { - computePageFromPath, - selectPageTitle, - selectCurrentPage, - selectCurrentParams, - selectHistoryStack, - selectHistoryIndex, -} from "redux/selectors/navigation"; -import { doSearch } from "redux/actions/search"; -import { toQueryString } from "util/query_params"; -import amplitude from "amplitude-js"; +import * as ACTIONS from 'constants/action_types'; +import { selectHistoryStack, selectHistoryIndex } from 'redux/selectors/navigation'; +import { toQueryString } from 'util/query_params'; +import amplitude from 'amplitude-js'; export function doNavigate(path, params = {}, options = {}) { - return function(dispatch, getState) { + return function(dispatch) { if (!path) { return; } @@ -22,40 +14,38 @@ export function doNavigate(path, params = {}, options = {}) { url += `?${toQueryString(params)}`; } - const scrollY = options.scrollY; + const { scrollY } = options; - amplitude.getInstance().logEvent("NAVIGATION", { destination: url }); + amplitude.getInstance().logEvent('NAVIGATION', { destination: url }); dispatch({ - type: types.HISTORY_NAVIGATE, + type: ACTIONS.HISTORY_NAVIGATE, data: { url, index: options.index, scrollY }, }); }; } export function doAuthNavigate(pathAfterAuth = null, params = {}) { - return function(dispatch, getState) { + return function(dispatch) { if (pathAfterAuth) { dispatch({ - type: types.CHANGE_AFTER_AUTH_PATH, + type: ACTIONS.CHANGE_AFTER_AUTH_PATH, data: { path: `${pathAfterAuth}?${toQueryString(params)}`, }, }); } - dispatch(doNavigate("/auth")); + dispatch(doNavigate('/auth')); }; } export function doHistoryTraverse(dispatch, state, modifier) { - const stack = selectHistoryStack(state), - index = selectHistoryIndex(state) + modifier; + const stack = selectHistoryStack(state); + const index = selectHistoryIndex(state) + modifier; if (index >= 0 && index < stack.length) { const historyItem = stack[index]; - return dispatch( - doNavigate(historyItem.path, {}, { scrollY: historyItem.scrollY, index }) - ); + dispatch(doNavigate(historyItem.path, {}, { scrollY: historyItem.scrollY, index })); } } @@ -72,9 +62,9 @@ export function doHistoryForward() { } export function doRecordScroll(scroll) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.WINDOW_SCROLLED, + type: ACTIONS.WINDOW_SCROLLED, data: { scrollY: scroll }, }); }; diff --git a/src/renderer/redux/actions/rewards.js b/src/renderer/redux/actions/rewards.js index 67200a63e..4c4a278cd 100644 --- a/src/renderer/redux/actions/rewards.js +++ b/src/renderer/redux/actions/rewards.js @@ -1,30 +1,26 @@ -import * as types from "constants/action_types"; -import * as modals from "constants/modal_types"; -import lbryio from "lbryio"; -import rewards from "rewards"; -import { selectUnclaimedRewardsByType } from "redux/selectors/rewards"; -import { selectUserIsRewardApproved } from "redux/selectors/user"; -import { selectClaimedRewardsById } from "../selectors/rewards"; +import * as ACTIONS from 'constants/action_types'; +import * as MODALS from 'constants/modal_types'; +import Lbryio from 'lbryio'; +import rewards from 'rewards'; +import { selectUnclaimedRewardsByType } from 'redux/selectors/rewards'; +import { selectUserIsRewardApproved } from 'redux/selectors/user'; export function doRewardList() { - return function(dispatch, getState) { - const state = getState(); - + return function(dispatch) { dispatch({ - type: types.FETCH_REWARDS_STARTED, + type: ACTIONS.FETCH_REWARDS_STARTED, }); - lbryio - .call("reward", "list", { multiple_rewards_per_type: true }) + Lbryio.call('reward', 'list', { multiple_rewards_per_type: true }) .then(userRewards => { dispatch({ - type: types.FETCH_REWARDS_COMPLETED, + type: ACTIONS.FETCH_REWARDS_COMPLETED, data: { userRewards }, }); }) .catch(() => { dispatch({ - type: types.FETCH_REWARDS_COMPLETED, + type: ACTIONS.FETCH_REWARDS_COMPLETED, data: { userRewards: [] }, }); }); @@ -33,10 +29,10 @@ export function doRewardList() { export function doClaimRewardType(rewardType) { return function(dispatch, getState) { - const state = getState(), - rewardsByType = selectUnclaimedRewardsByType(state), - reward = rewardsByType[rewardType], - userIsRewardApproved = selectUserIsRewardApproved(state); + const state = getState(); + const rewardsByType = selectUnclaimedRewardsByType(state); + const reward = rewardsByType[rewardType]; + const userIsRewardApproved = selectUserIsRewardApproved(state); if (!reward || reward.transaction_id) { // already claimed or doesn't exist, do nothing @@ -44,35 +40,37 @@ export function doClaimRewardType(rewardType) { } if (!userIsRewardApproved && rewardType !== rewards.TYPE_CONFIRM_EMAIL) { - return dispatch({ - type: types.OPEN_MODAL, - data: { modal: modals.REWARD_APPROVAL_REQUIRED }, + dispatch({ + type: ACTIONS.OPEN_MODAL, + data: { modal: MODALS.REWARD_APPROVAL_REQUIRED }, }); + + return; } dispatch({ - type: types.CLAIM_REWARD_STARTED, + type: ACTIONS.CLAIM_REWARD_STARTED, data: { reward }, }); - const success = reward => { + const success = successReward => { dispatch({ - type: types.CLAIM_REWARD_SUCCESS, + type: ACTIONS.CLAIM_REWARD_SUCCESS, data: { - reward, + reward: successReward, }, }); - if (reward.reward_type == rewards.TYPE_CONFIRM_EMAIL) { + if (successReward.reward_type === rewards.TYPE_CONFIRM_EMAIL) { dispatch({ - type: types.OPEN_MODAL, - data: { modal: modals.FIRST_REWARD }, + type: ACTIONS.OPEN_MODAL, + data: { modal: MODALS.FIRST_REWARD }, }); } }; const failure = error => { dispatch({ - type: types.CLAIM_REWARD_FAILURE, + type: ACTIONS.CLAIM_REWARD_FAILURE, data: { reward, error }, }); }; @@ -83,30 +81,28 @@ export function doClaimRewardType(rewardType) { export function doClaimEligiblePurchaseRewards() { return function(dispatch, getState) { - const state = getState(), - rewardsByType = selectUnclaimedRewardsByType(state), - userIsRewardApproved = selectUserIsRewardApproved(state); + const state = getState(); + const rewardsByType = selectUnclaimedRewardsByType(state); + const userIsRewardApproved = selectUserIsRewardApproved(state); - if (!userIsRewardApproved || !lbryio.enabled) { + if (!userIsRewardApproved || !Lbryio.enabled) { return; } if (rewardsByType[rewards.TYPE_FIRST_STREAM]) { dispatch(doClaimRewardType(rewards.TYPE_FIRST_STREAM)); } else { - [rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_FEATURED_DOWNLOAD].forEach( - type => { - dispatch(doClaimRewardType(type)); - } - ); + [rewards.TYPE_MANY_DOWNLOADS, rewards.TYPE_FEATURED_DOWNLOAD].forEach(type => { + dispatch(doClaimRewardType(type)); + }); } }; } export function doClaimRewardClearError(reward) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.CLAIM_REWARD_CLEAR_ERROR, + type: ACTIONS.CLAIM_REWARD_CLEAR_ERROR, data: { reward }, }); }; diff --git a/src/renderer/redux/actions/search.js b/src/renderer/redux/actions/search.js index aa881f50d..66de54ef1 100644 --- a/src/renderer/redux/actions/search.js +++ b/src/renderer/redux/actions/search.js @@ -1,30 +1,32 @@ -import * as types from "constants/action_types"; -import lbryuri from "lbryuri"; -import { doResolveUri } from "redux/actions/content"; -import { doNavigate } from "redux/actions/navigation"; -import { selectCurrentPage } from "redux/selectors/navigation"; -import batchActions from "util/batchActions"; +import * as ACTIONS from 'constants/action_types'; +import Lbryuri from 'lbryuri'; +import { doResolveUri } from 'redux/actions/content'; +import { doNavigate } from 'redux/actions/navigation'; +import { selectCurrentPage } from 'redux/selectors/navigation'; +import batchActions from 'util/batchActions'; +// eslint-disable-next-line import/prefer-default-export export function doSearch(rawQuery) { return function(dispatch, getState) { const state = getState(); const page = selectCurrentPage(state); - const query = rawQuery.replace(/^lbry:\/\//i, ""); + const query = rawQuery.replace(/^lbry:\/\//i, ''); if (!query) { - return dispatch({ - type: types.SEARCH_CANCELLED, + dispatch({ + type: ACTIONS.SEARCH_CANCELLED, }); + return; } dispatch({ - type: types.SEARCH_STARTED, + type: ACTIONS.SEARCH_STARTED, data: { query }, }); - if (page != "search") { - dispatch(doNavigate("search", { query })); + if (page !== 'search') { + dispatch(doNavigate('search', { query })); } else { fetch(`https://lighthouse.lbry.io/search?s=${query}`) .then( @@ -38,7 +40,7 @@ export function doSearch(rawQuery) { const actions = []; data.forEach(result => { - const uri = lbryuri.build({ + const uri = Lbryuri.build({ name: result.name, claimId: result.claimId, }); @@ -47,7 +49,7 @@ export function doSearch(rawQuery) { }); actions.push({ - type: types.SEARCH_COMPLETED, + type: ACTIONS.SEARCH_COMPLETED, data: { query, uris, @@ -55,9 +57,9 @@ export function doSearch(rawQuery) { }); dispatch(batchActions(...actions)); }) - .catch(err => { + .catch(() => { dispatch({ - type: types.SEARCH_CANCELLED, + type: ACTIONS.SEARCH_CANCELLED, }); }); } diff --git a/src/renderer/redux/actions/settings.js b/src/renderer/redux/actions/settings.js index ba8b5ebcd..ec6506b15 100644 --- a/src/renderer/redux/actions/settings.js +++ b/src/renderer/redux/actions/settings.js @@ -1,17 +1,15 @@ -import * as types from "constants/action_types"; -import * as settings from "constants/settings"; -import { doAlertError } from "redux/actions/app"; -import batchActions from "util/batchActions"; +import * as ACTIONS from 'constants/action_types'; +import * as SETTINGS from 'constants/settings'; -import lbry from "lbry"; -import fs from "fs"; -import http from "http"; +import Lbry from 'lbry'; +import Fs from 'fs'; +import Http from 'http'; export function doFetchDaemonSettings() { - return function(dispatch, getState) { - lbry.settings_get().then(settings => { + return function(dispatch) { + Lbry.settings_get().then(settings => { dispatch({ - type: types.DAEMON_SETTINGS_RECEIVED, + type: ACTIONS.DAEMON_SETTINGS_RECEIVED, data: { settings, }, @@ -21,15 +19,15 @@ export function doFetchDaemonSettings() { } export function doSetDaemonSetting(key, value) { - return function(dispatch, getState) { + return function(dispatch) { const settings = {}; settings[key] = value; - lbry.settings_set(settings).then(settings); - lbry.settings_get().then(settings => { + Lbry.settings_set(settings).then(settings); + Lbry.settings_get().then(remoteSettings => { dispatch({ - type: types.DAEMON_SETTINGS_RECEIVED, + type: ACTIONS.DAEMON_SETTINGS_RECEIVED, data: { - settings, + remoteSettings, }, }); }); @@ -38,7 +36,7 @@ export function doSetDaemonSetting(key, value) { export function doSetClientSetting(key, value) { return { - type: types.CLIENT_SETTING_CHANGED, + type: ACTIONS.CLIENT_SETTING_CHANGED, data: { key, value, @@ -47,100 +45,98 @@ export function doSetClientSetting(key, value) { } export function doGetThemes() { - return function(dispatch, getState) { - const themes = ["light", "dark"]; - dispatch(doSetClientSetting(settings.THEMES, themes)); + return function(dispatch) { + const themes = ['light', 'dark']; + dispatch(doSetClientSetting(SETTINGS.THEMES, themes)); }; } export function doDownloadLanguage(langFile) { - return function(dispatch, getState) { + return function(dispatch) { const destinationPath = `${app.i18n.directory}/${langFile}`; - const language = langFile.replace(".json", ""); - const req = http.get( + const language = langFile.replace('.json', ''); + const errorHandler = () => { + Fs.unlink(destinationPath, () => {}); // Delete the file async. (But we don't check the result) + + dispatch({ + type: ACTIONS.DOWNLOAD_LANGUAGE_FAILED, + data: { language }, + }); + }; + + const req = Http.get( { headers: { - "Content-Type": "text/html", + 'Content-Type': 'text/html', }, - host: "i18n.lbry.io", + host: 'i18n.lbry.io', path: `/langs/${langFile}`, }, response => { if (response.statusCode === 200) { - const file = fs.createWriteStream(destinationPath); + const file = Fs.createWriteStream(destinationPath); - file.on("error", errorHandler); - file.on("finish", () => { + file.on('error', errorHandler); + file.on('finish', () => { file.close(); // push to our local list dispatch({ - type: types.DOWNLOAD_LANGUAGE_SUCCEEDED, + type: ACTIONS.DOWNLOAD_LANGUAGE_SUCCEEDED, data: { language }, }); }); response.pipe(file); } else { - errorHandler(new Error("Language request failed.")); + errorHandler(new Error('Language request failed.')); } } ); - const errorHandler = err => { - fs.unlink(destinationPath, () => {}); // Delete the file async. (But we don't check the result) - - dispatch({ - type: types.DOWNLOAD_LANGUAGE_FAILED, - data: { language }, - }); - }; - req.setTimeout(30000, () => { req.abort(); }); - req.on("error", errorHandler); + req.on('error', errorHandler); req.end(); }; } export function doDownloadLanguages() { - return function(dispatch, getState) { + return function() { // temporarily disable i18n so I can get a working build out -- Jeremy - return; - - if (!fs.existsSync(app.i18n.directory)) { - fs.mkdirSync(app.i18n.directory); - } - - function checkStatus(response) { - if (response.status >= 200 && response.status < 300) { - return response; - } - throw new Error( - __("The list of available languages could not be retrieved.") - ); - } - - function parseJSON(response) { - return response.json(); - } - - return fetch("http://i18n.lbry.io") - .then(checkStatus) - .then(parseJSON) - .then(files => { - const actions = files.map(doDownloadLanguage); - dispatch(batchActions(...actions)); - }); + // if (!Fs.existsSync(app.i18n.directory)) { + // Fs.mkdirSync(app.i18n.directory); + // } + // + // function checkStatus(response) { + // if (response.status >= 200 && response.status < 300) { + // return response; + // } + // throw new Error( + // __("The list of available languages could not be retrieved.") + // ); + // } + // + // function parseJSON(response) { + // return response.json(); + // } + // + // return fetch("http://i18n.lbry.io") + // .then(checkStatus) + // .then(parseJSON) + // .then(files => { + // const actions = files.map(doDownloadLanguage); + // dispatch(batchActions(...actions)); + // }); }; } export function doChangeLanguage(language) { - return function(dispatch, getState) { - dispatch(doSetClientSetting(settings.LANGUAGE, language)); + return function(dispatch) { + dispatch(doSetClientSetting(SETTINGS.LANGUAGE, language)); app.i18n.setLocale(language); }; } diff --git a/src/renderer/redux/actions/shape_shift.js b/src/renderer/redux/actions/shape_shift.js index 520dff9cb..293b565ef 100644 --- a/src/renderer/redux/actions/shape_shift.js +++ b/src/renderer/redux/actions/shape_shift.js @@ -1,7 +1,7 @@ // @flow -import Promise from "bluebird"; -import * as types from "constants/action_types"; -import { coinRegexPatterns } from "util/shape_shift"; +import Promise from 'bluebird'; +import * as ACTIONS from 'constants/action_types'; +import { coinRegexPatterns } from 'util/shape_shift'; import type { GetSupportedCoinsSuccess, GetCoinStatsStart, @@ -11,26 +11,26 @@ import type { PrepareShapeShiftFail, GetActiveShiftSuccess, GetActiveShiftFail, -} from "redux/reducers/shape_shift"; -import type { FormikActions } from "types/common"; +} from 'redux/reducers/shape_shift'; +import type { FormikActions } from 'types/common'; // use promise chains instead of callbacks for shapeshift api -const shapeShift = Promise.promisifyAll(require("shapeshift.io")); +const shapeShift = Promise.promisifyAll(require('shapeshift.io')); // All ShapeShift actions // Action types defined in the reducer will contain some payload export type Action = - | { type: types.GET_SUPPORTED_COINS_START } - | { type: types.GET_SUPPORTED_COINS_FAIL } + | { type: ACTIONS.GET_SUPPORTED_COINS_START } + | { type: ACTIONS.GET_SUPPORTED_COINS_FAIL } | GetSupportedCoinsSuccess | GetCoinStatsStart - | { type: types.GET_COIN_STATS_START } + | { type: ACTIONS.GET_COIN_STATS_START } | GetCoinStatsFail | GetCoinStatsSuccess - | { type: types.PREPARE_SHAPE_SHIFT_START } + | { type: ACTIONS.PREPARE_SHAPE_SHIFT_START } | PrepareShapeShiftFail | PrepareShapeShiftSuccess - | { type: types.GET_ACTIVE_SHIFT_START } + | { type: ACTIONS.GET_ACTIVE_SHIFT_START } | GetActiveShiftFail | GetActiveShiftSuccess; @@ -38,10 +38,8 @@ export type Action = // It would be nice to import these from types/common // Not sure how that would work since they rely on the Action type type PromiseAction = Promise; +export type Dispatch = (action: Action | PromiseAction | Array) => any; type ThunkAction = (dispatch: Dispatch) => any; -export type Dispatch = ( - action: Action | ThunkAction | PromiseAction | Array -) => any; // ShapeShift form values export type ShapeShiftFormValues = { @@ -50,15 +48,26 @@ export type ShapeShiftFormValues = { receiveAddress: string, }; +export const getCoinStats = (coin: string) => (dispatch: Dispatch): ThunkAction => { + const pair = `${coin.toLowerCase()}_lbc`; + + dispatch({ type: ACTIONS.GET_COIN_STATS_START, data: coin }); + + return shapeShift + .marketInfoAsync(pair) + .then(marketInfo => dispatch({ type: ACTIONS.GET_COIN_STATS_SUCCESS, data: marketInfo })) + .catch(err => dispatch({ type: ACTIONS.GET_COIN_STATS_FAIL, data: err })); +}; + export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { - dispatch({ type: types.GET_SUPPORTED_COINS_START }); + dispatch({ type: ACTIONS.GET_SUPPORTED_COINS_START }); return shapeShift .coinsAsync() .then(coinData => { let supportedCoins = []; Object.keys(coinData).forEach(symbol => { - if (coinData[symbol].status === "available") { + if (coinData[symbol].status === 'available') { supportedCoins.push(coinData[symbol]); } }); @@ -69,69 +78,43 @@ export const shapeShiftInit = () => (dispatch: Dispatch): ThunkAction => { .map(coin => coin.symbol); dispatch({ - type: types.GET_SUPPORTED_COINS_SUCCESS, + type: ACTIONS.GET_SUPPORTED_COINS_SUCCESS, data: supportedCoins, }); dispatch(getCoinStats(supportedCoins[0])); }) - .catch(err => - dispatch({ type: types.GET_SUPPORTED_COINS_FAIL, data: err }) - ); + .catch(err => dispatch({ type: ACTIONS.GET_SUPPORTED_COINS_FAIL, data: err })); }; -export const getCoinStats = (coin: string) => ( +export const createShapeShift = (values: ShapeShiftFormValues, actions: FormikActions) => ( dispatch: Dispatch ): ThunkAction => { - const pair = `${coin.toLowerCase()}_lbc`; - - dispatch({ type: types.GET_COIN_STATS_START, data: coin }); - - return shapeShift - .marketInfoAsync(pair) - .then(marketInfo => - dispatch({ type: types.GET_COIN_STATS_SUCCESS, data: marketInfo }) - ) - .catch(err => dispatch({ type: types.GET_COIN_STATS_FAIL, data: err })); -}; - -export const createShapeShift = ( - values: ShapeShiftFormValues, - actions: FormikActions -) => (dispatch: Dispatch): ThunkAction => { - const { - originCoin, - returnAddress, - receiveAddress: withdrawalAddress, - } = values; + const { originCoin, returnAddress, receiveAddress: withdrawalAddress } = values; const pair = `${originCoin.toLowerCase()}_lbc`; const options = { returnAddress, }; - dispatch({ type: types.PREPARE_SHAPE_SHIFT_START }); + dispatch({ type: ACTIONS.PREPARE_SHAPE_SHIFT_START }); return shapeShift .shiftAsync(withdrawalAddress, pair, options) - .then(res => - dispatch({ type: types.PREPARE_SHAPE_SHIFT_SUCCESS, data: res }) - ) + .then(res => dispatch({ type: ACTIONS.PREPARE_SHAPE_SHIFT_SUCCESS, data: res })) .catch(err => { - dispatch({ type: types.PREPARE_SHAPE_SHIFT_FAIL, data: err }); + dispatch({ type: ACTIONS.PREPARE_SHAPE_SHIFT_FAIL, data: err }); // for formik to stop the submit actions.setSubmitting(false); }); }; -export const getActiveShift = (depositAddress: string) => ( - dispatch: Dispatch -): ThunkAction => { - dispatch({ type: types.GET_ACTIVE_SHIFT_START }); +export const getActiveShift = (depositAddress: string) => (dispatch: Dispatch): ThunkAction => { + dispatch({ type: ACTIONS.GET_ACTIVE_SHIFT_START }); return shapeShift .statusAsync(depositAddress) - .then(res => dispatch({ type: types.GET_ACTIVE_SHIFT_SUCCESS, data: res })) - .catch(err => dispatch({ type: types.GET_ACTIVE_SHIFT_FAIL, data: err })); + .then(res => dispatch({ type: ACTIONS.GET_ACTIVE_SHIFT_SUCCESS, data: res })) + .catch(err => dispatch({ type: ACTIONS.GET_ACTIVE_SHIFT_FAIL, data: err })); }; export const clearShapeShift = () => (dispatch: Dispatch): Action => - dispatch({ type: types.CLEAR_SHAPE_SHIFT }); + dispatch({ type: ACTIONS.CLEAR_SHAPE_SHIFT }); diff --git a/src/renderer/redux/actions/subscriptions.js b/src/renderer/redux/actions/subscriptions.js index 6963b95bf..e3eb939ed 100644 --- a/src/renderer/redux/actions/subscriptions.js +++ b/src/renderer/redux/actions/subscriptions.js @@ -1,27 +1,18 @@ // @flow -import * as actions from "constants/action_types"; -import type { - Subscription, - Action, - Dispatch, -} from "redux/reducers/subscriptions"; -import lbry from "lbry"; +import * as ACTIONS from 'constants/action_types'; +import type { Subscription, Dispatch } from 'redux/reducers/subscriptions'; -export const doChannelSubscribe = (subscription: Subscription) => ( - dispatch: Dispatch -) => +export const doChannelSubscribe = (subscription: Subscription) => (dispatch: Dispatch) => dispatch({ - type: actions.CHANNEL_SUBSCRIBE, + type: ACTIONS.CHANNEL_SUBSCRIBE, data: subscription, }); -export const doChannelUnsubscribe = (subscription: Subscription) => ( - dispatch: Dispatch -) => +export const doChannelUnsubscribe = (subscription: Subscription) => (dispatch: Dispatch) => dispatch({ - type: actions.CHANNEL_UNSUBSCRIBE, + type: ACTIONS.CHANNEL_UNSUBSCRIBE, data: subscription, }); export const setHasFetchedSubscriptions = () => (dispatch: Dispatch) => - dispatch({ type: actions.HAS_FETCHED_SUBSCRIPTIONS }); + dispatch({ type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS }); diff --git a/src/renderer/redux/actions/user.js b/src/renderer/redux/actions/user.js index 3fb7f8f43..1dfbee4ca 100644 --- a/src/renderer/redux/actions/user.js +++ b/src/renderer/redux/actions/user.js @@ -1,30 +1,54 @@ -import * as types from "constants/action_types"; -import * as modals from "constants/modal_types"; -import lbryio from "lbryio"; -import { doOpenModal, doShowSnackBar } from "redux/actions/app"; -import { doRewardList, doClaimRewardType } from "redux/actions/rewards"; -import { selectEmailToVerify, selectUser } from "redux/selectors/user"; -import rewards from "rewards"; +import * as ACTIONS from 'constants/action_types'; +import * as MODALS from 'constants/modal_types'; +import Lbryio from 'lbryio'; +import { doOpenModal, doShowSnackBar } from 'redux/actions/app'; +import { doRewardList, doClaimRewardType } from 'redux/actions/rewards'; +import { selectEmailToVerify } from 'redux/selectors/user'; +import rewards from 'rewards'; + +export function doFetchInviteStatus() { + return function(dispatch) { + dispatch({ + type: ACTIONS.USER_INVITE_STATUS_FETCH_STARTED, + }); + + Lbryio.call('user', 'invite_status') + .then(status => { + dispatch({ + type: ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS, + data: { + invitesRemaining: status.invites_remaining ? status.invites_remaining : 0, + invitees: status.invitees, + }, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE, + data: { error }, + }); + }); + }; +} export function doAuthenticate() { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.AUTHENTICATION_STARTED, + type: ACTIONS.AUTHENTICATION_STARTED, }); - lbryio - .authenticate() + Lbryio.authenticate() .then(user => { dispatch({ - type: types.AUTHENTICATION_SUCCESS, + type: ACTIONS.AUTHENTICATION_SUCCESS, data: { user }, }); dispatch(doRewardList()); dispatch(doFetchInviteStatus()); }) .catch(error => { - dispatch(doOpenModal(modals.AUTHENTICATION_FAILURE)); + dispatch(doOpenModal(MODALS.AUTHENTICATION_FAILURE)); dispatch({ - type: types.AUTHENTICATION_FAILURE, + type: ACTIONS.AUTHENTICATION_FAILURE, data: { error }, }); }); @@ -32,23 +56,22 @@ export function doAuthenticate() { } export function doUserFetch() { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.USER_FETCH_STARTED, + type: ACTIONS.USER_FETCH_STARTED, }); - lbryio - .getCurrentUser() + Lbryio.getCurrentUser() .then(user => { dispatch(doRewardList()); dispatch({ - type: types.USER_FETCH_SUCCESS, + type: ACTIONS.USER_FETCH_SUCCESS, data: { user }, }); }) .catch(error => { dispatch({ - type: types.USER_FETCH_FAILURE, + type: ACTIONS.USER_FETCH_FAILURE, data: { error }, }); }); @@ -56,15 +79,15 @@ export function doUserFetch() { } export function doUserEmailNew(email) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.USER_EMAIL_NEW_STARTED, + type: ACTIONS.USER_EMAIL_NEW_STARTED, email, }); const success = () => { dispatch({ - type: types.USER_EMAIL_NEW_SUCCESS, + type: ACTIONS.USER_EMAIL_NEW_SUCCESS, data: { email }, }); dispatch(doUserFetch()); @@ -72,28 +95,20 @@ export function doUserEmailNew(email) { const failure = error => { dispatch({ - type: types.USER_EMAIL_NEW_FAILURE, + type: ACTIONS.USER_EMAIL_NEW_FAILURE, data: { error }, }); }; - lbryio - .call( - "user_email", - "new", - { email, send_verification_email: true }, - "post" - ) + Lbryio.call('user_email', 'new', { email, send_verification_email: true }, 'post') .catch(error => { - if (error.response && error.response.status == 409) { - return lbryio - .call( - "user_email", - "resend_token", - { email, only_if_expired: true }, - "post" - ) - .then(success, failure); + if (error.response && error.response.status === 409) { + return Lbryio.call( + 'user_email', + 'resend_token', + { email, only_if_expired: true }, + 'post' + ).then(success, failure); } throw error; }) @@ -104,35 +119,34 @@ export function doUserEmailNew(email) { export function doUserEmailVerify(verificationToken) { return function(dispatch, getState) { const email = selectEmailToVerify(getState()); - verificationToken = verificationToken.toString().trim(); + const trimmedVerificationToken = verificationToken.toString().trim(); dispatch({ - type: types.USER_EMAIL_VERIFY_STARTED, - code: verificationToken, + type: ACTIONS.USER_EMAIL_VERIFY_STARTED, + code: trimmedVerificationToken, }); - lbryio - .call( - "user_email", - "confirm", - { verification_token: verificationToken, email }, - "post" - ) + Lbryio.call( + 'user_email', + 'confirm', + { verification_token: trimmedVerificationToken, email }, + 'post' + ) .then(userEmail => { if (userEmail.is_verified) { dispatch({ - type: types.USER_EMAIL_VERIFY_SUCCESS, + type: ACTIONS.USER_EMAIL_VERIFY_SUCCESS, data: { email }, }); - dispatch(doClaimRewardType(rewards.TYPE_CONFIRM_EMAIL)), - dispatch(doUserFetch()); + dispatch(doClaimRewardType(rewards.TYPE_CONFIRM_EMAIL)); + dispatch(doUserFetch()); } else { - throw new Error("Your email is still not verified."); // shouldn't happen + throw new Error('Your email is still not verified.'); // shouldn't happen } }) .catch(error => { dispatch({ - type: types.USER_EMAIL_VERIFY_FAILURE, + type: ACTIONS.USER_EMAIL_VERIFY_FAILURE, data: { error }, }); }); @@ -140,30 +154,27 @@ export function doUserEmailVerify(verificationToken) { } export function doUserIdentityVerify(stripeToken) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.USER_IDENTITY_VERIFY_STARTED, + type: ACTIONS.USER_IDENTITY_VERIFY_STARTED, token: stripeToken, }); - lbryio - .call("user", "verify_identity", { stripe_token: stripeToken }, "post") + Lbryio.call('user', 'verify_identity', { stripe_token: stripeToken }, 'post') .then(user => { if (user.is_identity_verified) { dispatch({ - type: types.USER_IDENTITY_VERIFY_SUCCESS, + type: ACTIONS.USER_IDENTITY_VERIFY_SUCCESS, data: { user }, }); dispatch(doClaimRewardType(rewards.TYPE_NEW_USER)); } else { - throw new Error( - "Your identity is still not verified. This should not happen." - ); // shouldn't happen + throw new Error('Your identity is still not verified. This should not happen.'); // shouldn't happen } }) .catch(error => { dispatch({ - type: types.USER_IDENTITY_VERIFY_FAILURE, + type: ACTIONS.USER_IDENTITY_VERIFY_FAILURE, data: { error: error.toString() }, }); }); @@ -171,61 +182,32 @@ export function doUserIdentityVerify(stripeToken) { } export function doFetchAccessToken() { - return function(dispatch, getState) { + return function(dispatch) { const success = token => dispatch({ - type: types.FETCH_ACCESS_TOKEN_SUCCESS, + type: ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS, data: { token }, }); - lbryio.getAuthToken().then(success); - }; -} - -export function doFetchInviteStatus() { - return function(dispatch, getState) { - dispatch({ - type: types.USER_INVITE_STATUS_FETCH_STARTED, - }); - - lbryio - .call("user", "invite_status") - .then(status => { - dispatch({ - type: types.USER_INVITE_STATUS_FETCH_SUCCESS, - data: { - invitesRemaining: status.invites_remaining - ? status.invites_remaining - : 0, - invitees: status.invitees, - }, - }); - }) - .catch(error => { - dispatch({ - type: types.USER_INVITE_STATUS_FETCH_FAILURE, - data: { error }, - }); - }); + Lbryio.getAuthToken().then(success); }; } export function doUserInviteNew(email) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.USER_INVITE_NEW_STARTED, + type: ACTIONS.USER_INVITE_NEW_STARTED, }); - lbryio - .call("user", "invite", { email }, "post") - .then(invite => { + Lbryio.call('user', 'invite', { email }, 'post') + .then(() => { dispatch({ - type: types.USER_INVITE_NEW_SUCCESS, + type: ACTIONS.USER_INVITE_NEW_SUCCESS, data: { email }, }); dispatch( doShowSnackBar({ - message: __("Invite sent to %s", email), + message: __('Invite sent to %s', email), }) ); @@ -233,7 +215,7 @@ export function doUserInviteNew(email) { }) .catch(error => { dispatch({ - type: types.USER_INVITE_NEW_FAILURE, + type: ACTIONS.USER_INVITE_NEW_FAILURE, data: { error }, }); }); diff --git a/src/renderer/redux/actions/wallet.js b/src/renderer/redux/actions/wallet.js index 0d8d44429..10974085e 100644 --- a/src/renderer/redux/actions/wallet.js +++ b/src/renderer/redux/actions/wallet.js @@ -1,19 +1,19 @@ -import * as types from "constants/action_types"; -import lbry from "lbry"; +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; import { selectDraftTransaction, selectDraftTransactionAmount, selectBalance, -} from "redux/selectors/wallet"; -import { doOpenModal, doShowSnackBar } from "redux/actions/app"; -import { doNavigate } from "redux/actions/navigation"; -import * as modals from "constants/modal_types"; +} from 'redux/selectors/wallet'; +import { doOpenModal, doShowSnackBar } from 'redux/actions/app'; +import { doNavigate } from 'redux/actions/navigation'; +import * as MODALS from 'constants/modal_types'; export function doUpdateBalance() { - return function(dispatch, getState) { - lbry.wallet_balance().then(balance => + return function(dispatch) { + Lbry.wallet_balance().then(balance => dispatch({ - type: types.UPDATE_BALANCE, + type: ACTIONS.UPDATE_BALANCE, data: { balance, }, @@ -23,36 +23,34 @@ export function doUpdateBalance() { } export function doBalanceSubscribe() { - return function(dispatch, getState) { + return function(dispatch) { dispatch(doUpdateBalance()); setInterval(() => dispatch(doUpdateBalance()), 5000); }; } export function doFetchTransactions(fetch_tip_info = true) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.FETCH_TRANSACTIONS_STARTED, + type: ACTIONS.FETCH_TRANSACTIONS_STARTED, }); - lbry - .transaction_list({ include_tip_info: fetch_tip_info }) - .then(results => { - dispatch({ - type: types.FETCH_TRANSACTIONS_COMPLETED, - data: { - transactions: results, - }, - }); + Lbry.transaction_list({ include_tip_info: fetch_tip_info }).then(results => { + dispatch({ + type: ACTIONS.FETCH_TRANSACTIONS_COMPLETED, + data: { + transactions: results, + }, }); + }); }; } export function doFetchBlock(height) { - return function(dispatch, getState) { - lbry.block_show({ height }).then(block => { + return function(dispatch) { + Lbry.block_show({ height }).then(block => { dispatch({ - type: types.FETCH_BLOCK_SUCCESS, + type: ACTIONS.FETCH_BLOCK_SUCCESS, data: { block }, }); }); @@ -60,15 +58,15 @@ export function doFetchBlock(height) { } export function doGetNewAddress() { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.GET_NEW_ADDRESS_STARTED, + type: ACTIONS.GET_NEW_ADDRESS_STARTED, }); - lbry.wallet_new_address().then(address => { - localStorage.setItem("wallet_address", address); + Lbry.wallet_new_address().then(address => { + localStorage.setItem('wallet_address', address); dispatch({ - type: types.GET_NEW_ADDRESS_COMPLETED, + type: ACTIONS.GET_NEW_ADDRESS_COMPLETED, data: { address }, }); }); @@ -76,16 +74,16 @@ export function doGetNewAddress() { } export function doCheckAddressIsMine(address) { - return function(dispatch, getState) { + return function(dispatch) { dispatch({ - type: types.CHECK_ADDRESS_IS_MINE_STARTED, + type: ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED, }); - lbry.wallet_is_address_mine({ address }).then(isMine => { + Lbry.wallet_is_address_mine({ address }).then(isMine => { if (!isMine) dispatch(doGetNewAddress()); dispatch({ - type: types.CHECK_ADDRESS_IS_MINE_COMPLETED, + type: ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED, }); }); }; @@ -99,113 +97,111 @@ export function doSendDraftTransaction() { const amount = selectDraftTransactionAmount(state); if (balance - amount <= 0) { - return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS)); + dispatch(doOpenModal(MODALS.INSUFFICIENT_CREDITS)); + return; } dispatch({ - type: types.SEND_TRANSACTION_STARTED, + type: ACTIONS.SEND_TRANSACTION_STARTED, }); const successCallback = results => { if (results === true) { dispatch({ - type: types.SEND_TRANSACTION_COMPLETED, + type: ACTIONS.SEND_TRANSACTION_COMPLETED, }); dispatch( doShowSnackBar({ message: __(`You sent ${amount} LBC`), - linkText: __("History"), - linkTarget: __("/wallet"), + linkText: __('History'), + linkTarget: __('/wallet'), }) ); } else { dispatch({ - type: types.SEND_TRANSACTION_FAILED, + type: ACTIONS.SEND_TRANSACTION_FAILED, data: { error: results }, }); - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); } }; const errorCallback = error => { dispatch({ - type: types.SEND_TRANSACTION_FAILED, + type: ACTIONS.SEND_TRANSACTION_FAILED, data: { error: error.message }, }); - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); }; - lbry - .wallet_send({ - amount: draftTx.amount, - address: draftTx.address, - }) - .then(successCallback, errorCallback); + Lbry.wallet_send({ + amount: draftTx.amount, + address: draftTx.address, + }).then(successCallback, errorCallback); }; } export function doSetDraftTransactionAmount(amount) { return { - type: types.SET_DRAFT_TRANSACTION_AMOUNT, + type: ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT, data: { amount }, }; } export function doSetDraftTransactionAddress(address) { return { - type: types.SET_DRAFT_TRANSACTION_ADDRESS, + type: ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS, data: { address }, }; } -export function doSendSupport(amount, claim_id, uri) { +export function doSendSupport(amount, claimId, uri) { return function(dispatch, getState) { const state = getState(); const balance = selectBalance(state); if (balance - amount <= 0) { - return dispatch(doOpenModal(modals.INSUFFICIENT_CREDITS)); + dispatch(doOpenModal(MODALS.INSUFFICIENT_CREDITS)); + return; } dispatch({ - type: types.SUPPORT_TRANSACTION_STARTED, + type: ACTIONS.SUPPORT_TRANSACTION_STARTED, }); const successCallback = results => { if (results.txid) { dispatch({ - type: types.SUPPORT_TRANSACTION_COMPLETED, + type: ACTIONS.SUPPORT_TRANSACTION_COMPLETED, }); dispatch( doShowSnackBar({ message: __(`You sent ${amount} LBC as support, Mahalo!`), - linkText: __("History"), - linkTarget: __("/wallet"), + linkText: __('History'), + linkTarget: __('/wallet'), }) ); - dispatch(doNavigate("/show", { uri })); + dispatch(doNavigate('/show', { uri })); } else { dispatch({ - type: types.SUPPORT_TRANSACTION_FAILED, + type: ACTIONS.SUPPORT_TRANSACTION_FAILED, data: { error: results.code }, }); - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); } }; const errorCallback = error => { dispatch({ - type: types.SUPPORT_TRANSACTION_FAILED, + type: ACTIONS.SUPPORT_TRANSACTION_FAILED, data: { error: error.code }, }); - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + dispatch(doOpenModal(MODALS.TRANSACTION_FAILED)); }; - lbry - .wallet_send({ - claim_id, - amount, - }) - .then(successCallback, errorCallback); + Lbry.wallet_send({ + claimId, + amount, + }).then(successCallback, errorCallback); }; } diff --git a/src/renderer/redux/reducers/app.js b/src/renderer/redux/reducers/app.js index b18062e0c..c8a821fa8 100644 --- a/src/renderer/redux/reducers/app.js +++ b/src/renderer/redux/reducers/app.js @@ -1,11 +1,10 @@ // @flow -import * as types from "constants/action_types"; -import * as modalTypes from "constants/modal_types"; +import * as ACTIONS from 'constants/action_types'; +import * as MODALS from 'constants/modal_types'; -const { remote } = require("electron"); +const { remote } = require('electron'); -const application = remote.app; const win = remote.BrowserWindow.getFocusedWindow(); const reducers = {}; @@ -41,12 +40,12 @@ const defaultState: AppState = { modal: null, modalProps: {}, platform: process.platform, - upgradeSkipped: sessionStorage.getItem("upgradeSkipped") === "true", + upgradeSkipped: sessionStorage.getItem('upgradeSkipped') === 'true', daemonVersionMatched: null, daemonReady: false, hasSignature: false, badgeNumber: 0, - volume: Number(sessionStorage.getItem("volume")) || 1, + volume: Number(sessionStorage.getItem('volume')) || 1, downloadProgress: undefined, upgradeDownloading: undefined, @@ -57,26 +56,26 @@ const defaultState: AppState = { snackBar: undefined, }; -reducers[types.DAEMON_READY] = function(state, action) { +reducers[ACTIONS.DAEMON_READY] = function(state) { return Object.assign({}, state, { daemonReady: true, }); }; -reducers[types.DAEMON_VERSION_MATCH] = function(state, action) { +reducers[ACTIONS.DAEMON_VERSION_MATCH] = function(state) { return Object.assign({}, state, { daemonVersionMatched: true, }); }; -reducers[types.DAEMON_VERSION_MISMATCH] = function(state, action) { +reducers[ACTIONS.DAEMON_VERSION_MISMATCH] = function(state) { return Object.assign({}, state, { daemonVersionMatched: false, - modal: modalTypes.INCOMPATIBLE_DAEMON, + modal: MODALS.INCOMPATIBLE_DAEMON, }); }; -reducers[types.UPGRADE_CANCELLED] = function(state, action) { +reducers[ACTIONS.UPGRADE_CANCELLED] = function(state) { return Object.assign({}, state, { downloadProgress: null, upgradeDownloadComplete: false, @@ -84,7 +83,7 @@ reducers[types.UPGRADE_CANCELLED] = function(state, action) { }); }; -reducers[types.UPGRADE_DOWNLOAD_COMPLETED] = function(state, action) { +reducers[ACTIONS.UPGRADE_DOWNLOAD_COMPLETED] = function(state, action) { return Object.assign({}, state, { downloadPath: action.data.path, upgradeDownloading: false, @@ -92,14 +91,14 @@ reducers[types.UPGRADE_DOWNLOAD_COMPLETED] = function(state, action) { }); }; -reducers[types.UPGRADE_DOWNLOAD_STARTED] = function(state, action) { +reducers[ACTIONS.UPGRADE_DOWNLOAD_STARTED] = function(state) { return Object.assign({}, state, { upgradeDownloading: true, }); }; -reducers[types.SKIP_UPGRADE] = function(state, action) { - sessionStorage.setItem("upgradeSkipped", "true"); +reducers[ACTIONS.SKIP_UPGRADE] = function(state) { + sessionStorage.setItem('upgradeSkipped', 'true'); return Object.assign({}, state, { isUpgradeSkipped: true, @@ -107,46 +106,46 @@ reducers[types.SKIP_UPGRADE] = function(state, action) { }); }; -reducers[types.UPDATE_VERSION] = function(state, action) { +reducers[ACTIONS.UPDATE_VERSION] = function(state, action) { return Object.assign({}, state, { version: action.data.version, }); }; -reducers[types.CHECK_UPGRADE_SUCCESS] = function(state, action) { +reducers[ACTIONS.CHECK_UPGRADE_SUCCESS] = function(state, action) { return Object.assign({}, state, { isUpgradeAvailable: action.data.upgradeAvailable, remoteVersion: action.data.remoteVersion, }); }; -reducers[types.CHECK_UPGRADE_SUBSCRIBE] = function(state, action) { +reducers[ACTIONS.CHECK_UPGRADE_SUBSCRIBE] = function(state, action) { return Object.assign({}, state, { checkUpgradeTimer: action.data.checkUpgradeTimer, }); }; -reducers[types.OPEN_MODAL] = function(state, action) { +reducers[ACTIONS.OPEN_MODAL] = function(state, action) { return Object.assign({}, state, { modal: action.data.modal, modalProps: action.data.modalProps || {}, }); }; -reducers[types.CLOSE_MODAL] = function(state, action) { +reducers[ACTIONS.CLOSE_MODAL] = function(state) { return Object.assign({}, state, { modal: undefined, modalProps: {}, }); }; -reducers[types.UPGRADE_DOWNLOAD_PROGRESSED] = function(state, action) { +reducers[ACTIONS.UPGRADE_DOWNLOAD_PROGRESSED] = function(state, action) { return Object.assign({}, state, { downloadProgress: action.data.percent, }); }; -reducers[types.SHOW_SNACKBAR] = function(state, action) { +reducers[ACTIONS.SHOW_SNACKBAR] = function(state, action) { const { message, linkText, linkTarget, isError } = action.data; const snackBar = Object.assign({}, state.snackBar); const snacks = Object.assign([], snackBar.snacks); @@ -165,7 +164,7 @@ reducers[types.SHOW_SNACKBAR] = function(state, action) { }); }; -reducers[types.REMOVE_SNACKBAR_SNACK] = function(state, action) { +reducers[ACTIONS.REMOVE_SNACKBAR_SNACK] = function(state) { const snackBar = Object.assign({}, state.snackBar); const snacks = Object.assign([], snackBar.snacks); snacks.shift(); @@ -179,8 +178,8 @@ reducers[types.REMOVE_SNACKBAR_SNACK] = function(state, action) { }); }; -reducers[types.DOWNLOADING_COMPLETED] = function(state, action) { - const badgeNumber = state.badgeNumber; +reducers[ACTIONS.DOWNLOADING_COMPLETED] = function(state) { + const { badgeNumber } = state; // Don't update the badge number if the window is focused if (win && win.isFocused()) return Object.assign({}, state); @@ -190,13 +189,13 @@ reducers[types.DOWNLOADING_COMPLETED] = function(state, action) { }); }; -reducers[types.WINDOW_FOCUSED] = function(state, action) { +reducers[ACTIONS.WINDOW_FOCUSED] = function(state) { return Object.assign({}, state, { badgeNumber: 0, }); }; -reducers[types.VOLUME_CHANGED] = function(state, action) { +reducers[ACTIONS.VOLUME_CHANGED] = function(state, action) { return Object.assign({}, state, { volume: action.data.volume, }); diff --git a/src/renderer/redux/reducers/availability.js b/src/renderer/redux/reducers/availability.js index 2c4a4dc93..48133ff50 100644 --- a/src/renderer/redux/reducers/availability.js +++ b/src/renderer/redux/reducers/availability.js @@ -1,9 +1,9 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = {}; -reducers[types.FETCH_AVAILABILITY_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_AVAILABILITY_STARTED] = function(state, action) { const { uri } = action.data; const newFetching = Object.assign({}, state.fetching); @@ -14,7 +14,7 @@ reducers[types.FETCH_AVAILABILITY_STARTED] = function(state, action) { }); }; -reducers[types.FETCH_AVAILABILITY_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_AVAILABILITY_COMPLETED] = function(state, action) { const { uri, availability } = action.data; const newFetching = Object.assign({}, state.fetching); diff --git a/src/renderer/redux/reducers/claims.js b/src/renderer/redux/reducers/claims.js index 60f5e042b..6547dd5f4 100644 --- a/src/renderer/redux/reducers/claims.js +++ b/src/renderer/redux/reducers/claims.js @@ -1,15 +1,15 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = {}; -reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { +reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = function(state, action) { const { resolveInfo } = action.data; const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); - for (const [uri, { certificate, claim }] of Object.entries(resolveInfo)) { + Object.entries(resolveInfo).forEach(([uri, { certificate, claim }]) => { if (claim) { byId[claim.claim_id] = claim; byUri[uri] = claim.claim_id; @@ -25,7 +25,7 @@ reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { } else { byUri[uri] = null; } - } + }); return Object.assign({}, state, { byId, @@ -33,37 +33,32 @@ reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { }); }; -reducers[types.FETCH_CLAIM_LIST_MINE_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = function(state) { return Object.assign({}, state, { isFetchingClaimListMine: true, }); }; -reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) { const { claims } = action.data; - const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const pendingById = Object.assign({}, state.pendingById); - const abandoningById = Object.assign({}, state.abandoningById); - claims - .filter(claim => claim.category && claim.category.match(/claim/)) - .forEach(claim => { - byId[claim.claim_id] = claim; + claims.filter(claim => claim.category && claim.category.match(/claim/)).forEach(claim => { + byId[claim.claim_id] = claim; - const pending = Object.values(pendingById).find( - pendingClaim => - pendingClaim.name == claim.name && - pendingClaim.channel_name == claim.channel_name - ); + const pending = Object.values(pendingById).find( + pendingClaim => + pendingClaim.name === claim.name && pendingClaim.channel_name === claim.channel_name + ); - if (pending) { - delete pendingById[pending.claim_id]; - } - }); + if (pending) { + delete pendingById[pending.claim_id]; + } + }); // Remove old timed out pending publishes - const old = Object.values(pendingById) + Object.values(pendingById) .filter(pendingClaim => Date.now() - pendingClaim.time >= 20 * 60 * 1000) .forEach(pendingClaim => { delete pendingById[pendingClaim.claim_id]; @@ -77,11 +72,11 @@ reducers[types.FETCH_CLAIM_LIST_MINE_COMPLETED] = function(state, action) { }); }; -reducers[types.FETCH_CHANNEL_LIST_MINE_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_CHANNEL_LIST_MINE_STARTED] = function(state) { return Object.assign({}, state, { fetchingMyChannels: true }); }; -reducers[types.FETCH_CHANNEL_LIST_MINE_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_CHANNEL_LIST_MINE_COMPLETED] = function(state, action) { const { claims } = action.data; const myChannelClaims = new Set(state.myChannelClaims); const byId = Object.assign({}, state.byId); @@ -98,7 +93,7 @@ reducers[types.FETCH_CHANNEL_LIST_MINE_COMPLETED] = function(state, action) { }); }; -reducers[types.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) { const { uri, page } = action.data; const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); @@ -109,7 +104,7 @@ reducers[types.FETCH_CHANNEL_CLAIMS_STARTED] = function(state, action) { }); }; -reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { const { uri, claims, page } = action.data; const claimsByChannel = Object.assign({}, state.claimsByChannel); @@ -139,7 +134,7 @@ reducers[types.FETCH_CHANNEL_CLAIMS_COMPLETED] = function(state, action) { }); }; -reducers[types.ABANDON_CLAIM_STARTED] = function(state, action) { +reducers[ACTIONS.ABANDON_CLAIM_STARTED] = function(state, action) { const { claimId } = action.data; const abandoningById = Object.assign({}, state.abandoningById); @@ -150,7 +145,7 @@ reducers[types.ABANDON_CLAIM_STARTED] = function(state, action) { }); }; -reducers[types.ABANDON_CLAIM_SUCCEEDED] = function(state, action) { +reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = function(state, action) { const { claimId } = action.data; const byId = Object.assign({}, state.byId); const claimsByUri = Object.assign({}, state.claimsByUri); @@ -169,7 +164,7 @@ reducers[types.ABANDON_CLAIM_SUCCEEDED] = function(state, action) { }); }; -reducers[types.CREATE_CHANNEL_COMPLETED] = function(state, action) { +reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = function(state, action) { const { channelClaim } = action.data; const byId = Object.assign({}, state.byId); const myChannelClaims = new Set(state.myChannelClaims); diff --git a/src/renderer/redux/reducers/content.js b/src/renderer/redux/reducers/content.js index 9c3dabac5..b16c911b1 100644 --- a/src/renderer/redux/reducers/content.js +++ b/src/renderer/redux/reducers/content.js @@ -1,4 +1,4 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = { @@ -7,13 +7,13 @@ const defaultState = { channelClaimCounts: {}, }; -reducers[types.FETCH_FEATURED_CONTENT_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_FEATURED_CONTENT_STARTED] = function(state) { return Object.assign({}, state, { fetchingFeaturedContent: true, }); }; -reducers[types.FETCH_FEATURED_CONTENT_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_FEATURED_CONTENT_COMPLETED] = function(state, action) { const { uris, success } = action.data; return Object.assign({}, state, { @@ -23,42 +23,40 @@ reducers[types.FETCH_FEATURED_CONTENT_COMPLETED] = function(state, action) { }); }; -reducers[types.FETCH_REWARD_CONTENT_COMPLETED] = function(state, action) { - const { claimIds, success } = action.data; +reducers[ACTIONS.FETCH_REWARD_CONTENT_COMPLETED] = function(state, action) { + const { claimIds } = action.data; return Object.assign({}, state, { rewardedContentClaimIds: claimIds, }); }; -reducers[types.RESOLVE_URIS_STARTED] = function(state, action) { +reducers[ACTIONS.RESOLVE_URIS_STARTED] = function(state, action) { const { uris } = action.data; const oldResolving = state.resolvingUris || []; const newResolving = Object.assign([], oldResolving); - for (const uri of uris) { + uris.forEach(uri => { if (!newResolving.includes(uri)) { newResolving.push(uri); } - } + }); return Object.assign({}, state, { resolvingUris: newResolving, }); }; -reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { +reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = function(state, action) { const { resolveInfo } = action.data; const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - for (const [uri, { certificate, claims_in_channel }] of Object.entries( - resolveInfo - )) { - if (certificate && !isNaN(claims_in_channel)) { - channelClaimCounts[uri] = claims_in_channel; + Object.entries(resolveInfo).forEach(([uri, { certificate, claimsInChannel }]) => { + if (certificate && !Number.isNaN(claimsInChannel)) { + channelClaimCounts[uri] = claimsInChannel; } - } + }); return Object.assign({}, state, { channelClaimCounts, @@ -66,12 +64,12 @@ reducers[types.RESOLVE_URIS_COMPLETED] = function(state, action) { }); }; -reducers[types.SET_PLAYING_URI] = (state, action) => +reducers[ACTIONS.SET_PLAYING_URI] = (state, action) => Object.assign({}, state, { playingUri: action.data.uri, }); -reducers[types.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = function(state, action) { const channelClaimCounts = Object.assign({}, state.channelClaimCounts); const { uri, totalClaims } = action.data; diff --git a/src/renderer/redux/reducers/cost_info.js b/src/renderer/redux/reducers/cost_info.js index 27e04f0a3..18c6214ac 100644 --- a/src/renderer/redux/reducers/cost_info.js +++ b/src/renderer/redux/reducers/cost_info.js @@ -1,9 +1,9 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = {}; -reducers[types.FETCH_COST_INFO_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_COST_INFO_STARTED] = function(state, action) { const { uri } = action.data; const newFetching = Object.assign({}, state.fetching); newFetching[uri] = true; @@ -13,7 +13,7 @@ reducers[types.FETCH_COST_INFO_STARTED] = function(state, action) { }); }; -reducers[types.FETCH_COST_INFO_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_COST_INFO_COMPLETED] = function(state, action) { const { uri, costInfo } = action.data; const newByUri = Object.assign({}, state.byUri); const newFetching = Object.assign({}, state.fetching); diff --git a/src/renderer/redux/reducers/file_info.js b/src/renderer/redux/reducers/file_info.js index d900a860f..25ae15546 100644 --- a/src/renderer/redux/reducers/file_info.js +++ b/src/renderer/redux/reducers/file_info.js @@ -1,16 +1,15 @@ -import * as types from "constants/action_types"; -import lbryuri from "lbryuri"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = {}; -reducers[types.FILE_LIST_STARTED] = function(state, action) { +reducers[ACTIONS.FILE_LIST_STARTED] = function(state) { return Object.assign({}, state, { isFetchingFileList: true, }); }; -reducers[types.FILE_LIST_SUCCEEDED] = function(state, action) { +reducers[ACTIONS.FILE_LIST_SUCCEEDED] = function(state, action) { const { fileInfos } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint); @@ -28,7 +27,7 @@ reducers[types.FILE_LIST_SUCCEEDED] = function(state, action) { }); }; -reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_FILE_INFO_STARTED] = function(state, action) { const { outpoint } = action.data; const newFetching = Object.assign({}, state.fetching); @@ -39,7 +38,7 @@ reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) { }); }; -reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_FILE_INFO_COMPLETED] = function(state, action) { const { fileInfo, outpoint } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -54,7 +53,7 @@ reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) { }); }; -reducers[types.DOWNLOADING_STARTED] = function(state, action) { +reducers[ACTIONS.DOWNLOADING_STARTED] = function(state, action) { const { uri, outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -72,8 +71,8 @@ reducers[types.DOWNLOADING_STARTED] = function(state, action) { }); }; -reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) { - const { uri, outpoint, fileInfo } = action.data; +reducers[ACTIONS.DOWNLOADING_PROGRESSED] = function(state, action) { + const { outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); const newDownloading = Object.assign({}, state.downloadingByOutpoint); @@ -87,8 +86,8 @@ reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) { }); }; -reducers[types.DOWNLOADING_COMPLETED] = function(state, action) { - const { uri, outpoint, fileInfo } = action.data; +reducers[ACTIONS.DOWNLOADING_COMPLETED] = function(state, action) { + const { outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); const newDownloading = Object.assign({}, state.downloadingByOutpoint); @@ -102,7 +101,7 @@ reducers[types.DOWNLOADING_COMPLETED] = function(state, action) { }); }; -reducers[types.FILE_DELETE] = function(state, action) { +reducers[ACTIONS.FILE_DELETE] = function(state, action) { const { outpoint } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -117,7 +116,7 @@ reducers[types.FILE_DELETE] = function(state, action) { }); }; -reducers[types.LOADING_VIDEO_STARTED] = function(state, action) { +reducers[ACTIONS.LOADING_VIDEO_STARTED] = function(state, action) { const { uri } = action.data; const newLoading = Object.assign({}, state.urisLoading); @@ -129,7 +128,7 @@ reducers[types.LOADING_VIDEO_STARTED] = function(state, action) { }); }; -reducers[types.LOADING_VIDEO_FAILED] = function(state, action) { +reducers[ACTIONS.LOADING_VIDEO_FAILED] = function(state, action) { const { uri } = action.data; const newLoading = Object.assign({}, state.urisLoading); @@ -141,13 +140,14 @@ reducers[types.LOADING_VIDEO_FAILED] = function(state, action) { }); }; -reducers[types.FETCH_DATE] = function(state, action) { +reducers[ACTIONS.FETCH_DATE] = function(state, action) { const { time } = action.data; if (time) { return Object.assign({}, state, { publishedDate: time, }); } + return null; }; export default function reducer(state = defaultState, action) { diff --git a/src/renderer/redux/reducers/navigation.js b/src/renderer/redux/reducers/navigation.js index 990657df7..581fd52d2 100644 --- a/src/renderer/redux/reducers/navigation.js +++ b/src/renderer/redux/reducers/navigation.js @@ -1,38 +1,36 @@ -import * as types from "constants/action_types"; -import { parseQueryParams } from "util/query_params"; +import * as ACTIONS from 'constants/action_types'; -const currentPath = () => { - const hash = document.location.hash; - if (hash !== "") return hash.replace(/^#/, ""); - return "/discover"; +const getCurrentPath = () => { + const { hash } = document.location; + if (hash !== '') return hash.replace(/^#/, ''); + return '/discover'; }; const reducers = {}; const defaultState = { - currentPath: currentPath(), - pathAfterAuth: "/discover", + currentPath: getCurrentPath(), + pathAfterAuth: '/discover', index: 0, stack: [], }; -reducers[types.DAEMON_READY] = function(state, action) { +reducers[ACTIONS.DAEMON_READY] = function(state) { const { currentPath } = state; - const params = parseQueryParams(currentPath.split("?")[1] || ""); return Object.assign({}, state, { stack: [{ path: currentPath, scrollY: 0 }], }); }; -reducers[types.CHANGE_AFTER_AUTH_PATH] = function(state, action) { +reducers[ACTIONS.CHANGE_AFTER_AUTH_PATH] = function(state, action) { return Object.assign({}, state, { pathAfterAuth: action.data.path, }); }; -reducers[types.HISTORY_NAVIGATE] = (state, action) => { +reducers[ACTIONS.HISTORY_NAVIGATE] = (state, action) => { const { stack, index } = state; - const { url: path, index: newIndex, scrollY } = action.data; + const { url: path, index: newIndex } = action.data; const newState = { currentPath: path, @@ -46,12 +44,11 @@ reducers[types.HISTORY_NAVIGATE] = (state, action) => { newState.index = newState.stack.length - 1; } - history.replaceState(null, null, `#${path}`); // this allows currentPath() to retain the URL on reload return Object.assign({}, state, newState); }; -reducers[types.WINDOW_SCROLLED] = (state, action) => { - const { stack, index } = state; +reducers[ACTIONS.WINDOW_SCROLLED] = (state, action) => { + const { index } = state; const { scrollY } = action.data; return Object.assign({}, state, { diff --git a/src/renderer/redux/reducers/rewards.js b/src/renderer/redux/reducers/rewards.js index 77d20064e..f9a108f12 100644 --- a/src/renderer/redux/reducers/rewards.js +++ b/src/renderer/redux/reducers/rewards.js @@ -1,4 +1,4 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = { @@ -9,17 +9,17 @@ const defaultState = { claimErrorsByType: {}, }; -reducers[types.FETCH_REWARDS_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_REWARDS_STARTED] = function(state) { return Object.assign({}, state, { fetching: true, }); }; -reducers[types.FETCH_REWARDS_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_REWARDS_COMPLETED] = function(state, action) { const { userRewards } = action.data; - let unclaimedRewards = {}, - claimedRewards = {}; + const unclaimedRewards = {}; + const claimedRewards = {}; userRewards.forEach(reward => { if (reward.transaction_id) { claimedRewards[reward.id] = reward; @@ -35,7 +35,7 @@ reducers[types.FETCH_REWARDS_COMPLETED] = function(state, action) { }); }; -function setClaimRewardState(state, reward, isClaiming, errorMessage = "") { +function setClaimRewardState(state, reward, isClaiming, errorMessage = '') { const newClaimPendingByType = Object.assign({}, state.claimPendingByType); const newClaimErrorsByType = Object.assign({}, state.claimErrorsByType); if (isClaiming) { @@ -55,21 +55,17 @@ function setClaimRewardState(state, reward, isClaiming, errorMessage = "") { }); } -reducers[types.CLAIM_REWARD_STARTED] = function(state, action) { +reducers[ACTIONS.CLAIM_REWARD_STARTED] = function(state, action) { const { reward } = action.data; - return setClaimRewardState(state, reward, true, ""); + return setClaimRewardState(state, reward, true, ''); }; -reducers[types.CLAIM_REWARD_SUCCESS] = function(state, action) { +reducers[ACTIONS.CLAIM_REWARD_SUCCESS] = function(state, action) { const { reward } = action.data; - const unclaimedRewardsByType = Object.assign( - {}, - state.unclaimedRewardsByType - ); + const unclaimedRewardsByType = Object.assign({}, state.unclaimedRewardsByType); const existingReward = unclaimedRewardsByType[reward.reward_type]; - delete state.unclaimedRewardsByType[reward.reward_type]; const newReward = Object.assign({}, reward, { reward_title: existingReward.reward_title, @@ -84,24 +80,19 @@ reducers[types.CLAIM_REWARD_SUCCESS] = function(state, action) { claimedRewardsById, }); - return setClaimRewardState(newState, newReward, false, ""); + return setClaimRewardState(newState, newReward, false, ''); }; -reducers[types.CLAIM_REWARD_FAILURE] = function(state, action) { +reducers[ACTIONS.CLAIM_REWARD_FAILURE] = function(state, action) { const { reward, error } = action.data; - return setClaimRewardState(state, reward, false, error ? error.message : ""); + return setClaimRewardState(state, reward, false, error ? error.message : ''); }; -reducers[types.CLAIM_REWARD_CLEAR_ERROR] = function(state, action) { +reducers[ACTIONS.CLAIM_REWARD_CLEAR_ERROR] = function(state, action) { const { reward } = action.data; - return setClaimRewardState( - state, - reward, - state.claimPendingByType[reward.reward_type], - "" - ); + return setClaimRewardState(state, reward, state.claimPendingByType[reward.reward_type], ''); }; export default function reducer(state = defaultState, action) { diff --git a/src/renderer/redux/reducers/search.js b/src/renderer/redux/reducers/search.js index c44c78cd2..00764c2b7 100644 --- a/src/renderer/redux/reducers/search.js +++ b/src/renderer/redux/reducers/search.js @@ -1,4 +1,4 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; const defaultState = { @@ -6,15 +6,13 @@ const defaultState = { searching: false, }; -reducers[types.SEARCH_STARTED] = function(state, action) { - const { query } = action.data; - +reducers[ACTIONS.SEARCH_STARTED] = function(state) { return Object.assign({}, state, { searching: true, }); }; -reducers[types.SEARCH_COMPLETED] = function(state, action) { +reducers[ACTIONS.SEARCH_COMPLETED] = function(state, action) { const { query, uris } = action.data; return Object.assign({}, state, { @@ -23,7 +21,7 @@ reducers[types.SEARCH_COMPLETED] = function(state, action) { }); }; -reducers[types.SEARCH_CANCELLED] = function(state, action) { +reducers[ACTIONS.SEARCH_CANCELLED] = function(state) { return Object.assign({}, state, { searching: false, }); diff --git a/src/renderer/redux/reducers/settings.js b/src/renderer/redux/reducers/settings.js index 28413c504..b3cf5794a 100644 --- a/src/renderer/redux/reducers/settings.js +++ b/src/renderer/redux/reducers/settings.js @@ -1,6 +1,6 @@ -import * as types from "constants/action_types"; -import * as settings from "constants/settings"; -import LANGUAGES from "constants/languages"; +import * as ACTIONS from 'constants/action_types'; +import * as SETTINGS from 'constants/settings'; +import LANGUAGES from 'constants/languages'; function getLocalStorageSetting(setting, fallback) { const localStorageVal = localStorage.getItem(`setting_${setting}`); @@ -10,38 +10,30 @@ function getLocalStorageSetting(setting, fallback) { const reducers = {}; const defaultState = { clientSettings: { - instantPurchaseEnabled: getLocalStorageSetting( - settings.INSTANT_PURCHASE_ENABLED, - false - ), - instantPurchaseMax: getLocalStorageSetting(settings.INSTANT_PURCHASE_MAX, { - currency: "LBC", + instantPurchaseEnabled: getLocalStorageSetting(SETTINGS.INSTANT_PURCHASE_ENABLED, false), + instantPurchaseMax: getLocalStorageSetting(SETTINGS.INSTANT_PURCHASE_MAX, { + currency: 'LBC', amount: 0.1, }), - showNsfw: getLocalStorageSetting(settings.SHOW_NSFW, false), - showUnavailable: getLocalStorageSetting(settings.SHOW_UNAVAILABLE, true), - welcome_acknowledged: getLocalStorageSetting( - settings.NEW_USER_ACKNOWLEDGED, - false - ), - email_collection_acknowledged: getLocalStorageSetting( - settings.EMAIL_COLLECTION_ACKNOWLEDGED - ), + showNsfw: getLocalStorageSetting(SETTINGS.SHOW_NSFW, false), + showUnavailable: getLocalStorageSetting(SETTINGS.SHOW_UNAVAILABLE, true), + welcome_acknowledged: getLocalStorageSetting(SETTINGS.NEW_USER_ACKNOWLEDGED, false), + email_collection_acknowledged: getLocalStorageSetting(SETTINGS.EMAIL_COLLECTION_ACKNOWLEDGED), credit_required_acknowledged: false, // this needs to be re-acknowledged every run - language: getLocalStorageSetting(settings.LANGUAGE, "en"), - theme: getLocalStorageSetting(settings.THEME, "light"), - themes: getLocalStorageSetting(settings.THEMES, []), + language: getLocalStorageSetting(SETTINGS.LANGUAGE, 'en'), + theme: getLocalStorageSetting(SETTINGS.THEME, 'light'), + themes: getLocalStorageSetting(SETTINGS.THEMES, []), }, languages: {}, }; -reducers[types.DAEMON_SETTINGS_RECEIVED] = function(state, action) { +reducers[ACTIONS.DAEMON_SETTINGS_RECEIVED] = function(state, action) { return Object.assign({}, state, { daemonSettings: action.data.settings, }); }; -reducers[types.CLIENT_SETTING_CHANGED] = function(state, action) { +reducers[ACTIONS.CLIENT_SETTING_CHANGED] = function(state, action) { const { key, value } = action.data; const clientSettings = Object.assign({}, state.clientSettings); @@ -55,16 +47,14 @@ reducers[types.CLIENT_SETTING_CHANGED] = function(state, action) { }); }; -reducers[types.DOWNLOAD_LANGUAGE_SUCCEEDED] = function(state, action) { +reducers[ACTIONS.DOWNLOAD_LANGUAGE_SUCCEEDED] = function(state, action) { const languages = Object.assign({}, state.languages); - const language = action.data.language; + const { language } = action.data; const langCode = language.substring(0, 2); if (LANGUAGES[langCode]) { - languages[language] = `${LANGUAGES[langCode][0]} (${ - LANGUAGES[langCode][1] - })`; + languages[language] = `${LANGUAGES[langCode][0]} (${LANGUAGES[langCode][1]})`; } else { languages[langCode] = langCode; } @@ -72,7 +62,7 @@ reducers[types.DOWNLOAD_LANGUAGE_SUCCEEDED] = function(state, action) { return Object.assign({}, state, { languages }); }; -reducers[types.DOWNLOAD_LANGUAGE_FAILED] = function(state, action) { +reducers[ACTIONS.DOWNLOAD_LANGUAGE_FAILED] = function(state, action) { const languages = Object.assign({}, state.languages); delete languages[action.data.language]; return Object.assign({}, state, { languages }); diff --git a/src/renderer/redux/reducers/shape_shift.js b/src/renderer/redux/reducers/shape_shift.js index 71b59addd..81b78fe34 100644 --- a/src/renderer/redux/reducers/shape_shift.js +++ b/src/renderer/redux/reducers/shape_shift.js @@ -1,7 +1,7 @@ // @flow -import { handleActions } from "util/redux-utils"; -import * as actions from "constants/action_types"; -import * as statuses from "constants/shape_shift"; +import handleActions from 'util/redux-utils'; +import * as ACTIONS from 'constants/action_types'; +import * as STATUSES from 'constants/shape_shift'; export type ShapeShiftState = { loading: boolean, @@ -24,40 +24,6 @@ export type ShapeShiftState = { shapeShiftRate: ?number, }; -// All ShapeShift actions that will have some payload -export type GetSupportedCoinsSuccess = { - type: actions.GET_SUPPORTED_COINS_SUCCESS, - data: Array, -}; -export type GetCoinStatsStart = { - type: actions.GET_SUPPORTED_COINS_SUCCESS, - data: string, -}; -export type GetCoinStatsSuccess = { - type: actions.GET_COIN_STATS_SUCCESS, - data: ShapeShiftMarketInfo, -}; -export type GetCoinStatsFail = { - type: actions.GET_COIN_STATS_FAIL, - data: string, -}; -export type PrepareShapeShiftSuccess = { - type: actions.PREPARE_SHAPE_SHIFT_SUCCESS, - data: ActiveShiftInfo, -}; -export type PrepareShapeShiftFail = { - type: actions.PREPARE_SHAPE_SHIFT_FAIL, - data: ShapeShiftErrorResponse, -}; -export type GetActiveShiftSuccess = { - type: actions.GET_ACTIVE_SHIFT_SUCCESS, - data: string, -}; -export type GetActiveShiftFail = { - type: actions.GET_ACTIVE_SHIFT_FAIL, - data: ShapeShiftErrorResponse, -}; - // ShapeShift sub-types // Defined for actions that contain an object in the payload type ShapeShiftMarketInfo = { @@ -78,6 +44,40 @@ type ShapeShiftErrorResponse = { message: string, }; +// All ShapeShift actions that will have some payload +export type GetSupportedCoinsSuccess = { + type: ACTIONS.GET_SUPPORTED_COINS_SUCCESS, + data: Array, +}; +export type GetCoinStatsStart = { + type: ACTIONS.GET_SUPPORTED_COINS_SUCCESS, + data: string, +}; +export type GetCoinStatsSuccess = { + type: ACTIONS.GET_COIN_STATS_SUCCESS, + data: ShapeShiftMarketInfo, +}; +export type GetCoinStatsFail = { + type: ACTIONS.GET_COIN_STATS_FAIL, + data: string, +}; +export type PrepareShapeShiftSuccess = { + type: ACTIONS.PREPARE_SHAPE_SHIFT_SUCCESS, + data: ActiveShiftInfo, +}; +export type PrepareShapeShiftFail = { + type: ACTIONS.PREPARE_SHAPE_SHIFT_FAIL, + data: ShapeShiftErrorResponse, +}; +export type GetActiveShiftSuccess = { + type: ACTIONS.GET_ACTIVE_SHIFT_SUCCESS, + data: string, +}; +export type GetActiveShiftFail = { + type: ACTIONS.GET_ACTIVE_SHIFT_FAIL, + data: ShapeShiftErrorResponse, +}; + const defaultState: ShapeShiftState = { loading: true, updating: false, @@ -98,14 +98,12 @@ const defaultState: ShapeShiftState = { export default handleActions( { - [actions.GET_SUPPORTED_COINS_START]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ + [ACTIONS.GET_SUPPORTED_COINS_START]: (state: ShapeShiftState): ShapeShiftState => ({ ...state, loading: true, error: undefined, }), - [actions.GET_SUPPORTED_COINS_SUCCESS]: ( + [ACTIONS.GET_SUPPORTED_COINS_SUCCESS]: ( state: ShapeShiftState, action: GetSupportedCoinsSuccess ): ShapeShiftState => { @@ -116,15 +114,13 @@ export default handleActions( shiftSupportedCoins, }; }, - [actions.GET_SUPPORTED_COINS_FAIL]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ + [ACTIONS.GET_SUPPORTED_COINS_FAIL]: (state: ShapeShiftState): ShapeShiftState => ({ ...state, loading: false, - error: "Error getting available coins", + error: 'Error getting available coins', }), - [actions.GET_COIN_STATS_START]: ( + [ACTIONS.GET_COIN_STATS_START]: ( state: ShapeShiftState, action: GetCoinStatsStart ): ShapeShiftState => { @@ -135,7 +131,7 @@ export default handleActions( originCoin: coin, }; }, - [actions.GET_COIN_STATS_SUCCESS]: ( + [ACTIONS.GET_COIN_STATS_SUCCESS]: ( state: ShapeShiftState, action: GetCoinStatsSuccess ): ShapeShiftState => { @@ -148,14 +144,12 @@ export default handleActions( originCoinDepositMax: marketInfo.limit, // this will come in scientific notation // toFixed shows the real number, then regex to remove trailing zeros - originCoinDepositMin: marketInfo.minimum - .toFixed(10) - .replace(/\.?0+$/, ""), + originCoinDepositMin: marketInfo.minimum.toFixed(10).replace(/\.?0+$/, ''), originCoinDepositFee: marketInfo.minerFee, shapeShiftRate: marketInfo.rate, }; }, - [actions.GET_COIN_STATS_FAIL]: ( + [ACTIONS.GET_COIN_STATS_FAIL]: ( state: ShapeShiftState, action: GetCoinStatsFail ): ShapeShiftState => { @@ -167,13 +161,11 @@ export default handleActions( }; }, - [actions.PREPARE_SHAPE_SHIFT_START]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ + [ACTIONS.PREPARE_SHAPE_SHIFT_START]: (state: ShapeShiftState): ShapeShiftState => ({ ...state, error: undefined, }), - [actions.PREPARE_SHAPE_SHIFT_SUCCESS]: ( + [ACTIONS.PREPARE_SHAPE_SHIFT_SUCCESS]: ( state: ShapeShiftState, action: PrepareShapeShiftSuccess ) => { @@ -185,13 +177,10 @@ export default handleActions( shiftCoinType: activeShiftInfo.depositType, shiftReturnAddress: activeShiftInfo.returnAddress, shiftOrderId: activeShiftInfo.orderId, - shiftState: statuses.NO_DEPOSITS, + shiftState: STATUSES.NO_DEPOSITS, }; }, - [actions.PREPARE_SHAPE_SHIFT_FAIL]: ( - state: ShapeShiftState, - action: PrepareShapeShiftFail - ) => { + [ACTIONS.PREPARE_SHAPE_SHIFT_FAIL]: (state: ShapeShiftState, action: PrepareShapeShiftFail) => { const error: ShapeShiftErrorResponse = action.data; return { ...state, @@ -199,7 +188,7 @@ export default handleActions( }; }, - [actions.CLEAR_SHAPE_SHIFT]: (state: ShapeShiftState): ShapeShiftState => ({ + [ACTIONS.CLEAR_SHAPE_SHIFT]: (state: ShapeShiftState): ShapeShiftState => ({ ...state, loading: false, updating: false, @@ -211,14 +200,12 @@ export default handleActions( originCoin: state.shiftSupportedCoins[0], }), - [actions.GET_ACTIVE_SHIFT_START]: ( - state: ShapeShiftState - ): ShapeShiftState => ({ + [ACTIONS.GET_ACTIVE_SHIFT_START]: (state: ShapeShiftState): ShapeShiftState => ({ ...state, error: undefined, updating: true, }), - [actions.GET_ACTIVE_SHIFT_SUCCESS]: ( + [ACTIONS.GET_ACTIVE_SHIFT_SUCCESS]: ( state: ShapeShiftState, action: GetActiveShiftSuccess ): ShapeShiftState => { @@ -229,7 +216,7 @@ export default handleActions( shiftState: status, }; }, - [actions.GET_ACTIVE_SHIFT_FAIL]: ( + [ACTIONS.GET_ACTIVE_SHIFT_FAIL]: ( state: ShapeShiftState, action: GetActiveShiftFail ): ShapeShiftState => { diff --git a/src/renderer/redux/reducers/subscriptions.js b/src/renderer/redux/reducers/subscriptions.js index f0de6819c..2e93f8dc6 100644 --- a/src/renderer/redux/reducers/subscriptions.js +++ b/src/renderer/redux/reducers/subscriptions.js @@ -1,6 +1,11 @@ // @flow -import * as actions from "constants/action_types"; -import { handleActions } from "util/redux-utils"; +import * as ACTIONS from 'constants/action_types'; +import handleActions from 'util/redux-utils'; + +export type Subscription = { + channelName: string, + uri: string, +}; // Subscription redux types export type SubscriptionState = { @@ -8,30 +13,22 @@ export type SubscriptionState = { hasFetchedSubscriptions: boolean, }; -export type Subscription = { - channelName: string, - uri: string, -}; - // Subscription action types type doChannelSubscribe = { - type: actions.CHANNEL_SUBSCRIBE, + type: ACTIONS.CHANNEL_SUBSCRIBE, data: Subscription, }; type doChannelUnsubscribe = { - type: actions.CHANNEL_UNSUBSCRIBE, + type: ACTIONS.CHANNEL_UNSUBSCRIBE, data: Subscription, }; type HasFetchedSubscriptions = { - type: actions.HAS_FETCHED_SUBSCRIPTIONS, + type: ACTIONS.HAS_FETCHED_SUBSCRIPTIONS, }; -export type Action = - | doChannelSubscribe - | doChannelUnsubscribe - | HasFetchedSubscriptions; +export type Action = doChannelSubscribe | doChannelUnsubscribe | HasFetchedSubscriptions; export type Dispatch = (action: Action) => any; const defaultState = { @@ -41,7 +38,7 @@ const defaultState = { export default handleActions( { - [actions.CHANNEL_SUBSCRIBE]: ( + [ACTIONS.CHANNEL_SUBSCRIBE]: ( state: SubscriptionState, action: doChannelSubscribe ): SubscriptionState => { @@ -54,7 +51,7 @@ export default handleActions( subscriptions: newSubscriptions, }; }, - [actions.CHANNEL_UNSUBSCRIBE]: ( + [ACTIONS.CHANNEL_UNSUBSCRIBE]: ( state: SubscriptionState, action: doChannelUnsubscribe ): SubscriptionState => { @@ -62,20 +59,14 @@ export default handleActions( const newSubscriptions = state.subscriptions .slice() - .filter( - subscription => - subscription.channelName !== subscriptionToRemove.channelName - ); + .filter(subscription => subscription.channelName !== subscriptionToRemove.channelName); return { ...state, subscriptions: newSubscriptions, }; }, - [actions.HAS_FETCHED_SUBSCRIPTIONS]: ( - state: SubscriptionState, - action: HasFetchedSubscriptions - ): SubscriptionState => ({ + [ACTIONS.HAS_FETCHED_SUBSCRIPTIONS]: (state: SubscriptionState): SubscriptionState => ({ ...state, hasFetchedSubscriptions: true, }), diff --git a/src/renderer/redux/reducers/user.js b/src/renderer/redux/reducers/user.js index ef4bd6f87..be8c5f1c7 100644 --- a/src/renderer/redux/reducers/user.js +++ b/src/renderer/redux/reducers/user.js @@ -1,4 +1,4 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; @@ -6,9 +6,9 @@ const defaultState = { authenticationIsPending: false, userIsPending: false, emailNewIsPending: false, - emailNewErrorMessage: "", - emailToVerify: "", - inviteNewErrorMessage: "", + emailNewErrorMessage: '', + emailToVerify: '', + inviteNewErrorMessage: '', inviteNewIsPending: false, inviteStatusIsPending: false, invitesRemaining: undefined, @@ -16,7 +16,7 @@ const defaultState = { user: undefined, }; -reducers[types.AUTHENTICATION_STARTED] = function(state, action) { +reducers[ACTIONS.AUTHENTICATION_STARTED] = function(state) { return Object.assign({}, state, { authenticationIsPending: true, userIsPending: true, @@ -24,7 +24,7 @@ reducers[types.AUTHENTICATION_STARTED] = function(state, action) { }); }; -reducers[types.AUTHENTICATION_SUCCESS] = function(state, action) { +reducers[ACTIONS.AUTHENTICATION_SUCCESS] = function(state, action) { return Object.assign({}, state, { authenticationIsPending: false, userIsPending: false, @@ -32,7 +32,7 @@ reducers[types.AUTHENTICATION_SUCCESS] = function(state, action) { }); }; -reducers[types.AUTHENTICATION_FAILURE] = function(state, action) { +reducers[ACTIONS.AUTHENTICATION_FAILURE] = function(state) { return Object.assign({}, state, { authenticationIsPending: false, userIsPending: false, @@ -40,35 +40,35 @@ reducers[types.AUTHENTICATION_FAILURE] = function(state, action) { }); }; -reducers[types.USER_FETCH_STARTED] = function(state, action) { +reducers[ACTIONS.USER_FETCH_STARTED] = function(state) { return Object.assign({}, state, { userIsPending: true, user: defaultState.user, }); }; -reducers[types.USER_FETCH_SUCCESS] = function(state, action) { +reducers[ACTIONS.USER_FETCH_SUCCESS] = function(state, action) { return Object.assign({}, state, { userIsPending: false, user: action.data.user, }); }; -reducers[types.USER_FETCH_FAILURE] = function(state, action) { +reducers[ACTIONS.USER_FETCH_FAILURE] = function(state) { return Object.assign({}, state, { userIsPending: true, user: null, }); }; -reducers[types.USER_EMAIL_NEW_STARTED] = function(state, action) { +reducers[ACTIONS.USER_EMAIL_NEW_STARTED] = function(state) { return Object.assign({}, state, { emailNewIsPending: true, - emailNewErrorMessage: "", + emailNewErrorMessage: '', }); }; -reducers[types.USER_EMAIL_NEW_SUCCESS] = function(state, action) { +reducers[ACTIONS.USER_EMAIL_NEW_SUCCESS] = function(state, action) { const user = Object.assign({}, state.user); user.primary_email = action.data.email; return Object.assign({}, state, { @@ -78,68 +78,67 @@ reducers[types.USER_EMAIL_NEW_SUCCESS] = function(state, action) { }); }; -reducers[types.USER_EMAIL_NEW_EXISTS] = function(state, action) { - const user = Object.assign({}, state.user); +reducers[ACTIONS.USER_EMAIL_NEW_EXISTS] = function(state, action) { return Object.assign({}, state, { emailToVerify: action.data.email, emailNewIsPending: false, }); }; -reducers[types.USER_EMAIL_NEW_FAILURE] = function(state, action) { +reducers[ACTIONS.USER_EMAIL_NEW_FAILURE] = function(state, action) { return Object.assign({}, state, { emailNewIsPending: false, emailNewErrorMessage: action.data.error, }); }; -reducers[types.USER_EMAIL_VERIFY_STARTED] = function(state, action) { +reducers[ACTIONS.USER_EMAIL_VERIFY_STARTED] = function(state) { return Object.assign({}, state, { emailVerifyIsPending: true, - emailVerifyErrorMessage: "", + emailVerifyErrorMessage: '', }); }; -reducers[types.USER_EMAIL_VERIFY_SUCCESS] = function(state, action) { +reducers[ACTIONS.USER_EMAIL_VERIFY_SUCCESS] = function(state, action) { const user = Object.assign({}, state.user); user.primary_email = action.data.email; return Object.assign({}, state, { - emailToVerify: "", + emailToVerify: '', emailVerifyIsPending: false, user, }); }; -reducers[types.USER_EMAIL_VERIFY_FAILURE] = function(state, action) { +reducers[ACTIONS.USER_EMAIL_VERIFY_FAILURE] = function(state, action) { return Object.assign({}, state, { emailVerifyIsPending: false, emailVerifyErrorMessage: action.data.error, }); }; -reducers[types.USER_IDENTITY_VERIFY_STARTED] = function(state, action) { +reducers[ACTIONS.USER_IDENTITY_VERIFY_STARTED] = function(state) { return Object.assign({}, state, { identityVerifyIsPending: true, - identityVerifyErrorMessage: "", + identityVerifyErrorMessage: '', }); }; -reducers[types.USER_IDENTITY_VERIFY_SUCCESS] = function(state, action) { +reducers[ACTIONS.USER_IDENTITY_VERIFY_SUCCESS] = function(state, action) { return Object.assign({}, state, { identityVerifyIsPending: false, - identityVerifyErrorMessage: "", + identityVerifyErrorMessage: '', user: action.data.user, }); }; -reducers[types.USER_IDENTITY_VERIFY_FAILURE] = function(state, action) { +reducers[ACTIONS.USER_IDENTITY_VERIFY_FAILURE] = function(state, action) { return Object.assign({}, state, { identityVerifyIsPending: false, identityVerifyErrorMessage: action.data.error, }); }; -reducers[types.FETCH_ACCESS_TOKEN_SUCCESS] = function(state, action) { +reducers[ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS] = function(state, action) { const { token } = action.data; return Object.assign({}, state, { @@ -147,13 +146,13 @@ reducers[types.FETCH_ACCESS_TOKEN_SUCCESS] = function(state, action) { }); }; -reducers[types.USER_INVITE_STATUS_FETCH_STARTED] = function(state, action) { +reducers[ACTIONS.USER_INVITE_STATUS_FETCH_STARTED] = function(state) { return Object.assign({}, state, { inviteStatusIsPending: true, }); }; -reducers[types.USER_INVITE_STATUS_FETCH_SUCCESS] = function(state, action) { +reducers[ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS] = function(state, action) { return Object.assign({}, state, { inviteStatusIsPending: false, invitesRemaining: action.data.invitesRemaining, @@ -161,28 +160,28 @@ reducers[types.USER_INVITE_STATUS_FETCH_SUCCESS] = function(state, action) { }); }; -reducers[types.USER_INVITE_NEW_STARTED] = function(state, action) { +reducers[ACTIONS.USER_INVITE_NEW_STARTED] = function(state) { return Object.assign({}, state, { inviteNewIsPending: true, - inviteNewErrorMessage: "", + inviteNewErrorMessage: '', }); }; -reducers[types.USER_INVITE_NEW_SUCCESS] = function(state, action) { +reducers[ACTIONS.USER_INVITE_NEW_SUCCESS] = function(state) { return Object.assign({}, state, { inviteNewIsPending: false, - inviteNewErrorMessage: "", + inviteNewErrorMessage: '', }); }; -reducers[types.USER_INVITE_NEW_FAILURE] = function(state, action) { +reducers[ACTIONS.USER_INVITE_NEW_FAILURE] = function(state, action) { return Object.assign({}, state, { inviteNewIsPending: false, inviteNewErrorMessage: action.data.error.message, }); }; -reducers[types.USER_INVITE_STATUS_FETCH_FAILURE] = function(state, action) { +reducers[ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE] = function(state) { return Object.assign({}, state, { inviteStatusIsPending: false, invitesRemaining: null, diff --git a/src/renderer/redux/reducers/wallet.js b/src/renderer/redux/reducers/wallet.js index 233bcea25..403c57486 100644 --- a/src/renderer/redux/reducers/wallet.js +++ b/src/renderer/redux/reducers/wallet.js @@ -1,7 +1,7 @@ -import * as types from "constants/action_types"; +import * as ACTIONS from 'constants/action_types'; const reducers = {}; -const address = localStorage.getItem("receiveAddress"); +const receiveAddress = localStorage.getItem('receiveAddress'); const buildDraftTransaction = () => ({ amount: undefined, address: undefined, @@ -12,19 +12,19 @@ const defaultState = { blocks: {}, transactions: {}, fetchingTransactions: false, - receiveAddress: address, + receiveAddress, gettingNewAddress: false, draftTransaction: buildDraftTransaction(), sendingSupport: false, }; -reducers[types.FETCH_TRANSACTIONS_STARTED] = function(state, action) { +reducers[ACTIONS.FETCH_TRANSACTIONS_STARTED] = function(state) { return Object.assign({}, state, { fetchingTransactions: true, }); }; -reducers[types.FETCH_TRANSACTIONS_COMPLETED] = function(state, action) { +reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = function(state, action) { const byId = Object.assign({}, state.transactions); const { transactions } = action.data; @@ -39,41 +39,41 @@ reducers[types.FETCH_TRANSACTIONS_COMPLETED] = function(state, action) { }); }; -reducers[types.GET_NEW_ADDRESS_STARTED] = function(state, action) { +reducers[ACTIONS.GET_NEW_ADDRESS_STARTED] = function(state) { return Object.assign({}, state, { gettingNewAddress: true, }); }; -reducers[types.GET_NEW_ADDRESS_COMPLETED] = function(state, action) { +reducers[ACTIONS.GET_NEW_ADDRESS_COMPLETED] = function(state, action) { const { address } = action.data; - localStorage.setItem("receiveAddress", address); + localStorage.setItem('receiveAddress', address); return Object.assign({}, state, { gettingNewAddress: false, receiveAddress: address, }); }; -reducers[types.UPDATE_BALANCE] = function(state, action) { +reducers[ACTIONS.UPDATE_BALANCE] = function(state, action) { return Object.assign({}, state, { balance: action.data.balance, }); }; -reducers[types.CHECK_ADDRESS_IS_MINE_STARTED] = function(state, action) { +reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED] = function(state) { return Object.assign({}, state, { checkingAddressOwnership: true, }); }; -reducers[types.CHECK_ADDRESS_IS_MINE_COMPLETED] = function(state, action) { +reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED] = function(state) { return Object.assign({}, state, { checkingAddressOwnership: false, }); }; -reducers[types.SET_DRAFT_TRANSACTION_AMOUNT] = function(state, action) { +reducers[ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT] = function(state, action) { const oldDraft = state.draftTransaction; const newDraft = Object.assign({}, oldDraft, { amount: parseFloat(action.data.amount), @@ -84,7 +84,7 @@ reducers[types.SET_DRAFT_TRANSACTION_AMOUNT] = function(state, action) { }); }; -reducers[types.SET_DRAFT_TRANSACTION_ADDRESS] = function(state, action) { +reducers[ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS] = function(state, action) { const oldDraft = state.draftTransaction; const newDraft = Object.assign({}, oldDraft, { address: action.data.address, @@ -95,7 +95,7 @@ reducers[types.SET_DRAFT_TRANSACTION_ADDRESS] = function(state, action) { }); }; -reducers[types.SEND_TRANSACTION_STARTED] = function(state, action) { +reducers[ACTIONS.SEND_TRANSACTION_STARTED] = function(state) { const newDraftTransaction = Object.assign({}, state.draftTransaction, { sending: true, }); @@ -105,13 +105,13 @@ reducers[types.SEND_TRANSACTION_STARTED] = function(state, action) { }); }; -reducers[types.SEND_TRANSACTION_COMPLETED] = function(state, action) { +reducers[ACTIONS.SEND_TRANSACTION_COMPLETED] = function(state) { return Object.assign({}, state, { draftTransaction: buildDraftTransaction(), }); }; -reducers[types.SEND_TRANSACTION_FAILED] = function(state, action) { +reducers[ACTIONS.SEND_TRANSACTION_FAILED] = function(state, action) { const newDraftTransaction = Object.assign({}, state.draftTransaction, { sending: false, error: action.data.error, @@ -122,28 +122,28 @@ reducers[types.SEND_TRANSACTION_FAILED] = function(state, action) { }); }; -reducers[types.SUPPORT_TRANSACTION_STARTED] = function(state, action) { +reducers[ACTIONS.SUPPORT_TRANSACTION_STARTED] = function(state) { return Object.assign({}, state, { sendingSupport: true, }); }; -reducers[types.SUPPORT_TRANSACTION_COMPLETED] = function(state, action) { +reducers[ACTIONS.SUPPORT_TRANSACTION_COMPLETED] = function(state) { return Object.assign({}, state, { sendingSupport: false, }); }; -reducers[types.SUPPORT_TRANSACTION_FAILED] = function(state, action) { +reducers[ACTIONS.SUPPORT_TRANSACTION_FAILED] = function(state, action) { return Object.assign({}, state, { error: action.data.error, sendingSupport: false, }); }; -reducers[types.FETCH_BLOCK_SUCCESS] = (state, action) => { - const { block, block: { height } } = action.data, - blocks = Object.assign({}, state.blocks); +reducers[ACTIONS.FETCH_BLOCK_SUCCESS] = (state, action) => { + const { block, block: { height } } = action.data; + const blocks = Object.assign({}, state.blocks); blocks[height] = block; diff --git a/src/renderer/redux/selectors/app.js b/src/renderer/redux/selectors/app.js index 24c2f2b95..7a43f7fb3 100644 --- a/src/renderer/redux/selectors/app.js +++ b/src/renderer/redux/selectors/app.js @@ -1,32 +1,26 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; -export const _selectState = state => state.app || {}; +export const selectState = state => state.app || {}; -export const selectPlatform = createSelector( - _selectState, - state => state.platform -); +export const selectPlatform = createSelector(selectState, state => state.platform); export const selectUpdateUrl = createSelector(selectPlatform, platform => { switch (platform) { - case "darwin": - return "https://lbry.io/get/lbry.dmg"; - case "linux": - return "https://lbry.io/get/lbry.deb"; - case "win32": - return "https://lbry.io/get/lbry.exe"; + case 'darwin': + return 'https://lbry.io/get/lbry.dmg'; + case 'linux': + return 'https://lbry.io/get/lbry.deb'; + case 'win32': + return 'https://lbry.io/get/lbry.exe'; default: - throw "Unknown platform"; + throw Error('Unknown platform'); } }); -export const selectRemoteVersion = createSelector( - _selectState, - state => state.remoteVersion -); +export const selectRemoteVersion = createSelector(selectState, state => state.remoteVersion); export const selectIsUpgradeAvailable = createSelector( - _selectState, + selectState, state => state.isUpgradeAvailable ); @@ -35,81 +29,54 @@ export const selectUpgradeFilename = createSelector( selectRemoteVersion, (platform, version) => { switch (platform) { - case "darwin": + case 'darwin': return `LBRY_${version}.dmg`; - case "linux": + case 'linux': return `LBRY_${version}_amd64.deb`; - case "win32": + case 'win32': return `LBRY_${version}.exe`; default: - throw "Unknown platform"; + throw Error('Unknown platform'); } } ); -export const selectCurrentModal = createSelector( - _selectState, - state => state.modal -); +export const selectCurrentModal = createSelector(selectState, state => state.modal); -export const selectDownloadProgress = createSelector( - _selectState, - state => state.downloadProgress -); +export const selectDownloadProgress = createSelector(selectState, state => state.downloadProgress); export const selectDownloadComplete = createSelector( - _selectState, + selectState, state => state.upgradeDownloadCompleted ); -export const selectIsUpgradeSkipped = createSelector( - _selectState, - state => state.isUpgradeSkipped -); +export const selectIsUpgradeSkipped = createSelector(selectState, state => state.isUpgradeSkipped); -export const selectUpgradeDownloadPath = createSelector( - _selectState, - state => state.downloadPath -); +export const selectUpgradeDownloadPath = createSelector(selectState, state => state.downloadPath); -export const selectUpgradeDownloadItem = createSelector( - _selectState, - state => state.downloadItem -); +export const selectUpgradeDownloadItem = createSelector(selectState, state => state.downloadItem); -export const selectModalProps = createSelector( - _selectState, - state => state.modalProps -); +export const selectModalProps = createSelector(selectState, state => state.modalProps); -export const selectDaemonReady = createSelector( - _selectState, - state => state.daemonReady -); +export const selectDaemonReady = createSelector(selectState, state => state.daemonReady); export const selectDaemonVersionMatched = createSelector( - _selectState, + selectState, state => state.daemonVersionMatched ); -export const selectSnackBar = createSelector( - _selectState, - state => state.snackBar || {} -); +export const selectSnackBar = createSelector(selectState, state => state.snackBar || {}); export const selectSnackBarSnacks = createSelector( selectSnackBar, snackBar => snackBar.snacks || [] ); -export const selectBadgeNumber = createSelector( - _selectState, - state => state.badgeNumber -); +export const selectBadgeNumber = createSelector(selectState, state => state.badgeNumber); export const selectCurrentLanguage = createSelector( - _selectState, - () => app.i18n.getLocale() || "en" + selectState, + () => app.i18n.getLocale() || 'en' ); -export const selectVolume = createSelector(_selectState, state => state.volume); +export const selectVolume = createSelector(selectState, state => state.volume); diff --git a/src/renderer/redux/selectors/availability.js b/src/renderer/redux/selectors/availability.js index 679f25ca0..afa7ac7f6 100644 --- a/src/renderer/redux/selectors/availability.js +++ b/src/renderer/redux/selectors/availability.js @@ -1,22 +1,7 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; -const _selectState = state => state.availability; +const selectState = state => state.availability; -export const selectAvailabilityByUri = createSelector( - _selectState, - state => state.byUri || {} -); +const selectFetchingAvailability = createSelector(selectState, state => state.fetching || {}); -export const makeSelectIsAvailableForUri = uri => - createSelector( - selectAvailabilityByUri, - byUri => (!byUri || byUri[uri] === undefined ? undefined : byUri[uri] > 0) - ); - -export const selectFetchingAvailability = createSelector( - _selectState, - state => state.fetching || {} -); - -export const makeSelectFetchingAvailabilityForUri = uri => - createSelector(selectFetchingAvailability, byUri => byUri && byUri[uri]); +export { selectFetchingAvailability as default }; diff --git a/src/renderer/redux/selectors/claims.js b/src/renderer/redux/selectors/claims.js index 3fc571aa0..b0a62174a 100644 --- a/src/renderer/redux/selectors/claims.js +++ b/src/renderer/redux/selectors/claims.js @@ -1,77 +1,79 @@ -import { createSelector } from "reselect"; -import lbryuri from "lbryuri"; -import { makeSelectCurrentParam } from "./navigation"; +import { createSelector } from 'reselect'; +import Lbryuri from 'lbryuri'; +import { makeSelectCurrentParam } from 'redux/selectors/navigation'; -const _selectState = state => state.claims || {}; +const selectState = state => state.claims || {}; -export const selectClaimsById = createSelector( - _selectState, - state => state.byId || {} -); +export const selectClaimsById = createSelector(selectState, state => state.byId || {}); -export const selectClaimsByUri = createSelector( - _selectState, - selectClaimsById, - (state, byId) => { - const byUri = state.claimsByUri || {}; - const claims = {}; +export const selectClaimsByUri = createSelector(selectState, selectClaimsById, (state, byId) => { + const byUri = state.claimsByUri || {}; + const claims = {}; - Object.keys(byUri).forEach(uri => { - const claimId = byUri[uri]; + Object.keys(byUri).forEach(uri => { + const claimId = byUri[uri]; - // NOTE returning a null claim allows us to differentiate between an - // undefined (never fetched claim) and one which just doesn't exist. Not - // the cleanest solution but couldn't think of anything better right now - if (claimId === null) { - claims[uri] = null; - } else { - const claim = byId[claimId]; + // NOTE returning a null claim allows us to differentiate between an + // undefined (never fetched claim) and one which just doesn't exist. Not + // the cleanest solution but couldn't think of anything better right now + if (claimId === null) { + claims[uri] = null; + } else { + const claim = byId[claimId]; - claims[uri] = claim; - } - }); + claims[uri] = claim; + } + }); - return claims; - } -); + return claims; +}); export const selectAllClaimsByChannel = createSelector( - _selectState, + selectState, state => state.claimsByChannel || {} ); export const makeSelectClaimForUri = uri => - createSelector( - selectClaimsByUri, - claims => claims && claims[lbryuri.normalize(uri)] - ); + createSelector(selectClaimsByUri, claims => claims && claims[Lbryuri.normalize(uri)]); + +export const selectMyClaimsRaw = createSelector(selectState, state => state.myClaims); + +export const selectAbandoningIds = createSelector(selectState, state => + Object.keys(state.abandoningById || {}) +); + +export const selectMyActiveClaims = createSelector( + selectMyClaimsRaw, + selectAbandoningIds, + (claims, abandoningIds) => + new Set( + claims && + claims + .map(claim => claim.claim_id) + .filter(claimId => Object.keys(abandoningIds).indexOf(claimId) === -1) + ) +); export const makeSelectClaimIsMine = rawUri => { - const uri = lbryuri.normalize(rawUri); + const uri = Lbryuri.normalize(rawUri); return createSelector( selectClaimsByUri, selectMyActiveClaims, (claims, myClaims) => - claims && - claims[uri] && - claims[uri].claim_id && - myClaims.has(claims[uri].claim_id) + claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id) ); }; export const selectAllFetchingChannelClaims = createSelector( - _selectState, + selectState, state => state.fetchingChannelClaims || {} ); export const makeSelectFetchingChannelClaims = uri => - createSelector( - selectAllFetchingChannelClaims, - fetching => fetching && fetching[uri] - ); + createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]); export const makeSelectClaimsInChannelForCurrentPage = uri => { - const pageSelector = makeSelectCurrentParam("page"); + const pageSelector = makeSelectCurrentParam('page'); return createSelector( selectClaimsById, @@ -90,53 +92,27 @@ export const makeSelectClaimsInChannelForCurrentPage = uri => { export const makeSelectMetadataForUri = uri => createSelector(makeSelectClaimForUri(uri), claim => { - const metadata = - claim && claim.value && claim.value.stream && claim.value.stream.metadata; + const metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; const value = metadata || (claim === undefined ? undefined : null); return value; }); export const makeSelectTitleForUri = uri => - createSelector( - makeSelectMetadataForUri(uri), - metadata => metadata && metadata.title - ); + createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); export const makeSelectContentTypeForUri = uri => createSelector(makeSelectClaimForUri(uri), claim => { - const source = - claim && claim.value && claim.value.stream && claim.value.stream.source; + const source = claim && claim.value && claim.value.stream && claim.value.stream.source; return source ? source.contentType : undefined; }); export const selectIsFetchingClaimListMine = createSelector( - _selectState, + selectState, state => !!state.isFetchingClaimListMine ); -export const selectMyClaimsRaw = createSelector( - _selectState, - state => state.myClaims -); - -export const selectAbandoningIds = createSelector(_selectState, state => - Object.keys(state.abandoningById || {}) -); - -export const selectMyActiveClaims = createSelector( - selectMyClaimsRaw, - selectAbandoningIds, - (claims, abandoningIds) => - new Set( - claims && - claims - .map(claim => claim.claim_id) - .filter(claimId => Object.keys(abandoningIds).indexOf(claimId) === -1) - ) -); - -export const selectPendingClaims = createSelector(_selectState, state => +export const selectPendingClaims = createSelector(selectState, state => Object.values(state.pendingById || {}) ); @@ -151,46 +127,38 @@ export const selectMyClaims = createSelector( myClaimIds.forEach(id => { const claim = byId[id]; - if (claim && abandoningIds.indexOf(id) == -1) claims.push(claim); + if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); return [...claims, ...pendingClaims]; } ); -export const selectMyClaimsWithoutChannels = createSelector( - selectMyClaims, - myClaims => myClaims.filter(claim => !claim.name.match(/^@/)) +export const selectMyClaimsWithoutChannels = createSelector(selectMyClaims, myClaims => + myClaims.filter(claim => !claim.name.match(/^@/)) ); export const selectAllMyClaimsByOutpoint = createSelector( selectMyClaimsRaw, claims => - new Set( - claims && claims.length - ? claims.map(claim => `${claim.txid}:${claim.nout}`) - : null - ) + new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null) ); -export const selectMyClaimsOutpoints = createSelector( - selectMyClaims, - myClaims => { - const outpoints = []; +export const selectMyClaimsOutpoints = createSelector(selectMyClaims, myClaims => { + const outpoints = []; - myClaims.forEach(claim => outpoints.push(`${claim.txid}:${claim.nout}`)); + myClaims.forEach(claim => outpoints.push(`${claim.txid}:${claim.nout}`)); - return outpoints; - } -); + return outpoints; +}); export const selectFetchingMyChannels = createSelector( - _selectState, + selectState, state => !!state.fetchingMyChannels ); export const selectMyChannelClaims = createSelector( - _selectState, + selectState, selectClaimsById, (state, byId) => { const ids = state.myChannelClaims || []; diff --git a/src/renderer/redux/selectors/content.js b/src/renderer/redux/selectors/content.js index 7d7f01ef9..31e415dbe 100644 --- a/src/renderer/redux/selectors/content.js +++ b/src/renderer/redux/selectors/content.js @@ -1,35 +1,26 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; -export const _selectState = state => state.content || {}; +export const selectState = state => state.content || {}; -export const selectFeaturedUris = createSelector( - _selectState, - state => state.featuredUris -); +export const selectFeaturedUris = createSelector(selectState, state => state.featuredUris); export const selectFetchingFeaturedUris = createSelector( - _selectState, + selectState, state => !!state.fetchingFeaturedContent ); -export const selectResolvingUris = createSelector( - _selectState, - state => state.resolvingUris || [] -); +export const selectResolvingUris = createSelector(selectState, state => state.resolvingUris || []); -export const selectPlayingUri = createSelector( - _selectState, - state => state.playingUri -); +export const selectPlayingUri = createSelector(selectState, state => state.playingUri); export const makeSelectIsUriResolving = uri => createSelector( selectResolvingUris, - resolvingUris => resolvingUris && resolvingUris.indexOf(uri) != -1 + resolvingUris => resolvingUris && resolvingUris.indexOf(uri) !== -1 ); export const selectChannelClaimCounts = createSelector( - _selectState, + selectState, state => state.channelClaimCounts || {} ); @@ -43,6 +34,6 @@ export const makeSelectTotalPagesForChannel = uri => ); export const selectRewardContentClaimIds = createSelector( - _selectState, + selectState, state => state.rewardedContentClaimIds ); diff --git a/src/renderer/redux/selectors/cost_info.js b/src/renderer/redux/selectors/cost_info.js index 20eae1a69..04d5b09e5 100644 --- a/src/renderer/redux/selectors/cost_info.js +++ b/src/renderer/redux/selectors/cost_info.js @@ -1,33 +1,20 @@ -import { createSelector } from "reselect"; -import { selectCurrentParams } from "redux/selectors/navigation"; +import { createSelector } from 'reselect'; +import { selectCurrentParams } from 'redux/selectors/navigation'; -export const _selectState = state => state.costInfo || {}; +export const selectState = state => state.costInfo || {}; -export const selectAllCostInfoByUri = createSelector( - _selectState, - state => state.byUri || {} -); +export const selectAllCostInfoByUri = createSelector(selectState, state => state.byUri || {}); export const makeSelectCostInfoForUri = uri => - createSelector( - selectAllCostInfoByUri, - costInfos => costInfos && costInfos[uri] - ); + createSelector(selectAllCostInfoByUri, costInfos => costInfos && costInfos[uri]); export const selectCostForCurrentPageUri = createSelector( selectAllCostInfoByUri, selectCurrentParams, - (costInfo, params) => - params.uri && costInfo[params.uri] ? costInfo[params.uri].cost : undefined + (costInfo, params) => (params.uri && costInfo[params.uri] ? costInfo[params.uri].cost : undefined) ); -export const selectFetchingCostInfo = createSelector( - _selectState, - state => state.fetching || {} -); +export const selectFetchingCostInfo = createSelector(selectState, state => state.fetching || {}); export const makeSelectFetchingCostInfoForUri = uri => - createSelector( - selectFetchingCostInfo, - fetchingByUri => fetchingByUri && fetchingByUri[uri] - ); + createSelector(selectFetchingCostInfo, fetchingByUri => fetchingByUri && fetchingByUri[uri]); diff --git a/src/renderer/redux/selectors/file_info.js b/src/renderer/redux/selectors/file_info.js index 74482abf0..9e2409911 100644 --- a/src/renderer/redux/selectors/file_info.js +++ b/src/renderer/redux/selectors/file_info.js @@ -1,45 +1,39 @@ -import lbry from "lbry"; -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; import { selectClaimsByUri, selectIsFetchingClaimListMine, selectMyClaims, selectMyClaimsOutpoints, -} from "redux/selectors/claims"; +} from 'redux/selectors/claims'; -export const _selectState = state => state.fileInfo || {}; +export const selectState = state => state.fileInfo || {}; export const selectFileInfosByOutpoint = createSelector( - _selectState, + selectState, state => state.byOutpoint || {} ); export const selectIsFetchingFileList = createSelector( - _selectState, - state => !!state.isFetchingFileList + selectState, + state => state.isFetchingFileList ); export const selectIsFetchingFileListDownloadedOrPublished = createSelector( selectIsFetchingFileList, selectIsFetchingClaimListMine, - (isFetchingFileList, isFetchingClaimListMine) => - isFetchingFileList || isFetchingClaimListMine + (isFetchingFileList, isFetchingClaimListMine) => isFetchingFileList || isFetchingClaimListMine ); export const makeSelectFileInfoForUri = uri => - createSelector( - selectClaimsByUri, - selectFileInfosByOutpoint, - (claims, byOutpoint) => { - const claim = claims[uri], - outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; + createSelector(selectClaimsByUri, selectFileInfosByOutpoint, (claims, byOutpoint) => { + const claim = claims[uri]; + const outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; - return outpoint ? byOutpoint[outpoint] : undefined; - } - ); + return outpoint ? byOutpoint[outpoint] : undefined; + }); export const selectDownloadingByOutpoint = createSelector( - _selectState, + selectState, state => state.downloadingByOutpoint || {} ); @@ -53,17 +47,13 @@ export const makeSelectDownloadingForUri = uri => } ); -export const selectUrisLoading = createSelector( - _selectState, - state => state.urisLoading || {} -); +export const selectUrisLoading = createSelector(selectState, state => state.urisLoading || {}); export const makeSelectLoadingForUri = uri => createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); -export const selectFileInfosPendingPublish = createSelector( - _selectState, - state => Object.values(state.pendingByOutpoint || {}) +export const selectFileInfosPendingPublish = createSelector(selectState, state => + Object.values(state.pendingByOutpoint || {}) ); export const selectFileInfosDownloaded = createSelector( @@ -141,18 +131,15 @@ export const selectDownloadingFileInfos = createSelector( } ); -export const selectTotalDownloadProgress = createSelector( - selectDownloadingFileInfos, - fileInfos => { - const progress = []; +export const selectTotalDownloadProgress = createSelector(selectDownloadingFileInfos, fileInfos => { + const progress = []; - fileInfos.forEach(fileInfo => { - progress.push(fileInfo.written_bytes / fileInfo.total_bytes * 100); - }); + fileInfos.forEach(fileInfo => { + progress.push(fileInfo.written_bytes / fileInfo.total_bytes * 100); + }); - const totalProgress = progress.reduce((a, b) => a + b, 0); + const totalProgress = progress.reduce((a, b) => a + b, 0); - if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; - return -1; - } -); + if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; + return -1; +}); diff --git a/src/renderer/redux/selectors/navigation.js b/src/renderer/redux/selectors/navigation.js index 7d401127a..dc0b507a1 100644 --- a/src/renderer/redux/selectors/navigation.js +++ b/src/renderer/redux/selectors/navigation.js @@ -1,17 +1,12 @@ -import { createSelector } from "reselect"; -import { parseQueryParams, toQueryString } from "util/query_params"; -import * as settings from "constants/settings.js"; -import lbryuri from "lbryuri"; +import { createSelector } from 'reselect'; +import { parseQueryParams, toQueryString } from 'util/query_params'; +import Lbryuri from 'lbryuri'; -export const _selectState = state => state.navigation || {}; +export const selectState = state => state.navigation || {}; -export const selectCurrentPath = createSelector( - _selectState, - state => state.currentPath -); +export const selectCurrentPath = createSelector(selectState, state => state.currentPath); -export const computePageFromPath = path => - path.replace(/^\//, "").split("?")[0]; +export const computePageFromPath = path => path.replace(/^\//, '').split('?')[0]; export const selectCurrentPage = createSelector(selectCurrentPath, path => computePageFromPath(path) @@ -21,50 +16,47 @@ export const selectCurrentParams = createSelector(selectCurrentPath, path => { if (path === undefined) return {}; if (!path.match(/\?/)) return {}; - return parseQueryParams(path.split("?")[1]); + return parseQueryParams(path.split('?')[1]); }); export const makeSelectCurrentParam = param => - createSelector( - selectCurrentParams, - params => (params ? params[param] : undefined) - ); + createSelector(selectCurrentParams, params => (params ? params[param] : undefined)); export const selectHeaderLinks = createSelector(selectCurrentPage, page => { // This contains intentional fall throughs switch (page) { - case "wallet": - case "history": - case "send": - case "getcredits": - case "invite": - case "rewards": - case "backup": + case 'wallet': + case 'history': + case 'send': + case 'getcredits': + case 'invite': + case 'rewards': + case 'backup': return { - wallet: __("Overview"), - getcredits: __("Get Credits"), - send: __("Send / Receive"), - rewards: __("Rewards"), - invite: __("Invites"), - history: __("History"), + wallet: __('Overview'), + getcredits: __('Get Credits'), + send: __('Send / Receive'), + rewards: __('Rewards'), + invite: __('Invites'), + history: __('History'), }; - case "downloaded": - case "published": + case 'downloaded': + case 'published': return { - downloaded: __("Downloaded"), - published: __("Published"), + downloaded: __('Downloaded'), + published: __('Published'), }; - case "settings": - case "help": + case 'settings': + case 'help': return { - settings: __("Settings"), - help: __("Help"), + settings: __('Settings'), + help: __('Help'), }; - case "discover": - case "subscriptions": + case 'discover': + case 'subscriptions': return { - discover: __("Discover"), - subscriptions: __("Subscriptions"), + discover: __('Discover'), + subscriptions: __('Subscriptions'), }; default: return null; @@ -76,86 +68,72 @@ export const selectPageTitle = createSelector( selectCurrentParams, (page, params) => { switch (page) { - case "settings": - return __("Settings"); - case "report": - return __("Report"); - case "wallet": - return __("Wallet"); - case "send": - return __("Send or Receive LBRY Credits"); - case "getcredits": - return __("Get LBRY Credits"); - case "backup": - return __("Backup Your Wallet"); - case "rewards": - return __("Rewards"); - case "invite": - return __("Invites"); - case "start": - return __("Start"); - case "publish": - return params.id ? __("Edit") : __("Publish"); - case "help": - return __("Help"); - case "developer": - return __("Developer"); - case "show": { - const parts = [lbryuri.normalize(params.uri)]; + case 'settings': + return __('Settings'); + case 'report': + return __('Report'); + case 'wallet': + return __('Wallet'); + case 'send': + return __('Send or Receive LBRY Credits'); + case 'getcredits': + return __('Get LBRY Credits'); + case 'backup': + return __('Backup Your Wallet'); + case 'rewards': + return __('Rewards'); + case 'invite': + return __('Invites'); + case 'start': + return __('Start'); + case 'publish': + return params.id ? __('Edit') : __('Publish'); + case 'help': + return __('Help'); + case 'developer': + return __('Developer'); + case 'show': { + const parts = [Lbryuri.normalize(params.uri)]; // If the params has any keys other than "uri" if (Object.keys(params).length > 1) { parts.push(toQueryString(Object.assign({}, params, { uri: null }))); } - return parts.join("?"); + return parts.join('?'); } - case "downloaded": - return __("Downloads & Purchases"); - case "published": - return __("Publishes"); - case "search": - return params.query - ? __("Search results for %s", params.query) - : __("Search"); - case "subscriptions": - return __("Your Subscriptions"); - case "discover": + case 'downloaded': + return __('Downloads & Purchases'); + case 'published': + return __('Publications'); + case 'search': + return params.query ? __('Search results for %s', params.query) : __('Search'); + case 'subscriptions': + return __('Your Subscriptions'); + case 'discover': case false: case null: - case "": - return ""; + case '': + return ''; default: - return page[0].toUpperCase() + (page.length > 0 ? page.substr(1) : ""); + return page[0].toUpperCase() + (page.length > 0 ? page.substr(1) : ''); } } ); -export const selectPathAfterAuth = createSelector( - _selectState, - state => state.pathAfterAuth -); +export const selectPathAfterAuth = createSelector(selectState, state => state.pathAfterAuth); -export const selectIsBackDisabled = createSelector( - _selectState, - state => state.index === 0 -); +export const selectIsBackDisabled = createSelector(selectState, state => state.index === 0); export const selectIsForwardDisabled = createSelector( - _selectState, + selectState, state => state.index === state.stack.length - 1 ); -export const selectHistoryIndex = createSelector( - _selectState, - state => state.index -); +export const selectHistoryIndex = createSelector(selectState, state => state.index); -export const selectHistoryStack = createSelector( - _selectState, - state => state.stack -); +export const selectHistoryStack = createSelector(selectState, state => state.stack); // returns current page attributes (scrollY, path) export const selectActiveHistoryEntry = createSelector( - _selectState, + selectState, state => state.stack[state.index] ); diff --git a/src/renderer/redux/selectors/rewards.js b/src/renderer/redux/selectors/rewards.js index ed6ef4605..cb0c83f52 100644 --- a/src/renderer/redux/selectors/rewards.js +++ b/src/renderer/redux/selectors/rewards.js @@ -1,16 +1,15 @@ -import { createSelector } from "reselect"; -import { selectUser } from "redux/selectors/user"; -import rewards from "rewards"; +import { createSelector } from 'reselect'; +import REWARDS from 'rewards'; -const _selectState = state => state.rewards || {}; +const selectState = state => state.rewards || {}; export const selectUnclaimedRewardsByType = createSelector( - _selectState, + selectState, state => state.unclaimedRewardsByType ); export const selectClaimedRewardsById = createSelector( - _selectState, + selectState, state => state.claimedRewardsById ); @@ -19,13 +18,12 @@ export const selectClaimedRewards = createSelector( byId => Object.values(byId) || [] ); -export const selectClaimedRewardsByTransactionId = createSelector( - selectClaimedRewards, - rewards => - rewards.reduce((map, reward) => { - map[reward.transaction_id] = reward; - return map; - }, {}) +export const selectClaimedRewardsByTransactionId = createSelector(selectClaimedRewards, rewards => + rewards.reduce((mapParam, reward) => { + const map = mapParam; + map[reward.transaction_id] = reward; + return map; + }, {}) ); export const selectUnclaimedRewards = createSelector( @@ -33,38 +31,20 @@ export const selectUnclaimedRewards = createSelector( byType => Object.values(byType).sort( (a, b) => - rewards.SORT_ORDER.indexOf(a.reward_type) < - rewards.SORT_ORDER.indexOf(b.reward_type) + REWARDS.SORT_ORDER.indexOf(a.reward_type) < REWARDS.SORT_ORDER.indexOf(b.reward_type) ? -1 : 1 ) || [] ); -export const selectIsRewardEligible = createSelector( - selectUser, - user => user.can_claim_rewards +export const selectFetchingRewards = createSelector(selectState, state => !!state.fetching); + +export const selectUnclaimedRewardValue = createSelector(selectUnclaimedRewards, rewards => + rewards.reduce((sum, reward) => sum + reward.reward_amount, 0) ); -export const selectFetchingRewards = createSelector( - _selectState, - state => !!state.fetching -); - -export const selectUnclaimedRewardValue = createSelector( - selectUnclaimedRewards, - rewards => rewards.reduce((sum, reward) => sum + reward.reward_amount, 0) -); - -export const selectHasClaimedReward = (state, props) => { - const reward = selectRewardsByType(state)[props.reward_type]; - return reward && reward.transaction_id !== ""; -}; - -export const makeSelectHasClaimedReward = () => - createSelector(selectHasClaimedReward, claimed => claimed); - export const selectClaimsPendingByType = createSelector( - _selectState, + selectState, state => state.claimPendingByType ); @@ -75,7 +55,7 @@ export const makeSelectIsRewardClaimPending = () => createSelector(selectIsClaimRewardPending, isClaiming => isClaiming); export const selectClaimErrorsByType = createSelector( - _selectState, + selectState, state => state.claimErrorsByType ); @@ -85,14 +65,9 @@ const selectClaimRewardError = (state, props) => export const makeSelectClaimRewardError = () => createSelector(selectClaimRewardError, errorMessage => errorMessage); -const selectRewardByType = (state, props) => - selectUnclaimedRewardsByType(state)[props.reward_type]; +const selectRewardByType = (state, props) => selectUnclaimedRewardsByType(state)[props.reward_type]; -export const makeSelectRewardByType = () => - createSelector(selectRewardByType, reward => reward); +export const makeSelectRewardByType = () => createSelector(selectRewardByType, reward => reward); export const makeSelectRewardAmountByType = () => - createSelector( - selectRewardByType, - reward => (reward ? reward.reward_amount : 0) - ); + createSelector(selectRewardByType, reward => (reward ? reward.reward_amount : 0)); diff --git a/src/renderer/redux/selectors/search.js b/src/renderer/redux/selectors/search.js index 8faf0a307..b34a5742f 100644 --- a/src/renderer/redux/selectors/search.js +++ b/src/renderer/redux/selectors/search.js @@ -1,40 +1,34 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; import { selectPageTitle, selectCurrentPage, selectCurrentParams, -} from "redux/selectors/navigation"; +} from 'redux/selectors/navigation'; -export const _selectState = state => state.search || {}; +export const selectState = state => state.search || {}; export const selectSearchQuery = createSelector( selectCurrentPage, selectCurrentParams, - (page, params) => (page === "search" ? params && params.query : null) + (page, params) => (page === 'search' ? params && params.query : null) ); -export const selectIsSearching = createSelector( - _selectState, - state => !!state.searching -); +export const selectIsSearching = createSelector(selectState, state => !!state.searching); -export const selectSearchUrisByQuery = createSelector( - _selectState, - state => state.urisByQuery -); +export const selectSearchUrisByQuery = createSelector(selectState, state => state.urisByQuery); export const makeSelectSearchUris = query => // replace statement below is kind of ugly, and repeated in doSearch action createSelector( selectSearchUrisByQuery, - byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, "") : query] + byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '') : query] ); export const selectWunderBarAddress = createSelector( selectCurrentPage, selectPageTitle, selectSearchQuery, - (page, title, query) => (page != "search" ? title : query || title) + (page, title, query) => (page !== 'search' ? title : query || title) ); export const selectWunderBarIcon = createSelector( @@ -42,44 +36,44 @@ export const selectWunderBarIcon = createSelector( selectCurrentParams, (page, params) => { switch (page) { - case "auth": - return "icon-user"; - case "settings": - return "icon-gear"; - case "help": - return "icon-question"; - case "report": - return "icon-file"; - case "downloaded": - return "icon-folder"; - case "published": - return "icon-folder"; - case "history": - return "icon-history"; - case "send": - return "icon-send"; - case "rewards": - return "icon-rocket"; - case "invite": - return "icon-envelope-open"; - case "getcredits": - return "icon-shopping-cart"; - case "wallet": - case "backup": - return "icon-bank"; - case "show": - return "icon-file"; - case "publish": - return params.id ? __("icon-pencil") : __("icon-upload"); - case "developer": - return "icon-code"; - case "discover": - case "search": - return "icon-search"; - case "subscriptions": - return "icon-th-list"; + case 'auth': + return 'icon-user'; + case 'settings': + return 'icon-gear'; + case 'help': + return 'icon-question'; + case 'report': + return 'icon-file'; + case 'downloaded': + return 'icon-folder'; + case 'published': + return 'icon-folder'; + case 'history': + return 'icon-history'; + case 'send': + return 'icon-send'; + case 'rewards': + return 'icon-rocket'; + case 'invite': + return 'icon-envelope-open'; + case 'getcredits': + return 'icon-shopping-cart'; + case 'wallet': + case 'backup': + return 'icon-bank'; + case 'show': + return 'icon-file'; + case 'publish': + return params.id ? __('icon-pencil') : __('icon-upload'); + case 'developer': + return 'icon-code'; + case 'discover': + case 'search': + return 'icon-search'; + case 'subscriptions': + return 'icon-th-list'; default: - return "icon-file"; + return 'icon-file'; } } ); diff --git a/src/renderer/redux/selectors/settings.js b/src/renderer/redux/selectors/settings.js index b0a7325dd..ba246f0cb 100644 --- a/src/renderer/redux/selectors/settings.js +++ b/src/renderer/redux/selectors/settings.js @@ -1,24 +1,17 @@ -import * as settings from "constants/settings"; -import { createSelector } from "reselect"; -import path from "path"; +import * as SETTINGS from 'constants/settings'; +import { createSelector } from 'reselect'; -const _selectState = state => state.settings || {}; +const selectState = state => state.settings || {}; -export const selectDaemonSettings = createSelector( - _selectState, - state => state.daemonSettings -); +export const selectDaemonSettings = createSelector(selectState, state => state.daemonSettings); export const selectClientSettings = createSelector( - _selectState, + selectState, state => state.clientSettings || {} ); export const makeSelectClientSetting = setting => - createSelector( - selectClientSettings, - settings => (settings ? settings[setting] : undefined) - ); + createSelector(selectClientSettings, settings => (settings ? settings[setting] : undefined)); export const selectSettingsIsGenerous = createSelector( selectDaemonSettings, @@ -26,14 +19,11 @@ export const selectSettingsIsGenerous = createSelector( ); // refactor me -export const selectShowNsfw = makeSelectClientSetting(settings.SHOW_NSFW); +export const selectShowNsfw = makeSelectClientSetting(SETTINGS.SHOW_NSFW); -export const selectLanguages = createSelector( - _selectState, - state => state.languages || {} -); +export const selectLanguages = createSelector(selectState, state => state.languages || {}); export const selectThemePath = createSelector( - makeSelectClientSetting(settings.THEME), - theme => `${staticResourcesPath}/themes/${theme || "light"}.css` + makeSelectClientSetting(SETTINGS.THEME), + theme => `${staticResourcesPath}/themes/${theme || 'light'}.css` ); diff --git a/src/renderer/redux/selectors/shape_shift.js b/src/renderer/redux/selectors/shape_shift.js index e60af9fb4..090006d73 100644 --- a/src/renderer/redux/selectors/shape_shift.js +++ b/src/renderer/redux/selectors/shape_shift.js @@ -1,7 +1,9 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; -const _selectState = state => state.shapeShift; +const selectState = state => state.shapeShift; -export const selectShapeShift = createSelector(_selectState, state => ({ +export const selectShapeShift = createSelector(selectState, state => ({ ...state, })); + +export { selectShapeShift as default }; diff --git a/src/renderer/redux/selectors/subscriptions.js b/src/renderer/redux/selectors/subscriptions.js index f3eb78a6e..50bedf3ef 100644 --- a/src/renderer/redux/selectors/subscriptions.js +++ b/src/renderer/redux/selectors/subscriptions.js @@ -1,15 +1,11 @@ -import * as settings from "constants/settings"; -import { createSelector } from "reselect"; -import { selectAllClaimsByChannel, selectClaimsById } from "./claims"; +import { createSelector } from 'reselect'; +import { selectAllClaimsByChannel, selectClaimsById } from './claims'; // get the entire subscriptions state -const _selectState = state => state.subscriptions || {}; +const selectState = state => state.subscriptions || {}; // list of saved channel names and uris -export const selectSubscriptions = createSelector( - _selectState, - state => state.subscriptions -); +export const selectSubscriptions = createSelector(selectState, state => state.subscriptions); export const selectSubscriptionsFromClaims = createSelector( selectAllClaimsByChannel, @@ -29,7 +25,7 @@ export const selectSubscriptionsFromClaims = createSelector( // if subscribed channel has content if (channelIds[subscription.uri]) { // This will need to be more robust, we will want to be able to load more than the first page - const pageOneChannelIds = channelIds[subscription.uri]["1"]; + const pageOneChannelIds = channelIds[subscription.uri]['1']; // we have the channel ids and the corresponding claims // loop over the list of ids and grab the claim @@ -40,9 +36,7 @@ export const selectSubscriptionsFromClaims = createSelector( } // all we really need is a uri for each claim - channelClaims = channelClaims.map( - claim => `${claim.name}#${claim.claim_id}` - ); + channelClaims = channelClaims.map(claim => `${claim.name}#${claim.claim_id}`); fetchedSubscriptions.push({ claims: channelClaims, diff --git a/src/renderer/redux/selectors/user.js b/src/renderer/redux/selectors/user.js index 8cc59bab0..de2c6c447 100644 --- a/src/renderer/redux/selectors/user.js +++ b/src/renderer/redux/selectors/user.js @@ -1,18 +1,15 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; -export const _selectState = state => state.user || {}; +export const selectState = state => state.user || {}; export const selectAuthenticationIsPending = createSelector( - _selectState, + selectState, state => state.authenticationIsPending ); -export const selectUserIsPending = createSelector( - _selectState, - state => state.userIsPending -); +export const selectUserIsPending = createSelector(selectState, state => state.userIsPending); -export const selectUser = createSelector(_selectState, state => state.user); +export const selectUser = createSelector(selectState, state => state.user); export const selectUserEmail = createSelector( selectUser, @@ -20,7 +17,7 @@ export const selectUserEmail = createSelector( ); export const selectEmailToVerify = createSelector( - _selectState, + selectState, selectUserEmail, (state, userEmail) => state.emailToVerify || userEmail ); @@ -31,32 +28,32 @@ export const selectUserIsRewardApproved = createSelector( ); export const selectEmailNewIsPending = createSelector( - _selectState, + selectState, state => state.emailNewIsPending ); export const selectEmailNewErrorMessage = createSelector( - _selectState, + selectState, state => state.emailNewErrorMessage ); export const selectEmailVerifyIsPending = createSelector( - _selectState, + selectState, state => state.emailVerifyIsPending ); export const selectEmailVerifyErrorMessage = createSelector( - _selectState, + selectState, state => state.emailVerifyErrorMessage ); export const selectIdentityVerifyIsPending = createSelector( - _selectState, + selectState, state => state.identityVerifyIsPending ); export const selectIdentityVerifyErrorMessage = createSelector( - _selectState, + selectState, state => state.identityVerifyErrorMessage ); @@ -65,37 +62,31 @@ export const selectUserIsVerificationCandidate = createSelector( user => user && (!user.has_verified_email || !user.is_identity_verified) ); -export const selectAccessToken = createSelector( - _selectState, - state => state.accessToken -); +export const selectAccessToken = createSelector(selectState, state => state.accessToken); export const selectUserInviteStatusIsPending = createSelector( - _selectState, + selectState, state => state.inviteStatusIsPending ); export const selectUserInvitesRemaining = createSelector( - _selectState, + selectState, state => state.invitesRemaining ); -export const selectUserInvitees = createSelector( - _selectState, - state => state.invitees -); +export const selectUserInvitees = createSelector(selectState, state => state.invitees); export const selectUserInviteStatusFailed = createSelector( selectUserInvitesRemaining, - inviteStatus => selectUserInvitesRemaining === null + () => selectUserInvitesRemaining === null ); export const selectUserInviteNewIsPending = createSelector( - _selectState, + selectState, state => state.inviteNewIsPending ); export const selectUserInviteNewErrorMessage = createSelector( - _selectState, + selectState, state => state.inviteNewErrorMessage ); diff --git a/src/renderer/redux/selectors/wallet.js b/src/renderer/redux/selectors/wallet.js index dca790e5b..bddedb8f4 100644 --- a/src/renderer/redux/selectors/wallet.js +++ b/src/renderer/redux/selectors/wallet.js @@ -1,99 +1,81 @@ -import { createSelector } from "reselect"; +import { createSelector } from 'reselect'; -export const _selectState = state => state.wallet || {}; +export const selectState = state => state.wallet || {}; -export const selectBalance = createSelector( - _selectState, - state => state.balance -); +export const selectBalance = createSelector(selectState, state => state.balance); -export const selectTransactionsById = createSelector( - _selectState, - state => state.transactions -); +export const selectTransactionsById = createSelector(selectState, state => state.transactions); -export const selectTransactionItems = createSelector( - selectTransactionsById, - byId => { - const items = []; +export const selectTransactionItems = createSelector(selectTransactionsById, byId => { + const items = []; - Object.keys(byId).forEach(txid => { - const tx = byId[txid]; + Object.keys(byId).forEach(txid => { + const tx = byId[txid]; - // ignore dust/fees - // it is fee only txn if all infos are also empty - if ( - Math.abs(tx.value) === Math.abs(tx.fee) && - tx.claim_info.length == 0 && - tx.support_info.length == 0 && - tx.update_info.length == 0 - ) { - return; - } + // ignore dust/fees + // it is fee only txn if all infos are also empty + if ( + Math.abs(tx.value) === Math.abs(tx.fee) && + tx.claim_info.length === 0 && + tx.support_info.length === 0 && + tx.update_info.length === 0 + ) { + return; + } - const append = []; + const append = []; + append.push( + ...tx.claim_info.map(item => + Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? 'channel' : 'publish', + }) + ) + ); + append.push( + ...tx.support_info.map(item => + Object.assign({}, tx, item, { + type: !item.is_tip ? 'support' : 'tip', + }) + ) + ); + append.push(...tx.update_info.map(item => Object.assign({}, tx, item, { type: 'update' }))); + + if (!append.length) { append.push( - ...tx.claim_info.map(item => - Object.assign({}, tx, item, { - type: item.claim_name[0] === "@" ? "channel" : "publish", - }) - ) - ); - append.push( - ...tx.support_info.map(item => - Object.assign({}, tx, item, { - type: !item.is_tip ? "support" : "tip", - }) - ) - ); - append.push( - ...tx.update_info.map(item => - Object.assign({}, tx, item, { type: "update" }) - ) - ); - - if (!append.length) { - append.push( - Object.assign({}, tx, { - type: tx.value < 0 ? "spend" : "receive", - }) - ); - } - - items.push( - ...append.map(item => { - // value on transaction, amount on outpoint - // amount is always positive, but should match sign of value - const amount = parseFloat( - item.balance_delta ? item.balance_delta : item.value - ); - - return { - txid, - date: tx.timestamp ? new Date(parseInt(tx.timestamp) * 1000) : null, - amount, - fee: amount < 0 ? -1 * tx.fee / append.length : 0, - claim_id: item.claim_id, - claim_name: item.claim_name, - type: item.type || "send", - nout: item.nout, - }; + Object.assign({}, tx, { + type: tx.value < 0 ? 'spend' : 'receive', }) ); - }); - return items.reverse(); - } -); + } -export const selectRecentTransactions = createSelector( - selectTransactionItems, - transactions => { - const threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => transaction.date > threshold); - } -); + items.push( + ...append.map(item => { + // value on transaction, amount on outpoint + // amount is always positive, but should match sign of value + const amount = parseFloat(item.balance_delta ? item.balance_delta : item.value); + + return { + txid, + date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, + amount, + fee: amount < 0 ? -1 * tx.fee / append.length : 0, + claim_id: item.claim_id, + claim_name: item.claim_name, + type: item.type || 'send', + nout: item.nout, + }; + }) + ); + }); + return items.reverse(); +}); + +export const selectRecentTransactions = createSelector(selectTransactionItems, transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => transaction.date > threshold); +}); export const selectHasTransactions = createSelector( selectTransactionItems, @@ -101,27 +83,21 @@ export const selectHasTransactions = createSelector( ); export const selectIsFetchingTransactions = createSelector( - _selectState, + selectState, state => state.fetchingTransactions ); -export const selectIsSendingSupport = createSelector( - _selectState, - state => state.sendingSupport -); +export const selectIsSendingSupport = createSelector(selectState, state => state.sendingSupport); -export const selectReceiveAddress = createSelector( - _selectState, - state => state.receiveAddress -); +export const selectReceiveAddress = createSelector(selectState, state => state.receiveAddress); export const selectGettingNewAddress = createSelector( - _selectState, + selectState, state => state.gettingNewAddress ); export const selectDraftTransaction = createSelector( - _selectState, + selectState, state => state.draftTransaction || {} ); @@ -140,11 +116,10 @@ export const selectDraftTransactionError = createSelector( draft => draft.error ); -export const selectBlocks = createSelector(_selectState, state => state.blocks); +export const selectBlocks = createSelector(selectState, state => state.blocks); export const makeSelectBlockDate = block => createSelector( selectBlocks, - blocks => - blocks && blocks[block] ? new Date(blocks[block].time * 1000) : undefined + blocks => (blocks && blocks[block] ? new Date(blocks[block].time * 1000) : undefined) ); diff --git a/src/renderer/rewards.js b/src/renderer/rewards.js index 72ca1fb44..de552230f 100644 --- a/src/renderer/rewards.js +++ b/src/renderer/rewards.js @@ -1,53 +1,32 @@ -import lbry from "lbry"; -import lbryio from "lbryio"; -import { doShowSnackBar } from "redux/actions/app"; +import Lbry from 'lbry'; +import Lbryio from 'lbryio'; +import { doShowSnackBar } from 'redux/actions/app'; function rewardMessage(type, amount) { return { - new_developer: __( - "You earned %s for registering as a new developer.", - amount - ), - new_user: __("You earned %s LBC new user reward.", amount), - confirm_email: __( - "You earned %s LBC for verifying your email address.", - amount - ), - new_channel: __( - "You earned %s LBC for creating a publisher identity.", - amount - ), - first_stream: __( - "You earned %s LBC for streaming your first video.", - amount - ), - many_downloads: __( - "You earned %s LBC for downloading a bunch of things.", - amount - ), - first_publish: __( - "You earned %s LBC for making your first publication.", - amount - ), - featured_download: __( - "You earned %s LBC for watching a featured download.", - amount - ), - referral: __("You earned %s LBC for referring someone.", amount), + new_developer: __('You earned %s for registering as a new developer.', amount), + new_user: __('You earned %s LBC new user reward.', amount), + confirm_email: __('You earned %s LBC for verifying your email address.', amount), + new_channel: __('You earned %s LBC for creating a publisher identity.', amount), + first_stream: __('You earned %s LBC for streaming your first video.', amount), + many_downloads: __('You earned %s LBC for downloading a bunch of things.', amount), + first_publish: __('You earned %s LBC for making your first publication.', amount), + featured_download: __('You earned %s LBC for watching a featured download.', amount), + referral: __('You earned %s LBC for referring someone.', amount), }[type]; } const rewards = {}; -rewards.TYPE_NEW_DEVELOPER = "new_developer"; -rewards.TYPE_NEW_USER = "new_user"; -rewards.TYPE_CONFIRM_EMAIL = "verified_email"; -rewards.TYPE_FIRST_CHANNEL = "new_channel"; -rewards.TYPE_FIRST_STREAM = "first_stream"; -rewards.TYPE_MANY_DOWNLOADS = "many_downloads"; -rewards.TYPE_FIRST_PUBLISH = "first_publish"; -rewards.TYPE_FEATURED_DOWNLOAD = "featured_download"; -rewards.TYPE_REFERRAL = "referral"; +rewards.TYPE_NEW_DEVELOPER = 'new_developer'; +rewards.TYPE_NEW_USER = 'new_user'; +rewards.TYPE_CONFIRM_EMAIL = 'verified_email'; +rewards.TYPE_FIRST_CHANNEL = 'new_channel'; +rewards.TYPE_FIRST_STREAM = 'first_stream'; +rewards.TYPE_MANY_DOWNLOADS = 'many_downloads'; +rewards.TYPE_FIRST_PUBLISH = 'first_publish'; +rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download'; +rewards.TYPE_REFERRAL = 'referral'; rewards.SORT_ORDER = [ rewards.TYPE_NEW_USER, rewards.TYPE_CONFIRM_EMAIL, @@ -62,18 +41,18 @@ rewards.SORT_ORDER = [ rewards.claimReward = function(type) { function requestReward(resolve, reject, params) { - if (!lbryio.enabled) { - reject(new Error(__("Rewards are not enabled."))); + if (!Lbryio.enabled) { + reject(new Error(__('Rewards are not enabled.'))); return; } - lbryio.call("reward", "new", params, "post").then(reward => { + Lbryio.call('reward', 'new', params, 'post').then(reward => { const message = rewardMessage(type, reward.reward_amount); // Display global notice const action = doShowSnackBar({ message, - linkText: __("Show All"), - linkTarget: "/rewards", + linkText: __('Show All'), + linkTarget: '/rewards', isError: false, }); window.app.store.dispatch(action); @@ -85,7 +64,7 @@ rewards.claimReward = function(type) { } return new Promise((resolve, reject) => { - lbry.wallet_unused_address().then(address => { + Lbry.wallet_unused_address().then(address => { const params = { reward_type: type, wallet_address: address, @@ -93,42 +72,38 @@ rewards.claimReward = function(type) { switch (type) { case rewards.TYPE_FIRST_CHANNEL: - lbry - .claim_list_mine() + Lbry.claim_list_mine() .then(claims => { const claim = claims .reverse() .find( - claim => - claim.name.length && - claim.name[0] == "@" && - claim.txid.length && - claim.category == "claim" + foundClaim => + foundClaim.name.length && + foundClaim.name[0] === '@' && + foundClaim.txid.length && + foundClaim.category === 'claim' ); if (claim) { params.transaction_id = claim.txid; requestReward(resolve, reject, params); } else { - reject( - new Error(__("Please create a channel identity first.")) - ); + reject(new Error(__('Please create a channel identity first.'))); } }) .catch(reject); break; case rewards.TYPE_FIRST_PUBLISH: - lbry - .claim_list_mine() + Lbry.claim_list_mine() .then(claims => { const claim = claims .reverse() .find( - claim => - claim.name.length && - claim.name[0] != "@" && - claim.txid.length && - claim.category == "claim" + foundClaim => + foundClaim.name.length && + foundClaim.name[0] !== '@' && + foundClaim.txid.length && + foundClaim.category === 'claim' ); if (claim) { params.transaction_id = claim.txid; @@ -138,12 +113,10 @@ rewards.claimReward = function(type) { claims.length ? new Error( __( - "Please publish something and wait for confirmation by the network to claim this reward." + 'Please publish something and wait for confirmation by the network to claim this reward.' ) ) - : new Error( - __("Please publish something to claim this reward.") - ) + : new Error(__('Please publish something to claim this reward.')) ); } }) diff --git a/src/renderer/scss/_gui.scss b/src/renderer/scss/_gui.scss index fa188a37f..da3f5334c 100644 --- a/src/renderer/scss/_gui.scss +++ b/src/renderer/scss/_gui.scss @@ -1,13 +1,11 @@ @import url(https://fonts.googleapis.com/css?family=Roboto:400,400i,500,500i,700); -html -{ +html { height: 100%; font-size: var(--font-size); } -body -{ +body { color: var(--text-color); font-family: 'Roboto', sans-serif; line-height: var(--font-line-height); @@ -19,30 +17,25 @@ body color: var(--text-selection-color); } -#window -{ +#window { min-height: 100vh; background: var(--window-bg); } -.credit-amount--indicator -{ +.credit-amount--indicator { font-weight: 500; color: var(--color-money); } -.credit-amount--fee -{ +.credit-amount--fee { font-size: 0.9em; color: var(--color-meta-light); } -.credit-amount--bold -{ +.credit-amount--bold { font-weight: 700; } -#main-content -{ +#main-content { margin: auto; display: flex; flex-direction: column; @@ -58,8 +51,7 @@ body margin-right: auto; max-width: 100%; } - main.main--single-column - { + main.main--single-column { width: $width-page-constrained; } @@ -76,7 +68,7 @@ body background: url('../../../static/img/busy.gif') no-repeat center center; width: $width; height: $spacing-vertical; - content: ""; + content: ''; left: 50%; margin-left: -1 / 2 * $width; display: inline-block; @@ -93,30 +85,37 @@ h2 { font-size: 1.75em; } -h3 { font-size: 1.4em; } +h3 { + font-size: 1.4em; +} h4 { font-size: 1.2em; } -h5 { font-size: 1.1em; } -sup, sub { - vertical-align: baseline; - position: relative; +h5 { + font-size: 1.1em; +} +sup, +sub { + vertical-align: baseline; + position: relative; +} +sup { + top: -0.4em; +} +sub { + top: 0.4em; } -sup { top: -0.4em; } -sub { top: 0.4em; } code { font: 0.8em Consolas, 'Lucida Console', 'Source Sans', monospace; background-color: var(--color-bg-alt); } -p -{ +p { margin-bottom: 0.8em; - &:last-child - { + &:last-child { margin-bottom: 0; } } @@ -137,8 +136,7 @@ p -webkit-box-orient: vertical; } -.busy-indicator -{ +.busy-indicator { background: url('../../../static/img/busy.gif') no-repeat center center; display: inline-block; margin: -1em 0; @@ -146,30 +144,26 @@ p min-height: 8px; vertical-align: middle; padding: 0 30px; - &:last-child - { + &:last-child { padding-right: 2px; } - &:first-child - { + &:first-child { padding-left: 2px; } } .help { - font-size: .85em; + font-size: 0.85em; color: var(--color-help); } -.meta -{ +.meta { font-size: 0.9em; color: var(--color-meta-light); } -.empty -{ - color:var(--color-meta-light); +.empty { + color: var(--color-meta-light); font-style: italic; } @@ -185,7 +179,6 @@ p display: block; margin-bottom: $spacing-vertical * 2/3; - text-align: right; line-height: 1; font-size: 0.85em; @@ -196,7 +189,6 @@ section.section-spaced { margin-bottom: $spacing-vertical; } -.text-center -{ +.text-center { text-align: center; } diff --git a/src/renderer/scss/_icons.scss b/src/renderer/scss/_icons.scss index 49e894145..c589a1ac5 100644 --- a/src/renderer/scss/_icons.scss +++ b/src/renderer/scss/_icons.scss @@ -1,16 +1,20 @@ @font-face { font-family: 'FontAwesome'; src: url('../../../static/font/fontawesome-webfont.eot?v=4.7.0'); - src: url('../../../static/font/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../../../static/font/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../../../static/font/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../../../static/font/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../../../static/font/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); + src: url('../../../static/font/fontawesome-webfont.eot?#iefix&v=4.7.0') + format('embedded-opentype'), + url('../../../static/font/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), + url('../../../static/font/fontawesome-webfont.woff?v=4.7.0') format('woff'), + url('../../../static/font/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), + url('../../../static/font/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } -[class*="icon-"] -{ +[class*='icon-'] { display: inline-block; text-align: center; - font-family: "FontAwesome"; + font-family: 'FontAwesome'; font-style: normal; font-weight: normal; font-variant: normal; @@ -23,7 +27,6 @@ transform: translate(0, 0); } - /* Adjustments for icon size and alignment */ .icon-rocket { color: orangered; @@ -37,1639 +40,1639 @@ /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen readers do not read off random characters that represent icons */ .icon-glass:before { - content: "\f000"; + content: '\f000'; } .icon-music:before { - content: "\f001"; + content: '\f001'; } .icon-search:before { - content: "\f002"; + content: '\f002'; } .icon-envelope-o:before { - content: "\f003"; + content: '\f003'; } .icon-heart:before { - content: "\f004"; + content: '\f004'; } .icon-star:before { - content: "\f005"; + content: '\f005'; } .icon-star-o:before { - content: "\f006"; + content: '\f006'; } .icon-user:before { - content: "\f007"; + content: '\f007'; } .icon-film:before { - content: "\f008"; + content: '\f008'; } .icon-th-large:before { - content: "\f009"; + content: '\f009'; } .icon-th:before { - content: "\f00a"; + content: '\f00a'; } .icon-th-list:before { - content: "\f00b"; + content: '\f00b'; } .icon-check:before { - content: "\f00c"; + content: '\f00c'; } .icon-remove:before, .icon-close:before, .icon-times:before { - content: "\f00d"; + content: '\f00d'; } .icon-search-plus:before { - content: "\f00e"; + content: '\f00e'; } .icon-search-minus:before { - content: "\f010"; + content: '\f010'; } .icon-power-off:before { - content: "\f011"; + content: '\f011'; } .icon-signal:before { - content: "\f012"; + content: '\f012'; } .icon-gear:before, .icon-cog:before { - content: "\f013"; + content: '\f013'; } .icon-trash-o:before { - content: "\f014"; + content: '\f014'; } .icon-home:before { - content: "\f015"; + content: '\f015'; } .icon-file-o:before { - content: "\f016"; + content: '\f016'; } .icon-clock-o:before { - content: "\f017"; + content: '\f017'; } .icon-road:before { - content: "\f018"; + content: '\f018'; } .icon-download:before { - content: "\f019"; + content: '\f019'; } .icon-arrow-circle-o-down:before { - content: "\f01a"; + content: '\f01a'; } .icon-arrow-circle-o-up:before { - content: "\f01b"; + content: '\f01b'; } .icon-inbox:before { - content: "\f01c"; + content: '\f01c'; } .icon-play-circle-o:before { - content: "\f01d"; + content: '\f01d'; } .icon-rotate-right:before, .icon-repeat:before { - content: "\f01e"; + content: '\f01e'; } .icon-refresh:before { - content: "\f021"; + content: '\f021'; } .icon-list-alt:before { - content: "\f022"; + content: '\f022'; } .icon-lock:before { - content: "\f023"; + content: '\f023'; } .icon-flag:before { - content: "\f024"; + content: '\f024'; } .icon-headphones:before { - content: "\f025"; + content: '\f025'; } .icon-volume-off:before { - content: "\f026"; + content: '\f026'; } .icon-volume-down:before { - content: "\f027"; + content: '\f027'; } .icon-volume-up:before { - content: "\f028"; + content: '\f028'; } .icon-qrcode:before { - content: "\f029"; + content: '\f029'; } .icon-barcode:before { - content: "\f02a"; + content: '\f02a'; } .icon-tag:before { - content: "\f02b"; + content: '\f02b'; } .icon-tags:before { - content: "\f02c"; + content: '\f02c'; } .icon-book:before { - content: "\f02d"; + content: '\f02d'; } .icon-bookmark:before { - content: "\f02e"; + content: '\f02e'; } .icon-print:before { - content: "\f02f"; + content: '\f02f'; } .icon-camera:before { - content: "\f030"; + content: '\f030'; } .icon-font:before { - content: "\f031"; + content: '\f031'; } .icon-bold:before { - content: "\f032"; + content: '\f032'; } .icon-italic:before { - content: "\f033"; + content: '\f033'; } .icon-text-height:before { - content: "\f034"; + content: '\f034'; } .icon-text-width:before { - content: "\f035"; + content: '\f035'; } .icon-align-left:before { - content: "\f036"; + content: '\f036'; } .icon-align-center:before { - content: "\f037"; + content: '\f037'; } .icon-align-right:before { - content: "\f038"; + content: '\f038'; } .icon-align-justify:before { - content: "\f039"; + content: '\f039'; } .icon-list:before { - content: "\f03a"; + content: '\f03a'; } .icon-dedent:before, .icon-outdent:before { - content: "\f03b"; + content: '\f03b'; } .icon-indent:before { - content: "\f03c"; + content: '\f03c'; } .icon-video-camera:before { - content: "\f03d"; + content: '\f03d'; } .icon-photo:before, .icon-image:before, .icon-picture-o:before { - content: "\f03e"; + content: '\f03e'; } .icon-pencil:before { - content: "\f040"; + content: '\f040'; } .icon-map-marker:before { - content: "\f041"; + content: '\f041'; } .icon-adjust:before { - content: "\f042"; + content: '\f042'; } .icon-tint:before { - content: "\f043"; + content: '\f043'; } .icon-edit:before, .icon-pencil-square-o:before { - content: "\f044"; + content: '\f044'; } .icon-share-square-o:before { - content: "\f045"; + content: '\f045'; } .icon-check-square-o:before { - content: "\f046"; + content: '\f046'; } .icon-arrows:before { - content: "\f047"; + content: '\f047'; } .icon-step-backward:before { - content: "\f048"; + content: '\f048'; } .icon-fast-backward:before { - content: "\f049"; + content: '\f049'; } .icon-backward:before { - content: "\f04a"; + content: '\f04a'; } .icon-play:before { - content: "\f04b"; + content: '\f04b'; } .icon-pause:before { - content: "\f04c"; + content: '\f04c'; } .icon-stop:before { - content: "\f04d"; + content: '\f04d'; } .icon-forward:before { - content: "\f04e"; + content: '\f04e'; } .icon-fast-forward:before { - content: "\f050"; + content: '\f050'; } .icon-step-forward:before { - content: "\f051"; + content: '\f051'; } .icon-eject:before { - content: "\f052"; + content: '\f052'; } .icon-chevron-left:before { - content: "\f053"; + content: '\f053'; } .icon-chevron-right:before { - content: "\f054"; + content: '\f054'; } .icon-plus-circle:before { - content: "\f055"; + content: '\f055'; } .icon-minus-circle:before { - content: "\f056"; + content: '\f056'; } .icon-times-circle:before { - content: "\f057"; + content: '\f057'; } .icon-check-circle:before { - content: "\f058"; + content: '\f058'; } .icon-question-circle:before { - content: "\f059"; + content: '\f059'; } .icon-info-circle:before { - content: "\f05a"; + content: '\f05a'; } .icon-crosshairs:before { - content: "\f05b"; + content: '\f05b'; } .icon-times-circle-o:before { - content: "\f05c"; + content: '\f05c'; } .icon-check-circle-o:before { - content: "\f05d"; + content: '\f05d'; } .icon-ban:before { - content: "\f05e"; + content: '\f05e'; } .icon-arrow-left:before { - content: "\f060"; + content: '\f060'; } .icon-arrow-right:before { - content: "\f061"; + content: '\f061'; } .icon-arrow-up:before { - content: "\f062"; + content: '\f062'; } .icon-arrow-down:before { - content: "\f063"; + content: '\f063'; } .icon-mail-forward:before, .icon-share:before { - content: "\f064"; + content: '\f064'; } .icon-expand:before { - content: "\f065"; + content: '\f065'; } .icon-compress:before { - content: "\f066"; + content: '\f066'; } .icon-plus:before { - content: "\f067"; + content: '\f067'; } .icon-minus:before { - content: "\f068"; + content: '\f068'; } .icon-asterisk:before { - content: "\f069"; + content: '\f069'; } .icon-exclamation-circle:before { - content: "\f06a"; + content: '\f06a'; } .icon-gift:before { - content: "\f06b"; + content: '\f06b'; } .icon-leaf:before { - content: "\f06c"; + content: '\f06c'; } .icon-fire:before { - content: "\f06d"; + content: '\f06d'; } .icon-eye:before { - content: "\f06e"; + content: '\f06e'; } .icon-eye-slash:before { - content: "\f070"; + content: '\f070'; } .icon-warning:before, .icon-exclamation-triangle:before { - content: "\f071"; + content: '\f071'; } .icon-plane:before { - content: "\f072"; + content: '\f072'; } .icon-calendar:before { - content: "\f073"; + content: '\f073'; } .icon-random:before { - content: "\f074"; + content: '\f074'; } .icon-comment:before { - content: "\f075"; + content: '\f075'; } .icon-magnet:before { - content: "\f076"; + content: '\f076'; } .icon-chevron-up:before { - content: "\f077"; + content: '\f077'; } .icon-chevron-down:before { - content: "\f078"; + content: '\f078'; } .icon-retweet:before { - content: "\f079"; + content: '\f079'; } .icon-shopping-cart:before { - content: "\f07a"; + content: '\f07a'; } .icon-folder:before { - content: "\f07b"; + content: '\f07b'; } .icon-folder-open:before { - content: "\f07c"; + content: '\f07c'; } .icon-arrows-v:before { - content: "\f07d"; + content: '\f07d'; } .icon-arrows-h:before { - content: "\f07e"; + content: '\f07e'; } .icon-bar-chart-o:before, .icon-bar-chart:before { - content: "\f080"; + content: '\f080'; } .icon-twitter-square:before { - content: "\f081"; + content: '\f081'; } .icon-facebook-square:before { - content: "\f082"; + content: '\f082'; } .icon-camera-retro:before { - content: "\f083"; + content: '\f083'; } .icon-key:before { - content: "\f084"; + content: '\f084'; } .icon-gears:before, .icon-cogs:before { - content: "\f085"; + content: '\f085'; } .icon-comments:before { - content: "\f086"; + content: '\f086'; } .icon-thumbs-o-up:before { - content: "\f087"; + content: '\f087'; } .icon-thumbs-o-down:before { - content: "\f088"; + content: '\f088'; } .icon-star-half:before { - content: "\f089"; + content: '\f089'; } .icon-heart-o:before { - content: "\f08a"; + content: '\f08a'; } .icon-sign-out:before { - content: "\f08b"; + content: '\f08b'; } .icon-linkedin-square:before { - content: "\f08c"; + content: '\f08c'; } .icon-thumb-tack:before { - content: "\f08d"; + content: '\f08d'; } .icon-external-link:before { - content: "\f08e"; + content: '\f08e'; } .icon-sign-in:before { - content: "\f090"; + content: '\f090'; } .icon-trophy:before { - content: "\f091"; + content: '\f091'; } .icon-github-square:before { - content: "\f092"; + content: '\f092'; } .icon-upload:before { - content: "\f093"; + content: '\f093'; } .icon-lemon-o:before { - content: "\f094"; + content: '\f094'; } .icon-phone:before { - content: "\f095"; + content: '\f095'; } .icon-square-o:before { - content: "\f096"; + content: '\f096'; } .icon-bookmark-o:before { - content: "\f097"; + content: '\f097'; } .icon-phone-square:before { - content: "\f098"; + content: '\f098'; } .icon-twitter:before { - content: "\f099"; + content: '\f099'; } .icon-facebook-f:before, .icon-facebook:before { - content: "\f09a"; + content: '\f09a'; } .icon-github:before { - content: "\f09b"; + content: '\f09b'; } .icon-unlock:before { - content: "\f09c"; + content: '\f09c'; } .icon-credit-card:before { - content: "\f09d"; + content: '\f09d'; } .icon-rss:before { - content: "\f09e"; + content: '\f09e'; } .icon-hdd-o:before { - content: "\f0a0"; + content: '\f0a0'; } .icon-bullhorn:before { - content: "\f0a1"; + content: '\f0a1'; } .icon-bell:before { - content: "\f0f3"; + content: '\f0f3'; } .icon-certificate:before { - content: "\f0a3"; + content: '\f0a3'; } .icon-hand-o-right:before { - content: "\f0a4"; + content: '\f0a4'; } .icon-hand-o-left:before { - content: "\f0a5"; + content: '\f0a5'; } .icon-hand-o-up:before { - content: "\f0a6"; + content: '\f0a6'; } .icon-hand-o-down:before { - content: "\f0a7"; + content: '\f0a7'; } .icon-arrow-circle-left:before { - content: "\f0a8"; + content: '\f0a8'; } .icon-arrow-circle-right:before { - content: "\f0a9"; + content: '\f0a9'; } .icon-arrow-circle-up:before { - content: "\f0aa"; + content: '\f0aa'; } .icon-arrow-circle-down:before { - content: "\f0ab"; + content: '\f0ab'; } .icon-globe:before { - content: "\f0ac"; + content: '\f0ac'; } .icon-wrench:before { - content: "\f0ad"; + content: '\f0ad'; } .icon-tasks:before { - content: "\f0ae"; + content: '\f0ae'; } .icon-filter:before { - content: "\f0b0"; + content: '\f0b0'; } .icon-briefcase:before { - content: "\f0b1"; + content: '\f0b1'; } .icon-arrows-alt:before { - content: "\f0b2"; + content: '\f0b2'; } .icon-group:before, .icon-users:before { - content: "\f0c0"; + content: '\f0c0'; } .icon-chain:before, .icon-link:before { - content: "\f0c1"; + content: '\f0c1'; } .icon-cloud:before { - content: "\f0c2"; + content: '\f0c2'; } .icon-flask:before { - content: "\f0c3"; + content: '\f0c3'; } .icon-cut:before, .icon-scissors:before { - content: "\f0c4"; + content: '\f0c4'; } .icon-copy:before, .icon-files-o:before { - content: "\f0c5"; + content: '\f0c5'; } .icon-paperclip:before { - content: "\f0c6"; + content: '\f0c6'; } .icon-save:before, .icon-floppy-o:before { - content: "\f0c7"; + content: '\f0c7'; } .icon-square:before { - content: "\f0c8"; + content: '\f0c8'; } .icon-navicon:before, .icon-reorder:before, .icon-bars:before { - content: "\f0c9"; + content: '\f0c9'; } .icon-list-ul:before { - content: "\f0ca"; + content: '\f0ca'; } .icon-list-ol:before { - content: "\f0cb"; + content: '\f0cb'; } .icon-strikethrough:before { - content: "\f0cc"; + content: '\f0cc'; } .icon-underline:before { - content: "\f0cd"; + content: '\f0cd'; } .icon-table:before { - content: "\f0ce"; + content: '\f0ce'; } .icon-magic:before { - content: "\f0d0"; + content: '\f0d0'; } .icon-truck:before { - content: "\f0d1"; + content: '\f0d1'; } .icon-pinterest:before { - content: "\f0d2"; + content: '\f0d2'; } .icon-pinterest-square:before { - content: "\f0d3"; + content: '\f0d3'; } .icon-google-plus-square:before { - content: "\f0d4"; + content: '\f0d4'; } .icon-google-plus:before { - content: "\f0d5"; + content: '\f0d5'; } .icon-money:before { - content: "\f0d6"; + content: '\f0d6'; } .icon-caret-down:before { - content: "\f0d7"; + content: '\f0d7'; } .icon-caret-up:before { - content: "\f0d8"; + content: '\f0d8'; } .icon-caret-left:before { - content: "\f0d9"; + content: '\f0d9'; } .icon-caret-right:before { - content: "\f0da"; + content: '\f0da'; } .icon-columns:before { - content: "\f0db"; + content: '\f0db'; } .icon-unsorted:before, .icon-sort:before { - content: "\f0dc"; + content: '\f0dc'; } .icon-sort-down:before, .icon-sort-desc:before { - content: "\f0dd"; + content: '\f0dd'; } .icon-sort-up:before, .icon-sort-asc:before { - content: "\f0de"; + content: '\f0de'; } .icon-envelope:before { - content: "\f0e0"; + content: '\f0e0'; } .icon-linkedin:before { - content: "\f0e1"; + content: '\f0e1'; } .icon-rotate-left:before, .icon-undo:before { - content: "\f0e2"; + content: '\f0e2'; } .icon-legal:before, .icon-gavel:before { - content: "\f0e3"; + content: '\f0e3'; } .icon-dashboard:before, .icon-tachometer:before { - content: "\f0e4"; + content: '\f0e4'; } .icon-comment-o:before { - content: "\f0e5"; + content: '\f0e5'; } .icon-comments-o:before { - content: "\f0e6"; + content: '\f0e6'; } .icon-flash:before, .icon-bolt:before { - content: "\f0e7"; + content: '\f0e7'; } .icon-sitemap:before { - content: "\f0e8"; + content: '\f0e8'; } .icon-umbrella:before { - content: "\f0e9"; + content: '\f0e9'; } .icon-paste:before, .icon-clipboard:before { - content: "\f0ea"; + content: '\f0ea'; } .icon-lightbulb-o:before { - content: "\f0eb"; + content: '\f0eb'; } .icon-exchange:before { - content: "\f0ec"; + content: '\f0ec'; } .icon-cloud-download:before { - content: "\f0ed"; + content: '\f0ed'; } .icon-cloud-upload:before { - content: "\f0ee"; + content: '\f0ee'; } .icon-user-md:before { - content: "\f0f0"; + content: '\f0f0'; } .icon-stethoscope:before { - content: "\f0f1"; + content: '\f0f1'; } .icon-suitcase:before { - content: "\f0f2"; + content: '\f0f2'; } .icon-bell-o:before { - content: "\f0a2"; + content: '\f0a2'; } .icon-coffee:before { - content: "\f0f4"; + content: '\f0f4'; } .icon-cutlery:before { - content: "\f0f5"; + content: '\f0f5'; } .icon-file-text-o:before { - content: "\f0f6"; + content: '\f0f6'; } .icon-building-o:before { - content: "\f0f7"; + content: '\f0f7'; } .icon-hospital-o:before { - content: "\f0f8"; + content: '\f0f8'; } .icon-ambulance:before { - content: "\f0f9"; + content: '\f0f9'; } .icon-medkit:before { - content: "\f0fa"; + content: '\f0fa'; } .icon-fighter-jet:before { - content: "\f0fb"; + content: '\f0fb'; } .icon-beer:before { - content: "\f0fc"; + content: '\f0fc'; } .icon-h-square:before { - content: "\f0fd"; + content: '\f0fd'; } .icon-plus-square:before { - content: "\f0fe"; + content: '\f0fe'; } .icon-angle-double-left:before { - content: "\f100"; + content: '\f100'; } .icon-angle-double-right:before { - content: "\f101"; + content: '\f101'; } .icon-angle-double-up:before { - content: "\f102"; + content: '\f102'; } .icon-angle-double-down:before { - content: "\f103"; + content: '\f103'; } .icon-angle-left:before { - content: "\f104"; + content: '\f104'; } .icon-angle-right:before { - content: "\f105"; + content: '\f105'; } .icon-angle-up:before { - content: "\f106"; + content: '\f106'; } .icon-angle-down:before { - content: "\f107"; + content: '\f107'; } .icon-desktop:before { - content: "\f108"; + content: '\f108'; } .icon-laptop:before { - content: "\f109"; + content: '\f109'; } .icon-tablet:before { - content: "\f10a"; + content: '\f10a'; } .icon-mobile-phone:before, .icon-mobile:before { - content: "\f10b"; + content: '\f10b'; } .icon-circle-o:before { - content: "\f10c"; + content: '\f10c'; } .icon-quote-left:before { - content: "\f10d"; + content: '\f10d'; } .icon-quote-right:before { - content: "\f10e"; + content: '\f10e'; } .icon-spinner:before { - content: "\f110"; + content: '\f110'; } .icon-circle:before { - content: "\f111"; + content: '\f111'; } .icon-mail-reply:before, .icon-reply:before { - content: "\f112"; + content: '\f112'; } .icon-github-alt:before { - content: "\f113"; + content: '\f113'; } .icon-folder-o:before { - content: "\f114"; + content: '\f114'; } .icon-folder-open-o:before { - content: "\f115"; + content: '\f115'; } .icon-smile-o:before { - content: "\f118"; + content: '\f118'; } .icon-frown-o:before { - content: "\f119"; + content: '\f119'; } .icon-meh-o:before { - content: "\f11a"; + content: '\f11a'; } .icon-gamepad:before { - content: "\f11b"; + content: '\f11b'; } .icon-keyboard-o:before { - content: "\f11c"; + content: '\f11c'; } .icon-flag-o:before { - content: "\f11d"; + content: '\f11d'; } .icon-flag-checkered:before { - content: "\f11e"; + content: '\f11e'; } .icon-terminal:before { - content: "\f120"; + content: '\f120'; } .icon-code:before { - content: "\f121"; + content: '\f121'; } .icon-mail-reply-all:before, .icon-reply-all:before { - content: "\f122"; + content: '\f122'; } .icon-star-half-empty:before, .icon-star-half-full:before, .icon-star-half-o:before { - content: "\f123"; + content: '\f123'; } .icon-location-arrow:before { - content: "\f124"; + content: '\f124'; } .icon-crop:before { - content: "\f125"; + content: '\f125'; } .icon-code-fork:before { - content: "\f126"; + content: '\f126'; } .icon-unlink:before, .icon-chain-broken:before { - content: "\f127"; + content: '\f127'; } .icon-question:before { - content: "\f128"; + content: '\f128'; } .icon-info:before { - content: "\f129"; + content: '\f129'; } .icon-exclamation:before { - content: "\f12a"; + content: '\f12a'; } .icon-superscript:before { - content: "\f12b"; + content: '\f12b'; } .icon-subscript:before { - content: "\f12c"; + content: '\f12c'; } .icon-eraser:before { - content: "\f12d"; + content: '\f12d'; } .icon-puzzle-piece:before { - content: "\f12e"; + content: '\f12e'; } .icon-microphone:before { - content: "\f130"; + content: '\f130'; } .icon-microphone-slash:before { - content: "\f131"; + content: '\f131'; } .icon-shield:before { - content: "\f132"; + content: '\f132'; } .icon-calendar-o:before { - content: "\f133"; + content: '\f133'; } .icon-fire-extinguisher:before { - content: "\f134"; + content: '\f134'; } .icon-rocket:before { - content: "\f135"; + content: '\f135'; } .icon-maxcdn:before { - content: "\f136"; + content: '\f136'; } .icon-chevron-circle-left:before { - content: "\f137"; + content: '\f137'; } .icon-chevron-circle-right:before { - content: "\f138"; + content: '\f138'; } .icon-chevron-circle-up:before { - content: "\f139"; + content: '\f139'; } .icon-chevron-circle-down:before { - content: "\f13a"; + content: '\f13a'; } .icon-html5:before { - content: "\f13b"; + content: '\f13b'; } .icon-css3:before { - content: "\f13c"; + content: '\f13c'; } .icon-anchor:before { - content: "\f13d"; + content: '\f13d'; } .icon-unlock-alt:before { - content: "\f13e"; + content: '\f13e'; } .icon-bullseye:before { - content: "\f140"; + content: '\f140'; } .icon-ellipsis-h:before { - content: "\f141"; + content: '\f141'; } .icon-ellipsis-v:before { - content: "\f142"; + content: '\f142'; } .icon-rss-square:before { - content: "\f143"; + content: '\f143'; } .icon-play-circle:before { - content: "\f144"; + content: '\f144'; } .icon-ticket:before { - content: "\f145"; + content: '\f145'; } .icon-minus-square:before { - content: "\f146"; + content: '\f146'; } .icon-minus-square-o:before { - content: "\f147"; + content: '\f147'; } .icon-level-up:before { - content: "\f148"; + content: '\f148'; } .icon-level-down:before { - content: "\f149"; + content: '\f149'; } .icon-check-square:before { - content: "\f14a"; + content: '\f14a'; } .icon-pencil-square:before { - content: "\f14b"; + content: '\f14b'; } .icon-external-link-square:before { - content: "\f14c"; + content: '\f14c'; } .icon-share-square:before { - content: "\f14d"; + content: '\f14d'; } .icon-compass:before { - content: "\f14e"; + content: '\f14e'; } .icon-toggle-down:before, .icon-caret-square-o-down:before { - content: "\f150"; + content: '\f150'; } .icon-toggle-up:before, .icon-caret-square-o-up:before { - content: "\f151"; + content: '\f151'; } .icon-toggle-right:before, .icon-caret-square-o-right:before { - content: "\f152"; + content: '\f152'; } .icon-euro:before, .icon-eur:before { - content: "\f153"; + content: '\f153'; } .icon-gbp:before { - content: "\f154"; + content: '\f154'; } .icon-dollar:before, .icon-usd:before { - content: "\f155"; + content: '\f155'; } .icon-rupee:before, .icon-inr:before { - content: "\f156"; + content: '\f156'; } .icon-cny:before, .icon-rmb:before, .icon-yen:before, .icon-jpy:before { - content: "\f157"; + content: '\f157'; } .icon-ruble:before, .icon-rouble:before, .icon-rub:before { - content: "\f158"; + content: '\f158'; } .icon-won:before, .icon-krw:before { - content: "\f159"; + content: '\f159'; } .icon-bitcoin:before, .icon-btc:before { - content: "\f15a"; + content: '\f15a'; } .icon-file:before { - content: "\f15b"; + content: '\f15b'; } .icon-file-text:before { - content: "\f15c"; + content: '\f15c'; } .icon-sort-alpha-asc:before { - content: "\f15d"; + content: '\f15d'; } .icon-sort-alpha-desc:before { - content: "\f15e"; + content: '\f15e'; } .icon-sort-amount-asc:before { - content: "\f160"; + content: '\f160'; } .icon-sort-amount-desc:before { - content: "\f161"; + content: '\f161'; } .icon-sort-numeric-asc:before { - content: "\f162"; + content: '\f162'; } .icon-sort-numeric-desc:before { - content: "\f163"; + content: '\f163'; } .icon-thumbs-up:before { - content: "\f164"; + content: '\f164'; } .icon-thumbs-down:before { - content: "\f165"; + content: '\f165'; } .icon-youtube-square:before { - content: "\f166"; + content: '\f166'; } .icon-youtube:before { - content: "\f167"; + content: '\f167'; } .icon-xing:before { - content: "\f168"; + content: '\f168'; } .icon-xing-square:before { - content: "\f169"; + content: '\f169'; } .icon-youtube-play:before { - content: "\f16a"; + content: '\f16a'; } .icon-dropbox:before { - content: "\f16b"; + content: '\f16b'; } .icon-stack-overflow:before { - content: "\f16c"; + content: '\f16c'; } .icon-instagram:before { - content: "\f16d"; + content: '\f16d'; } .icon-flickr:before { - content: "\f16e"; + content: '\f16e'; } .icon-adn:before { - content: "\f170"; + content: '\f170'; } .icon-bitbucket:before { - content: "\f171"; + content: '\f171'; } .icon-bitbucket-square:before { - content: "\f172"; + content: '\f172'; } .icon-tumblr:before { - content: "\f173"; + content: '\f173'; } .icon-tumblr-square:before { - content: "\f174"; + content: '\f174'; } .icon-long-arrow-down:before { - content: "\f175"; + content: '\f175'; } .icon-long-arrow-up:before { - content: "\f176"; + content: '\f176'; } .icon-long-arrow-left:before { - content: "\f177"; + content: '\f177'; } .icon-long-arrow-right:before { - content: "\f178"; + content: '\f178'; } .icon-apple:before { - content: "\f179"; + content: '\f179'; } .icon-windows:before { - content: "\f17a"; + content: '\f17a'; } .icon-android:before { - content: "\f17b"; + content: '\f17b'; } .icon-linux:before { - content: "\f17c"; + content: '\f17c'; } .icon-dribbble:before { - content: "\f17d"; + content: '\f17d'; } .icon-skype:before { - content: "\f17e"; + content: '\f17e'; } .icon-foursquare:before { - content: "\f180"; + content: '\f180'; } .icon-trello:before { - content: "\f181"; + content: '\f181'; } .icon-female:before { - content: "\f182"; + content: '\f182'; } .icon-male:before { - content: "\f183"; + content: '\f183'; } .icon-gittip:before, .icon-gratipay:before { - content: "\f184"; + content: '\f184'; } .icon-sun-o:before { - content: "\f185"; + content: '\f185'; } .icon-moon-o:before { - content: "\f186"; + content: '\f186'; } .icon-archive:before { - content: "\f187"; + content: '\f187'; } .icon-bug:before { - content: "\f188"; + content: '\f188'; } .icon-vk:before { - content: "\f189"; + content: '\f189'; } .icon-weibo:before { - content: "\f18a"; + content: '\f18a'; } .icon-renren:before { - content: "\f18b"; + content: '\f18b'; } .icon-pagelines:before { - content: "\f18c"; + content: '\f18c'; } .icon-stack-exchange:before { - content: "\f18d"; + content: '\f18d'; } .icon-arrow-circle-o-right:before { - content: "\f18e"; + content: '\f18e'; } .icon-arrow-circle-o-left:before { - content: "\f190"; + content: '\f190'; } .icon-toggle-left:before, .icon-caret-square-o-left:before { - content: "\f191"; + content: '\f191'; } .icon-dot-circle-o:before { - content: "\f192"; + content: '\f192'; } .icon-wheelchair:before { - content: "\f193"; + content: '\f193'; } .icon-vimeo-square:before { - content: "\f194"; + content: '\f194'; } .icon-turkish-lira:before, .icon-try:before { - content: "\f195"; + content: '\f195'; } .icon-plus-square-o:before { - content: "\f196"; + content: '\f196'; } .icon-space-shuttle:before { - content: "\f197"; + content: '\f197'; } .icon-slack:before { - content: "\f198"; + content: '\f198'; } .icon-envelope-square:before { - content: "\f199"; + content: '\f199'; } .icon-wordpress:before { - content: "\f19a"; + content: '\f19a'; } .icon-openid:before { - content: "\f19b"; + content: '\f19b'; } .icon-institution:before, .icon-bank:before, .icon-university:before { - content: "\f19c"; + content: '\f19c'; } .icon-mortar-board:before, .icon-graduation-cap:before { - content: "\f19d"; + content: '\f19d'; } .icon-yahoo:before { - content: "\f19e"; + content: '\f19e'; } .icon-google:before { - content: "\f1a0"; + content: '\f1a0'; } .icon-reddit:before { - content: "\f1a1"; + content: '\f1a1'; } .icon-reddit-square:before { - content: "\f1a2"; + content: '\f1a2'; } .icon-stumbleupon-circle:before { - content: "\f1a3"; + content: '\f1a3'; } .icon-stumbleupon:before { - content: "\f1a4"; + content: '\f1a4'; } .icon-delicious:before { - content: "\f1a5"; + content: '\f1a5'; } .icon-digg:before { - content: "\f1a6"; + content: '\f1a6'; } .icon-pied-piper:before { - content: "\f1a7"; + content: '\f1a7'; } .icon-pied-piper-alt:before { - content: "\f1a8"; + content: '\f1a8'; } .icon-drupal:before { - content: "\f1a9"; + content: '\f1a9'; } .icon-joomla:before { - content: "\f1aa"; + content: '\f1aa'; } .icon-language:before { - content: "\f1ab"; + content: '\f1ab'; } .icon-fax:before { - content: "\f1ac"; + content: '\f1ac'; } .icon-building:before { - content: "\f1ad"; + content: '\f1ad'; } .icon-child:before { - content: "\f1ae"; + content: '\f1ae'; } .icon-paw:before { - content: "\f1b0"; + content: '\f1b0'; } .icon-spoon:before { - content: "\f1b1"; + content: '\f1b1'; } .icon-cube:before { - content: "\f1b2"; + content: '\f1b2'; } .icon-cubes:before { - content: "\f1b3"; + content: '\f1b3'; } .icon-behance:before { - content: "\f1b4"; + content: '\f1b4'; } .icon-behance-square:before { - content: "\f1b5"; + content: '\f1b5'; } .icon-steam:before { - content: "\f1b6"; + content: '\f1b6'; } .icon-steam-square:before { - content: "\f1b7"; + content: '\f1b7'; } .icon-recycle:before { - content: "\f1b8"; + content: '\f1b8'; } .icon-automobile:before, .icon-car:before { - content: "\f1b9"; + content: '\f1b9'; } .icon-cab:before, .icon-taxi:before { - content: "\f1ba"; + content: '\f1ba'; } .icon-tree:before { - content: "\f1bb"; + content: '\f1bb'; } .icon-spotify:before { - content: "\f1bc"; + content: '\f1bc'; } .icon-deviantart:before { - content: "\f1bd"; + content: '\f1bd'; } .icon-soundcloud:before { - content: "\f1be"; + content: '\f1be'; } .icon-database:before { - content: "\f1c0"; + content: '\f1c0'; } .icon-file-pdf-o:before { - content: "\f1c1"; + content: '\f1c1'; } .icon-file-word-o:before { - content: "\f1c2"; + content: '\f1c2'; } .icon-file-excel-o:before { - content: "\f1c3"; + content: '\f1c3'; } .icon-file-powerpoint-o:before { - content: "\f1c4"; + content: '\f1c4'; } .icon-file-photo-o:before, .icon-file-picture-o:before, .icon-file-image-o:before { - content: "\f1c5"; + content: '\f1c5'; } .icon-file-zip-o:before, .icon-file-archive-o:before { - content: "\f1c6"; + content: '\f1c6'; } .icon-file-sound-o:before, .icon-file-audio-o:before { - content: "\f1c7"; + content: '\f1c7'; } .icon-file-movie-o:before, .icon-file-video-o:before { - content: "\f1c8"; + content: '\f1c8'; } .icon-file-code-o:before { - content: "\f1c9"; + content: '\f1c9'; } .icon-vine:before { - content: "\f1ca"; + content: '\f1ca'; } .icon-codepen:before { - content: "\f1cb"; + content: '\f1cb'; } .icon-jsfiddle:before { - content: "\f1cc"; + content: '\f1cc'; } .icon-life-bouy:before, .icon-life-buoy:before, .icon-life-saver:before, .icon-support:before, .icon-life-ring:before { - content: "\f1cd"; + content: '\f1cd'; } .icon-circle-o-notch:before { - content: "\f1ce"; + content: '\f1ce'; } .icon-ra:before, .icon-rebel:before { - content: "\f1d0"; + content: '\f1d0'; } .icon-ge:before, .icon-empire:before { - content: "\f1d1"; + content: '\f1d1'; } .icon-git-square:before { - content: "\f1d2"; + content: '\f1d2'; } .icon-git:before { - content: "\f1d3"; + content: '\f1d3'; } .icon-hacker-news:before { - content: "\f1d4"; + content: '\f1d4'; } .icon-tencent-weibo:before { - content: "\f1d5"; + content: '\f1d5'; } .icon-qq:before { - content: "\f1d6"; + content: '\f1d6'; } .icon-wechat:before, .icon-weixin:before { - content: "\f1d7"; + content: '\f1d7'; } .icon-send:before, .icon-paper-plane:before { - content: "\f1d8"; + content: '\f1d8'; } .icon-send-o:before, .icon-paper-plane-o:before { - content: "\f1d9"; + content: '\f1d9'; } .icon-history:before { - content: "\f1da"; + content: '\f1da'; } .icon-genderless:before, .icon-circle-thin:before { - content: "\f1db"; + content: '\f1db'; } .icon-header:before { - content: "\f1dc"; + content: '\f1dc'; } .icon-paragraph:before { - content: "\f1dd"; + content: '\f1dd'; } .icon-sliders:before { - content: "\f1de"; + content: '\f1de'; } .icon-share-alt:before { - content: "\f1e0"; + content: '\f1e0'; } .icon-share-alt-square:before { - content: "\f1e1"; + content: '\f1e1'; } .icon-bomb:before { - content: "\f1e2"; + content: '\f1e2'; } .icon-soccer-ball-o:before, .icon-futbol-o:before { - content: "\f1e3"; + content: '\f1e3'; } .icon-tty:before { - content: "\f1e4"; + content: '\f1e4'; } .icon-binoculars:before { - content: "\f1e5"; + content: '\f1e5'; } .icon-plug:before { - content: "\f1e6"; + content: '\f1e6'; } .icon-slideshare:before { - content: "\f1e7"; + content: '\f1e7'; } .icon-twitch:before { - content: "\f1e8"; + content: '\f1e8'; } .icon-yelp:before { - content: "\f1e9"; + content: '\f1e9'; } .icon-newspaper-o:before { - content: "\f1ea"; + content: '\f1ea'; } .icon-wifi:before { - content: "\f1eb"; + content: '\f1eb'; } .icon-calculator:before { - content: "\f1ec"; + content: '\f1ec'; } .icon-paypal:before { - content: "\f1ed"; + content: '\f1ed'; } .icon-google-wallet:before { - content: "\f1ee"; + content: '\f1ee'; } .icon-cc-visa:before { - content: "\f1f0"; + content: '\f1f0'; } .icon-cc-mastercard:before { - content: "\f1f1"; + content: '\f1f1'; } .icon-cc-discover:before { - content: "\f1f2"; + content: '\f1f2'; } .icon-cc-amex:before { - content: "\f1f3"; + content: '\f1f3'; } .icon-cc-paypal:before { - content: "\f1f4"; + content: '\f1f4'; } .icon-cc-stripe:before { - content: "\f1f5"; + content: '\f1f5'; } .icon-bell-slash:before { - content: "\f1f6"; + content: '\f1f6'; } .icon-bell-slash-o:before { - content: "\f1f7"; + content: '\f1f7'; } .icon-trash:before { - content: "\f1f8"; + content: '\f1f8'; } .icon-copyright:before { - content: "\f1f9"; + content: '\f1f9'; } .icon-at:before { - content: "\f1fa"; + content: '\f1fa'; } .icon-eyedropper:before { - content: "\f1fb"; + content: '\f1fb'; } .icon-paint-brush:before { - content: "\f1fc"; + content: '\f1fc'; } .icon-birthday-cake:before { - content: "\f1fd"; + content: '\f1fd'; } .icon-area-chart:before { - content: "\f1fe"; + content: '\f1fe'; } .icon-pie-chart:before { - content: "\f200"; + content: '\f200'; } .icon-line-chart:before { - content: "\f201"; + content: '\f201'; } .icon-lastfm:before { - content: "\f202"; + content: '\f202'; } .icon-lastfm-square:before { - content: "\f203"; + content: '\f203'; } .icon-toggle-off:before { - content: "\f204"; + content: '\f204'; } .icon-toggle-on:before { - content: "\f205"; + content: '\f205'; } .icon-bicycle:before { - content: "\f206"; + content: '\f206'; } .icon-bus:before { - content: "\f207"; + content: '\f207'; } .icon-ioxhost:before { - content: "\f208"; + content: '\f208'; } .icon-angellist:before { - content: "\f209"; + content: '\f209'; } .icon-cc:before { - content: "\f20a"; + content: '\f20a'; } .icon-shekel:before, .icon-sheqel:before, .icon-ils:before { - content: "\f20b"; + content: '\f20b'; } .icon-meanpath:before { - content: "\f20c"; + content: '\f20c'; } .icon-buysellads:before { - content: "\f20d"; + content: '\f20d'; } .icon-connectdevelop:before { - content: "\f20e"; + content: '\f20e'; } .icon-dashcube:before { - content: "\f210"; + content: '\f210'; } .icon-forumbee:before { - content: "\f211"; + content: '\f211'; } .icon-leanpub:before { - content: "\f212"; + content: '\f212'; } .icon-sellsy:before { - content: "\f213"; + content: '\f213'; } .icon-shirtsinbulk:before { - content: "\f214"; + content: '\f214'; } .icon-simplybuilt:before { - content: "\f215"; + content: '\f215'; } .icon-skyatlas:before { - content: "\f216"; + content: '\f216'; } .icon-cart-plus:before { - content: "\f217"; + content: '\f217'; } .icon-cart-arrow-down:before { - content: "\f218"; + content: '\f218'; } .icon-diamond:before { - content: "\f219"; + content: '\f219'; } .icon-ship:before { - content: "\f21a"; + content: '\f21a'; } .icon-user-secret:before { - content: "\f21b"; + content: '\f21b'; } .icon-motorcycle:before { - content: "\f21c"; + content: '\f21c'; } .icon-street-view:before { - content: "\f21d"; + content: '\f21d'; } .icon-heartbeat:before { - content: "\f21e"; + content: '\f21e'; } .icon-venus:before { - content: "\f221"; + content: '\f221'; } .icon-mars:before { - content: "\f222"; + content: '\f222'; } .icon-mercury:before { - content: "\f223"; + content: '\f223'; } .icon-transgender:before { - content: "\f224"; + content: '\f224'; } .icon-transgender-alt:before { - content: "\f225"; + content: '\f225'; } .icon-venus-double:before { - content: "\f226"; + content: '\f226'; } .icon-mars-double:before { - content: "\f227"; + content: '\f227'; } .icon-venus-mars:before { - content: "\f228"; + content: '\f228'; } .icon-mars-stroke:before { - content: "\f229"; + content: '\f229'; } .icon-mars-stroke-v:before { - content: "\f22a"; + content: '\f22a'; } .icon-mars-stroke-h:before { - content: "\f22b"; + content: '\f22b'; } .icon-neuter:before { - content: "\f22c"; + content: '\f22c'; } .icon-facebook-official:before { - content: "\f230"; + content: '\f230'; } .icon-pinterest-p:before { - content: "\f231"; + content: '\f231'; } .icon-whatsapp:before { - content: "\f232"; + content: '\f232'; } .icon-server:before { - content: "\f233"; + content: '\f233'; } .icon-user-plus:before { - content: "\f234"; + content: '\f234'; } .icon-user-times:before { - content: "\f235"; + content: '\f235'; } .icon-hotel:before, .icon-bed:before { - content: "\f236"; + content: '\f236'; } .icon-viacoin:before { - content: "\f237"; + content: '\f237'; } .icon-train:before { - content: "\f238"; + content: '\f238'; } .icon-subway:before { - content: "\f239"; + content: '\f239'; } .icon-medium:before { - content: "\f23a"; + content: '\f23a'; } .icon-address-book:before { - content: "\f2b9"; + content: '\f2b9'; } .icon-envelope-open:before { - content: "\f2b6"; + content: '\f2b6'; } diff --git a/src/renderer/scss/_reset.scss b/src/renderer/scss/_reset.scss index e951875a8..b93394c96 100644 --- a/src/renderer/scss/_reset.scss +++ b/src/renderer/scss/_reset.scss @@ -1,39 +1,70 @@ -body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, select, textarea, p, blockquote, th, td, iframe -{ - margin:0; - padding:0; +body, +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +h4, +h5, +h6, +pre, +code, +form, +fieldset, +legend, +input, +select, +textarea, +p, +blockquote, +th, +td, +iframe { + margin: 0; + padding: 0; } -:focus -{ +:focus { outline: 0; } input::-webkit-search-cancel-button { /* Remove default */ -webkit-appearance: none; } -table -{ +table { border-collapse: collapse; - border-spacing:0; + border-spacing: 0; } -fieldset, img, iframe -{ - border: 0; +fieldset, +img, +iframe { + border: 0; } -h1, h2, h3, h4, h5, h6 -{ - font-weight:normal; +h1, +h2, +h3, +h4, +h5, +h6 { + font-weight: normal; } -ol, ul -{ +ol, +ul { + list-style-position: inside; + > li { list-style-position: inside; - > li { list-style-position: inside; } + } } -input, textarea, select -{ - font-family:inherit; - font-size:inherit; - font-weight:inherit; +input, +textarea, +select { + font-family: inherit; + font-size: inherit; + font-weight: inherit; border: 0 none; } img { @@ -42,8 +73,7 @@ img { vertical-align: middle; -ms-interpolation-mode: bicubic; } -a -{ - color: inherit; - text-decoration: none; -} \ No newline at end of file +a { + color: inherit; + text-decoration: none; +} diff --git a/src/renderer/scss/_vars.scss b/src/renderer/scss/_vars.scss index b9e0f49e8..15436a5b1 100644 --- a/src/renderer/scss/_vars.scss +++ b/src/renderer/scss/_vars.scss @@ -6,28 +6,27 @@ $width-page-constrained: 800px; $text-color: #000; :root { - /* Colors */ - --color-brand: #155B4A; - --color-primary: #155B4A; - --color-primary-light: saturate(lighten(#155B4A, 50%), 20%); - --color-light-alt: hsl(hue(#155B4A), 15, 85); - --color-dark-overlay: rgba(32,32,32,0.9); + --color-brand: #155b4a; + --color-primary: #155b4a; + --color-primary-light: saturate(lighten(#155b4a, 50%), 20%); + --color-light-alt: hsl(hue(#155b4a), 15, 85); + --color-dark-overlay: rgba(32, 32, 32, 0.9); --color-help: rgba(0, 0, 0, 0.54); --color-notice: #8a6d3b; --color-error: #a94442; --color-load-screen-text: #c3c3c3; --color-meta-light: #505050; - --color-money: #216C2A; + --color-money: #216c2a; --color-download: rgba(0, 0, 0, 0.75); --color-canvas: #f5f5f5; --color-bg: #ffffff; - --color-bg-alt: #D9D9D9; + --color-bg-alt: #d9d9d9; /* Misc */ --content-max-width: 1000px; --nsfw-blur-intensity: 20px; - --height-video-embedded: $width-page-constrained * 9 / 16 ; + --height-video-embedded: $width-page-constrained * 9 / 16; /* Font */ --font-size: 16px; @@ -35,20 +34,21 @@ $text-color: #000; --font-size-subtext-multiple: 0.82; /* Shadows */ - --box-shadow-layer: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); - --box-shadow-focus: 2px 4px 4px 0 rgba(0,0,0,.14),2px 5px 3px -2px rgba(0,0,0,.2),2px 3px 7px 0 rgba(0,0,0,.12); + --box-shadow-layer: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + --box-shadow-focus: 2px 4px 4px 0 rgba(0, 0, 0, 0.14), 2px 5px 3px -2px rgba(0, 0, 0, 0.2), + 2px 3px 7px 0 rgba(0, 0, 0, 0.12); /* Transition */ - --transition-duration: .225s; + --transition-duration: 0.225s; --transition-type: ease; /* Text */ --text-color: $text-color; - --text-help-color: #EEE; + --text-help-color: #eee; --text-max-width: 660px; --text-link-padding: 4px; - --text-selection-bg: rgba(saturate(lighten(#155B4A, 20%), 20%), 1); // temp color - --text-selection-color: #FFF; + --text-selection-bg: rgba(saturate(lighten(#155b4a, 20%), 20%), 1); // temp color + --text-selection-color: #fff; /* Window */ --window-bg: var(--color-canvas); @@ -72,7 +72,7 @@ $text-color: #000; /* input:hover */ --input-hover-border-color: rgba(0, 0, 0, 0.87); - /* input:placeholder */ + /* input:placeholder */ --input-placeholder-color: rgba(0, 0, 0, 0.42); --input-placeholder-opacity: 1; @@ -82,9 +82,9 @@ $text-color: #000; /* Button */ --button-bg: var(--color-bg-alt); - --button-color: #FFF; + --button-color: #fff; --button-primary-bg: var(--color-primary); - --button-primary-color: #FFF; + --button-primary-color: #fff; --button-padding: $spacing-vertical * 2/3; --button-height: $spacing-vertical * 1.5; --button-intra-margin: $spacing-vertical; @@ -93,14 +93,14 @@ $text-color: #000; /* Header */ --header-bg: var(--color-bg); --header-color: #666; - --header-active-color: rgba(0,0,0, 0.85); + --header-active-color: rgba(0, 0, 0, 0.85); --header-height: $spacing-vertical * 2.5; --header-button-bg: transparent; //var(--button-bg); --header-button-hover-bg: rgba(100, 100, 100, 0.15); /* Header -> search */ --search-bg: rgba(255, 255, 255, 0.7); - --search-border:1px solid #ccc; + --search-border: 1px solid #ccc; --search-color: #666; --search-active-color: var(--header-active-color); --search-active-shadow: 0 0 3px 0px var(--text-selection-bg); @@ -130,7 +130,7 @@ $text-color: #000; /* Modal */ --modal-width: 440px; --modal-bg: var(--color-bg); - --modal-overlay-bg: rgba(#F5F5F5, 0.75); // --color-canvas: #F5F5F5 + --modal-overlay-bg: rgba(#f5f5f5, 0.75); // --color-canvas: #F5F5F5 --modal-border: 1px solid rgb(204, 204, 204); /* Menu */ @@ -146,7 +146,7 @@ $text-color: #000; /* Scrollbar */ --scrollbar-radius: 10px; - --scrollbar-thumb-bg: rgba(0, 0, 0, 0.20); + --scrollbar-thumb-bg: rgba(0, 0, 0, 0.2); --scrollbar-thumb-hover-bg: rgba(0, 0, 0, 0.35); --scrollbar-thumb-active-bg: var(--color-primary); --scrollbar-track-bg: transparent; @@ -156,6 +156,5 @@ $text-color: #000; /* Animation :) */ --animation-duration: 0.3s; - --animation-style: cubic-bezier(.55,0,.1,1); - + --animation-style: cubic-bezier(0.55, 0, 0.1, 1); } diff --git a/src/renderer/scss/all.scss b/src/renderer/scss/all.scss index 40c63b1f4..7d39cb43a 100644 --- a/src/renderer/scss/all.scss +++ b/src/renderer/scss/all.scss @@ -1,31 +1,31 @@ @charset "UTF-8"; -@import "_reset"; -@import "_vars"; -@import "_icons"; -@import "_gui"; -@import "component/_table"; -@import "component/_button.scss"; -@import "component/_card.scss"; -@import "component/_file-download.scss"; -@import "component/_file-selector.scss"; -@import "component/_file-tile.scss"; -@import "component/_form-field.scss"; -@import "component/_header.scss"; -@import "component/_menu.scss"; -@import "component/_tooltip.scss"; -@import "component/_load-screen.scss"; -@import "component/_channel-indicator.scss"; -@import "component/_notice.scss"; -@import "component/_modal.scss"; -@import "component/_snack-bar.scss"; -@import "component/_video.scss"; -@import "component/_pagination.scss"; -@import "component/_markdown-editor.scss"; -@import "component/_scrollbar.scss"; -@import "component/_tabs.scss"; -@import "component/_divider.scss"; -@import "component/_checkbox.scss"; -@import "component/_radio.scss"; -@import "component/_shapeshift.scss"; -@import "component/_spinner.scss"; -@import "page/_show.scss"; +@import '_reset'; +@import '_vars'; +@import '_icons'; +@import '_gui'; +@import 'component/_table'; +@import 'component/_button.scss'; +@import 'component/_card.scss'; +@import 'component/_file-download.scss'; +@import 'component/_file-selector.scss'; +@import 'component/_file-tile.scss'; +@import 'component/_form-field.scss'; +@import 'component/_header.scss'; +@import 'component/_menu.scss'; +@import 'component/_tooltip.scss'; +@import 'component/_load-screen.scss'; +@import 'component/_channel-indicator.scss'; +@import 'component/_notice.scss'; +@import 'component/_modal.scss'; +@import 'component/_snack-bar.scss'; +@import 'component/_video.scss'; +@import 'component/_pagination.scss'; +@import 'component/_markdown-editor.scss'; +@import 'component/_scrollbar.scss'; +@import 'component/_tabs.scss'; +@import 'component/_divider.scss'; +@import 'component/_checkbox.scss'; +@import 'component/_radio.scss'; +@import 'component/_shapeshift.scss'; +@import 'component/_spinner.scss'; +@import 'page/_show.scss'; diff --git a/src/renderer/scss/component/_button.scss b/src/renderer/scss/component/_button.scss index e3dad6330..576ca4c33 100644 --- a/src/renderer/scss/component/_button.scss +++ b/src/renderer/scss/component/_button.scss @@ -1,4 +1,4 @@ -@import "../mixin/link.scss"; +@import '../mixin/link.scss'; $button-focus-shift: 12%; @@ -6,14 +6,13 @@ $button-focus-shift: 12%; position: relative; display: inline-block; - + .button-set-item - { + + .button-set-item { margin-left: var(--button-intra-margin); } } -.button-block, .faux-button-block -{ +.button-block, +.faux-button-block { display: inline-block; height: var(--button-height); line-height: var(--button-height); @@ -22,26 +21,21 @@ $button-focus-shift: 12%; text-align: center; border-radius: var(--button-radius); text-transform: uppercase; - .icon - { + .icon { top: 0em; } - .icon:first-child - { + .icon:first-child { padding-right: 5px; } - .icon:last-child - { + .icon:last-child { padding-left: 5px; } - .icon:only-child - { + .icon:only-child { padding-left: 0; padding-right: 0; } } -.button-block -{ +.button-block { cursor: pointer; font-weight: 500; font-size: 14px; @@ -57,9 +51,7 @@ $button-focus-shift: 12%; } } -.button-primary -{ - +.button-primary { color: var(--button-primary-color); background-color: var(--button-primary-bg); box-shadow: var(--box-shadow-layer); @@ -70,14 +62,12 @@ $button-focus-shift: 12%; //box-shadow: $box-shadow-focus; } } -.button-alt -{ +.button-alt { background-color: var(--button-bg); box-shadow: var(--box-shadow-layer); } -.button-text -{ +.button-text { @include text-link(); display: inline-block; @@ -85,17 +75,15 @@ $button-focus-shift: 12%; margin: 0 var(--text-link-padding); } } -.button-text-help -{ +.button-text-help { @include text-link(var(--text-help-color)); font-size: 0.8em; } -.button--flat -{ +.button--flat { box-shadow: none !important; } .button--submit { - font-family: inherit; - line-height: 0; -} \ No newline at end of file + font-family: inherit; + line-height: 0; +} diff --git a/src/renderer/scss/component/_card.scss b/src/renderer/scss/component/_card.scss index 5d0b5e76a..cef50a1fb 100644 --- a/src/renderer/scss/component/_card.scss +++ b/src/renderer/scss/component/_card.scss @@ -12,12 +12,11 @@ //below added to prevent scrollbar on long titles when show page loads, would prefer a cleaner CSS solution overflow-x: hidden; } -.card--obscured -{ +.card--obscured { position: relative; } .card--obscured .card__inner { - filter: blur( var(--nsfw-blur-intensity) ); + filter: blur(var(--nsfw-blur-intensity)); } .card__title-primary, .card__title-identity, @@ -52,7 +51,6 @@ margin-top: var(--card-margin); margin-bottom: var(--card-margin); user-select: none; - } .card__actions--bottom { margin-top: $spacing-vertical * 1/3; @@ -88,7 +86,7 @@ $font-size-subtext-multiple: 0.82; .card__subtext { color: var(--color-meta-light); - font-size: calc( var(--font-size-subtext-multiple) * 1.0em ); + font-size: calc(var(--font-size-subtext-multiple) * 1em); margin-top: $spacing-vertical * 1/3; margin-bottom: $spacing-vertical * 1/3; } @@ -96,7 +94,9 @@ $font-size-subtext-multiple: 0.82; white-space: pre-wrap; } .card__subtext--two-lines { - height: calc( var(--font-size) * var(--font-size-subtext-multiple) * var(--font-line-height) * 2); /*this is so one line text still has the proper height*/ + height: calc( + var(--font-size) * var(--font-size-subtext-multiple) * var(--font-line-height) * 2 + ); /*this is so one line text still has the proper height*/ } .card-overlay { position: absolute; @@ -117,7 +117,7 @@ $font-size-subtext-multiple: 0.82; cursor: pointer; } .card--link { - transition: transform 0.2s var(--animation-style); + transition: transform 0.2s var(--animation-style); } .card--link:hover { position: relative; @@ -126,7 +126,7 @@ $font-size-subtext-multiple: 0.82; transform: scale(var(--card-link-scaling)) translateX(var(--card-hover-translate)); transform-origin: 50% 50%; overflow-x: visible; - overflow-y: visible + overflow-y: visible; } .card--link:hover ~ .card--link { transform: translateX(calc(var(--card-hover-translate) * 2)); @@ -139,49 +139,49 @@ $font-size-subtext-multiple: 0.82; } .card__media--autothumb { - position: relative + position: relative; } .card__media--autothumb.purple { - background-color: #9c27b0 + background-color: #9c27b0; } .card__media--autothumb.red { - background-color: #e53935 + background-color: #e53935; } .card__media--autothumb.pink { - background-color: #e91e63 + background-color: #e91e63; } .card__media--autothumb.indigo { - background-color: #3f51b5 + background-color: #3f51b5; } .card__media--autothumb.blue { - background-color: #2196f3 + background-color: #2196f3; } .card__media--autothumb.light-blue { - background-color: #039be5 + background-color: #039be5; } .card__media--autothumb.cyan { - background-color: #00acc1 + background-color: #00acc1; } .card__media--autothumb.teal { - background-color: #009688 + background-color: #009688; } .card__media--autothumb.green { - background-color: #43a047 + background-color: #43a047; } .card__media--autothumb.yellow { - background-color: #ffeb3b + background-color: #ffeb3b; } .card__media--autothumb.orange { - background-color: #ffa726 + background-color: #ffa726; } .card__media--autothumb .card__autothumb__text { - font-size: 2.0em; + font-size: 2em; width: 100%; color: #ffffff; text-align: center; position: absolute; - top: 36% + top: 36%; } .card__indicators { @@ -194,17 +194,17 @@ $font-size-subtext-multiple: 0.82; white-space: normal; } .card--small .card__media { - height: calc( var(--card-small-width) * 9 / 16); + height: calc(var(--card-small-width) * 9 / 16); } .card--form { - width: calc( var(--input-width) + var(--card-padding) * 2); + width: calc(var(--input-width) + var(--card-padding) * 2); } .card__subtitle { color: var(--color-help); font-size: 0.85em; - line-height: calc( var(--font-line-height) * 1 / 0.85); + line-height: calc(var(--font-line-height) * 1 / 0.85); } .card--file-subtitle { @@ -219,8 +219,7 @@ $font-size-subtext-multiple: 0.82; padding-left: 20px; } -.card-series-submit -{ +.card-series-submit { margin-left: auto; margin-right: auto; max-width: var(--card-max-width); @@ -279,7 +278,7 @@ $padding-right-card-hover-hack: 30px; position: absolute; padding: 0 var(--card-margin); height: 100%; - top: calc( $padding-top-card-hover-hack - var(--card-margin) ); + top: calc($padding-top-card-hover-hack - var(--card-margin)); } .card-row__nav .card-row__scroll-button { background: var(--card-bg); @@ -295,8 +294,8 @@ $padding-right-card-hover-hack: 30px; transition: transform 0.2s var(--animation-style); &:hover { - opacity: 1.0; - transform: scale(calc( var(--card-link-scaling) * 1.1)); + opacity: 1; + transform: scale(calc(var(--card-link-scaling) * 1.1)); } } .card-row__nav--left { @@ -311,11 +310,11 @@ if we keep doing things like this, we should add a real grid system, but I'm goi */ .card-grid { $margin-card-grid: $spacing-vertical * 2/3; - display:flex; + display: flex; flex-wrap: wrap; > .card { width: $width-page-constrained / 2 - $margin-card-grid / 2; - flex-grow:1; + flex-grow: 1; } > .card:nth-of-type(2n - 1):not(:last-child) { margin-right: $margin-card-grid; diff --git a/src/renderer/scss/component/_channel-indicator.scss b/src/renderer/scss/component/_channel-indicator.scss index 50b7648d0..7c437780c 100644 --- a/src/renderer/scss/component/_channel-indicator.scss +++ b/src/renderer/scss/component/_channel-indicator.scss @@ -1,4 +1,3 @@ - .channel-name { display: inline-flex; overflow: hidden; diff --git a/src/renderer/scss/component/_checkbox.scss b/src/renderer/scss/component/_checkbox.scss index 92b7599cb..b72f7c896 100644 --- a/src/renderer/scss/component/_checkbox.scss +++ b/src/renderer/scss/component/_checkbox.scss @@ -1,4 +1,6 @@ -*, *:before, *:after { +*, +*:before, +*:after { box-sizing: border-box; } @@ -7,17 +9,18 @@ $md-checkbox-border-color: var(--input-border-color); $md-checkbox-size: 20px; $md-checkbox-padding: 4px; $md-checkmark-width: 2px; -$md-checkmark-color: #FFF; +$md-checkmark-color: #fff; .form-field--checkbox { position: relative; label { cursor: pointer; - &:before, &:after { - content: ""; + &:before, + &:after { + content: ''; position: absolute; - left:0; + left: 0; top: 0; } @@ -29,7 +32,7 @@ $md-checkmark-color: #FFF; border: 2px solid $md-checkbox-border-color; border-radius: 2px; cursor: pointer; - transition: background .3s; + transition: background 0.3s; } &:after { @@ -37,19 +40,17 @@ $md-checkmark-color: #FFF; } } - input[type="checkbox"] { + input[type='checkbox'] { outline: 0; visibility: hidden; margin-right: 16px; &:checked { - - + label:before{ + + label:before { background: $md-checkbox-checked-color; - border:none; + border: none; } + label:after { - $md-checkmark-size: $md-checkbox-size - 2*$md-checkbox-padding; transform: rotate(-45deg); @@ -65,5 +66,4 @@ $md-checkmark-color: #FFF; } } } - } diff --git a/src/renderer/scss/component/_file-download.scss b/src/renderer/scss/component/_file-download.scss index dcde4b31b..04eb6fc90 100644 --- a/src/renderer/scss/component/_file-download.scss +++ b/src/renderer/scss/component/_file-download.scss @@ -1,16 +1,15 @@ -.file-download, .file-download__overlay { - .button__content { - margin: 0 var(--text-link-padding); - } +.file-download, +.file-download__overlay { + .button__content { + margin: 0 var(--text-link-padding); + } } -.file-download -{ +.file-download { position: relative; color: var(--color-download); } -.file-download__overlay -{ +.file-download__overlay { background: var(--color-download); color: var(--color-bg); position: absolute; diff --git a/src/renderer/scss/component/_file-tile.scss b/src/renderer/scss/component/_file-tile.scss index 3542ac2ea..eccb74446 100644 --- a/src/renderer/scss/component/_file-tile.scss +++ b/src/renderer/scss/component/_file-tile.scss @@ -19,5 +19,4 @@ $height-file-tile: $spacing-vertical * 6; .card__title-primary { margin-top: 0; } - } diff --git a/src/renderer/scss/component/_form-field.scss b/src/renderer/scss/component/_form-field.scss index 1d7398d7a..042565611 100644 --- a/src/renderer/scss/component/_form-field.scss +++ b/src/renderer/scss/component/_form-field.scss @@ -1,9 +1,7 @@ -.form-row-submit -{ +.form-row-submit { margin-top: $spacing-vertical; } -.form-row-submit--with-footer -{ +.form-row-submit--with-footer { margin-bottom: $spacing-vertical; } @@ -11,7 +9,7 @@ margin-top: $spacing-vertical * 5/6; margin-bottom: 0px; line-height: 1; - font-size:calc( 0.9 * var(--font-size)); + font-size: calc(0.9 * var(--font-size)); } .form-row__label-row--prefix { float: left; @@ -19,7 +17,8 @@ } .form-row--focus { - .form-field__label, .form-field__prefix { + .form-field__label, + .form-field__prefix { color: var(--color-primary) !important; } } @@ -37,26 +36,27 @@ background: var(--select-bg); color: var(--select-color); &:focus { - outline: var(--input-border-size) solid var(--color-primary); + outline: var(--input-border-size) solid var(--color-primary); } } - input[type="radio"], input[type="checkbox"], { - &:checked + .form-field__label, { + input[type='radio'], + input[type='checkbox'] { + &:checked + .form-field__label { color: var(--text-color); } } - input[type="text"].input-copyable { + input[type='text'].input-copyable { background: var(--input-bg); - color: var(--input-disabled-color); + color: var(--input-disabled-color); line-height: 1; padding-top: $spacing-vertical * 1/3; padding-bottom: $spacing-vertical * 1/3; padding-left: 5px; padding-right: 5px; width: 100%; - font-family: "Consolas", "Lucida Console", "Adobe Source Code Pro", monospace; + font-family: 'Consolas', 'Lucida Console', 'Adobe Source Code Pro', monospace; &.input-copyable--with-copy-btn { width: 85%; @@ -64,44 +64,44 @@ } input[readonly] { - color: var(--input-disabled-color) !important; - border-bottom: 1px dashed var(--input-disabled-border-color) !important; + color: var(--input-disabled-color) !important; + border-bottom: 1px dashed var(--input-disabled-border-color) !important; } input[readonly]:focus { - background: var(--input-bg) !important; - border-bottom: 1px dashed var(--input-disabled-border-color) !important; + background: var(--input-bg) !important; + border-bottom: 1px dashed var(--input-disabled-border-color) !important; } textarea, - input[type="text"], - input[type="password"], - input[type="email"], - input[type="number"], - input[type="search"], - input[type="date"]{ + input[type='text'], + input[type='password'], + input[type='email'], + input[type='number'], + input[type='search'], + input[type='date'] { background: var(--input-bg); border-bottom: var(--input-border-size) solid var(--input-border-color); - caret-color: var(--color-primary); + caret-color: var(--color-primary); color: var(--input-color); cursor: pointer; line-height: 1; - padding:0 1px 8px 1px; + padding: 0 1px 8px 1px; box-sizing: border-box; -webkit-appearance: none; - transition: all var(--transition-duration) var(--transition-type); + transition: all var(--transition-duration) var(--transition-type); &::-webkit-input-placeholder { color: var(--input-placeholder-color); opacity: var(--input-placeholder-opacity) !important; - } + } &:focus { border-color: var(--color-primary); background: var(--input-active-bg); } - &:hover:not(:focus){ + &:hover:not(:focus) { border-color: var(--input-hover-border-color); } @@ -112,11 +112,10 @@ &.form-field__input--inline { padding-top: 0; padding-bottom: 0; - border-bottom-width: var(--input-border-size); + border-bottom-width: var(--input-border-size); margin-left: 8px; margin-right: 8px; } - } textarea { @@ -132,7 +131,8 @@ display: block; } -.form-field__label, .form-row__label { +.form-field__label, +.form-row__label { color: var(--form-label-color); &[for] { cursor: pointer; @@ -167,17 +167,18 @@ width: 100%; } -.form-field__error, .form-field__helper { +.form-field__error, +.form-field__helper { margin-top: $spacing-vertical * 1/3; font-size: 0.8em; - transition: opacity var(--transition-duration) var(--transition-type); + transition: opacity var(--transition-duration) var(--transition-type); } .form-field__error { color: var(--color-error); } .form-field__helper { - color:var(--color-help); + color: var(--color-help); } .form-field__input.form-field__input-SimpleMDE .CodeMirror-scroll { diff --git a/src/renderer/scss/component/_header.scss b/src/renderer/scss/component/_header.scss index bdc72dcbd..a8967d0eb 100644 --- a/src/renderer/scss/component/_header.scss +++ b/src/renderer/scss/component/_header.scss @@ -1,6 +1,4 @@ - -#header -{ +#header { color: var(--header-color); background: var(--header-bg); display: flex; @@ -19,11 +17,11 @@ padding-left: $spacing-vertical / 4; padding-right: $spacing-vertical / 4; .button-alt { - background: var(--header-button-bg) !important; - font-size: 1em; + background: var(--header-button-bg) !important; + font-size: 1em; } .button-alt:hover { - background: var(--header-button-hover-bg) !important; + background: var(--header-button-hover-bg) !important; } } @@ -31,17 +29,18 @@ flex-grow: 1; } -.wunderbar -{ +.wunderbar { position: relative; .icon { position: absolute; left: 10px; - top: $spacing-vertical / 2 - 4px; //hacked + top: $spacing-vertical / 2 - 4px; //hacked } } -.wunderbar--active .icon-search { color: var(--color-primary); } +.wunderbar--active .icon-search { + color: var(--color-primary); +} // below styles should be inside the common input styling // will come back to this with the redesign - sean diff --git a/src/renderer/scss/component/_load-screen.scss b/src/renderer/scss/component/_load-screen.scss index cfd369c95..05cce635e 100644 --- a/src/renderer/scss/component/_load-screen.scss +++ b/src/renderer/scss/component/_load-screen.scss @@ -1,4 +1,3 @@ - .load-screen { color: white; background: var(--color-brand); diff --git a/src/renderer/scss/component/_markdown-editor.scss b/src/renderer/scss/component/_markdown-editor.scss index 5a1786b48..7211c0d08 100644 --- a/src/renderer/scss/component/_markdown-editor.scss +++ b/src/renderer/scss/component/_markdown-editor.scss @@ -1,17 +1,17 @@ .CodeMirror { - background: var(--color-canvas) !important; - border: 0px !important; - border-radius: 0px !important; - color: var(--text-color) !important; - box-shadow: var(--box-shadow-layer); + background: var(--color-canvas) !important; + border: 0px !important; + border-radius: 0px !important; + color: var(--text-color) !important; + box-shadow: var(--box-shadow-layer); } .editor-toolbar { - opacity: 1 !important; - border: 0 !important; - background: var(--color-bg-alt); - border-radius: 0 !important; - box-shadow: var(--box-shadow-layer); + opacity: 1 !important; + border: 0 !important; + background: var(--color-bg-alt); + border-radius: 0 !important; + box-shadow: var(--box-shadow-layer); } .editor-toolbar i.separator { @@ -20,85 +20,85 @@ } .editor-toolbar.fullscreen { - background: var(--color-bg) !important; + background: var(--color-bg) !important; } div.editor-toolbar a { - opacity: 0.64; - color: var(--text-color) !important; + opacity: 0.64; + color: var(--text-color) !important; } .editor-toolbar a.active, .editor-toolbar a:hover { - opacity: 1; - background: var(--button-bg) !important; - border-color: transparent !important; + opacity: 1; + background: var(--button-bg) !important; + border-color: transparent !important; } .editor-toolbar.disabled-for-preview a:not(.no-disable) { - background: var(--color-bg-alt) !important; - border-color: transparent !important; + background: var(--color-bg-alt) !important; + border-color: transparent !important; } .editor-statusbar { - color: var(--form-label-color) !important; + color: var(--form-label-color) !important; } .editor-preview { - background: var(--card-bg) !important; - border: 0 !important; + background: var(--card-bg) !important; + border: 0 !important; } .editor-preview-side { - background: var(--color-bg-alt) !important; - border: 1px solid var(--input-border-color) !important; + background: var(--color-bg-alt) !important; + border: 1px solid var(--input-border-color) !important; } .editor-preview pre, .editor-preview-side pre { - background: #eee; + background: #eee; } .editor-preview table td, .editor-preview table th, .editor-preview-side table td, .editor-preview-side table th { - border: 1px solid var(--input-border-color) !important; + border: 1px solid var(--input-border-color) !important; } .CodeMirror .CodeMirror-code .cm-tag { - color: #63a35c; + color: #63a35c; } .CodeMirror .CodeMirror-code .cm-attribute { - color: #795da3; + color: #795da3; } .CodeMirror .CodeMirror-code .cm-string { - color: #183691; + color: #183691; } .CodeMirror .CodeMirror-selected { - background: var(--text-selection-bg) !important; - color: var(--text-selection-color) !important; + background: var(--text-selection-bg) !important; + color: var(--text-selection-color) !important; } -.CodeMirror .CodeMirror-cursor{ - border-color: var(--color-primary) !important; +.CodeMirror .CodeMirror-cursor { + border-color: var(--color-primary) !important; } .CodeMirror .CodeMirror-code .cm-comment { - background: rgba(0, 0, 0, .05); + background: rgba(0, 0, 0, 0.05); } .CodeMirror .CodeMirror-code .cm-link { - color: #7f8c8d; + color: #7f8c8d; } .CodeMirror .CodeMirror-code .cm-url { - color: #aab2b3; + color: #aab2b3; } .CodeMirror .CodeMirror-placeholder { - opacity: .5; + opacity: 0.5; } diff --git a/src/renderer/scss/component/_menu.scss b/src/renderer/scss/component/_menu.scss index 19af2af66..c04f11610 100644 --- a/src/renderer/scss/component/_menu.scss +++ b/src/renderer/scss/component/_menu.scss @@ -1,4 +1,3 @@ - $border-radius-menu: 2px; .menu-container { diff --git a/src/renderer/scss/component/_modal.scss b/src/renderer/scss/component/_modal.scss index 26fa408df..d5a561334 100644 --- a/src/renderer/scss/component/_modal.scss +++ b/src/renderer/scss/component/_modal.scss @@ -1,5 +1,5 @@ - -.modal-overlay, .error-modal-overlay { +.modal-overlay, +.error-modal-overlay { position: fixed; display: flex; justify-content: center; @@ -72,11 +72,12 @@ max-width: none; width: var(--modal-width); } -.error-modal__error-list { /*shitty hack/temp fix for long errors making modal unusable*/ +.error-modal__error-list { + /*shitty hack/temp fix for long errors making modal unusable*/ border: 1px solid var(--input-border-color); padding: 8px; list-style: none; max-height: 400px; - max-width: var(--modal-width); + max-width: var(--modal-width); overflow-y: hidden; } diff --git a/src/renderer/scss/component/_notice.scss b/src/renderer/scss/component/_notice.scss index 112658987..277fe0615 100644 --- a/src/renderer/scss/component/_notice.scss +++ b/src/renderer/scss/component/_notice.scss @@ -1,17 +1,16 @@ - .notice { - padding: 10px 20px; - border: 1px solid #000; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - border-radius: 5px; + padding: 10px 20px; + border: 1px solid #000; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + border-radius: 5px; - color: #468847; - background-color: #dff0d8; - border-color: #d6e9c6; + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; } .notice--error { - color: #b94a48; - background-color: #f2dede; - border-color: #eed3d7; + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; } diff --git a/src/renderer/scss/component/_pagination.scss b/src/renderer/scss/component/_pagination.scss index 4851f366a..9c70d32f4 100644 --- a/src/renderer/scss/component/_pagination.scss +++ b/src/renderer/scss/component/_pagination.scss @@ -1,4 +1,3 @@ - .pagination { display: block; padding: 0; @@ -13,7 +12,9 @@ border-radius: 2px; &:not(.pagination__item--selected):hover { background: rgba(0, 0, 0, 0.2); - > a { cursor: hand } + > a { + cursor: hand; + } } > a { display: inline-block; @@ -21,12 +22,13 @@ } } -.pagination__item--previous, .pagination__item--next { +.pagination__item--previous, +.pagination__item--next { font-size: 1.2em; } .pagination__item--break { - padding: 0 $spacing-vertical * 2 / 3; + padding: 0 $spacing-vertical * 2 / 3; } .pagination__item--selected { diff --git a/src/renderer/scss/component/_radio.scss b/src/renderer/scss/component/_radio.scss index 3e54da009..4d511816f 100644 --- a/src/renderer/scss/component/_radio.scss +++ b/src/renderer/scss/component/_radio.scss @@ -5,50 +5,50 @@ $md-radio-checked-size: 10px; $md-radio-ripple-size: 15px; .form-field--radio { - position: relative; + position: relative; - label { + label { + cursor: pointer; + + &:before, + &:after { + content: ''; + position: absolute; + left: 0; + top: 0; + border-radius: 50%; + transition: all 0.3s ease; + transition-property: transform, border-color; + } + + &:before { + width: $md-radio-size; + height: $md-radio-size; + background: transparent; + border: 2px solid $md-radio-border-color; cursor: pointer; - - &:before, &:after { - content: ""; - position: absolute; - left:0; - top: 0; - border-radius: 50%; - transition: all .3s ease; - transition-property: transform, border-color; - } - - &:before { - width: $md-radio-size; - height: $md-radio-size; - background: transparent; - border: 2px solid $md-radio-border-color; - cursor: pointer; - } - - &:after { - top: $md-radio-size / 2 - $md-radio-checked-size / 2; - left: $md-radio-size / 2 - $md-radio-checked-size / 2; - width:$md-radio-checked-size; - height:$md-radio-checked-size; - transform: scale(0); - background:$md-radio-checked-color; - } - } - input[type="radio"] { - visibility: hidden; - margin-right: 16px; - - &:checked + label:before { - border-color: $md-radio-checked-color; - } - - &:checked + label:after { - transform: scale(1); - } + &:after { + top: $md-radio-size / 2 - $md-radio-checked-size / 2; + left: $md-radio-size / 2 - $md-radio-checked-size / 2; + width: $md-radio-checked-size; + height: $md-radio-checked-size; + transform: scale(0); + background: $md-radio-checked-color; } + } + + input[type='radio'] { + visibility: hidden; + margin-right: 16px; + + &:checked + label:before { + border-color: $md-radio-checked-color; + } + + &:checked + label:after { + transform: scale(1); + } + } } diff --git a/src/renderer/scss/component/_scrollbar.scss b/src/renderer/scss/component/_scrollbar.scss index 048428132..c501d0ddd 100644 --- a/src/renderer/scss/component/_scrollbar.scss +++ b/src/renderer/scss/component/_scrollbar.scss @@ -1,24 +1,24 @@ ::-webkit-scrollbar { - width: 8px; - overflow: auto; + width: 8px; + overflow: auto; } ::-webkit-scrollbar-track { - background: var(--scrollbar-track-bg); - border-radius: var(--scrollbar-radius); - margin: 4px; + background: var(--scrollbar-track-bg); + border-radius: var(--scrollbar-radius); + margin: 4px; } ::-webkit-scrollbar-thumb { - border-radius: var(--scrollbar-radius); - background-color: var(--scrollbar-thumb-bg); - transition: background-color 0.3s ease; + border-radius: var(--scrollbar-radius); + background-color: var(--scrollbar-thumb-bg); + transition: background-color 0.3s ease; } ::-webkit-scrollbar-thumb:hover { - background-color: var(--scrollbar-thumb-hover-bg); + background-color: var(--scrollbar-thumb-hover-bg); } ::-webkit-scrollbar-thumb:active { - background-color: var(--scrollbar-thumb-active-bg); + background-color: var(--scrollbar-thumb-active-bg); } diff --git a/src/renderer/scss/component/_shapeshift.scss b/src/renderer/scss/component/_shapeshift.scss index 6e12a0522..cbe040180 100644 --- a/src/renderer/scss/component/_shapeshift.scss +++ b/src/renderer/scss/component/_shapeshift.scss @@ -34,7 +34,6 @@ margin-left: 40px; } - .shapeshift__link { padding-left: 10px; } diff --git a/src/renderer/scss/component/_snack-bar.scss b/src/renderer/scss/component/_snack-bar.scss index 75d2e3491..ccc81e0b9 100644 --- a/src/renderer/scss/component/_snack-bar.scss +++ b/src/renderer/scss/component/_snack-bar.scss @@ -1,4 +1,3 @@ - $padding-snack-horizontal: $spacing-vertical; .snack-bar { @@ -24,7 +23,7 @@ $padding-snack-horizontal: $spacing-vertical; border-radius: 2px; - transition: all var(--transition-duration) var(--transition-type); + transition: all var(--transition-duration) var(--transition-type); z-index: 10000; /*hack to get it over react modal */ } diff --git a/src/renderer/scss/component/_spinner.scss b/src/renderer/scss/component/_spinner.scss index ec339e5a1..f3e0485f7 100644 --- a/src/renderer/scss/component/_spinner.scss +++ b/src/renderer/scss/component/_spinner.scss @@ -55,4 +55,4 @@ &:after { background: var(--color-bg); } -} \ No newline at end of file +} diff --git a/src/renderer/scss/component/_table.scss b/src/renderer/scss/component/_table.scss index 06f33aaf0..1c6b17369 100644 --- a/src/renderer/scss/component/_table.scss +++ b/src/renderer/scss/component/_table.scss @@ -1,9 +1,9 @@ - table.table-standard { word-wrap: break-word; max-width: 100%; - th, td { + th, + td { padding: $spacing-vertical/2 8px; } th { @@ -13,7 +13,8 @@ table.table-standard { td { vertical-align: top; } - thead th, > tr:first-child th { + thead th, + > tr:first-child th { vertical-align: bottom; font-weight: 500; font-size: 0.9em; @@ -32,7 +33,7 @@ table.table-standard { } tfoot td { padding: $spacing-vertical / 2 8px; - font-size: .85em; + font-size: 0.85em; } tbody { tr { @@ -62,9 +63,19 @@ table.table-stretch { } table.table-transactions { - td:nth-of-type(1) { width: 15%; } - td:nth-of-type(2) { width: 15%; } - td:nth-of-type(3) { width: 15%; } - td:nth-of-type(4) { width: 40%; } - td:nth-of-type(5) { width: 15%; } + td:nth-of-type(1) { + width: 15%; + } + td:nth-of-type(2) { + width: 15%; + } + td:nth-of-type(3) { + width: 15%; + } + td:nth-of-type(4) { + width: 40%; + } + td:nth-of-type(5) { + width: 15%; + } } diff --git a/src/renderer/scss/component/_tabs.scss b/src/renderer/scss/component/_tabs.scss index c990c8adf..69f6bc7a3 100644 --- a/src/renderer/scss/component/_tabs.scss +++ b/src/renderer/scss/component/_tabs.scss @@ -1,14 +1,12 @@ /* Tabs */ -nav.sub-header -{ +nav.sub-header { text-transform: uppercase; max-width: $width-page-constrained; margin-bottom: 40px; border-bottom: var(--divider); user-select: none; - > a - { + > a { height: 38px; line-height: 38px; text-align: center; @@ -21,16 +19,13 @@ nav.sub-header color: var(--tab-color); position: relative; - &:first-child - { + &:first-child { margin-left: 0; } - &:last-child - { + &:last-child { margin-right: 0; } - &.sub-header-selected - { + &.sub-header-selected { color: var(--tab-active-color); &:before { width: 100%; @@ -45,8 +40,7 @@ nav.sub-header animation-timing-function: var(--animation-style); } } - &:hover - { + &:hover { color: var(--tab-active-color); } } @@ -60,8 +54,11 @@ nav.sub-header } } - @keyframes activeTab { - from {width: 0;} - to {width: 100%;} + from { + width: 0; + } + to { + width: 100%; + } } diff --git a/src/renderer/scss/component/_tooltip.scss b/src/renderer/scss/component/_tooltip.scss index 58889f657..d017996c1 100644 --- a/src/renderer/scss/component/_tooltip.scss +++ b/src/renderer/scss/component/_tooltip.scss @@ -1,4 +1,4 @@ -@import "../mixin/link.scss"; +@import '../mixin/link.scss'; .tooltip { position: relative; @@ -27,7 +27,7 @@ .tooltip--header .tooltip__link { @include text-link(#aaa); - font-size: calc( var(--font-size) * 3/4 ); + font-size: calc(var(--font-size) * 3/4); margin-left: var(--button-padding); vertical-align: middle; } diff --git a/src/renderer/scss/component/_video.scss b/src/renderer/scss/component/_video.scss index d6021849e..aa449c48e 100644 --- a/src/renderer/scss/component/_video.scss +++ b/src/renderer/scss/component/_video.scss @@ -1,4 +1,3 @@ - $height-video-embedded: $width-page-constrained * 9 / 16; video { @@ -32,13 +31,11 @@ video { height: $height-video-embedded; } } -.video--obscured .video__cover -{ +.video--obscured .video__cover { position: relative; filter: blur(var(--nsfw-blur-intensity)); } - .video__loading-screen { height: 100%; display: flex; diff --git a/src/renderer/scss/mixin/link.scss b/src/renderer/scss/mixin/link.scss index ae6e752da..df55e49ba 100644 --- a/src/renderer/scss/mixin/link.scss +++ b/src/renderer/scss/mixin/link.scss @@ -1,6 +1,5 @@ -@mixin text-link($color: var(--color-primary), $hover-opacity: 0.70) { - .icon - { +@mixin text-link($color: var(--color-primary), $hover-opacity: 0.7) { + .icon { &:first-child { padding-right: 5px; } @@ -15,10 +14,9 @@ text-decoration: none; } } - &:hover - { + &:hover { opacity: $hover-opacity; - transition: opacity var(--transition-duration) var(--transition-type); + transition: opacity var(--transition-duration) var(--transition-type); text-decoration: underline; .icon { text-decoration: none; diff --git a/src/renderer/store.js b/src/renderer/store.js index 9e6176b0e..fc8e5e9f2 100644 --- a/src/renderer/store.js +++ b/src/renderer/store.js @@ -1,29 +1,27 @@ -import { createLogger } from "redux-logger"; -import appReducer from "redux/reducers/app"; -import availabilityReducer from "redux/reducers/availability"; -import claimsReducer from "redux/reducers/claims"; -import contentReducer from "redux/reducers/content"; -import costInfoReducer from "redux/reducers/cost_info"; -import fileInfoReducer from "redux/reducers/file_info"; -import navigationReducer from "redux/reducers/navigation"; -import rewardsReducer from "redux/reducers/rewards"; -import searchReducer from "redux/reducers/search"; -import settingsReducer from "redux/reducers/settings"; -import userReducer from "redux/reducers/user"; -import walletReducer from "redux/reducers/wallet"; -import shapeShiftReducer from "redux/reducers/shape_shift"; -import subscriptionsReducer from "redux/reducers/subscriptions"; -import { persistStore, autoRehydrate } from "redux-persist"; -import createCompressor from "redux-persist-transform-compress"; -import createFilter from "redux-persist-transform-filter"; -import localForage from "localforage"; -import { createStore, applyMiddleware, compose, combineReducers } from "redux"; -import thunk from "redux-thunk"; - -const env = process.env.NODE_ENV || "production" +import { createLogger } from 'redux-logger'; +import appReducer from 'redux/reducers/app'; +import availabilityReducer from 'redux/reducers/availability'; +import claimsReducer from 'redux/reducers/claims'; +import contentReducer from 'redux/reducers/content'; +import costInfoReducer from 'redux/reducers/cost_info'; +import fileInfoReducer from 'redux/reducers/file_info'; +import navigationReducer from 'redux/reducers/navigation'; +import rewardsReducer from 'redux/reducers/rewards'; +import searchReducer from 'redux/reducers/search'; +import settingsReducer from 'redux/reducers/settings'; +import userReducer from 'redux/reducers/user'; +import walletReducer from 'redux/reducers/wallet'; +import shapeShiftReducer from 'redux/reducers/shape_shift'; +import subscriptionsReducer from 'redux/reducers/subscriptions'; +import { persistStore, autoRehydrate } from 'redux-persist'; +import createCompressor from 'redux-persist-transform-compress'; +import createFilter from 'redux-persist-transform-filter'; +import localForage from 'localforage'; +import { createStore, applyMiddleware, compose, combineReducers } from 'redux'; +import thunk from 'redux-thunk'; function isFunction(object) { - return typeof object === "function"; + return typeof object === 'function'; } function isNotFunction(object) { @@ -32,10 +30,8 @@ function isNotFunction(object) { function createBulkThunkMiddleware() { return ({ dispatch, getState }) => next => action => { - if (action.type === "BATCH_ACTIONS") { - action.actions - .filter(isFunction) - .map(actionFn => actionFn(dispatch, getState)); + if (action.type === 'BATCH_ACTIONS') { + action.actions.filter(isFunction).map(actionFn => actionFn(dispatch, getState)); } return next(action); }; @@ -44,10 +40,8 @@ function createBulkThunkMiddleware() { function enableBatching(reducer) { return function batchingReducer(state, action) { switch (action.type) { - case "BATCH_ACTIONS": - return action.actions - .filter(isNotFunction) - .reduce(batchingReducer, state); + case 'BATCH_ACTIONS': + return action.actions.filter(isNotFunction).reduce(batchingReducer, state); default: return reducer(state, action); } @@ -74,13 +68,14 @@ const reducers = combineReducers({ const bulkThunk = createBulkThunkMiddleware(); const middleware = [thunk, bulkThunk]; -if (env === "development") { +if (app.env === 'development') { const logger = createLogger({ collapsed: true, }); middleware.push(logger); } +// eslint-disable-next-line no-underscore-dangle const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore( @@ -88,18 +83,18 @@ const store = createStore( {}, // initial state composeEnhancers( autoRehydrate({ - log: env === "development", + log: app.env === 'development', }), applyMiddleware(...middleware) ) ); const compressor = createCompressor(); -const saveClaimsFilter = createFilter("claims", ["byId", "claimsByUri"]); -const subscriptionsFilter = createFilter("subscriptions", ["subscriptions"]); +const saveClaimsFilter = createFilter('claims', ['byId', 'claimsByUri']); +const subscriptionsFilter = createFilter('subscriptions', ['subscriptions']); const persistOptions = { - whitelist: ["claims", "subscriptions"], + whitelist: ['claims', 'subscriptions'], // Order is important. Needs to be compressed last or other transforms can't // read the data transforms: [saveClaimsFilter, subscriptionsFilter, compressor], @@ -109,7 +104,7 @@ const persistOptions = { window.cacheStore = persistStore(store, persistOptions, err => { if (err) { - console.error("Unable to load saved settings"); + console.error('Unable to load saved SETTINGS'); } }); diff --git a/src/renderer/types/common.js b/src/renderer/types/common.js index ea8c0d815..5f3636de3 100644 --- a/src/renderer/types/common.js +++ b/src/renderer/types/common.js @@ -1,3 +1,5 @@ +// @flow + export type FormikActions = { setSubmitting: boolean => mixed, }; diff --git a/src/renderer/util/batchActions.js b/src/renderer/util/batchActions.js index d8cb486a5..4bc4eee7f 100644 --- a/src/renderer/util/batchActions.js +++ b/src/renderer/util/batchActions.js @@ -1,7 +1,7 @@ // https://github.com/reactjs/redux/issues/911 function batchActions(...actions) { return { - type: "BATCH_ACTIONS", + type: 'BATCH_ACTIONS', actions, }; } diff --git a/src/renderer/util/formatCredits.js b/src/renderer/util/formatCredits.js index fea63a00a..98383c05f 100644 --- a/src/renderer/util/formatCredits.js +++ b/src/renderer/util/formatCredits.js @@ -1,19 +1,16 @@ export function formatCredits(amount, precision) { - return amount.toFixed(precision || 1).replace(/\.?0+$/, ""); + return amount.toFixed(precision || 1).replace(/\.?0+$/, ''); } -export function formatFullPrice(amount, precision) { - let formated = ""; +export function formatFullPrice(amount, precision = 1) { + let formated = ''; - const quantity = amount.toString().split("."); + const quantity = amount.toString().split('.'); const fraction = quantity[1]; if (fraction) { - // Set precision - precision = precision || 1; - - const decimals = fraction.split(""); - const first = decimals.filter(number => number != "0")[0]; + const decimals = fraction.split(''); + const first = decimals.filter(number => number !== '0')[0]; const index = decimals.indexOf(first); // Set format fraction diff --git a/src/renderer/util/query_params.js b/src/renderer/util/query_params.js index 76ed1c754..e7f04d150 100644 --- a/src/renderer/util/query_params.js +++ b/src/renderer/util/query_params.js @@ -1,26 +1,28 @@ export function parseQueryParams(queryString) { - if (queryString === "") return {}; + if (queryString === '') return {}; const parts = queryString - .split("?") + .split('?') .pop() - .split("&") - .map(p => p.split("=")); + .split('&') + .map(p => p.split('=')); const params = {}; - parts.forEach(arr => { - params[arr[0]] = arr[1]; + parts.forEach(array => { + const [first, second] = array; + params[first] = second; }); return params; } export function toQueryString(params) { - if (!params) return ""; + if (!params) return ''; const parts = []; - for (const key in params) { - if (params.hasOwnProperty(key) && params[key]) { + Object.keys(params).forEach(key => { + if (Object.prototype.hasOwnProperty.call(params, key) && params[key]) { parts.push(`${key}=${params[key]}`); } - } - return parts.join("&"); + }); + + return parts.join('&'); } diff --git a/src/renderer/util/redux-utils.js b/src/renderer/util/redux-utils.js index b50e55812..4ff5adc21 100644 --- a/src/renderer/util/redux-utils.js +++ b/src/renderer/util/redux-utils.js @@ -1,10 +1,7 @@ // util for creating reducers // based off of redux-actions // https://redux-actions.js.org/docs/api/handleAction.html#handleactions -export const handleActions = (actionMap, defaultState) => ( - state = defaultState, - action -) => { +const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { const handler = actionMap[action.type]; if (handler) { @@ -16,3 +13,5 @@ export const handleActions = (actionMap, defaultState) => ( // returning a copy here breaks redux-persist return state; }; + +export { handleActions as default }; diff --git a/src/renderer/util/setBadge.js b/src/renderer/util/setBadge.js index 372b8d4e1..005e63a11 100644 --- a/src/renderer/util/setBadge.js +++ b/src/renderer/util/setBadge.js @@ -1,7 +1,7 @@ -const { remote } = require("electron"); +const { remote } = require('electron'); const application = remote.app; -const dock = application.dock; +const { dock } = application; const win = remote.BrowserWindow.getFocusedWindow(); const setBadge = text => { if (!dock) return; diff --git a/src/renderer/util/setProgressBar.js b/src/renderer/util/setProgressBar.js index 942d4288c..936a90f47 100644 --- a/src/renderer/util/setProgressBar.js +++ b/src/renderer/util/setProgressBar.js @@ -1,6 +1,5 @@ -const { remote } = require("electron"); +import { remote } from 'electron'; -const application = remote.app; const win = remote.getCurrentWindow(); const setProgressBar = progress => { diff --git a/src/renderer/util/shape_shift.js b/src/renderer/util/shape_shift.js index 5b04100e3..b61880e35 100644 --- a/src/renderer/util/shape_shift.js +++ b/src/renderer/util/shape_shift.js @@ -19,7 +19,7 @@ const validateAddress = (coinType, address) => { return coinRegex.test(address); }; -export const validateShapeShiftForm = (vals, props) => { +export const validateShapeShiftForm = vals => { const errors = {}; if (!vals.returnAddress) { @@ -36,13 +36,13 @@ export const validateShapeShiftForm = (vals, props) => { }; const exampleCoinAddresses = { - BTC: "1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq", - BCH: "1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq", - ETH: "0x8507cA6a274123fC8f80d929AF9D83602bC4e8cC", - DASH: "XedBP7vLPFXbS3URjrH2Z57Fg9SWftBmQ6", - LTC: "LgZivMvFMTDoqcA5weCQ2QrmRp7pa56bBk", + BTC: '1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq', + BCH: '1745oPaHeW7Fmpb1fUKTtasYfxr4zu9bwq', + ETH: '0x8507cA6a274123fC8f80d929AF9D83602bC4e8cC', + DASH: 'XedBP7vLPFXbS3URjrH2Z57Fg9SWftBmQ6', + LTC: 'LgZivMvFMTDoqcA5weCQ2QrmRp7pa56bBk', XMR: - "466XMeJEcowYGx7RzUJj3VDWBZgRWErVQQX6tHYbsacS5QF6v3tidE6LZZnTJgzeEh6bKEEJ6GC9jHirrUKvJwVKVj9e7jm", + '466XMeJEcowYGx7RzUJj3VDWBZgRWErVQQX6tHYbsacS5QF6v3tidE6LZZnTJgzeEh6bKEEJ6GC9jHirrUKvJwVKVj9e7jm', }; export const getExampleAddress = coin => exampleCoinAddresses[coin]; diff --git a/src/renderer/util/throttle.js b/src/renderer/util/throttle.js index bbb5e316c..941633deb 100644 --- a/src/renderer/util/throttle.js +++ b/src/renderer/util/throttle.js @@ -6,21 +6,25 @@ // as much as it can, without ever going more than once per `wait` duration; // but if you'd like to disable the execution on the leading edge, pass // `{leading: false}`. To disable execution on the trailing edge, ditto. -export default function throttle(func, wait, options) { - let timeout, context, args, result; +export default function throttle(func, wait, options = {}) { + let timeout; + let context; + let args; + let result; let previous = 0; const getNow = () => new Date().getTime(); - if (!options) options = {}; - const later = function() { previous = options.leading === false ? 0 : getNow(); timeout = null; result = func.apply(context, args); - if (!timeout) context = args = null; + if (!timeout) { + context = null; + args = null; + } }; - const throttled = function() { + const throttled = function(...funcArgs) { const now = getNow(); if (!previous && options.leading === false) previous = now; @@ -28,7 +32,7 @@ export default function throttle(func, wait, options) { const remaining = wait - (now - previous); context = this; - args = arguments; + args = funcArgs; if (remaining <= 0 || remaining > wait) { if (timeout) { @@ -39,7 +43,10 @@ export default function throttle(func, wait, options) { previous = now; result = func.apply(context, args); - if (!timeout) context = args = null; + if (!timeout) { + context = null; + args = null; + } } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } @@ -49,7 +56,9 @@ export default function throttle(func, wait, options) { throttled.cancel = function() { clearTimeout(timeout); previous = 0; - timeout = context = args = null; + timeout = null; + context = null; + args = null; }; return throttled; diff --git a/webpack.renderer.additions.js b/webpack.renderer.additions.js index d3465623a..b18039ad1 100644 --- a/webpack.renderer.additions.js +++ b/webpack.renderer.additions.js @@ -1,7 +1,7 @@ -const Path = require("path"); -const FlowFlowPlugin = require("./flowtype-plugin"); +const Path = require('path'); +const FlowFlowPlugin = require('./flowtype-plugin'); -const ELECTRON_RENDERER_PROCESS_ROOT = Path.resolve(__dirname, "src/renderer/"); +const ELECTRON_RENDERER_PROCESS_ROOT = Path.resolve(__dirname, 'src/renderer/'); module.exports = { // This rule is temporarily necessary until https://github.com/electron-userland/electron-webpack/issues/60 is fixed. @@ -9,27 +9,24 @@ module.exports = { rules: [ { test: /\.jsx?$/, - loader: "babel-loader", + loader: 'babel-loader', options: { - presets: ["env", "react", "stage-2"], + presets: ['env', 'react', 'stage-2'], }, }, ], }, // This allows imports to be made from the renderer process root (https://moduscreate.com/blog/es6-es2015-import-no-relative-path-webpack/). resolve: { - modules: [ELECTRON_RENDERER_PROCESS_ROOT, "node_modules", __dirname], - extensions: [".js", ".jsx", ".scss"], + modules: [ELECTRON_RENDERER_PROCESS_ROOT, 'node_modules', __dirname], + extensions: ['.js', '.jsx', '.scss'], }, }; -if (process.env.NODE_ENV === "development") { - module.exports = { - ...module.exports, - plugins: [ - new FlowFlowPlugin({ - warn: true, - }), - ] - }; +if (process.env.NODE_ENV === 'development') { + module.exports.plugins = [ + new FlowFlowPlugin({ + warn: true, + }), + ]; } diff --git a/yarn.lock b/yarn.lock index 690ed20b2..23c03e6d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5085,9 +5085,9 @@ keypress@0.1.x: version "0.1.0" resolved "https://registry.yarnpkg.com/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a" -keytar@^4.0.3: - version "4.0.5" - resolved "https://registry.yarnpkg.com/keytar/-/keytar-4.0.5.tgz#cc1255ef06eeea1a12440b773f7d4a375b048729" +keytar@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/keytar/-/keytar-4.1.0.tgz#9e3933e489d656de1a868e1293709313044989d7" dependencies: nan "2.5.1" From e103778b8a7b6d6cebc34a52b43d514cb1f51260 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 21 Dec 2017 18:08:54 -0300 Subject: [PATCH 28/66] Prettyprint and autolint component files --- src/renderer/component/address/index.js | 6 +- src/renderer/component/address/view.jsx | 18 +- src/renderer/component/app/index.js | 14 +- src/renderer/component/app/view.jsx | 26 +- src/renderer/component/cardMedia/index.js | 6 +- src/renderer/component/cardMedia/view.jsx | 35 +- src/renderer/component/cardVerify/index.js | 8 +- src/renderer/component/cardVerify/view.jsx | 38 +- src/renderer/component/channelTile/index.js | 16 +- src/renderer/component/channelTile/view.jsx | 22 +- src/renderer/component/common.js | 40 +- src/renderer/component/common/spinner.jsx | 28 +- src/renderer/component/dateTime/index.js | 15 +- src/renderer/component/dateTime/view.jsx | 20 +- src/renderer/component/file-selector.js | 23 +- src/renderer/component/fileActions/index.js | 14 +- src/renderer/component/fileActions/view.jsx | 18 +- src/renderer/component/fileCard/index.js | 24 +- src/renderer/component/fileCard/view.jsx | 47 +-- src/renderer/component/fileDetails/index.js | 12 +- src/renderer/component/fileDetails/view.jsx | 47 +-- .../component/fileDownloadLink/index.js | 16 +- .../component/fileDownloadLink/view.jsx | 49 +-- src/renderer/component/fileList/index.js | 6 +- src/renderer/component/fileList/view.jsx | 59 ++- .../component/fileListSearch/index.js | 13 +- .../component/fileListSearch/view.jsx | 26 +- src/renderer/component/filePrice/index.js | 12 +- src/renderer/component/filePrice/view.jsx | 12 +- src/renderer/component/fileTile/index.js | 24 +- src/renderer/component/fileTile/view.jsx | 70 ++-- src/renderer/component/form.js | 54 +-- src/renderer/component/formField/index.js | 6 +- src/renderer/component/formField/view.jsx | 92 ++--- .../component/formFieldPrice/index.js | 6 +- .../component/formFieldPrice/view.jsx | 27 +- src/renderer/component/header/index.js | 25 +- src/renderer/component/header/view.jsx | 38 +- src/renderer/component/icon/index.js | 6 +- src/renderer/component/icon/view.jsx | 17 +- src/renderer/component/inviteList/index.js | 11 +- src/renderer/component/inviteList/view.jsx | 65 ++- src/renderer/component/inviteNew/index.js | 14 +- src/renderer/component/inviteNew/view.jsx | 24 +- src/renderer/component/link/index.js | 8 +- src/renderer/component/link/view.jsx | 22 +- .../component/linkTransaction/index.js | 6 +- .../component/linkTransaction/view.jsx | 6 +- src/renderer/component/load_screen.js | 14 +- src/renderer/component/menu.js | 27 +- src/renderer/component/nsfwOverlay/index.js | 10 +- src/renderer/component/nsfwOverlay/view.jsx | 32 +- src/renderer/component/publishForm/index.js | 8 +- .../publishForm/internal/channelSection.jsx | 60 ++- src/renderer/component/publishForm/view.jsx | 377 ++++++++---------- src/renderer/component/rewardLink/index.js | 15 +- src/renderer/component/rewardLink/view.jsx | 24 +- .../component/rewardListClaimed/index.js | 8 +- .../component/rewardListClaimed/view.jsx | 36 +- src/renderer/component/rewardSummary/index.js | 8 +- src/renderer/component/rewardSummary/view.jsx | 25 +- src/renderer/component/rewardTile/index.js | 6 +- src/renderer/component/rewardTile/view.jsx | 14 +- src/renderer/component/router/index.js | 11 +- src/renderer/component/router/view.jsx | 40 +- src/renderer/component/shapeShift/index.js | 12 +- .../shapeShift/internal/active-shift.jsx | 47 +-- .../component/shapeShift/internal/form.jsx | 23 +- .../shapeShift/internal/market_info.jsx | 12 +- src/renderer/component/shapeShift/view.jsx | 49 +-- src/renderer/component/snackBar/index.js | 10 +- src/renderer/component/snackBar/view.jsx | 12 +- src/renderer/component/splash/index.js | 13 +- src/renderer/component/splash/view.jsx | 60 ++- src/renderer/component/subHeader/index.js | 13 +- src/renderer/component/subHeader/view.jsx | 18 +- .../component/subscribeButton/index.js | 11 +- .../component/subscribeButton/view.jsx | 39 +- src/renderer/component/theme/index.js | 8 +- src/renderer/component/theme/view.jsx | 11 +- src/renderer/component/tooltip.js | 8 +- .../component/transactionList/index.js | 14 +- .../internal/TransactionListItem.jsx | 61 +-- .../component/transactionList/view.jsx | 60 ++- .../component/transactionListRecent/index.js | 10 +- .../component/transactionListRecent/view.jsx | 20 +- .../component/truncatedMarkdown/index.js | 6 +- .../component/truncatedMarkdown/view.jsx | 23 +- src/renderer/component/uriIndicator/index.js | 14 +- src/renderer/component/uriIndicator/view.jsx | 44 +- src/renderer/component/userEmailNew/index.js | 17 +- src/renderer/component/userEmailNew/view.jsx | 17 +- .../component/userEmailVerify/index.js | 14 +- .../component/userEmailVerify/view.jsx | 29 +- src/renderer/component/userVerify/index.js | 16 +- src/renderer/component/userVerify/view.jsx | 74 ++-- src/renderer/component/video/index.js | 25 +- .../video/internal/loading-screen.jsx | 4 +- .../component/video/internal/play-button.jsx | 22 +- .../component/video/internal/player.jsx | 74 ++-- src/renderer/component/video/view.jsx | 56 +-- src/renderer/component/walletAddress/index.js | 13 +- src/renderer/component/walletAddress/view.jsx | 16 +- src/renderer/component/walletBalance/index.js | 8 +- src/renderer/component/walletBalance/view.jsx | 16 +- src/renderer/component/walletSend/index.js | 13 +- src/renderer/component/walletSend/view.jsx | 31 +- src/renderer/component/walletSendTip/index.js | 15 +- src/renderer/component/walletSendTip/view.jsx | 36 +- src/renderer/component/wunderbar/index.js | 21 +- src/renderer/component/wunderbar/view.jsx | 51 +-- src/renderer/modal/modal.js | 40 +- .../modal/modalAffirmPurchase/index.js | 12 +- .../modal/modalAffirmPurchase/view.jsx | 18 +- src/renderer/modal/modalAuthFailure/index.js | 8 +- src/renderer/modal/modalAuthFailure/view.jsx | 16 +- src/renderer/modal/modalCreditIntro/index.js | 22 +- src/renderer/modal/modalCreditIntro/view.jsx | 39 +- src/renderer/modal/modalDownloading/index.js | 13 +- src/renderer/modal/modalDownloading/view.jsx | 36 +- .../modal/modalEmailCollection/index.js | 14 +- .../modal/modalEmailCollection/view.jsx | 25 +- src/renderer/modal/modalError/index.js | 8 +- src/renderer/modal/modalError/view.jsx | 44 +- src/renderer/modal/modalFileTimeout/index.js | 10 +- src/renderer/modal/modalFileTimeout/view.jsx | 12 +- src/renderer/modal/modalFirstReward/index.js | 12 +- src/renderer/modal/modalFirstReward/view.jsx | 18 +- .../modal/modalIncompatibleDaemon/index.js | 8 +- .../modal/modalIncompatibleDaemon/view.jsx | 19 +- src/renderer/modal/modalRemoveFile/index.js | 17 +- src/renderer/modal/modalRemoveFile/view.jsx | 31 +- src/renderer/modal/modalRevokeClaim/index.js | 12 +- src/renderer/modal/modalRevokeClaim/view.jsx | 60 ++- .../modalRewardApprovalRequired/index.js | 10 +- .../modalRewardApprovalRequired/view.jsx | 14 +- src/renderer/modal/modalRouter/index.js | 39 +- src/renderer/modal/modalRouter/view.jsx | 56 +-- .../modal/modalTransactionFailed/index.js | 8 +- .../modal/modalTransactionFailed/view.jsx | 12 +- src/renderer/modal/modalUpgrade/index.js | 8 +- src/renderer/modal/modalUpgrade/view.jsx | 27 +- src/renderer/modal/modalWelcome/index.js | 14 +- src/renderer/modal/modalWelcome/view.jsx | 28 +- src/renderer/page/auth/index.js | 12 +- src/renderer/page/auth/view.jsx | 37 +- src/renderer/page/backup/index.js | 8 +- src/renderer/page/backup/view.jsx | 22 +- src/renderer/page/channel/index.js | 24 +- src/renderer/page/channel/view.jsx | 31 +- src/renderer/page/discover/index.js | 13 +- src/renderer/page/discover/view.jsx | 102 ++--- src/renderer/page/file/index.js | 25 +- src/renderer/page/file/view.jsx | 67 ++-- src/renderer/page/fileListDownloaded/index.js | 19 +- src/renderer/page/fileListDownloaded/view.jsx | 36 +- src/renderer/page/fileListPublished/index.js | 19 +- src/renderer/page/fileListPublished/view.jsx | 36 +- src/renderer/page/getCredits/index.js | 6 +- src/renderer/page/getCredits/view.jsx | 81 ++-- src/renderer/page/help/index.js | 14 +- src/renderer/page/help/view.jsx | 105 +++-- src/renderer/page/invite/index.js | 10 +- src/renderer/page/invite/view.jsx | 20 +- src/renderer/page/publish/index.js | 23 +- src/renderer/page/publish/view.jsx | 8 +- src/renderer/page/report.js | 36 +- src/renderer/page/rewards/index.js | 19 +- src/renderer/page/rewards/view.jsx | 106 ++--- src/renderer/page/search/index.js | 10 +- src/renderer/page/search/view.jsx | 27 +- src/renderer/page/sendCredits/index.js | 6 +- src/renderer/page/sendCredits/view.jsx | 24 +- src/renderer/page/settings/index.js | 24 +- src/renderer/page/settings/view.jsx | 96 ++--- src/renderer/page/show/index.js | 12 +- src/renderer/page/show/view.jsx | 24 +- src/renderer/page/subscriptions/index.js | 20 +- src/renderer/page/subscriptions/view.jsx | 27 +- src/renderer/page/transactionHistory/index.js | 13 +- src/renderer/page/transactionHistory/view.jsx | 23 +- src/renderer/page/wallet/index.js | 6 +- src/renderer/page/wallet/view.jsx | 32 +- 183 files changed, 2122 insertions(+), 2883 deletions(-) diff --git a/src/renderer/component/address/index.js b/src/renderer/component/address/index.js index 00bec962e..b861b75c5 100644 --- a/src/renderer/component/address/index.js +++ b/src/renderer/component/address/index.js @@ -1,6 +1,6 @@ -import { connect } from "react-redux"; -import { doShowSnackBar } from "redux/actions/app"; -import Address from "./view"; +import { connect } from 'react-redux'; +import { doShowSnackBar } from 'redux/actions/app'; +import Address from './view'; export default connect(null, { doShowSnackBar, diff --git a/src/renderer/component/address/view.jsx b/src/renderer/component/address/view.jsx index 96049eb35..65ea563c0 100644 --- a/src/renderer/component/address/view.jsx +++ b/src/renderer/component/address/view.jsx @@ -1,8 +1,8 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { clipboard } from "electron"; -import Link from "component/link"; -import classnames from "classnames"; +import React from 'react'; +import PropTypes from 'prop-types'; +import { clipboard } from 'electron'; +import Link from 'component/link'; +import classnames from 'classnames'; export default class Address extends React.PureComponent { static propTypes = { @@ -21,8 +21,8 @@ export default class Address extends React.PureComponent { return (
{ @@ -32,7 +32,7 @@ export default class Address extends React.PureComponent { this._inputElem.select(); }} readOnly="readonly" - value={address || ""} + value={address || ''} /> {showCopyButton && ( @@ -41,7 +41,7 @@ export default class Address extends React.PureComponent { icon="clipboard" onClick={() => { clipboard.writeText(address); - doShowSnackBar({ message: __("Address copied") }); + doShowSnackBar({ message: __('Address copied') }); }} /> diff --git a/src/renderer/component/app/index.js b/src/renderer/component/app/index.js index 66b50bb71..c7173f606 100644 --- a/src/renderer/component/app/index.js +++ b/src/renderer/component/app/index.js @@ -1,14 +1,14 @@ -import React from "react"; -import { connect } from "react-redux"; +import React from 'react'; +import { connect } from 'react-redux'; import { selectPageTitle, selectHistoryIndex, selectActiveHistoryEntry, -} from "redux/selectors/navigation"; -import { selectUser } from "redux/selectors/user"; -import { doAlertError } from "redux/actions/app"; -import { doRecordScroll } from "redux/actions/navigation"; -import App from "./view"; +} from 'redux/selectors/navigation'; +import { selectUser } from 'redux/selectors/user'; +import { doAlertError } from 'redux/actions/app'; +import { doRecordScroll } from 'redux/actions/navigation'; +import App from './view'; const select = (state, props) => ({ pageTitle: selectPageTitle(state), diff --git a/src/renderer/component/app/view.jsx b/src/renderer/component/app/view.jsx index 11e66e252..fb43b6574 100644 --- a/src/renderer/component/app/view.jsx +++ b/src/renderer/component/app/view.jsx @@ -1,10 +1,10 @@ -import React from "react"; -import Router from "component/router/index"; -import Header from "component/header"; -import Theme from "component/theme"; -import ModalRouter from "modal/modalRouter"; -import ReactModal from "react-modal"; -import throttle from "util/throttle"; +import React from 'react'; +import Router from 'component/router/index'; +import Header from 'component/header'; +import Theme from 'component/theme'; +import ModalRouter from 'modal/modalRouter'; +import ReactModal from 'react-modal'; +import throttle from 'util/throttle'; class App extends React.PureComponent { constructor() { @@ -15,25 +15,25 @@ class App extends React.PureComponent { componentWillMount() { const { alertError } = this.props; - document.addEventListener("unhandledError", event => { + document.addEventListener('unhandledError', event => { alertError(event.detail); }); } componentDidMount() { const { recordScroll } = this.props; - const mainContent = document.getElementById("main-content"); + const mainContent = document.getElementById('main-content'); this.mainContent = mainContent; const scrollListener = () => recordScroll(this.mainContent.scrollTop); - this.mainContent.addEventListener("scroll", throttle(scrollListener, 750)); + this.mainContent.addEventListener('scroll', throttle(scrollListener, 750)); - ReactModal.setAppElement("#window"); //fuck this + ReactModal.setAppElement('#window'); // fuck this } componentWillUnmount() { - this.mainContent.removeEventListener("scroll", this.scrollListener); + this.mainContent.removeEventListener('scroll', this.scrollListener); } componentWillReceiveProps(props) { @@ -50,7 +50,7 @@ class App extends React.PureComponent { } setTitleFromProps(props) { - window.document.title = props.pageTitle || "LBRY"; + window.document.title = props.pageTitle || 'LBRY'; } render() { diff --git a/src/renderer/component/cardMedia/index.js b/src/renderer/component/cardMedia/index.js index 3616b0331..1f7988712 100644 --- a/src/renderer/component/cardMedia/index.js +++ b/src/renderer/component/cardMedia/index.js @@ -1,6 +1,6 @@ -import React from "react"; -import { connect } from "react-redux"; -import CardMedia from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import CardMedia from './view'; const select = state => ({}); const perform = dispatch => ({}); diff --git a/src/renderer/component/cardMedia/view.jsx b/src/renderer/component/cardMedia/view.jsx index d0f45f4ac..06f80f1d7 100644 --- a/src/renderer/component/cardMedia/view.jsx +++ b/src/renderer/component/cardMedia/view.jsx @@ -1,18 +1,18 @@ -import React from "react"; +import React from 'react'; class CardMedia extends React.PureComponent { static AUTO_THUMB_CLASSES = [ - "purple", - "red", - "pink", - "indigo", - "blue", - "light-blue", - "cyan", - "teal", - "green", - "yellow", - "orange", + 'purple', + 'red', + 'pink', + 'indigo', + 'blue', + 'light-blue', + 'cyan', + 'teal', + 'green', + 'yellow', + 'orange', ]; componentWillMount() { @@ -29,12 +29,7 @@ class CardMedia extends React.PureComponent { const atClass = this.state.autoThumbClass; if (thumbnail) { - return ( -
- ); + return
; } return ( @@ -42,8 +37,8 @@ class CardMedia extends React.PureComponent {
{title && title - .replace(/\s+/g, "") - .substring(0, Math.min(title.replace(" ", "").length, 5)) + .replace(/\s+/g, '') + .substring(0, Math.min(title.replace(' ', '').length, 5)) .toUpperCase()}
diff --git a/src/renderer/component/cardVerify/index.js b/src/renderer/component/cardVerify/index.js index 53bdf05b9..390622f3d 100644 --- a/src/renderer/component/cardVerify/index.js +++ b/src/renderer/component/cardVerify/index.js @@ -1,7 +1,7 @@ -import React from "react"; -import { connect } from "react-redux"; -import { selectUserEmail } from "redux/selectors/user"; -import CardVerify from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import { selectUserEmail } from 'redux/selectors/user'; +import CardVerify from './view'; const select = state => ({ email: selectUserEmail(state), diff --git a/src/renderer/component/cardVerify/view.jsx b/src/renderer/component/cardVerify/view.jsx index 4494cbf6c..4690b61d2 100644 --- a/src/renderer/component/cardVerify/view.jsx +++ b/src/renderer/component/cardVerify/view.jsx @@ -1,6 +1,6 @@ -import React from "react"; -import PropTypes from "prop-types"; -import Link from "component/link"; +import React from 'react'; +import PropTypes from 'prop-types'; +import Link from 'component/link'; let scriptLoading = false; let scriptLoaded = false; @@ -48,8 +48,8 @@ class CardVerify extends React.Component { scriptLoading = true; - const script = document.createElement("script"); - script.src = "https://checkout.stripe.com/checkout.js"; + const script = document.createElement('script'); + script.src = 'https://checkout.stripe.com/checkout.js'; script.async = 1; this.loadPromise = (() => { @@ -69,12 +69,8 @@ class CardVerify extends React.Component { }; }); const wrappedPromise = new Promise((accept, cancel) => { - promise.then( - () => (canceled ? cancel({ isCanceled: true }) : accept()) - ); - promise.catch( - error => (canceled ? cancel({ isCanceled: true }) : cancel(error)) - ); + promise.then(() => (canceled ? cancel({ isCanceled: true }) : accept())); + promise.catch(error => (canceled ? cancel({ isCanceled: true }) : cancel(error))); }); return { @@ -85,9 +81,7 @@ class CardVerify extends React.Component { }; })(); - this.loadPromise.promise - .then(this.onScriptLoaded) - .catch(this.onScriptError); + this.loadPromise.promise.then(this.onScriptLoaded).catch(this.onScriptError); document.body.appendChild(script); } @@ -119,7 +113,7 @@ class CardVerify extends React.Component { }; onScriptError = (...args) => { - throw new Error("Unable to load credit validation script."); + throw new Error('Unable to load credit validation script.'); }; onClosed = () => { @@ -139,10 +133,10 @@ class CardVerify extends React.Component { CardVerify.stripeHandler.open({ allowRememberMe: false, closed: this.onClosed, - description: __("Confirm Identity"), + description: __('Confirm Identity'), email: this.props.email, - locale: "auto", - panelLabel: "Verify", + locale: 'auto', + panelLabel: 'Verify', token: this.props.token, zipCode: true, }); @@ -151,9 +145,7 @@ class CardVerify extends React.Component { onClick = () => { if (scriptDidError) { try { - throw new Error( - "Tried to call onClick, but StripeCheckout failed to load" - ); + throw new Error('Tried to call onClick, but StripeCheckout failed to load'); } catch (x) {} } else if (CardVerify.stripeHandler) { this.showStripeDialog(); @@ -168,9 +160,7 @@ class CardVerify extends React.Component { button="alt" label={this.props.label} icon="icon-lock" - disabled={ - this.props.disabled || this.state.open || this.hasPendingClick - } + disabled={this.props.disabled || this.state.open || this.hasPendingClick} onClick={this.onClick.bind(this)} /> ); diff --git a/src/renderer/component/channelTile/index.js b/src/renderer/component/channelTile/index.js index 4c86e8b14..51a4835f6 100644 --- a/src/renderer/component/channelTile/index.js +++ b/src/renderer/component/channelTile/index.js @@ -1,11 +1,11 @@ -import React from "react"; -import { connect } from "react-redux"; -import { makeSelectClaimForUri } from "redux/selectors/claims"; -import { doNavigate } from "redux/actions/navigation"; -import { doResolveUri } from "redux/actions/content"; -import { makeSelectTotalItemsForChannel } from "redux/selectors/content"; -import { makeSelectIsUriResolving } from "redux/selectors/content"; -import ChannelTile from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import { makeSelectClaimForUri } from 'redux/selectors/claims'; +import { doNavigate } from 'redux/actions/navigation'; +import { doResolveUri } from 'redux/actions/content'; +import { makeSelectTotalItemsForChannel } from 'redux/selectors/content'; +import { makeSelectIsUriResolving } from 'redux/selectors/content'; +import ChannelTile from './view'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), diff --git a/src/renderer/component/channelTile/view.jsx b/src/renderer/component/channelTile/view.jsx index e4a4ed8be..73efed63a 100644 --- a/src/renderer/component/channelTile/view.jsx +++ b/src/renderer/component/channelTile/view.jsx @@ -1,6 +1,6 @@ -import React from "react"; -import CardMedia from "component/cardMedia"; -import { TruncatedText, BusyMessage } from "component/common.js"; +import React from 'react'; +import CardMedia from 'component/cardMedia'; +import { TruncatedText, BusyMessage } from 'component/common.js'; class ChannelTile extends React.PureComponent { componentDidMount() { @@ -26,12 +26,12 @@ class ChannelTile extends React.PureComponent { channelId = claim.claim_id; } - let onClick = () => navigate("/show", { uri }); + const onClick = () => navigate('/show', { uri }); return (
-
+
{channelName && }
@@ -40,19 +40,15 @@ class ChannelTile extends React.PureComponent {
- {isResolvingUri && ( - - )} + {isResolvingUri && } {totalItems > 0 && ( - This is a channel with {totalItems}{" "} - {totalItems === 1 ? " item" : " items"} inside of it. + This is a channel with {totalItems} {totalItems === 1 ? ' item' : ' items'}{' '} + inside of it. )} {!isResolvingUri && - !totalItems && ( - This is an empty channel. - )} + !totalItems && This is an empty channel.}
diff --git a/src/renderer/component/common.js b/src/renderer/component/common.js index 681fc8ab1..bf4a4d8ce 100644 --- a/src/renderer/component/common.js +++ b/src/renderer/component/common.js @@ -1,7 +1,7 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { formatCredits, formatFullPrice } from "util/formatCredits"; -import lbry from "../lbry.js"; +import React from 'react'; +import PropTypes from 'prop-types'; +import { formatCredits, formatFullPrice } from 'util/formatCredits'; +import lbry from '../lbry.js'; // component/icon.js export class Icon extends React.PureComponent { @@ -13,9 +13,9 @@ export class Icon extends React.PureComponent { render() { const { fixed, className } = this.props; - const spanClassName = `icon ${ - "fixed" in this.props ? "icon-fixed-width " : "" - }${this.props.icon} ${this.props.className || ""}`; + const spanClassName = `icon ${'fixed' in this.props ? 'icon-fixed-width ' : ''}${ + this.props.icon + } ${this.props.className || ''}`; return ; } } @@ -31,10 +31,7 @@ export class TruncatedText extends React.PureComponent { render() { return ( - + {this.props.children} ); @@ -70,14 +67,14 @@ export class CreditAmount extends React.PureComponent { showFree: PropTypes.bool, showFullPrice: PropTypes.bool, showPlus: PropTypes.bool, - look: PropTypes.oneOf(["indicator", "plain", "fee"]), + look: PropTypes.oneOf(['indicator', 'plain', 'fee']), }; static defaultProps = { precision: 2, label: true, showFree: false, - look: "indicator", + look: 'indicator', showFullPrice: false, showPlus: false, }; @@ -100,13 +97,13 @@ export class CreditAmount extends React.PureComponent { let amountText; if (this.props.showFree && parseFloat(this.props.amount) === 0) { - amountText = __("free"); + amountText = __('free'); } else { if (this.props.label) { const label = - typeof this.props.label === "string" + typeof this.props.label === 'string' ? this.props.label - : parseFloat(amount) == 1 ? __("credit") : __("credits"); + : parseFloat(amount) == 1 ? __('credit') : __('credits'); amountText = `${formattedAmount} ${label}`; } else { @@ -118,15 +115,12 @@ export class CreditAmount extends React.PureComponent { } return ( - + {amountText} {this.props.isEstimate ? ( * @@ -152,7 +146,7 @@ export class Thumbnail extends React.PureComponent { constructor(props) { super(props); - this._defaultImageUri = lbry.imagePath("default-thumb.svg"); + this._defaultImageUri = lbry.imagePath('default-thumb.svg'); this._maxLoadTime = 10000; this._isMounted = false; @@ -177,7 +171,7 @@ export class Thumbnail extends React.PureComponent { } render() { - const className = this.props.className ? this.props.className : "", + const className = this.props.className ? this.props.className : '', otherProps = Object.assign({}, this.props); delete otherProps.className; return ( diff --git a/src/renderer/component/common/spinner.jsx b/src/renderer/component/common/spinner.jsx index 8863459c8..14938f9b9 100644 --- a/src/renderer/component/common/spinner.jsx +++ b/src/renderer/component/common/spinner.jsx @@ -1,16 +1,14 @@ -import React from "react"; -import classnames from "classnames"; +import React from 'react'; +import classnames from 'classnames'; -export default ({ dark, className }) => { - return ( -
- ); -}; +export default ({ dark, className }) => ( +
+); diff --git a/src/renderer/component/dateTime/index.js b/src/renderer/component/dateTime/index.js index dbef1e030..06009a4ca 100644 --- a/src/renderer/component/dateTime/index.js +++ b/src/renderer/component/dateTime/index.js @@ -1,14 +1,11 @@ -import React from "react"; -import { connect } from "react-redux"; -import { makeSelectBlockDate } from "redux/selectors/wallet"; -import { doFetchBlock } from "redux/actions/wallet"; -import DateTime from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import { makeSelectBlockDate } from 'redux/selectors/wallet'; +import { doFetchBlock } from 'redux/actions/wallet'; +import DateTime from './view'; const select = (state, props) => ({ - date: - !props.date && props.block - ? makeSelectBlockDate(props.block)(state) - : props.date, + date: !props.date && props.block ? makeSelectBlockDate(props.block)(state) : props.date, }); const perform = dispatch => ({ diff --git a/src/renderer/component/dateTime/view.jsx b/src/renderer/component/dateTime/view.jsx index b5dff1239..83f7fa755 100644 --- a/src/renderer/component/dateTime/view.jsx +++ b/src/renderer/component/dateTime/view.jsx @@ -1,15 +1,15 @@ -import React from "react"; +import React from 'react'; class DateTime extends React.PureComponent { - static SHOW_DATE = "date"; - static SHOW_TIME = "time"; - static SHOW_BOTH = "both"; + static SHOW_DATE = 'date'; + static SHOW_TIME = 'time'; + static SHOW_BOTH = 'both'; static defaultProps = { formatOptions: { - month: "long", - day: "numeric", - year: "numeric", + month: 'long', + day: 'numeric', + year: 'numeric', }, }; @@ -37,12 +37,12 @@ class DateTime extends React.PureComponent { {date && (show == DateTime.SHOW_BOTH || show === DateTime.SHOW_DATE) && - date.toLocaleDateString([locale, "en-US"], formatOptions)} - {show == DateTime.SHOW_BOTH && " "} + date.toLocaleDateString([locale, 'en-US'], formatOptions)} + {show == DateTime.SHOW_BOTH && ' '} {date && (show == DateTime.SHOW_BOTH || show === DateTime.SHOW_TIME) && date.toLocaleTimeString()} - {!date && "..."} + {!date && '...'} ); } diff --git a/src/renderer/component/file-selector.js b/src/renderer/component/file-selector.js index 5b5f06cf6..18284268b 100644 --- a/src/renderer/component/file-selector.js +++ b/src/renderer/component/file-selector.js @@ -1,17 +1,17 @@ -import React from "react"; -import PropTypes from "prop-types"; +import React from 'react'; +import PropTypes from 'prop-types'; -const { remote } = require("electron"); +const { remote } = require('electron'); class FileSelector extends React.PureComponent { static propTypes = { - type: PropTypes.oneOf(["file", "directory"]), + type: PropTypes.oneOf(['file', 'directory']), initPath: PropTypes.string, onFileChosen: PropTypes.func, }; static defaultProps = { - type: "file", + type: 'file', }; constructor(props) { @@ -28,10 +28,7 @@ class FileSelector extends React.PureComponent { handleButtonClick() { remote.dialog.showOpenDialog( { - properties: - this.props.type == "file" - ? ["openFile"] - : ["openDirectory", "createDirectory"], + properties: this.props.type == 'file' ? ['openFile'] : ['openDirectory', 'createDirectory'], }, paths => { if (!paths) { @@ -60,12 +57,10 @@ class FileSelector extends React.PureComponent { > - {this.props.type == "file" - ? __("Choose File") - : __("Choose Directory")} + {this.props.type == 'file' ? __('Choose File') : __('Choose Directory')} - {" "} + {' '}
diff --git a/src/renderer/component/fileActions/index.js b/src/renderer/component/fileActions/index.js index 71589679b..b848342c0 100644 --- a/src/renderer/component/fileActions/index.js +++ b/src/renderer/component/fileActions/index.js @@ -1,10 +1,10 @@ -import React from "react"; -import { connect } from "react-redux"; -import { makeSelectFileInfoForUri } from "redux/selectors/file_info"; -import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; -import { doOpenModal } from "redux/actions/app"; -import { makeSelectClaimIsMine } from "redux/selectors/claims"; -import FileActions from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; +import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info'; +import { doOpenModal } from 'redux/actions/app'; +import { makeSelectClaimIsMine } from 'redux/selectors/claims'; +import FileActions from './view'; const select = (state, props) => ({ fileInfo: makeSelectFileInfoForUri(props.uri)(state), diff --git a/src/renderer/component/fileActions/view.jsx b/src/renderer/component/fileActions/view.jsx index a382191ee..b2d83f3b9 100644 --- a/src/renderer/component/fileActions/view.jsx +++ b/src/renderer/component/fileActions/view.jsx @@ -1,7 +1,7 @@ -import React from "react"; -import Link from "component/link"; -import FileDownloadLink from "component/fileDownloadLink"; -import * as modals from "constants/modal_types"; +import React from 'react'; +import Link from 'component/link'; +import FileDownloadLink from 'component/fileDownloadLink'; +import * as modals from 'constants/modal_types'; class FileActions extends React.PureComponent { render() { @@ -17,7 +17,7 @@ class FileActions extends React.PureComponent { openModal(modals.CONFIRM_FILE_REMOVE, { uri })} /> @@ -28,22 +28,22 @@ class FileActions extends React.PureComponent { icon="icon-flag" href={`https://lbry.io/dmca?claim_id=${claimId}`} className="no-underline" - label={__("report")} + label={__('report')} /> )} {claimIsMine && ( ({ claim: makeSelectClaimForUri(props.uri)(state), diff --git a/src/renderer/component/fileCard/view.jsx b/src/renderer/component/fileCard/view.jsx index 00a42eb29..e741589d8 100644 --- a/src/renderer/component/fileCard/view.jsx +++ b/src/renderer/component/fileCard/view.jsx @@ -1,14 +1,14 @@ -import React from "react"; -import lbryuri from "lbryuri.js"; -import CardMedia from "component/cardMedia"; -import Link from "component/link"; -import { TruncatedText } from "component/common"; -import Icon from "component/icon"; -import FilePrice from "component/filePrice"; -import UriIndicator from "component/uriIndicator"; -import NsfwOverlay from "component/nsfwOverlay"; -import TruncatedMarkdown from "component/truncatedMarkdown"; -import * as icons from "constants/icons"; +import React from 'react'; +import lbryuri from 'lbryuri.js'; +import CardMedia from 'component/cardMedia'; +import Link from 'component/link'; +import { TruncatedText } from 'component/common'; +import Icon from 'component/icon'; +import FilePrice from 'component/filePrice'; +import UriIndicator from 'component/uriIndicator'; +import NsfwOverlay from 'component/nsfwOverlay'; +import TruncatedMarkdown from 'component/truncatedMarkdown'; +import * as icons from 'constants/icons'; class FileCard extends React.PureComponent { constructor(props) { @@ -59,35 +59,27 @@ class FileCard extends React.PureComponent { const uri = lbryuri.normalize(this.props.uri); const title = metadata && metadata.title ? metadata.title : uri; - const thumbnail = - metadata && metadata.thumbnail ? metadata.thumbnail : null; + const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null; const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; - const isRewardContent = - claim && rewardedContentClaimIds.includes(claim.claim_id); + const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); - let description = ""; + let description = ''; if (isResolvingUri && !claim) { - description = __("Loading..."); + description = __('Loading...'); } else if (metadata && metadata.description) { description = metadata.description; } else if (claim === null) { - description = __("This address contains no content."); + description = __('This address contains no content.'); } return (
- navigate("/show", { uri })} - className="card__link" - > + navigate('/show', { uri })} className="card__link">
@@ -95,8 +87,7 @@ class FileCard extends React.PureComponent {
- {" "} - {isRewardContent && }{" "} + {isRewardContent && }{' '} {fileInfo && } diff --git a/src/renderer/component/fileDetails/index.js b/src/renderer/component/fileDetails/index.js index fb29fe042..9b877dec9 100644 --- a/src/renderer/component/fileDetails/index.js +++ b/src/renderer/component/fileDetails/index.js @@ -1,13 +1,13 @@ -import React from "react"; -import { connect } from "react-redux"; +import React from 'react'; +import { connect } from 'react-redux'; import { makeSelectClaimForUri, makeSelectContentTypeForUri, makeSelectMetadataForUri, -} from "redux/selectors/claims"; -import FileDetails from "./view"; -import { doOpenFileInFolder } from "redux/actions/file_info"; -import { makeSelectFileInfoForUri } from "redux/selectors/file_info"; +} from 'redux/selectors/claims'; +import FileDetails from './view'; +import { doOpenFileInFolder } from 'redux/actions/file_info'; +import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), diff --git a/src/renderer/component/fileDetails/view.jsx b/src/renderer/component/fileDetails/view.jsx index 55afed97d..9b6753484 100644 --- a/src/renderer/component/fileDetails/view.jsx +++ b/src/renderer/component/fileDetails/view.jsx @@ -1,27 +1,20 @@ -import React from "react"; -import ReactMarkdown from "react-markdown"; -import lbry from "lbry.js"; -import FileActions from "component/fileActions"; -import Link from "component/link"; -import DateTime from "component/dateTime"; +import React from 'react'; +import ReactMarkdown from 'react-markdown'; +import lbry from 'lbry.js'; +import FileActions from 'component/fileActions'; +import Link from 'component/link'; +import DateTime from 'component/dateTime'; -const path = require("path"); +const path = require('path'); class FileDetails extends React.PureComponent { render() { - const { - claim, - contentType, - fileInfo, - metadata, - openFolder, - uri, - } = this.props; + const { claim, contentType, fileInfo, metadata, openFolder, uri } = this.props; if (!claim || !metadata) { return (
- {__("Empty claim or metadata info.")} + {__('Empty claim or metadata info.')}
); } @@ -29,9 +22,7 @@ class FileDetails extends React.PureComponent { const { description, language, license } = metadata; const mediaType = lbry.getMediaType(contentType); - const downloadPath = fileInfo - ? path.normalize(fileInfo.download_path) - : null; + const downloadPath = fileInfo ? path.normalize(fileInfo.download_path) : null; return (
@@ -40,33 +31,31 @@ class FileDetails extends React.PureComponent {
- + - + - + {downloadPath && ( - + )} diff --git a/src/renderer/component/fileDownloadLink/index.js b/src/renderer/component/fileDownloadLink/index.js index 9ac3982a4..40f578ca4 100644 --- a/src/renderer/component/fileDownloadLink/index.js +++ b/src/renderer/component/fileDownloadLink/index.js @@ -1,15 +1,15 @@ -import React from "react"; -import { connect } from "react-redux"; +import React from 'react'; +import { connect } from 'react-redux'; import { makeSelectFileInfoForUri, makeSelectDownloadingForUri, makeSelectLoadingForUri, -} from "redux/selectors/file_info"; -import { makeSelectCostInfoForUri } from "redux/selectors/cost_info"; -import { doFetchAvailability } from "redux/actions/availability"; -import { doOpenFileInShell } from "redux/actions/file_info"; -import { doPurchaseUri, doStartDownload } from "redux/actions/content"; -import FileDownloadLink from "./view"; +} from 'redux/selectors/file_info'; +import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info'; +import { doFetchAvailability } from 'redux/actions/availability'; +import { doOpenFileInShell } from 'redux/actions/file_info'; +import { doPurchaseUri, doStartDownload } from 'redux/actions/content'; +import FileDownloadLink from './view'; const select = (state, props) => ({ fileInfo: makeSelectFileInfoForUri(props.uri)(state), diff --git a/src/renderer/component/fileDownloadLink/view.jsx b/src/renderer/component/fileDownloadLink/view.jsx index 32d0fe3c4..0c23db718 100644 --- a/src/renderer/component/fileDownloadLink/view.jsx +++ b/src/renderer/component/fileDownloadLink/view.jsx @@ -1,6 +1,6 @@ -import React from "react"; -import { Icon, BusyMessage } from "component/common"; -import Link from "component/link"; +import React from 'react'; +import { Icon, BusyMessage } from 'component/common'; +import Link from 'component/link'; class FileDownloadLink extends React.PureComponent { componentWillMount() { @@ -34,24 +34,14 @@ class FileDownloadLink extends React.PureComponent { } render() { - const { - fileInfo, - downloading, - uri, - openInShell, - purchaseUri, - costInfo, - loading, - } = this.props; + const { fileInfo, downloading, uri, openInShell, purchaseUri, costInfo, loading } = this.props; if (loading || downloading) { const progress = fileInfo && fileInfo.written_bytes ? fileInfo.written_bytes / fileInfo.total_bytes * 100 : 0, - label = fileInfo - ? progress.toFixed(0) + __("% complete") - : __("Connecting..."), + label = fileInfo ? progress.toFixed(0) + __('% complete') : __('Connecting...'), labelWithIcon = ( @@ -63,7 +53,7 @@ class FileDownloadLink extends React.PureComponent {
{labelWithIcon}
@@ -72,24 +62,23 @@ class FileDownloadLink extends React.PureComponent { ); } else if (fileInfo === null && !downloading) { if (!costInfo) { - return ; - } else { - return ( - { - purchaseUri(uri); - }} - /> - ); + return ; } + return ( + { + purchaseUri(uri); + }} + /> + ); } else if (fileInfo && fileInfo.download_path) { return ( ({}); diff --git a/src/renderer/component/fileList/view.jsx b/src/renderer/component/fileList/view.jsx index 10dd2d2d7..ba1ba296c 100644 --- a/src/renderer/component/fileList/view.jsx +++ b/src/renderer/component/fileList/view.jsx @@ -1,23 +1,23 @@ -import React from "react"; -import lbryuri from "lbryuri.js"; -import FormField from "component/formField"; -import FileTile from "component/fileTile"; -import { BusyMessage } from "component/common.js"; +import React from 'react'; +import lbryuri from 'lbryuri.js'; +import FormField from 'component/formField'; +import FileTile from 'component/fileTile'; +import { BusyMessage } from 'component/common.js'; class FileList extends React.PureComponent { constructor(props) { super(props); this.state = { - sortBy: "date", + sortBy: 'date', }; this._sortFunctions = { - date: function(fileInfos) { + date(fileInfos) { return fileInfos.slice().reverse(); }, - title: function(fileInfos) { - return fileInfos.slice().sort(function(fileInfo1, fileInfo2) { + title(fileInfos) { + return fileInfos.slice().sort((fileInfo1, fileInfo2) => { const title1 = fileInfo1.value ? fileInfo1.value.stream.metadata.title.toLowerCase() : fileInfo1.name; @@ -28,25 +28,21 @@ class FileList extends React.PureComponent { return -1; } else if (title1 > title2) { return 1; - } else { - return 0; } + return 0; }); }, - filename: function(fileInfos) { - return fileInfos - .slice() - .sort(function({ file_name: fileName1 }, { file_name: fileName2 }) { - const fileName1Lower = fileName1.toLowerCase(); - const fileName2Lower = fileName2.toLowerCase(); - if (fileName1Lower < fileName2Lower) { - return -1; - } else if (fileName2Lower > fileName1Lower) { - return 1; - } else { - return 0; - } - }); + filename(fileInfos) { + return fileInfos.slice().sort(({ file_name: fileName1 }, { file_name: fileName2 }) => { + const fileName1Lower = fileName1.toLowerCase(); + const fileName2Lower = fileName2.toLowerCase(); + if (fileName1Lower < fileName2Lower) { + return -1; + } else if (fileName2Lower > fileName1Lower) { + return 1; + } + return 0; + }); }, }; } @@ -54,9 +50,8 @@ class FileList extends React.PureComponent { getChannelSignature(fileInfo) { if (fileInfo.value) { return fileInfo.value.publisherSignature.certificateId; - } else { - return fileInfo.metadata.publisherSignature.certificateId; } + return fileInfo.metadata.publisherSignature.certificateId; } handleSortChanged(event) { @@ -71,7 +66,7 @@ class FileList extends React.PureComponent { const content = []; this._sortFunctions[sortBy](fileInfos).forEach(fileInfo => { - let uriParams = {}; + const uriParams = {}; if (fileInfo.channel_name) { uriParams.channelName = fileInfo.channel_name; @@ -89,7 +84,7 @@ class FileList extends React.PureComponent { uri={uri} showPrice={false} showLocal={false} - showActions={true} + showActions showEmpty={this.props.fileTileShowEmpty} /> ); @@ -98,10 +93,10 @@ class FileList extends React.PureComponent {
{fetching && } - {__("Sort by")}{" "} + {__('Sort by')}{' '} - - + + {content} diff --git a/src/renderer/component/fileListSearch/index.js b/src/renderer/component/fileListSearch/index.js index cd6e087f6..ec06231af 100644 --- a/src/renderer/component/fileListSearch/index.js +++ b/src/renderer/component/fileListSearch/index.js @@ -1,11 +1,8 @@ -import React from "react"; -import { connect } from "react-redux"; -import { doSearch } from "redux/actions/search"; -import { - selectIsSearching, - makeSelectSearchUris, -} from "redux/selectors/search"; -import FileListSearch from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import { doSearch } from 'redux/actions/search'; +import { selectIsSearching, makeSelectSearchUris } from 'redux/selectors/search'; +import FileListSearch from './view'; const select = (state, props) => ({ isSearching: selectIsSearching(state), diff --git a/src/renderer/component/fileListSearch/view.jsx b/src/renderer/component/fileListSearch/view.jsx index 00a759d5e..afe5d4f36 100644 --- a/src/renderer/component/fileListSearch/view.jsx +++ b/src/renderer/component/fileListSearch/view.jsx @@ -1,9 +1,9 @@ -import React from "react"; -import FileTile from "component/fileTile"; -import ChannelTile from "component/channelTile"; -import Link from "component/link"; -import { BusyMessage } from "component/common.js"; -import lbryuri from "lbryuri"; +import React from 'react'; +import FileTile from 'component/fileTile'; +import ChannelTile from 'component/channelTile'; +import Link from 'component/link'; +import { BusyMessage } from 'component/common.js'; +import lbryuri from 'lbryuri'; const SearchNoResults = props => { const { query } = props; @@ -11,8 +11,8 @@ const SearchNoResults = props => { return (
- {(__("No one has checked anything in for %s yet."), query)}{" "} - + {(__('No one has checked anything in for %s yet.'), query)}{' '} +
); @@ -38,18 +38,14 @@ class FileListSearch extends React.PureComponent { return (
- {isSearching && - !uris && ( - - )} + {isSearching && !uris && } - {isSearching && - uris && } + {isSearching && uris && } {uris && uris.length ? uris.map( uri => - lbryuri.parse(uri).name[0] === "@" ? ( + lbryuri.parse(uri).name[0] === '@' ? ( ) : ( diff --git a/src/renderer/component/filePrice/index.js b/src/renderer/component/filePrice/index.js index 7460b0a4e..93eaee79d 100644 --- a/src/renderer/component/filePrice/index.js +++ b/src/renderer/component/filePrice/index.js @@ -1,12 +1,12 @@ -import React from "react"; -import { connect } from "react-redux"; -import { doFetchCostInfoForUri } from "redux/actions/cost_info"; +import React from 'react'; +import { connect } from 'react-redux'; +import { doFetchCostInfoForUri } from 'redux/actions/cost_info'; import { makeSelectCostInfoForUri, makeSelectFetchingCostInfoForUri, -} from "redux/selectors/cost_info"; -import { makeSelectClaimForUri } from "redux/selectors/claims"; -import FilePrice from "./view"; +} from 'redux/selectors/cost_info'; +import { makeSelectClaimForUri } from 'redux/selectors/claims'; +import FilePrice from './view'; const select = (state, props) => ({ costInfo: makeSelectCostInfoForUri(props.uri)(state), diff --git a/src/renderer/component/filePrice/view.jsx b/src/renderer/component/filePrice/view.jsx index a2b5067df..5a5947f14 100644 --- a/src/renderer/component/filePrice/view.jsx +++ b/src/renderer/component/filePrice/view.jsx @@ -1,5 +1,5 @@ -import React from "react"; -import { CreditAmount } from "component/common"; +import React from 'react'; +import { CreditAmount } from 'component/common'; class FilePrice extends React.PureComponent { componentWillMount() { @@ -19,14 +19,12 @@ class FilePrice extends React.PureComponent { } render() { - const { costInfo, look = "indicator", showFullPrice = false } = this.props; + const { costInfo, look = 'indicator', showFullPrice = false } = this.props; const isEstimate = costInfo ? !costInfo.includesData : null; if (!costInfo) { - return ( - ??? - ); + return ???; } return ( @@ -34,7 +32,7 @@ class FilePrice extends React.PureComponent { label={false} amount={costInfo.cost} isEstimate={isEstimate} - showFree={true} + showFree showFullPrice={showFullPrice} /> ); diff --git a/src/renderer/component/fileTile/index.js b/src/renderer/component/fileTile/index.js index f352b1633..601a94a7e 100644 --- a/src/renderer/component/fileTile/index.js +++ b/src/renderer/component/fileTile/index.js @@ -1,18 +1,12 @@ -import React from "react"; -import { connect } from "react-redux"; -import { doNavigate } from "redux/actions/navigation"; -import { doResolveUri } from "redux/actions/content"; -import { - makeSelectClaimForUri, - makeSelectMetadataForUri, -} from "redux/selectors/claims"; -import { makeSelectFileInfoForUri } from "redux/selectors/file_info"; -import { selectShowNsfw } from "redux/selectors/settings"; -import { - makeSelectIsUriResolving, - selectRewardContentClaimIds, -} from "redux/selectors/content"; -import FileTile from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import { doNavigate } from 'redux/actions/navigation'; +import { doResolveUri } from 'redux/actions/content'; +import { makeSelectClaimForUri, makeSelectMetadataForUri } from 'redux/selectors/claims'; +import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; +import { selectShowNsfw } from 'redux/selectors/settings'; +import { makeSelectIsUriResolving, selectRewardContentClaimIds } from 'redux/selectors/content'; +import FileTile from './view'; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), diff --git a/src/renderer/component/fileTile/view.jsx b/src/renderer/component/fileTile/view.jsx index fbf3c9110..231cfc293 100644 --- a/src/renderer/component/fileTile/view.jsx +++ b/src/renderer/component/fileTile/view.jsx @@ -1,15 +1,15 @@ -import React from "react"; -import * as icons from "constants/icons"; -import lbryuri from "lbryuri.js"; -import CardMedia from "component/cardMedia"; -import { TruncatedText } from "component/common.js"; -import FilePrice from "component/filePrice"; -import NsfwOverlay from "component/nsfwOverlay"; -import Icon from "component/icon"; +import React from 'react'; +import * as icons from 'constants/icons'; +import lbryuri from 'lbryuri.js'; +import CardMedia from 'component/cardMedia'; +import { TruncatedText } from 'component/common.js'; +import FilePrice from 'component/filePrice'; +import NsfwOverlay from 'component/nsfwOverlay'; +import Icon from 'component/icon'; class FileTile extends React.PureComponent { - static SHOW_EMPTY_PUBLISH = "publish"; - static SHOW_EMPTY_PENDING = "pending"; + static SHOW_EMPTY_PUBLISH = 'publish'; + static SHOW_EMPTY_PENDING = 'pending'; static defaultProps = { showPrice: true, @@ -36,11 +36,7 @@ class FileTile extends React.PureComponent { } handleMouseOver() { - if ( - this.props.obscureNsfw && - this.props.metadata && - this.props.metadata.nsfw - ) { + if (this.props.obscureNsfw && this.props.metadata && this.props.metadata.nsfw) { this.setState({ showNsfwHelp: true, }); @@ -73,59 +69,49 @@ class FileTile extends React.PureComponent { const isClaimed = !!claim; const isClaimable = lbryuri.isClaimable(uri); const title = - isClaimed && metadata && metadata.title - ? metadata.title - : lbryuri.parse(uri).contentName; - const thumbnail = - metadata && metadata.thumbnail ? metadata.thumbnail : null; + isClaimed && metadata && metadata.title ? metadata.title : lbryuri.parse(uri).contentName; + const thumbnail = metadata && metadata.thumbnail ? metadata.thumbnail : null; const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; - const isRewardContent = - claim && rewardedContentClaimIds.includes(claim.claim_id); + const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); - let onClick = () => navigate("/show", { uri }); + let onClick = () => navigate('/show', { uri }); - let name = ""; + let name = ''; if (claim) { name = claim.name; } - let description = ""; + let description = ''; if (isClaimed) { description = metadata && metadata.description; } else if (isResolvingUri) { - description = __("Loading..."); + description = __('Loading...'); } else if (showEmpty === FileTile.SHOW_EMPTY_PUBLISH) { - onClick = () => navigate("/publish", {}); + onClick = () => navigate('/publish', {}); description = ( - {__("This location is unused.")}{" "} - {isClaimable && ( - {__("Put something here!")} - )} + {__('This location is unused.')}{' '} + {isClaimable && {__('Put something here!')}} ); } else if (showEmpty === FileTile.SHOW_EMPTY_PENDING) { - description = ( - - {__("This file is pending confirmation.")} - - ); + description = {__('This file is pending confirmation.')}; } return (
-
+
- {showPrice && }{" "} - {isRewardContent && }{" "} + {showPrice && }{' '} + {isRewardContent && }{' '} {showLocal && fileInfo && }

@@ -134,9 +120,7 @@ class FileTile extends React.PureComponent {

{description && (
- - {description} - + {description}
)}
diff --git a/src/renderer/component/form.js b/src/renderer/component/form.js index 229668ffe..135df952d 100644 --- a/src/renderer/component/form.js +++ b/src/renderer/component/form.js @@ -1,11 +1,11 @@ -import React from "react"; -import PropTypes from "prop-types"; -import FormField from "component/formField"; -import { Icon } from "component/common.js"; +import React from 'react'; +import PropTypes from 'prop-types'; +import FormField from 'component/formField'; +import { Icon } from 'component/common.js'; let formFieldCounter = 0; -export const formFieldNestedLabelTypes = ["radio", "checkbox"]; +export const formFieldNestedLabelTypes = ['radio', 'checkbox']; export function formFieldId() { return `form-field-${++formFieldCounter}`; @@ -26,11 +26,7 @@ export class Form extends React.PureComponent { } render() { - return ( -
this.handleSubmit(event)}> - {this.props.children} - - ); + return
this.handleSubmit(event)}>{this.props.children}; } } @@ -50,7 +46,7 @@ export class FormRow extends React.PureComponent { this._field = null; - this._fieldRequiredText = __("This field is required"); + this._fieldRequiredText = __('This field is required'); this.state = this.getStateFromProps(props); } @@ -63,11 +59,9 @@ export class FormRow extends React.PureComponent { return { isError: !!props.errorMessage, errorMessage: - typeof props.errorMessage === "string" + typeof props.errorMessage === 'string' ? props.errorMessage - : props.errorMessage instanceof Error - ? props.errorMessage.toString() - : "", + : props.errorMessage instanceof Error ? props.errorMessage.toString() : '', }; } @@ -85,7 +79,7 @@ export class FormRow extends React.PureComponent { clearError(text) { this.setState({ isError: false, - errorMessage: "", + errorMessage: '', }); } @@ -116,9 +110,7 @@ export class FormRow extends React.PureComponent { render() { const fieldProps = Object.assign({}, this.props), elementId = formFieldId(), - renderLabelInFormField = formFieldNestedLabelTypes.includes( - this.props.type - ); + renderLabelInFormField = formFieldNestedLabelTypes.includes(this.props.type); if (!renderLabelInFormField) { delete fieldProps.label; @@ -128,26 +120,24 @@ export class FormRow extends React.PureComponent { delete fieldProps.isFocus; return ( -
+
{this.props.label && !renderLabelInFormField ? (
) : ( - "" + '' )} { @@ -161,12 +151,12 @@ export class FormRow extends React.PureComponent { {!this.state.isError && this.props.helper ? (
{this.props.helper}
) : ( - "" + '' )} {this.state.isError ? (
{this.state.errorMessage}
) : ( - "" + '' )}
); @@ -176,14 +166,14 @@ export class FormRow extends React.PureComponent { export const Submit = props => { const { title, label, icon, disabled } = props; - const className = `${"button-block" + - " button-primary" + - " button-set-item" + - " button--submit"}${disabled ? " disabled" : ""}`; + const className = `${'button-block' + + ' button-primary' + + ' button-set-item' + + ' button--submit'}${disabled ? ' disabled' : ''}`; const content = ( - {"icon" in props ? : null} + {'icon' in props ? : null} {label ? {label} : null} ); diff --git a/src/renderer/component/formField/index.js b/src/renderer/component/formField/index.js index ca01b3e99..5977b6b2c 100644 --- a/src/renderer/component/formField/index.js +++ b/src/renderer/component/formField/index.js @@ -1,5 +1,5 @@ -import React from "react"; -import { connect } from "react-redux"; -import FormField from "./view"; +import React from 'react'; +import { connect } from 'react-redux'; +import FormField from './view'; export default connect(null, null, null, { withRef: true })(FormField); diff --git a/src/renderer/component/formField/view.jsx b/src/renderer/component/formField/view.jsx index bb8cc5024..960b08c17 100644 --- a/src/renderer/component/formField/view.jsx +++ b/src/renderer/component/formField/view.jsx @@ -1,11 +1,11 @@ -import React from "react"; -import PropTypes from "prop-types"; -import FileSelector from "component/file-selector.js"; -import SimpleMDE from "react-simplemde-editor"; -import { formFieldNestedLabelTypes, formFieldId } from "../form"; -import style from "react-simplemde-editor/dist/simplemde.min.css"; +import React from 'react'; +import PropTypes from 'prop-types'; +import FileSelector from 'component/file-selector.js'; +import SimpleMDE from 'react-simplemde-editor'; +import { formFieldNestedLabelTypes, formFieldId } from '../form'; +import style from 'react-simplemde-editor/dist/simplemde.min.css'; -const formFieldFileSelectorTypes = ["file", "directory"]; +const formFieldFileSelectorTypes = ['file', 'directory']; class FormField extends React.PureComponent { static propTypes = { @@ -14,10 +14,7 @@ class FormField extends React.PureComponent { postfix: PropTypes.string, hasError: PropTypes.bool, trim: PropTypes.bool, - regexp: PropTypes.oneOfType([ - PropTypes.instanceOf(RegExp), - PropTypes.string, - ]), + regexp: PropTypes.oneOfType([PropTypes.instanceOf(RegExp), PropTypes.string]), }; static defaultProps = { @@ -27,7 +24,7 @@ class FormField extends React.PureComponent { constructor(props) { super(props); - this._fieldRequiredText = __("This field is required"); + this._fieldRequiredText = __('This field is required'); this._type = null; this._element = null; this._extraElementProps = {}; @@ -39,22 +36,22 @@ class FormField extends React.PureComponent { } componentWillMount() { - if (["text", "number", "radio", "checkbox"].includes(this.props.type)) { - this._element = "input"; + if (['text', 'number', 'radio', 'checkbox'].includes(this.props.type)) { + this._element = 'input'; this._type = this.props.type; - } else if (this.props.type == "text-number") { - this._element = "input"; - this._type = "text"; - } else if (this.props.type == "SimpleMDE") { + } else if (this.props.type == 'text-number') { + this._element = 'input'; + this._type = 'text'; + } else if (this.props.type == 'SimpleMDE') { this._element = SimpleMDE; - this._type = "textarea"; + this._type = 'textarea'; this._extraElementProps.options = { placeholder: this.props.placeholder, - hideIcons: ["heading", "image", "fullscreen", "side-by-side"], + hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'], }; } else if (formFieldFileSelectorTypes.includes(this.props.type)) { - this._element = "input"; - this._type = "hidden"; + this._element = 'input'; + this._type = 'hidden'; } else { // Non field, e.g.
{__("Content-Type")}{__('Content-Type')} {mediaType}
{__("Language")}{__('Language')} {language}
{__("License")}{__('License')} {license}
{__("Downloaded to")}{__('Downloaded to')} - openFolder(downloadPath)}> - {downloadPath} - + openFolder(downloadPath)}>{downloadPath}