From 040b57352f0cbfc6e7439c7dfb12e2bfc4b10f35 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 18:35:07 -0300 Subject: [PATCH 01/18] 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" -- 2.45.3 From a40aecfb683992dbe7352d20b72d7b63d9165dcf Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 18:36:30 -0300 Subject: [PATCH 02/18] 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]; -- 2.45.3 From 29eb306934a4c548966a7eace524073e782f6cc2 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 13 Dec 2017 18:50:17 -0300 Subject: [PATCH 03/18] 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": { -- 2.45.3 From 93d63865be4ef48afacfcb204b01425af11d4c15 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 14 Dec 2017 09:58:07 -0300 Subject: [PATCH 04/18] 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)) { -- 2.45.3 From 01dd124d6009da7f61fd71e6d996e3b80b0a4b18 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 11:48:38 -0300 Subject: [PATCH 05/18] 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" -- 2.45.3 From ac821a5e4db0b846ada440a0d87134f0285ec39a Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:32:59 -0300 Subject: [PATCH 06/18] 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": { -- 2.45.3 From 11609780959a9f9aafb0137c2d6c2eead5feb610 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:34:18 -0300 Subject: [PATCH 07/18] 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 -- 2.45.3 From 97fe53d647a4997a14be2c1f521d62bb9db07bbc Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:35:13 -0300 Subject: [PATCH 08/18] 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 -- 2.45.3 From b0255f468a043a98d9944a2619804591641edf2f Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:36:03 -0300 Subject: [PATCH 09/18] 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 -- 2.45.3 From 3b26f0621019392f95a027e116a299b0eeefea39 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:37:19 -0300 Subject: [PATCH 10/18] 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; } -- 2.45.3 From a9d386e5dde739466612fa447e27c1e1b5170434 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 12:38:52 -0300 Subject: [PATCH 11/18] 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, + }), + ] + }; } -- 2.45.3 From 57b8cb82ea1fd6b1da4063535fc83b87d80ee0c8 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 16:06:59 -0300 Subject: [PATCH 12/18] 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", -- 2.45.3 From c1a6b5a9405dbdb372c2fbabdc20c5ed4e4e2cae Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Wed, 20 Dec 2017 17:05:00 -0300 Subject: [PATCH 13/18] 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" -- 2.45.3 From 4a48d0a52137bb13f2050bb9684a53abda9e2005 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 21 Dec 2017 12:17:33 -0300 Subject: [PATCH 14/18] 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" -- 2.45.3 From 7cd25e777aded97a7609e084ccff4ae0c8240a94 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 21 Dec 2017 14:32:51 -0300 Subject: [PATCH 15/18] 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" -- 2.45.3 From e103778b8a7b6d6cebc34a52b43d514cb1f51260 Mon Sep 17 00:00:00 2001 From: Igor Gassmann Date: Thu, 21 Dec 2017 18:08:54 -0300 Subject: [PATCH 16/18] 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}