From eb815532295396f79dba55a3e82d96a6efe41e31 Mon Sep 17 00:00:00 2001 From: svetlagasheva Date: Tue, 10 Dec 2019 18:55:48 +0200 Subject: [PATCH 01/28] eslint added --- .eslintrc.js | 85 +++++++++++++ package.json | 5 +- yarn.lock | 350 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 426 insertions(+), 14 deletions(-) create mode 100644 .eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..f7747c8ab --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,85 @@ +module.exports = { + "extends": [ + "eslint:recommended", + "plugin:react/recommended" + ], + "rules": { + "arrow-parens": "error", + "arrow-spacing": "error", + "block-spacing": "error", + "comma-spacing": [ + "error", + { + "before": false, + "after": true + } + ], + "eol-last": [ + "error", + "always" + ], + "eqeqeq": [ + "error", + "always" + ], + "func-call-spacing": [ + "error", + "never" + ], + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-console": [ + "error", + { + allow: ["error"] + } + ], + "no-extra-semi": "error", + "no-eq-null": "error", + "no-multi-spaces": "error", + "no-multiple-empty-lines": [ + "error", + { + "max": 2 + } + ], + "no-template-curly-in-string": "error", + "no-trailing-spaces": "error", + "no-useless-concat": "error", + "no-unreachable": "error", + "prefer-const": "error", + "quotes": [ + "warn", + "single" + ], + "semi": [ + "error", + "always" + ], + "semi-spacing": [ + "error", + { + "before": false, + "after": true + } + ], + "space-before-blocks": "error", + "valid-typeof": "error" + }, + "env": { + "node": true, + "browser": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 9, + "ecmaFeatures": { + "experimentalObjectRestSpread": true + } + } +} diff --git a/package.json b/package.json index da4427714..85d2ae48a 100755 --- a/package.json +++ b/package.json @@ -10,11 +10,14 @@ "start": "webpack-dev-server --mode development", "build": "webpack --mode production", "storybook": "start-storybook --ci --config-dir ./storybook --static-dir ./ --port 6060", - "test": "jest" + "test": "jest", + "lint": "eslint src" }, "dependencies": { "a-color-picker": "1.2.1", "classnames": "2.2.6", + "eslint": "^6.7.2", + "eslint-plugin-react": "^7.17.0", "events": "1.1.1", "hat": "0.0.3", "lodash.debounce": "4.0.8", diff --git a/yarn.lock b/yarn.lock index 31faaf37c..07e5dd3cf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2046,6 +2046,11 @@ acorn-globals@^4.1.0: acorn "^6.0.1" acorn-walk "^6.0.1" +acorn-jsx@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" + integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== + acorn-walk@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" @@ -2061,6 +2066,11 @@ acorn@^6.0.1, acorn@^6.2.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw== +acorn@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" + integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== + address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -2107,7 +2117,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== @@ -2139,6 +2149,13 @@ ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-escapes@^4.2.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.0.tgz#a4ce2b33d6b214b7950d8595c212f12ac9cc569d" + integrity sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg== + dependencies: + type-fest "^0.8.1" + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -2159,6 +2176,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -3167,7 +3189,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -3298,6 +3320,13 @@ cli-cursor@^2.1.0: dependencies: restore-cursor "^2.0.0" +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + cli-table3@0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -3711,7 +3740,7 @@ create-react-context@^0.3.0: gud "^1.0.0" warning "^4.0.3" -cross-spawn@6.0.5, cross-spawn@^6.0.0: +cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -3976,7 +4005,7 @@ debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -4188,6 +4217,13 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -4369,6 +4405,11 @@ emoji-regex@^7.0.1: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -4501,6 +4542,27 @@ escodegen@^1.9.1: optionalDependencies: source-map "~0.6.1" +eslint-plugin-eslint-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5" + integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg== + +eslint-plugin-react@^7.17.0: + version "7.17.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz#a31b3e134b76046abe3cd278e7482bd35a1d12d7" + integrity sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A== + dependencies: + array-includes "^3.0.3" + doctrine "^2.1.0" + eslint-plugin-eslint-plugin "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.2.3" + object.entries "^1.1.0" + object.fromentries "^2.0.1" + object.values "^1.1.0" + prop-types "^15.7.2" + resolve "^1.13.1" + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -4509,6 +4571,78 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^6.7.2: + version "6.7.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" + integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^7.0.0" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d" + integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA== + dependencies: + acorn "^7.1.0" + acorn-jsx "^5.1.0" + eslint-visitor-keys "^1.1.0" + esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" @@ -4519,6 +4653,13 @@ esprima@^4.0.0, esprima@~4.0.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" @@ -4526,7 +4667,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -4808,6 +4949,20 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +figures@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.1.0.tgz#4b198dd07d8d71530642864af2d45dd9e459c4ec" + integrity sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + file-loader@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-3.0.1.tgz#f8e0ba0b599918b51adfe45d66d1e771ad560faa" @@ -4908,6 +5063,20 @@ findup-sync@3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -5075,6 +5244,11 @@ function.prototype.name@^1.1.0: functions-have-names "^1.1.1" is-callable "^1.1.4" +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" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + functions-have-names@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.0.tgz#83da7583e4ea0c9ac5ff530f73394b033e0bf77d" @@ -5141,6 +5315,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + dependencies: + is-glob "^4.0.1" + glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" @@ -5207,6 +5388,13 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^12.1.0: + version "12.3.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.3.0.tgz#1e564ee5c4dded2ab098b0f88f24702a3c56be13" + integrity sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw== + dependencies: + type-fest "^0.8.1" + globalthis@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.0.tgz#c5fb98213a9b4595f59cf3e7074f141b4169daae" @@ -5661,6 +5849,11 @@ ignore@^3.3.5: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + image-size@~0.5.0: version "0.5.5" resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" @@ -5686,7 +5879,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.1.0: +import-fresh@^3.0.0, import-fresh@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== @@ -5795,6 +5988,25 @@ inquirer@^6.2.0: strip-ansi "^5.1.0" through "^2.3.6" +inquirer@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.0.tgz#9e2b032dde77da1db5db804758b8fea3a970519a" + integrity sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ== + dependencies: + ansi-escapes "^4.2.1" + chalk "^2.4.2" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^4.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + internal-ip@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" @@ -6012,6 +6224,11 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + is-function@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" @@ -6692,6 +6909,11 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +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" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -6745,6 +6967,14 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jsx-ast-utils@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" + integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== + dependencies: + array-includes "^3.0.3" + object.assign "^4.1.0" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -6856,7 +7086,7 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levn@~0.3.0: +levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= @@ -7199,7 +7429,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-fn@^2.0.0: +mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -7390,6 +7620,11 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + nan@^2.12.1: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -7709,7 +7944,7 @@ object.entries@^1.1.0: function-bind "^1.1.1" has "^1.0.3" -"object.fromentries@^2.0.0 || ^1.0.0": +"object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.1.tgz#050f077855c7af8ae6649f45c80b16ee2d31e704" integrity sha512-PUQv8Hbg3j2QX0IQYv3iAGCbGcu4yY4KQ92/dhA4sFSixBmSmp13UpDLs6jGK8rBtbmhNNIK99LD2k293jpiGA== @@ -7775,6 +8010,13 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + open@^6.1.0, open@^6.3.0: version "6.4.0" resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" @@ -7797,7 +8039,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.1: +optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -8638,6 +8880,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -9219,6 +9466,11 @@ regexp.prototype.flags@^1.2.0: dependencies: define-properties "^1.1.2" +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + regexpu-core@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" @@ -9381,7 +9633,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.8.1: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.3.2, resolve@^1.8.1: version "1.13.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w== @@ -9396,6 +9648,14 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -9416,6 +9676,13 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -9551,7 +9818,7 @@ selfsigned@^1.10.7: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -9755,6 +10022,15 @@ slash@^2.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -10077,6 +10353,15 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string-width@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + "string.prototype.matchall@^4.0.0 || ^3.0.1": version "4.0.0" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.0.tgz#47191e37b67dca43131706bc9c4550df31b2c471" @@ -10157,6 +10442,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -10167,6 +10459,11 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -10245,6 +10542,16 @@ symbol.prototype.description@^1.0.0: es-abstract "^1.16.0" has-symbols "^1.0.0" +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" @@ -10332,7 +10639,7 @@ test-exclude@^5.2.3: read-pkg-up "^4.0.0" require-main-filename "^2.0.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" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= @@ -10506,6 +10813,11 @@ type-fest@^0.3.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -10742,6 +11054,11 @@ v8-compile-cache@2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -11080,6 +11397,13 @@ write-file-atomic@2.4.1: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + ws@^5.2.0: version "5.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" From 78f7d614e4154c83585b73b8bc6a1fe8f157a136 Mon Sep 17 00:00:00 2001 From: svetlagasheva Date: Wed, 11 Dec 2019 11:10:51 +0200 Subject: [PATCH 02/28] disable react/prop-types rule --- .eslintrc.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index f7747c8ab..1fd52540f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -52,11 +52,13 @@ module.exports = { "no-trailing-spaces": "error", "no-useless-concat": "error", "no-unreachable": "error", + "no-unused-vars": "error", "prefer-const": "error", "quotes": [ "warn", "single" ], + "react/prop-types": 0, "semi": [ "error", "always" From d5de64fc05743332351f933650397246fad256fa Mon Sep 17 00:00:00 2001 From: svetlagasheva Date: Thu, 12 Dec 2019 11:41:24 +0200 Subject: [PATCH 03/28] linter overrides added --- .eslintrc.js | 61 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1fd52540f..cf07f3159 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,6 +3,11 @@ module.exports = { "eslint:recommended", "plugin:react/recommended" ], + "globals": { + "YT": "readonly", + "FB": "readonly" + }, + "ignorePatterns": ["src/routes/Settings/**", "src/routes/Player/**", "src/video/**"], "rules": { "arrow-parens": "error", "arrow-spacing": "error", @@ -58,7 +63,6 @@ module.exports = { "warn", "single" ], - "react/prop-types": 0, "semi": [ "error", "always" @@ -71,7 +75,8 @@ module.exports = { } ], "space-before-blocks": "error", - "valid-typeof": "error" + "valid-typeof": "error", + "react/no-unescaped-entities": 0 }, "env": { "node": true, @@ -83,5 +88,55 @@ module.exports = { "ecmaFeatures": { "experimentalObjectRestSpread": true } - } + }, + "overrides": [ + { + "files": [ + "src/common/Button/Button.js", + "src/common/Checkbox/Checkbox.js", + "src/common/ColorInput/ColorInput.js", + "src/common/Image/Image.js", + "src/common/MetaItem/MetaItem.js", + "src/common/Multiselect/Multiselect.js", + "src/common/TextInput/TextInput.js", + "src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js", + "src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js", + "src/common/PaginationInput/PaginationInput.js" + ], + "rules": { + "react/prop-types": 0, + } + }, + { + "files": [ + "src/routes/Intro/Intro.js", + "src/routes/Addons/useAddons.js", + "src/routes/Board/useItemOptions.js", + "src/common/NavBar/NavMenu/NavMenu.js", + "src/routes/Library/useItemOptions.js", + "src/common/Multiselect/Multiselect.js", + "src/common/NavBar/NotificationsMenu/NotificationsMenu.js" + ], + "rules": { + "no-unused-vars": "off" + } + }, + { + "files": [ + "src/common/NavBar/NavMenu/NavMenu.js" + ], + "rules": { + "quotes": "off" + } + }, + { + "files": [ + "src/services/Shell/Shell.js", + "src/services/Core/Core.js" + ], + "rules": { + "prefer-const": "off" + } + } + ] } From 41415f895dc0ecadf31955c8770258a310b9bb7d Mon Sep 17 00:00:00 2001 From: svetlagasheva Date: Thu, 12 Dec 2019 11:43:32 +0200 Subject: [PATCH 04/28] fix files according to linter rules --- src/common/MainNavBar/MainNavBar.js | 2 ++ src/common/ModalDialog/index.js | 2 +- .../NotificationsList/Notification/Notification.js | 2 +- .../NotificationPlaceholder.js | 3 +-- .../NotificationsList/NotificationsList.js | 2 +- src/common/PaginationInput/index.js | 2 +- src/common/Popup/Popup.js | 2 +- src/common/routesRegexp.js | 10 +++++----- src/router/Router/Router.js | 2 +- src/routes/Addons/Addon/Addon.js | 3 +-- src/routes/Addons/Addons.js | 6 ++++++ src/routes/Board/Board.js | 9 ++++++--- src/routes/Discover/Discover.js | 6 ++++++ src/routes/Intro/Intro.js | 12 ++++++++++-- src/routes/Library/Library.js | 8 +++++++- src/routes/Library/useItemOptions.js | 2 +- src/routes/Library/useLibrary.js | 2 +- src/routes/MetaDetails/MetaDetails.js | 5 +++++ src/routes/MetaDetails/StreamsList/StreamsList.js | 2 +- src/routes/Search/Search.js | 7 ++++++- src/services/Core/Core.js | 2 +- .../KeyboardNavigation/KeyboardNavigation.js | 2 +- src/services/ServicesContext/index.js | 2 +- src/services/Shell/Shell.js | 2 +- 24 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/common/MainNavBar/MainNavBar.js b/src/common/MainNavBar/MainNavBar.js index c6920ce42..507f8d229 100644 --- a/src/common/MainNavBar/MainNavBar.js +++ b/src/common/MainNavBar/MainNavBar.js @@ -23,6 +23,8 @@ const MainNavBar = React.memo(({ className }) => { ); }); +MainNavBar.displayName = 'MainNavBar'; + MainNavBar.propTypes = { className: PropTypes.string }; diff --git a/src/common/ModalDialog/index.js b/src/common/ModalDialog/index.js index 7dadbbd9e..6717dbe87 100644 --- a/src/common/ModalDialog/index.js +++ b/src/common/ModalDialog/index.js @@ -1,3 +1,3 @@ const ModalDialog = require('./ModalDialog'); -module.exports = ModalDialog; \ No newline at end of file +module.exports = ModalDialog; diff --git a/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js b/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js index 53c7b0e81..8bba1d435 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js @@ -80,7 +80,7 @@ const Notification = ({ className, id, type, name, poster, thumbnail, season, ep } ); -} +}; Notification.propTypes = { className: PropTypes.string, diff --git a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js index 3bbac1538..0ee602b64 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js @@ -1,7 +1,6 @@ const React = require('react'); const PropTypes = require('prop-types'); const classnames = require('classnames'); -const Icon = require('stremio-icons/dom'); const styles = require('./styles'); const NotificationPlaceholder = ({ className }) => { @@ -20,6 +19,6 @@ const NotificationPlaceholder = ({ className }) => { NotificationPlaceholder.propTypes = { className: PropTypes.string -} +}; module.exports = NotificationPlaceholder; diff --git a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js index e54bacb68..3fca82728 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js @@ -57,7 +57,7 @@ const NotificationsList = ({ className, metaItems }) => { } ); -} +}; NotificationsList.propTypes = { className: PropTypes.string, diff --git a/src/common/PaginationInput/index.js b/src/common/PaginationInput/index.js index 99f9edf62..4500ec5a6 100644 --- a/src/common/PaginationInput/index.js +++ b/src/common/PaginationInput/index.js @@ -1,3 +1,3 @@ const PaginationInput = require('./PaginationInput'); -module.exports = PaginationInput; \ No newline at end of file +module.exports = PaginationInput; diff --git a/src/common/Popup/Popup.js b/src/common/Popup/Popup.js index d0b26fa03..b956f764f 100644 --- a/src/common/Popup/Popup.js +++ b/src/common/Popup/Popup.js @@ -96,7 +96,7 @@ const Popup = ({ open, direction, renderLabel, renderMenu, dataset, onCloseReque : null }); -} +}; Popup.propTypes = { open: PropTypes.bool, diff --git a/src/common/routesRegexp.js b/src/common/routesRegexp.js index df7f4e069..113497ec5 100644 --- a/src/common/routesRegexp.js +++ b/src/common/routesRegexp.js @@ -8,11 +8,11 @@ const routesRegexp = { urlParamsNames: [] }, discover: { - regexp: /^\/discover(?:\/([^\/]*)\/([^\/]*)\/([^\/]*))?$/, + regexp: /^\/discover(?:\/([^/]*)\/([^/]*)\/([^/]*))?$/, urlParamsNames: ['addonTransportUrl', 'type', 'catalogId'] }, library: { - regexp: /^\/library(?:\/([^\/]*))?$/, + regexp: /^\/library(?:\/([^/]*))?$/, urlParamsNames: ['type'] }, search: { @@ -20,11 +20,11 @@ const routesRegexp = { urlParamsNames: [] }, metadetails: { - regexp: /^\/metadetails\/([^\/]*)\/([^\/]*)(?:\/([^\/]*))?$/, + regexp: /^\/metadetails\/([^/]*)\/([^/]*)(?:\/([^/]*))?$/, urlParamsNames: ['type', 'id', 'videoId'] }, addons: { - regexp: /^\/addons(?:\/([^\/]*)\/([^\/]*)\/([^\/]*))?$/, + regexp: /^\/addons(?:\/([^/]*)\/([^/]*)\/([^/]*))?$/, urlParamsNames: ['addonTransportUrl', 'catalogId', 'type'] }, settings: { @@ -32,7 +32,7 @@ const routesRegexp = { urlParamsNames: [] }, player: { - regexp: /^\/player\/([^\/]*)\/([^\/]*)\/([^\/]*)\/([^\/]*)$/, + regexp: /^\/player\/([^/]*)\/([^/]*)\/([^/]*)\/([^/]*)$/, urlParamsNames: ['type', 'id', 'videoId', 'stream'] } }; diff --git a/src/router/Router/Router.js b/src/router/Router/Router.js index dd8321e70..60fc0334b 100644 --- a/src/router/Router/Router.js +++ b/src/router/Router/Router.js @@ -95,7 +95,7 @@ const Router = ({ className, onPathNotMatch, ...props }) => {
{ views - .filter(view => view !== null) + .filter((view) => view !== null) .map(({ key, component, urlParams, queryParams }, index, views) => ( diff --git a/src/routes/Addons/Addon/Addon.js b/src/routes/Addons/Addon/Addon.js index 023c17732..f26dbcf3b 100644 --- a/src/routes/Addons/Addon/Addon.js +++ b/src/routes/Addons/Addon/Addon.js @@ -5,7 +5,7 @@ const Icon = require('stremio-icons/dom'); const { Button } = require('stremio/common'); const styles = require('./styles'); -const Addon = ({ className, id, name, logo, description, types, version, transportUrl, installed, toggle, onShareButtonClicked }) => { +const Addon = ({ className, id, name, logo, description, types, version, installed, toggle, onShareButtonClicked }) => { const onKeyUp = React.useCallback((event) => { if (event.key === 'Enter' && typeof toggle === 'function') { toggle(event); @@ -72,7 +72,6 @@ Addon.propTypes = { description: PropTypes.string, types: PropTypes.arrayOf(PropTypes.string), version: PropTypes.string, - transportUrl: PropTypes.string, installed: PropTypes.bool, toggle: PropTypes.func, onShareButtonClicked: PropTypes.func diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 0a8152a17..cd68402df 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const Icon = require('stremio-icons/dom'); const { Button, Multiselect, NavBar, TextInput, SharePrompt, ModalDialog } = require('stremio/common'); const Addon = require('./Addon'); @@ -163,4 +164,9 @@ const Addons = ({ urlParams, queryParams }) => { ); }; +Addons.propTypes = { + urlParams: PropTypes.instanceOf(URLSearchParams), + queryParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = Addons; diff --git a/src/routes/Board/Board.js b/src/routes/Board/Board.js index 33b6638ae..47f293f45 100644 --- a/src/routes/Board/Board.js +++ b/src/routes/Board/Board.js @@ -32,7 +32,7 @@ const Board = () => { {board.catalog_resources.map((catalog_resource, index) => { const title = `${catalog_resource.addon_name} - ${catalog_resource.request.path.id} ${catalog_resource.request.path.type_name}`; switch (catalog_resource.content.type) { - case 'Ready': + case 'Ready': { return ( { limit={10} /> ); - case 'Err': + } + case 'Err': { const message = `Error(${catalog_resource.content.content.type})${typeof catalog_resource.content.content.content === 'string' ? ` - ${catalog_resource.content.content.content}` : ''}`; return ( { limit={10} /> ); - case 'Loading': + } + case 'Loading': { return ( { limit={10} /> ); + } } })}
diff --git a/src/routes/Discover/Discover.js b/src/routes/Discover/Discover.js index 0db14b05e..72baa410b 100644 --- a/src/routes/Discover/Discover.js +++ b/src/routes/Discover/Discover.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); const { Button, MainNavBar, MetaItem, MetaPreview, Multiselect, ModalDialog, PaginationInput, useBinaryState } = require('stremio/common'); @@ -135,4 +136,9 @@ const Discover = ({ urlParams, queryParams }) => { ); }; +Discover.propTypes = { + urlParams: PropTypes.instanceOf(URLSearchParams), + queryParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = Discover; diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index 6b05700ab..8f4959499 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); const { useRouteFocused } = require('stremio-router'); @@ -73,14 +74,17 @@ const Intro = ({ queryParams }) => { React.useEffect(() => { const onEvent = ({ event, args }) => { switch (event) { - case 'CtxActionErr': + case 'CtxActionErr': { const [_action, error] = args; dispatch({ type: 'error', error: error.args.message }); - case 'CtxChanged': + break; + } + case 'CtxChanged': { const state = core.getState(); if (state.ctx.content.auth !== null) { window.location.replace('#/'); } + } } }; if (routeFocused) { @@ -343,4 +347,8 @@ const Intro = ({ queryParams }) => { ); }; +Intro.propTypes = { + queryParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = Intro; diff --git a/src/routes/Library/Library.js b/src/routes/Library/Library.js index 0f3013cfb..3de671136 100644 --- a/src/routes/Library/Library.js +++ b/src/routes/Library/Library.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const { Button, Multiselect, MainNavBar, MetaItem } = require('stremio/common'); const useLibrary = require('./useLibrary'); @@ -67,6 +68,11 @@ const Library = ({ urlParams, queryParams }) => { ); -} +}; + +Library.propTypes = { + urlParams: PropTypes.instanceOf(URLSearchParams), + queryParams: PropTypes.instanceOf(URLSearchParams) +}; module.exports = Library; diff --git a/src/routes/Library/useItemOptions.js b/src/routes/Library/useItemOptions.js index 870c14936..37edcd1a1 100644 --- a/src/routes/Library/useItemOptions.js +++ b/src/routes/Library/useItemOptions.js @@ -10,7 +10,7 @@ const DISMISS_OPTION = { value: 'dismiss' }; -const onSelect = (event) => { +const onSelect = (_event) => { // TODO {{event.value}} {{event.dataset}} }; diff --git a/src/routes/Library/useLibrary.js b/src/routes/Library/useLibrary.js index 4acaa6e78..b2426e055 100644 --- a/src/routes/Library/useLibrary.js +++ b/src/routes/Library/useLibrary.js @@ -90,6 +90,6 @@ const useLibrary = (urlParams, queryParams) => { init: initLibraryState, onNewState: onNewLibraryState }); -} +}; module.exports = useLibrary; diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index a19227a6c..16417e77a 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const { NavBar, MetaPreview, useInLibrary } = require('stremio/common'); const VideosList = require('./VideosList'); const StreamsList = require('./StreamsList'); @@ -98,4 +99,8 @@ const MetaDetails = ({ urlParams }) => { ); }; +MetaDetails.propTypes = { + urlParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = MetaDetails; diff --git a/src/routes/MetaDetails/StreamsList/StreamsList.js b/src/routes/MetaDetails/StreamsList/StreamsList.js index 01163b29a..2e0f8de86 100644 --- a/src/routes/MetaDetails/StreamsList/StreamsList.js +++ b/src/routes/MetaDetails/StreamsList/StreamsList.js @@ -44,7 +44,7 @@ const StreamsList = ({ className, streamsResources }) => { ); -} +}; StreamsList.propTypes = { className: PropTypes.string, diff --git a/src/routes/Search/Search.js b/src/routes/Search/Search.js index f76ea5c05..a860bce47 100644 --- a/src/routes/Search/Search.js +++ b/src/routes/Search/Search.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const Icon = require('stremio-icons/dom'); const { MainNavBar, MetaRow } = require('stremio/common'); const useSearch = require('./useSearch'); @@ -68,6 +69,10 @@ const Search = ({ queryParams }) => { ); -} +}; + +Search.propTypes = { + queryParams: PropTypes.instanceOf(URLSearchParams) +}; module.exports = Search; diff --git a/src/services/Core/Core.js b/src/services/Core/Core.js index dc0c48894..cbb741f3c 100644 --- a/src/services/Core/Core.js +++ b/src/services/Core/Core.js @@ -96,6 +96,6 @@ function Core() { this.getState = getState; Object.freeze(this); -}; +} module.exports = Core; diff --git a/src/services/KeyboardNavigation/KeyboardNavigation.js b/src/services/KeyboardNavigation/KeyboardNavigation.js index 4dc1586f5..bd46169d2 100644 --- a/src/services/KeyboardNavigation/KeyboardNavigation.js +++ b/src/services/KeyboardNavigation/KeyboardNavigation.js @@ -41,6 +41,6 @@ function KeyboardNavigation() { this.stop = stop; Object.freeze(this); -}; +} module.exports = KeyboardNavigation; diff --git a/src/services/ServicesContext/index.js b/src/services/ServicesContext/index.js index 95c276ac2..d61874550 100644 --- a/src/services/ServicesContext/index.js +++ b/src/services/ServicesContext/index.js @@ -4,4 +4,4 @@ const useServices = require('./useServices'); module.exports = { ServicesProvider, useServices -}; \ No newline at end of file +}; diff --git a/src/services/Shell/Shell.js b/src/services/Shell/Shell.js index efc3613ff..f1ae8bbb4 100644 --- a/src/services/Shell/Shell.js +++ b/src/services/Shell/Shell.js @@ -66,6 +66,6 @@ function Shell() { this.dispatch = dispatch; Object.freeze(this); -}; +} module.exports = Shell; From b2bfcee2f82b5b879a7267236faebf405d66998b Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Thu, 12 Dec 2019 18:34:25 +0200 Subject: [PATCH 05/28] useInLibrary hook linked with the core --- src/common/useInLibrary.js | 64 +++++++++++++++++++++++---- src/routes/MetaDetails/MetaDetails.js | 15 ++++++- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/src/common/useInLibrary.js b/src/common/useInLibrary.js index 2f595ed15..f9de835c0 100644 --- a/src/common/useInLibrary.js +++ b/src/common/useInLibrary.js @@ -1,12 +1,60 @@ -const useBinaryState = require('stremio/common/useBinaryState'); +const React = require('react'); +const { useServices } = require('stremio/services'); +const useModelState = require('stremio/common/useModelState'); -const useInLibrary = (id) => { - const [inLibrary, addToLibrary, removeFromLibrary, toggleInLibrary] = useBinaryState(false); - if (typeof id === 'string') { - return [inLibrary, addToLibrary, removeFromLibrary, toggleInLibrary]; - } else { - return [false, null, null, null]; - } +const useInLibrary = (metaItem) => { + const { core } = useServices(); + const initLibraryItemsState = React.useCallback(() => { + return core.getState('library_items'); + }, []); + const libraryItems = useModelState({ + model: 'library_items', + init: initLibraryItemsState + }); + const addToLibrary = React.useCallback((metaItem) => { + core.dispatch({ + action: 'UserOp', + args: { + userOp: 'AddToLibrary', + args: { + meta_item: metaItem, + now: new Date() + } + } + }); + }, []); + const removeFromLibrary = React.useCallback((id) => { + core.dispatch({ + action: 'UserOp', + args: { + userOp: 'RemoveFromLibrary', + args: { + id, + now: new Date() + } + } + }); + }, []); + const inLibrary = React.useMemo(() => { + return typeof metaItem === 'object' && metaItem !== null ? + libraryItems.ids.includes(metaItem.id) + : + false; + }, [metaItem, libraryItems]); + const toggleInLibrary = React.useMemo(() => { + if (typeof metaItem !== 'object' || metaItem === null) { + return null; + } + + return () => { + if (inLibrary) { + removeFromLibrary(metaItem.id); + } else { + addToLibrary(metaItem); + } + }; + }, [metaItem, inLibrary]); + return [inLibrary, toggleInLibrary]; }; module.exports = useInLibrary; diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index a19227a6c..a800ea1a7 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -11,7 +11,20 @@ const MetaDetails = ({ urlParams }) => { const [metaResourceRef, metaResources, selectedMetaResource] = useSelectableResource(metaDetails.selected.meta_resource_ref, metaDetails.meta_resources); const streamsResourceRef = metaDetails.selected.streams_resource_ref; const streamsResources = metaDetails.streams_resources; - const [inLibrary, , , toggleInLibrary] = useInLibrary(metaResourceRef !== null ? metaResourceRef.id : null); + const metaItem = React.useMemo(() => { + return selectedMetaResource !== null ? + selectedMetaResource.content.content + : + metaResourceRef !== null ? + { + id: metaResourceRef.id, + type: metaResourceRef.type_name, + name: '' + } + : + null; + }, [metaResourceRef, selectedMetaResource]); + const [inLibrary, toggleInLibrary] = useInLibrary(metaItem); return (
Date: Fri, 13 Dec 2019 13:34:28 +0200 Subject: [PATCH 06/28] Addons screen ui adapted to changes in core --- src/routes/Addons/Addons.js | 254 +++++++++++------------ src/routes/Addons/styles.less | 65 +++--- src/routes/Addons/useAddons.js | 25 ++- src/routes/Addons/useSelectableInputs.js | 18 +- 4 files changed, 188 insertions(+), 174 deletions(-) diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 0a8152a17..6e47ee363 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -1,49 +1,69 @@ const React = require('react'); const Icon = require('stremio-icons/dom'); -const { Button, Multiselect, NavBar, TextInput, SharePrompt, ModalDialog } = require('stremio/common'); +const { Button, Multiselect, NavBar, TextInput, SharePrompt, ModalDialog, useBinaryState } = require('stremio/common'); const Addon = require('./Addon'); -const AddonPrompt = require('./AddonPrompt'); const useAddons = require('./useAddons'); -const useSelectedAddon = require('./useSelectedAddon'); +const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); const Addons = ({ urlParams, queryParams }) => { - const inputRef = React.useRef(null); - const [query, setQuery] = React.useState(''); - const queryOnChange = React.useCallback((event) => { - setQuery(event.currentTarget.value); - }, []); - const [[addons, dropdowns, setSelectedAddon, installedAddons, error], installSelectedAddon, uninstallSelectedAddon] = useAddons(urlParams, queryParams); - const [addAddonModalOpened, setAddAddonModalOpened] = React.useState(false); - const [selectedAddon, clearSelectedAddon] = useSelectedAddon(queryParams.get('addon')); - const [sharedAddon, setSharedAddon] = React.useState(null); - const onAddAddonButtonClicked = React.useCallback(() => { - setAddAddonModalOpened(true); - }, []); - const onAddButtonClicked = React.useCallback(() => { - if (inputRef.current.value.length > 0) { - setSelectedAddon(inputRef.current.value); - setAddAddonModalOpened(false); + const addons = useAddons(urlParams); + const selectInputs = useSelectableInputs(addons); + const [addAddonModalOpen, openAddAddonModal, closeAddAddonModal] = useBinaryState(false); + const addAddonUrlInputRef = React.useRef(null); + const addAddonOnSubmit = React.useCallback(() => { + if (addAddonUrlInputRef.current !== null) { + // TODO install addon } - }, [setSelectedAddon]); - const installedAddon = React.useCallback((currentAddon) => { - return installedAddons.some((installedAddon) => installedAddon.transportUrl === currentAddon.transportUrl); - }, [installedAddons]); - const toggleAddon = React.useCallback(() => { - installedAddon(selectedAddon) ? uninstallSelectedAddon(selectedAddon) : installSelectedAddon(selectedAddon); - clearSelectedAddon(); - }, [selectedAddon]); + }, []); + const addAddonModalButtons = React.useMemo(() => { + return [ + { + className: styles['cancel-button'], + label: 'Cancel', + props: { + onClick: closeAddAddonModal + } + }, + { + label: 'Add', + props: { + onClick: addAddonOnSubmit + } + } + ]; + }, []); + const [search, setSearch] = React.useState(''); + const searchInputOnChange = React.useCallback((event) => { + setSearch(event.currentTarget.value); + }, []); + const [sharedTransportUrl, setSharedTransportUrl] = React.useState(null); + const shareModalOnClose = React.useCallback(() => { + setSharedTransportUrl(null); + }, []); + const onAddonShare = React.useCallback((event) => { + setSharedTransportUrl(event.dataset.transportUrl); + }, []); + React.useLayoutEffect(() => { + closeAddAddonModal(null); + setSearch(''); + setSharedTransportUrl(null); + }, [urlParams, queryParams]); return (
-
- - {dropdowns.map((dropdown, index) => ( - + {selectInputs.map((selectInput, index) => ( + ))}
-
- { - error !== null ? + { + addons.selectable.catalogs.length === 0 && addons.catalog_resource === null ? +
+ No addons +
+ : + addons.catalog_resource === null ?
- {error.type}{error.type === 'Other' ? ` - ${error.content}` : null} + No select
: - Array.isArray(addons) ? - addons.filter((addon) => query.length === 0 || - ((typeof addon.manifest.name === 'string' && addon.manifest.name.toLowerCase().includes(query.toLowerCase())) || - (typeof addon.manifest.description === 'string' && addon.manifest.description.toLowerCase().includes(query.toLowerCase())) - )) - .map((addon, index) => ( - setSelectedAddon(addon.transportUrl)} - onShareButtonClicked={() => setSharedAddon(addon)} - /> - )) - : + addons.catalog_resource.content.type === 'Err' ?
- Loading + Addons could not be loaded
- } -
- { - addAddonModalOpened ? - setAddAddonModalOpened(false) - } - }, - { - label: 'Add', - props: { - title: 'Add', - onClick: onAddButtonClicked - } - } - ]} - onCloseRequest={() => setAddAddonModalOpened(false)} - > - - - : - null - } - { - selectedAddon !== null ? - - - - : - null - } - { - sharedAddon !== null ? - setSharedAddon(null)}> - setSharedAddon(null)} - /> - - : - null + : + addons.catalog_resource.content.type === 'Loading' ? +
+ Loading +
+ : +
+ { + addons.catalog_resource.content.content + .filter((addon) => { + return search.length === 0 || + ( + (typeof addon.manifest.name === 'string' && addon.manifest.name.toLowerCase().includes(search.toLowerCase())) || + (typeof addon.manifest.description === 'string' && addon.manifest.description.toLowerCase().includes(search.toLowerCase())) + ); + }) + .map((addon, index) => ( + + )) + } +
}
+ { + addAddonModalOpen ? + + + + : + null + } + { + typeof sharedTransportUrl === 'string' ? + + + + : + null + }
); }; diff --git a/src/routes/Addons/styles.less b/src/routes/Addons/styles.less index ff3b7f2c1..b17fbfd46 100644 --- a/src/routes/Addons/styles.less +++ b/src/routes/Addons/styles.less @@ -1,3 +1,7 @@ +:import('~stremio/common/Multiselect/styles.less') { + multiselect-menu-container: menu-container; +} + .addons-container { display: flex; flex-direction: column; @@ -16,11 +20,12 @@ display: flex; flex-direction: column; - .top-bar-container { + .selectable-inputs-container { flex: none; + align-self: stretch; display: flex; flex-direction: row; - margin: 2rem; + padding: 1.5rem; overflow: visible; .add-button-container { @@ -30,7 +35,7 @@ align-items: center; height: 3rem; max-width: 15rem; - margin-right: 1rem; + margin-right: 1.5rem; padding: 0 1rem; background-color: var(--color-signal5); @@ -40,8 +45,8 @@ .icon { flex: none; - width: 1.5rem; - height: 1.5rem; + width: 1.2rem; + height: 1.2rem; margin-right: 1rem; fill: var(--color-surfacelighter); } @@ -56,12 +61,17 @@ } } - .dropdown { + .select-input-container { flex-grow: 0; flex-shrink: 1; flex-basis: 15rem; height: 3rem; - margin-right: 1rem; + margin-right: 1.5rem; + + .multiselect-menu-container { + max-height: calc(3.2rem * 7); + overflow: auto; + } } .search-bar-container { @@ -72,7 +82,6 @@ flex-direction: row; align-items: center; height: 3rem; - margin-right: 1rem; padding: 0 1rem; background-color: var(--color-backgroundlighter); cursor: text; @@ -82,7 +91,7 @@ } .icon { - display: block; + flex: none; width: 1.2rem; height: 1.2rem; margin-right: 1rem; @@ -91,7 +100,6 @@ .search-input { flex: 1; - align-self: stretch; color: var(--color-surfacelighter); &::placeholder { @@ -103,32 +111,31 @@ } } - .addons-list-container { + .message-container { flex: 1; align-self: stretch; - padding: 0 2rem; + padding: 0 1.5rem; + font-size: 2rem; + color: var(--color-surfacelighter); + } + + .addons-container { + flex: 1; + align-self: stretch; + padding: 0 1.5rem; overflow-y: auto; .addon { - width: 100%; - margin-bottom: 2rem; - } - - .message-container { - padding: 0 2rem; - font-size: 2rem; - color: var(--color-surfacelighter); + margin-bottom: 1.5rem; } } } } -.add-addon-prompt-container { - .url-content { - flex: 1; - width: 100%; - padding: 0.5rem; - font-size: 0.9rem; +.add-addon-modal-container { + .addon-url-input { + width: 25rem; + padding: 0.5rem 1rem; color: var(--color-surfacedark); border: thin solid var(--color-surface); } @@ -138,8 +145,8 @@ } } -.addon-prompt-container { - .cancel-button { - background-color: var(--color-surfacedark); +.share-modal-container { + .share-prompt-container { + width: 25rem; } } \ No newline at end of file diff --git a/src/routes/Addons/useAddons.js b/src/routes/Addons/useAddons.js index b29b23cd4..aad7086bc 100644 --- a/src/routes/Addons/useAddons.js +++ b/src/routes/Addons/useAddons.js @@ -15,8 +15,29 @@ const initAddonsState = () => ({ const mapAddonsStateWithCtx = (addons, ctx) => { const selectable = addons.selectable; - const catalog_resource = addons.catalog_resource; - // TODO add MY catalogId replace catalog content if resource catalog id is MY + // TODO replace catalog content if resource catalog id is MY + const catalog_resource = addons.catalog_resource !== null && addons.catalog_resource.content.type === 'Ready' ? + { + ...addons.catalog_resource, + content: { + ...addons.catalog_resource.content, + content: addons.catalog_resource.content.content.map((descriptor) => ({ + transportUrl: descriptor.transportUrl, + installed: ctx.content.addons.some((addon) => addon.transportUrl === descriptor.transportUrl), + manifest: { + id: descriptor.manifest.id, + name: descriptor.manifest.name, + version: descriptor.manifest.version, + logo: descriptor.manifest.logo, + description: descriptor.manifest.description, + types: descriptor.manifest.types, + catalogs: descriptor.manifest.catalogs, + } + })) + } + } + : + addons.catalog_resource; return { selectable, catalog_resource }; }; diff --git a/src/routes/Addons/useSelectableInputs.js b/src/routes/Addons/useSelectableInputs.js index 8376fa846..1b1c4dd15 100644 --- a/src/routes/Addons/useSelectableInputs.js +++ b/src/routes/Addons/useSelectableInputs.js @@ -15,18 +15,6 @@ const equalWithouExtra = (request1, request2) => { }; const mapSelectableInputs = (addons) => { - const selectedCatalogRequest = addons.catalog_resource !== null ? - addons.catalog_resource.request - : - { - base: null, - path: { - resource: 'addon_catalog', - id: null, - type_name: null, - extra: [] - } - }; const catalogSelect = { title: 'Select catalog', options: addons.selectable.catalogs @@ -36,7 +24,8 @@ const mapSelectableInputs = (addons) => { })), selected: addons.selectable.catalogs .filter(({ load_request: { path: { id } } }) => { - return id === selectedCatalogRequest.path.id; + return addons.catalog_resource !== null && + addons.catalog_resource.request.path.id === id; }) .map(({ load_request }) => JSON.stringify(load_request)), onSelect: (event) => { @@ -52,7 +41,8 @@ const mapSelectableInputs = (addons) => { })), selected: addons.selectable.types .filter(({ load_request }) => { - return equalWithouExtra(load_request, selectedCatalogRequest); + return addons.catalog_resource !== null && + equalWithouExtra(addons.catalog_resource.request, load_request); }) .map(({ load_request }) => JSON.stringify(load_request)), onSelect: (event) => { From 5939a98bc633ae062e9cc3f4ac8be4045531f03b Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Fri, 13 Dec 2019 18:12:00 +0200 Subject: [PATCH 07/28] redirect to addon details on submit --- src/routes/Addons/Addons.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 6e47ee363..504145fcf 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -13,9 +13,17 @@ const Addons = ({ urlParams, queryParams }) => { const addAddonUrlInputRef = React.useRef(null); const addAddonOnSubmit = React.useCallback(() => { if (addAddonUrlInputRef.current !== null) { - // TODO install addon + const queryParams = new URLSearchParams([['addon', addAddonUrlInputRef.current.value]]); + if (typeof urlParams.addonTransportUrl === 'string' && typeof urlParams.catalogId === 'string' && typeof urlParams.type === 'string') { + const addonTransportUrl = encodeURIComponent(urlParams.addonTransportUrl); + const catalogId = encodeURIComponent(urlParams.catalogId); + const type = encodeURIComponent(urlParams.type); + window.location.replace(`#/addons/${addonTransportUrl}/${catalogId}/${type}?${queryParams}`); + } else { + window.location.replace(`#/addons?${queryParams}`); + } } - }, []); + }, [urlParams]); const addAddonModalButtons = React.useMemo(() => { return [ { @@ -32,7 +40,7 @@ const Addons = ({ urlParams, queryParams }) => { } } ]; - }, []); + }, [addAddonOnSubmit]); const [search, setSearch] = React.useState(''); const searchInputOnChange = React.useCallback((event) => { setSearch(event.currentTarget.value); From bd03788c3d96aaed9f3f78bc676893095c1b5e42 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Fri, 13 Dec 2019 18:14:30 +0200 Subject: [PATCH 08/28] navigate to addon details moved in a separate function --- src/routes/Addons/Addons.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 504145fcf..054fd5b57 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -7,23 +7,26 @@ const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); const Addons = ({ urlParams, queryParams }) => { + const navigateToAddonDetails = React.useCallback((transportUrl) => { + const queryParams = new URLSearchParams([['addon', transportUrl]]); + if (typeof urlParams.addonTransportUrl === 'string' && typeof urlParams.catalogId === 'string' && typeof urlParams.type === 'string') { + const addonTransportUrl = encodeURIComponent(urlParams.addonTransportUrl); + const catalogId = encodeURIComponent(urlParams.catalogId); + const type = encodeURIComponent(urlParams.type); + window.location.replace(`#/addons/${addonTransportUrl}/${catalogId}/${type}?${queryParams}`); + } else { + window.location.replace(`#/addons?${queryParams}`); + } + }, [urlParams]); const addons = useAddons(urlParams); const selectInputs = useSelectableInputs(addons); const [addAddonModalOpen, openAddAddonModal, closeAddAddonModal] = useBinaryState(false); const addAddonUrlInputRef = React.useRef(null); const addAddonOnSubmit = React.useCallback(() => { if (addAddonUrlInputRef.current !== null) { - const queryParams = new URLSearchParams([['addon', addAddonUrlInputRef.current.value]]); - if (typeof urlParams.addonTransportUrl === 'string' && typeof urlParams.catalogId === 'string' && typeof urlParams.type === 'string') { - const addonTransportUrl = encodeURIComponent(urlParams.addonTransportUrl); - const catalogId = encodeURIComponent(urlParams.catalogId); - const type = encodeURIComponent(urlParams.type); - window.location.replace(`#/addons/${addonTransportUrl}/${catalogId}/${type}?${queryParams}`); - } else { - window.location.replace(`#/addons?${queryParams}`); - } + navigateToAddonDetails(addAddonUrlInputRef.current.value); } - }, [urlParams]); + }, [navigateToAddonDetails]); const addAddonModalButtons = React.useMemo(() => { return [ { From 160b8b4a5b1f9c0a5e511126015d48a8ce83a010 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Fri, 13 Dec 2019 18:16:41 +0200 Subject: [PATCH 09/28] onToggle cb added to Addon --- src/routes/Addons/Addons.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 054fd5b57..4dfaff765 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -55,6 +55,9 @@ const Addons = ({ urlParams, queryParams }) => { const onAddonShare = React.useCallback((event) => { setSharedTransportUrl(event.dataset.transportUrl); }, []); + const onAddonToggle = React.useCallback((event) => { + navigateToAddonDetails(event.dataset.transportUrl); + }, []); React.useLayoutEffect(() => { closeAddAddonModal(null); setSearch(''); @@ -128,8 +131,8 @@ const Addons = ({ urlParams, queryParams }) => { description={addon.manifest.description} types={addon.manifest.types} version={addon.manifest.version} - transportUrl={addon.transportUrl} onShare={onAddonShare} + onToggle={onAddonToggle} dataset={{ transportUrl: addon.transportUrl }} /> )) From 5282ad936799bc45aff763f2a0e1a720c42e3b03 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Fri, 13 Dec 2019 18:19:17 +0200 Subject: [PATCH 10/28] addons list ui fixed --- src/routes/Addons/Addons.js | 2 +- src/routes/Addons/styles.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 4dfaff765..c99f7bc30 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -111,7 +111,7 @@ const Addons = ({ urlParams, queryParams }) => { Loading
: -
+
{ addons.catalog_resource.content.content .filter((addon) => { diff --git a/src/routes/Addons/styles.less b/src/routes/Addons/styles.less index b17fbfd46..f7ef52dcd 100644 --- a/src/routes/Addons/styles.less +++ b/src/routes/Addons/styles.less @@ -119,7 +119,7 @@ color: var(--color-surfacelighter); } - .addons-container { + .addons-list-container { flex: 1; align-self: stretch; padding: 0 1.5rem; From 91c692a0c46e0eae0afa8633ce9555f5da863ed5 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Fri, 13 Dec 2019 18:20:03 +0200 Subject: [PATCH 11/28] useSelectedAddon dropped --- src/routes/Addons/useSelectedAddon.js | 35 --------------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/routes/Addons/useSelectedAddon.js diff --git a/src/routes/Addons/useSelectedAddon.js b/src/routes/Addons/useSelectedAddon.js deleted file mode 100644 index 5bffaec37..000000000 --- a/src/routes/Addons/useSelectedAddon.js +++ /dev/null @@ -1,35 +0,0 @@ -const React = require('react'); -const UrlUtils = require('url'); -const { routesRegexp, useLocationHash, useRouteActive } = require('stremio/common'); - -const useSelectedAddon = (transportUrl) => { - const [addon, setAddon] = React.useState(null); - const locationHash = useLocationHash(); - const active = useRouteActive(routesRegexp.addons.regexp); - React.useEffect(() => { - if (typeof transportUrl !== 'string') { - setAddon(null); - return; - } - - fetch(transportUrl) // TODO - .then((resp) => resp.json()) - .then((manifest) => setAddon({ manifest, transportUrl, flags: {} })); - }, [transportUrl]); - const clear = React.useCallback(() => { - if (active) { - const { pathname, search } = UrlUtils.parse(locationHash.slice(1)); - const queryParams = new URLSearchParams(search || ''); - queryParams.delete('addon'); - if ([...queryParams].length !== 0) { - window.location.replace(`#${pathname}?${queryParams.toString()}`); - } else { - window.location.replace(`#${pathname}`); - } - setAddon(null); - } - }, [active, locationHash]); - return [addon, clear, setAddon]; -}; - -module.exports = useSelectedAddon; From 3e1ab699f54b5d415932018af3afa07a1dcd9d9c Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Sun, 15 Dec 2019 01:38:16 +0200 Subject: [PATCH 12/28] Addon layout changed --- src/routes/Addons/Addon/Addon.js | 72 ++++++++++++++++++++--------- src/routes/Addons/Addon/styles.less | 25 +++------- src/routes/Addons/Addons.js | 57 ++++++++++++++--------- src/routes/Addons/useAddons.js | 3 +- 4 files changed, 93 insertions(+), 64 deletions(-) diff --git a/src/routes/Addons/Addon/Addon.js b/src/routes/Addons/Addon/Addon.js index 023c17732..d646ed2b9 100644 --- a/src/routes/Addons/Addon/Addon.js +++ b/src/routes/Addons/Addon/Addon.js @@ -2,24 +2,54 @@ const React = require('react'); const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); -const { Button } = require('stremio/common'); +const { Button, Image } = require('stremio/common'); const styles = require('./styles'); -const Addon = ({ className, id, name, logo, description, types, version, transportUrl, installed, toggle, onShareButtonClicked }) => { - const onKeyUp = React.useCallback((event) => { - if (event.key === 'Enter' && typeof toggle === 'function') { - toggle(event); +const Addon = ({ className, id, name, version, logo, description, types, installed, onToggle, onShare, dataset }) => { + const toggleButtonOnClick = React.useCallback((event) => { + if (typeof onToggle === 'function') { + onToggle({ + type: 'toggle', + nativeEvent: event.nativeEvent, + reactEvent: event, + dataset: dataset + }); } - }, [toggle]); + }, [onToggle, dataset]); + const shareButtonOnClick = React.useCallback((event) => { + if (typeof onShare === 'function') { + onShare({ + type: 'share', + nativeEvent: event.nativeEvent, + reactEvent: event, + dataset: dataset + }); + } + }, [onShare, dataset]); + const onKeyDown = React.useCallback((event) => { + if (event.key === 'Enter' && typeof onToggle === 'function') { + onToggle({ + type: 'toggle', + nativeEvent: event.nativeEvent, + reactEvent: event, + dataset: dataset + }); + } + }, [onToggle, dataset]); + const renderLogoFallback = React.useMemo(() => () => { + return ( + + ); + }, []); return ( - - @@ -68,14 +98,14 @@ Addon.propTypes = { className: PropTypes.string, id: PropTypes.string, name: PropTypes.string, + version: PropTypes.string, logo: PropTypes.string, description: PropTypes.string, types: PropTypes.arrayOf(PropTypes.string), - version: PropTypes.string, - transportUrl: PropTypes.string, installed: PropTypes.bool, - toggle: PropTypes.func, - onShareButtonClicked: PropTypes.func + onToggle: PropTypes.func, + onShare: PropTypes.func, + dataset: PropTypes.objectOf(PropTypes.string) }; module.exports = Addon; diff --git a/src/routes/Addons/Addon/styles.less b/src/routes/Addons/Addon/styles.less index 2ae172544..e57eea428 100644 --- a/src/routes/Addons/Addon/styles.less +++ b/src/routes/Addons/Addon/styles.less @@ -1,7 +1,6 @@ .addon-container { display: flex; flex-direction: row; - flex-wrap: wrap; align-items: flex-start; padding: 1rem; background-color: var(--color-backgroundlighter); @@ -17,6 +16,7 @@ display: block; width: 100%; height: 100%; + padding: 0.5rem; object-fit: contain; object-position: center; } @@ -31,14 +31,13 @@ } .info-container { - flex-grow: 1000; + flex-grow: 1; flex-shrink: 1; flex-basis: 0; display: flex; flex-direction: row; flex-wrap: wrap; align-items: baseline; - min-width: 40rem; padding: 0 0.5rem; .name-container { @@ -47,7 +46,7 @@ flex-basis: auto; padding: 0 0.5rem; max-height: 3.6em; - font-size: 1.5rem; + font-size: 1.6rem; color: var(--color-surfacelighter); } @@ -55,6 +54,7 @@ flex-grow: 1; flex-shrink: 1; flex-basis: auto; + margin-top: 0.5rem; padding: 0 0.5rem; max-height: 2.4em; color: var(--color-surfacelight); @@ -83,22 +83,14 @@ } .buttons-container { - flex-grow: 1; - flex-shrink: 0; - flex-basis: 0; - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: flex-end; - min-width: 17rem; + flex: none; + width: 17rem; .install-button-container, .uninstall-button-container, .share-button-container { - flex: none; display: flex; flex-direction: row; align-items: center; justify-content: center; - width: 17rem; height: 3.5rem; padding: 0 1rem; @@ -106,13 +98,8 @@ margin-top: 1rem; } - &:not(:last-child) { - margin-right: 1rem; - } - .icon { flex: none; - display: block; width: 1.5rem; height: 1.5rem; margin-right: 1rem; diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index c99f7bc30..083c16747 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -6,27 +6,32 @@ const useAddons = require('./useAddons'); const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); +const navigateToAddonDetails = (addonsCatalogRequest, transportUrl) => { + const queryParams = new URLSearchParams([['addon', transportUrl]]); + if (addonsCatalogRequest !== null) { + const addonTransportUrl = encodeURIComponent(addonsCatalogRequest.base); + const catalogId = encodeURIComponent(addonsCatalogRequest.path.id); + const type = encodeURIComponent(addonsCatalogRequest.path.type_name); + window.location.replace(`#/addons/${addonTransportUrl}/${catalogId}/${type}?${queryParams}`); + } else { + window.location.replace(`#/addons?${queryParams}`); + } +}; + const Addons = ({ urlParams, queryParams }) => { - const navigateToAddonDetails = React.useCallback((transportUrl) => { - const queryParams = new URLSearchParams([['addon', transportUrl]]); - if (typeof urlParams.addonTransportUrl === 'string' && typeof urlParams.catalogId === 'string' && typeof urlParams.type === 'string') { - const addonTransportUrl = encodeURIComponent(urlParams.addonTransportUrl); - const catalogId = encodeURIComponent(urlParams.catalogId); - const type = encodeURIComponent(urlParams.type); - window.location.replace(`#/addons/${addonTransportUrl}/${catalogId}/${type}?${queryParams}`); - } else { - window.location.replace(`#/addons?${queryParams}`); - } - }, [urlParams]); const addons = useAddons(urlParams); const selectInputs = useSelectableInputs(addons); const [addAddonModalOpen, openAddAddonModal, closeAddAddonModal] = useBinaryState(false); const addAddonUrlInputRef = React.useRef(null); const addAddonOnSubmit = React.useCallback(() => { if (addAddonUrlInputRef.current !== null) { - navigateToAddonDetails(addAddonUrlInputRef.current.value); + const addonsCatalogRequest = addons.catalog_resource !== null ? + addons.catalog_resource.request + : + null; + navigateToAddonDetails(addonsCatalogRequest, addAddonUrlInputRef.current.value); } - }, [navigateToAddonDetails]); + }, [addons]); const addAddonModalButtons = React.useMemo(() => { return [ { @@ -49,19 +54,23 @@ const Addons = ({ urlParams, queryParams }) => { setSearch(event.currentTarget.value); }, []); const [sharedTransportUrl, setSharedTransportUrl] = React.useState(null); - const shareModalOnClose = React.useCallback(() => { + const clearSharedTransportUrl = React.useCallback(() => { setSharedTransportUrl(null); }, []); const onAddonShare = React.useCallback((event) => { setSharedTransportUrl(event.dataset.transportUrl); }, []); const onAddonToggle = React.useCallback((event) => { - navigateToAddonDetails(event.dataset.transportUrl); - }, []); + const addonsCatalogRequest = addons.catalog_resource !== null ? + addons.catalog_resource.request + : + null; + navigateToAddonDetails(addonsCatalogRequest, event.dataset.transportUrl); + }, [addons]); React.useLayoutEffect(() => { - closeAddAddonModal(null); + closeAddAddonModal(); setSearch(''); - setSharedTransportUrl(null); + clearSharedTransportUrl(); }, [urlParams, queryParams]); return (
@@ -127,12 +136,13 @@ const Addons = ({ urlParams, queryParams }) => { className={styles['addon']} id={addon.manifest.id} name={addon.manifest.name} + version={addon.manifest.version} logo={addon.manifest.logo} description={addon.manifest.description} types={addon.manifest.types} - version={addon.manifest.version} - onShare={onAddonShare} + installed={addon.installed} onToggle={onAddonToggle} + onShare={onAddonShare} dataset={{ transportUrl: addon.transportUrl }} /> )) @@ -163,8 +173,11 @@ const Addons = ({ urlParams, queryParams }) => { - + onCloseRequest={clearSharedTransportUrl}> + : null diff --git a/src/routes/Addons/useAddons.js b/src/routes/Addons/useAddons.js index aad7086bc..57be65b45 100644 --- a/src/routes/Addons/useAddons.js +++ b/src/routes/Addons/useAddons.js @@ -30,8 +30,7 @@ const mapAddonsStateWithCtx = (addons, ctx) => { version: descriptor.manifest.version, logo: descriptor.manifest.logo, description: descriptor.manifest.description, - types: descriptor.manifest.types, - catalogs: descriptor.manifest.catalogs, + types: descriptor.manifest.types } })) } From d78f2f66964780cfdb83afdc3baaf1d5c8b3ccba Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 11:22:55 +0200 Subject: [PATCH 13/28] useAddonDetails hook implemented --- src/routes/Addons/useAddonDetails.js | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/routes/Addons/useAddonDetails.js diff --git a/src/routes/Addons/useAddonDetails.js b/src/routes/Addons/useAddonDetails.js new file mode 100644 index 000000000..afa45eceb --- /dev/null +++ b/src/routes/Addons/useAddonDetails.js @@ -0,0 +1,48 @@ +const React = require('react'); +const { useModelState } = require('stremio/common'); + +const initAddonDetailsState = () => ({ + descriptor: null +}); + +const mapAddonDetailsStateWithCtx = (addonDetails, ctx) => { + const descriptor = addonDetails.descriptor !== null && addonDetails.descriptor.content.type === 'Ready' ? + { + ...addonDetails.descriptor, + content: { + ...addonDetails.descriptor.content, + installed: ctx.content.addons.some((addon) => addon.transportUrl === addonDetails.descriptor.transport_url), + } + } + : + addonDetails.descriptor; + return { descriptor }; +}; + +const useAddonDetails = (queryParams) => { + const loadAddonDetailsAction = React.useMemo(() => { + if (queryParams.has('addon')) { + return { + action: 'Load', + args: { + load: 'AddonDetails', + args: { + transport_url: queryParams.get('addon') + } + } + }; + } else { + return { + action: 'Unload' + }; + } + }, [queryParams]); + return useModelState({ + model: 'addon_details', + action: loadAddonDetailsAction, + mapWithCtx: mapAddonDetailsStateWithCtx, + init: initAddonDetailsState, + }); +}; + +module.exports = useAddonDetails; From 7eccd100ab3f069eec89febcba590be0e04d8d2b Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 11:40:27 +0200 Subject: [PATCH 14/28] urlParams proptypes fixed --- src/routes/Addons/Addons.js | 6 +++++- src/routes/Discover/Discover.js | 6 +++++- src/routes/Library/Library.js | 4 +++- src/routes/MetaDetails/MetaDetails.js | 6 +++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 5362c92e3..3f7874666 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -188,7 +188,11 @@ const Addons = ({ urlParams, queryParams }) => { }; Addons.propTypes = { - urlParams: PropTypes.instanceOf(URLSearchParams), + urlParams: PropTypes.exact({ + addonTransportUrl: PropTypes.string, + catalogId: PropTypes.string, + type: PropTypes.string + }), queryParams: PropTypes.instanceOf(URLSearchParams) }; diff --git a/src/routes/Discover/Discover.js b/src/routes/Discover/Discover.js index 72baa410b..4f8358b32 100644 --- a/src/routes/Discover/Discover.js +++ b/src/routes/Discover/Discover.js @@ -137,7 +137,11 @@ const Discover = ({ urlParams, queryParams }) => { }; Discover.propTypes = { - urlParams: PropTypes.instanceOf(URLSearchParams), + urlParams: PropTypes.exact({ + addonTransportUrl: PropTypes.string, + type: PropTypes.string, + catalogId: PropTypes.string + }), queryParams: PropTypes.instanceOf(URLSearchParams) }; diff --git a/src/routes/Library/Library.js b/src/routes/Library/Library.js index 3de671136..d3c081646 100644 --- a/src/routes/Library/Library.js +++ b/src/routes/Library/Library.js @@ -71,7 +71,9 @@ const Library = ({ urlParams, queryParams }) => { }; Library.propTypes = { - urlParams: PropTypes.instanceOf(URLSearchParams), + urlParams: PropTypes.exact({ + type: PropTypes.string, + }), queryParams: PropTypes.instanceOf(URLSearchParams) }; diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index 42221f5a8..3cd804345 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -113,7 +113,11 @@ const MetaDetails = ({ urlParams }) => { }; MetaDetails.propTypes = { - urlParams: PropTypes.instanceOf(URLSearchParams) + urlParams: PropTypes.exact({ + type: PropTypes.string, + id: PropTypes.string, + videoId: PropTypes.string + }) }; module.exports = MetaDetails; From 6a07be3504959cbcbe67a1f8b189f04d22832b14 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 12:01:19 +0200 Subject: [PATCH 15/28] eslint moved to dev deps --- package.json | 4 ++-- yarn.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 85d2ae48a..9c26d2763 100755 --- a/package.json +++ b/package.json @@ -16,8 +16,6 @@ "dependencies": { "a-color-picker": "1.2.1", "classnames": "2.2.6", - "eslint": "^6.7.2", - "eslint-plugin-react": "^7.17.0", "events": "1.1.1", "hat": "0.0.3", "lodash.debounce": "4.0.8", @@ -50,6 +48,8 @@ "css-loader": "3.2.1", "cssnano": "4.1.10", "cssnano-preset-advanced": "4.0.7", + "eslint": "6.7.2", + "eslint-plugin-react": "7.17.0", "html-webpack-plugin": "3.2.0", "jest": "24.9.0", "less": "3.10.3", diff --git a/yarn.lock b/yarn.lock index 07e5dd3cf..11542419f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4547,7 +4547,7 @@ eslint-plugin-eslint-plugin@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-plugin/-/eslint-plugin-eslint-plugin-2.1.0.tgz#a7a00f15a886957d855feacaafee264f039e62d5" integrity sha512-kT3A/ZJftt28gbl/Cv04qezb/NQ1dwYIbi8lyf806XMxkus7DvOVCLIfTXMrorp322Pnoez7+zabXH29tADIDg== -eslint-plugin-react@^7.17.0: +eslint-plugin-react@7.17.0: version "7.17.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.17.0.tgz#a31b3e134b76046abe3cd278e7482bd35a1d12d7" integrity sha512-ODB7yg6lxhBVMeiH1c7E95FLD4E/TwmFjltiU+ethv7KPdCwgiFuOZg9zNRHyufStTDLl/dEFqI2Q1VPmCd78A== @@ -4591,7 +4591,7 @@ eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.7.2: +eslint@6.7.2: version "6.7.2" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== From 1b5eb1244240bea171d553d03d915ddad7c7a4cf Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 12:07:42 +0200 Subject: [PATCH 16/28] use eslintrc file --- .eslintrc.js => .eslintrc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) rename .eslintrc.js => .eslintrc (93%) diff --git a/.eslintrc.js b/.eslintrc similarity index 93% rename from .eslintrc.js rename to .eslintrc index cf07f3159..97c755374 100644 --- a/.eslintrc.js +++ b/.eslintrc @@ -1,4 +1,4 @@ -module.exports = { +{ "extends": [ "eslint:recommended", "plugin:react/recommended" @@ -7,7 +7,11 @@ module.exports = { "YT": "readonly", "FB": "readonly" }, - "ignorePatterns": ["src/routes/Settings/**", "src/routes/Player/**", "src/video/**"], + "ignorePatterns": [ + "src/routes/Settings/**", + "src/routes/Player/**", + "src/video/**" + ], "rules": { "arrow-parens": "error", "arrow-spacing": "error", @@ -41,7 +45,9 @@ module.exports = { "no-console": [ "error", { - allow: ["error"] + "allow": [ + "error" + ] } ], "no-extra-semi": "error", @@ -104,7 +110,7 @@ module.exports = { "src/common/PaginationInput/PaginationInput.js" ], "rules": { - "react/prop-types": 0, + "react/prop-types": 0 } }, { @@ -139,4 +145,4 @@ module.exports = { } } ] -} +} \ No newline at end of file From 8917c88f1cb141129706416d80abcf0bf8ed63d5 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 12:09:00 +0200 Subject: [PATCH 17/28] eslint detect react version --- .eslintrc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.eslintrc b/.eslintrc index 97c755374..60e232c22 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,6 +3,11 @@ "eslint:recommended", "plugin:react/recommended" ], + "settings": { + "react": { + "version": "detect" + } + }, "globals": { "YT": "readonly", "FB": "readonly" From fba4e9f18faef08eda24edde9efb1240ca1e5703 Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 13:06:43 +0200 Subject: [PATCH 18/28] eslint config updated --- .eslintrc | 78 +++++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 49 deletions(-) diff --git a/.eslintrc b/.eslintrc index 60e232c22..a9ac04609 100644 --- a/.eslintrc +++ b/.eslintrc @@ -12,6 +12,17 @@ "YT": "readonly", "FB": "readonly" }, + "env": { + "commonjs": true, + "browser": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 9, + "ecmaFeatures": { + "jsx": true + } + }, "ignorePatterns": [ "src/routes/Settings/**", "src/routes/Player/**", @@ -21,25 +32,10 @@ "arrow-parens": "error", "arrow-spacing": "error", "block-spacing": "error", - "comma-spacing": [ - "error", - { - "before": false, - "after": true - } - ], - "eol-last": [ - "error", - "always" - ], - "eqeqeq": [ - "error", - "always" - ], - "func-call-spacing": [ - "error", - "never" - ], + "comma-spacing": "error", + "eol-last": "error", + "eqeqeq": "error", + "func-call-spacing": "error", "indent": [ "error", 4, @@ -47,21 +43,14 @@ "SwitchCase": 1 } ], - "no-console": [ - "error", - { - "allow": [ - "error" - ] - } - ], + "no-console": "error", "no-extra-semi": "error", "no-eq-null": "error", "no-multi-spaces": "error", "no-multiple-empty-lines": [ "error", { - "max": 2 + "max": 1 } ], "no-template-curly-in-string": "error", @@ -71,34 +60,25 @@ "no-unused-vars": "error", "prefer-const": "error", "quotes": [ - "warn", + "error", "single" ], - "semi": [ - "error", - "always" - ], - "semi-spacing": [ + "quote-props": [ "error", + "as-needed", { - "before": false, - "after": true + "unnecessary": false } ], + "semi": "error", + "semi-spacing": "error", "space-before-blocks": "error", - "valid-typeof": "error", - "react/no-unescaped-entities": 0 - }, - "env": { - "node": true, - "browser": true, - "es6": true - }, - "parserOptions": { - "ecmaVersion": 9, - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } + "valid-typeof": [ + "error", + { + "requireStringLiterals": true + } + ] }, "overrides": [ { From 5a84605c1522b5b2b7bd31befc1286c924b9a06a Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Mon, 16 Dec 2019 13:07:11 +0200 Subject: [PATCH 19/28] console.error removed from intro --- src/routes/Intro/Intro.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index 8f4959499..984b29369 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -117,9 +117,7 @@ const Intro = ({ queryParams }) => { } }); }) - .catch((err) => { - console.error(err); - }); + .catch((err) => { }); } }); }, [state.email, state.password]); @@ -260,7 +258,7 @@ const Intro = ({ queryParams }) => {
Continue with Facebook
-
We won't post anything on your behalf
+
We won't post anything on your behalf
Date: Mon, 16 Dec 2019 14:59:18 +0200 Subject: [PATCH 20/28] eslint react/prop-types enabled for all --- .eslintrc | 17 ----------------- src/common/Button/Button.js | 10 ++++++++++ src/common/Checkbox/Checkbox.js | 7 +++++++ src/common/ColorInput/ColorInput.js | 9 +++++---- src/common/Image/Image.js | 3 ++- src/common/MetaItem/MetaItem.js | 5 +++-- src/common/MetaPreview/MetaPreview.js | 4 ++-- src/common/ModalDialog/ModalDialog.js | 2 +- src/common/Multiselect/Multiselect.js | 5 +++-- src/common/PaginationInput/PaginationInput.js | 1 + src/common/Popup/Popup.js | 2 +- src/common/TextInput/TextInput.js | 8 ++++++++ .../Intro/ConsentCheckbox/ConsentCheckbox.js | 15 ++++++++++----- .../CredentialsTextInput.js | 5 +++++ src/routes/Intro/Intro.js | 6 +++--- .../VideosList/SeasonsBar/SeasonsBar.js | 8 +++----- .../MetaDetails/VideosList/Video/Video.js | 3 ++- 17 files changed, 66 insertions(+), 44 deletions(-) diff --git a/.eslintrc b/.eslintrc index a9ac04609..81b685301 100644 --- a/.eslintrc +++ b/.eslintrc @@ -81,23 +81,6 @@ ] }, "overrides": [ - { - "files": [ - "src/common/Button/Button.js", - "src/common/Checkbox/Checkbox.js", - "src/common/ColorInput/ColorInput.js", - "src/common/Image/Image.js", - "src/common/MetaItem/MetaItem.js", - "src/common/Multiselect/Multiselect.js", - "src/common/TextInput/TextInput.js", - "src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js", - "src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js", - "src/common/PaginationInput/PaginationInput.js" - ], - "rules": { - "react/prop-types": 0 - } - }, { "files": [ "src/routes/Intro/Intro.js", diff --git a/src/common/Button/Button.js b/src/common/Button/Button.js index 21512b041..89d7d342d 100644 --- a/src/common/Button/Button.js +++ b/src/common/Button/Button.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const styles = require('./styles'); @@ -41,4 +42,13 @@ const Button = React.forwardRef(({ className, href, disabled, children, ...props Button.displayName = 'Button'; +Button.propTypes = { + className: PropTypes.string, + href: PropTypes.string, + disabled: PropTypes.bool, + children: PropTypes.node, + onKeyDown: PropTypes.func, + onMouseDown: PropTypes.func +}; + module.exports = Button; diff --git a/src/common/Checkbox/Checkbox.js b/src/common/Checkbox/Checkbox.js index 96c29f334..6fd3f3a72 100644 --- a/src/common/Checkbox/Checkbox.js +++ b/src/common/Checkbox/Checkbox.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); const Button = require('stremio/common/Button'); @@ -22,4 +23,10 @@ const Checkbox = React.forwardRef(({ className, checked, children, ...props }, r Checkbox.displayName = 'Checkbox'; +Checkbox.propTypes = { + className: PropTypes.string, + checked: PropTypes.bool, + children: PropTypes.node +}; + module.exports = Checkbox; diff --git a/src/common/ColorInput/ColorInput.js b/src/common/ColorInput/ColorInput.js index f493a11f1..7e846a4a8 100644 --- a/src/common/ColorInput/ColorInput.js +++ b/src/common/ColorInput/ColorInput.js @@ -16,9 +16,8 @@ const ColorInput = ({ className, value, dataset, onChange, ...props }) => { return parseColor(value); }); const labelButtonStyle = React.useMemo(() => ({ - ...props.style, backgroundColor: value - }), [props.style, value]); + }), [value]); const labelButtonOnClick = React.useCallback((event) => { if (typeof props.onClick === 'function') { props.onClick(event); @@ -76,9 +75,11 @@ const ColorInput = ({ className, value, dataset, onChange, ...props }) => { }; ColorInput.propTypes = { + className: PropTypes.string, value: PropTypes.string, - dataset: PropTypes.objectOf(String), - onChange: PropTypes.func + dataset: PropTypes.objectOf(PropTypes.string), + onChange: PropTypes.func, + onClick: PropTypes.func }; module.exports = ColorInput; diff --git a/src/common/Image/Image.js b/src/common/Image/Image.js index 520fade03..8091c2615 100644 --- a/src/common/Image/Image.js +++ b/src/common/Image/Image.js @@ -27,7 +27,8 @@ Image.propTypes = { src: PropTypes.string, alt: PropTypes.string, fallbackSrc: PropTypes.string, - renderFallback: PropTypes.func + renderFallback: PropTypes.func, + onError: PropTypes.func }; module.exports = Image; diff --git a/src/common/MetaItem/MetaItem.js b/src/common/MetaItem/MetaItem.js index 5c130933a..4d4f6cb1f 100644 --- a/src/common/MetaItem/MetaItem.js +++ b/src/common/MetaItem/MetaItem.js @@ -121,8 +121,9 @@ MetaItem.propTypes = { playIcon: PropTypes.bool, progress: PropTypes.number, options: PropTypes.array, - dataset: PropTypes.objectOf(String), - optionOnSelect: PropTypes.func + dataset: PropTypes.objectOf(PropTypes.string), + optionOnSelect: PropTypes.func, + onClick: PropTypes.func }; module.exports = MetaItem; diff --git a/src/common/MetaPreview/MetaPreview.js b/src/common/MetaPreview/MetaPreview.js index 9cd1b7d8e..0aca83e9a 100644 --- a/src/common/MetaPreview/MetaPreview.js +++ b/src/common/MetaPreview/MetaPreview.js @@ -179,7 +179,7 @@ const MetaPreview = ({ className, compact, name, logo, background, runtime, rele null } { - linksGroups.hasOwnProperty(IMDB_LINK_CATEGORY) ? + typeof linksGroups[IMDB_LINK_CATEGORY] === 'object' ? { PaginationInput.propTypes = { className: PropTypes.string, label: PropTypes.string, + dataset: PropTypes.objectOf(PropTypes.string), onSelect: PropTypes.func }; diff --git a/src/common/Popup/Popup.js b/src/common/Popup/Popup.js index b956f764f..59b89f26e 100644 --- a/src/common/Popup/Popup.js +++ b/src/common/Popup/Popup.js @@ -103,7 +103,7 @@ Popup.propTypes = { direction: PropTypes.oneOf(['top-left', 'bottom-left', 'top-right', 'bottom-right']), renderLabel: PropTypes.func.isRequired, renderMenu: PropTypes.func.isRequired, - dataset: PropTypes.objectOf(String), + dataset: PropTypes.objectOf(PropTypes.string), onCloseRequest: PropTypes.func }; diff --git a/src/common/TextInput/TextInput.js b/src/common/TextInput/TextInput.js index 4f7db50f1..8b9606d6f 100644 --- a/src/common/TextInput/TextInput.js +++ b/src/common/TextInput/TextInput.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const styles = require('./styles'); @@ -30,4 +31,11 @@ const TextInput = React.forwardRef((props, ref) => { TextInput.displayName = 'TextInput'; +TextInput.propTypes = { + className: PropTypes.string, + disabled: PropTypes.bool, + onKeyDown: PropTypes.func, + onSubmit: PropTypes.func +}; + module.exports = TextInput; diff --git a/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js b/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js index fe1898b4e..df05b7e60 100644 --- a/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js +++ b/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js @@ -4,16 +4,20 @@ const classnames = require('classnames'); const { Button, Checkbox } = require('stremio/common'); const styles = require('./styles'); -const ConsentCheckbox = React.forwardRef(({ className, checked, label, link, href, toggle, ...props }, ref) => { +const ConsentCheckbox = React.forwardRef(({ className, checked, label, link, href, onToggle, ...props }, ref) => { const checkboxOnClick = React.useCallback((event) => { if (typeof props.onClick === 'function') { props.onClick(event); } - if (!event.nativeEvent.togglePrevented && typeof toggle === 'function') { - toggle(event); + if (!event.nativeEvent.togglePrevented && typeof onToggle === 'function') { + onToggle({ + type: 'toggle', + reactEvent: event, + nativeEvent: event.nativeEvent + }); } - }, [toggle]); + }, [onToggle]); const linkOnClick = React.useCallback((event) => { event.nativeEvent.togglePrevented = true; }, []); @@ -42,7 +46,8 @@ ConsentCheckbox.propTypes = { label: PropTypes.string, link: PropTypes.string, href: PropTypes.string, - toggle: PropTypes.func + onToggle: PropTypes.func, + onClick: PropTypes.func }; module.exports = ConsentCheckbox; diff --git a/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js b/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js index d3c7696cf..43a2bb087 100644 --- a/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js +++ b/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const { TextInput } = require('stremio/common'); const CredentialsTextInput = React.forwardRef((props, ref) => { @@ -23,4 +24,8 @@ const CredentialsTextInput = React.forwardRef((props, ref) => { CredentialsTextInput.displayName = 'CredentialsTextInput'; +CredentialsTextInput.propTypes = { + onKeyDown: PropTypes.func +}; + module.exports = CredentialsTextInput; diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index 984b29369..dc26b97e7 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -296,7 +296,7 @@ const Intro = ({ queryParams }) => { link={'Terms and conditions'} href={'https://www.stremio.com/tos'} checked={state.termsAccepted} - toggle={toggleTermsAccepted} + onToggle={toggleTermsAccepted} /> { link={'Privacy Policy'} href={'https://www.stremio.com/privacy'} checked={state.privacyPolicyAccepted} - toggle={togglePrivacyPolicyAccepted} + onToggle={togglePrivacyPolicyAccepted} /> : diff --git a/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js b/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js index cfe24abe3..d830d710d 100644 --- a/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js +++ b/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js @@ -16,11 +16,9 @@ const SeasonsBar = ({ className, seasons, season, onSelect }) => { const selected = React.useMemo(() => { return [String(season)]; }, [season]); - const renderMultiselectLabelContent = React.useMemo(() => { - return () => ( -
Season {season}
- ); - }, [season]); + const renderMultiselectLabelContent = React.useMemo(() => () => ( +
Season {season}
+ ), [season]); const prevNextButtonOnClick = React.useCallback((event) => { if (typeof onSelect === 'function') { const seasonIndex = seasons.indexOf(season); diff --git a/src/routes/MetaDetails/VideosList/Video/Video.js b/src/routes/MetaDetails/VideosList/Video/Video.js index 2bcd22f27..4b13e30e6 100644 --- a/src/routes/MetaDetails/VideosList/Video/Video.js +++ b/src/routes/MetaDetails/VideosList/Video/Video.js @@ -6,7 +6,7 @@ const Icon = require('stremio-icons/dom'); const VideoPlaceholder = require('./VideoPlaceholder'); const styles = require('./styles'); -const Video = ({ className, title, thumbnail, episode, released, upcoming, watched, progress, ...props }) => { +const Video = ({ className, id, title, thumbnail, episode, released, upcoming, watched, progress, ...props }) => { return (