diff --git a/package-lock.json b/package-lock.json index d894b61d0..805dabc6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -148,6 +148,8 @@ "@types/react-native": "0.67.6", "@types/react-redux": "7.1.24", "@types/uuid": "8.3.4", + "@typescript-eslint/eslint-plugin": "5.30.5", + "@typescript-eslint/parser": "5.30.4", "babel-loader": "8.2.3", "babel-plugin-optional-require": "0.3.1", "circular-dependency-plugin": "5.2.0", @@ -5644,6 +5646,392 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.5.tgz", + "integrity": "sha512-lftkqRoBvc28VFXEoRgyZuztyVUQ04JvUnATSPtIRFAccbXTWL6DEtXGYMcbg998kXw1NLUJm7rTQ9eUt+q6Ig==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.30.5", + "@typescript-eslint/type-utils": "5.30.5", + "@typescript-eslint/utils": "5.30.5", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz", + "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/visitor-keys": "5.30.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz", + "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz", + "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.5", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.4.tgz", + "integrity": "sha512-/ge1HtU63wVoED4VnlU2o+FPFmi017bPYpeSrCmd8Ycsti4VSxXrmcpXXm7JpI4GT0Aa7qviabv1PEp6L5bboQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.30.4", + "@typescript-eslint/types": "5.30.4", + "@typescript-eslint/typescript-estree": "5.30.4", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.4.tgz", + "integrity": "sha512-DNzlQwGSiGefz71JwaHrpcaAX3zYkEcy8uVuan3YMKOa6qeW/y+7SaD8KIsIAruASwq6P+U4BjWBWtM2O+mwBQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.4", + "@typescript-eslint/visitor-keys": "5.30.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.5.tgz", + "integrity": "sha512-k9+ejlv1GgwN1nN7XjVtyCgE0BTzhzT1YsQF0rv4Vfj2U9xnslBgMYYvcEYAFVdvhuEscELJsB7lDkN7WusErw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.30.5", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.4.tgz", + "integrity": "sha512-NTEvqc+Vvu8Q6JeAKryHk2eqLKqsr2St3xhIjhOjQv5wQUBhaTuix4WOSacqj0ONWfKVU12Eug3LEAB95GBkMA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.4.tgz", + "integrity": "sha512-V4VnEs6/J9/nNizaA12IeU4SAeEYaiKr7XndLNfV5+3zZSB4hIu6EhHJixTKhvIqA+EEHgBl6re8pivBMLLO1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.4", + "@typescript-eslint/visitor-keys": "5.30.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.5.tgz", + "integrity": "sha512-o4SSUH9IkuA7AYIfAvatldovurqTAHrfzPApOZvdUq01hHojZojCFXx06D/aFpKCgWbMPRdJBWAC3sWp3itwTA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.30.5", + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/typescript-estree": "5.30.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz", + "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/visitor-keys": "5.30.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz", + "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz", + "integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/visitor-keys": "5.30.5", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz", + "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.5", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.4.tgz", + "integrity": "sha512-ulKGse3mruSc8x6l8ORSc6+1ORyJzKmZeIaRTu/WpaF/jx3vHvEn5XZUKF9XaVg2710mFmTAUlLcLYLPp/Zf/Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.30.4", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@vladmandic/human": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@vladmandic/human/-/human-2.6.5.tgz", @@ -18684,6 +19072,27 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -24339,6 +24748,227 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" }, + "@typescript-eslint/eslint-plugin": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.5.tgz", + "integrity": "sha512-lftkqRoBvc28VFXEoRgyZuztyVUQ04JvUnATSPtIRFAccbXTWL6DEtXGYMcbg998kXw1NLUJm7rTQ9eUt+q6Ig==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.30.5", + "@typescript-eslint/type-utils": "5.30.5", + "@typescript-eslint/utils": "5.30.5", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz", + "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/visitor-keys": "5.30.5" + } + }, + "@typescript-eslint/types": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz", + "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz", + "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.5", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.4.tgz", + "integrity": "sha512-/ge1HtU63wVoED4VnlU2o+FPFmi017bPYpeSrCmd8Ycsti4VSxXrmcpXXm7JpI4GT0Aa7qviabv1PEp6L5bboQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.30.4", + "@typescript-eslint/types": "5.30.4", + "@typescript-eslint/typescript-estree": "5.30.4", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.4.tgz", + "integrity": "sha512-DNzlQwGSiGefz71JwaHrpcaAX3zYkEcy8uVuan3YMKOa6qeW/y+7SaD8KIsIAruASwq6P+U4BjWBWtM2O+mwBQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.4", + "@typescript-eslint/visitor-keys": "5.30.4" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.5.tgz", + "integrity": "sha512-k9+ejlv1GgwN1nN7XjVtyCgE0BTzhzT1YsQF0rv4Vfj2U9xnslBgMYYvcEYAFVdvhuEscELJsB7lDkN7WusErw==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.30.5", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.4.tgz", + "integrity": "sha512-NTEvqc+Vvu8Q6JeAKryHk2eqLKqsr2St3xhIjhOjQv5wQUBhaTuix4WOSacqj0ONWfKVU12Eug3LEAB95GBkMA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.4.tgz", + "integrity": "sha512-V4VnEs6/J9/nNizaA12IeU4SAeEYaiKr7XndLNfV5+3zZSB4hIu6EhHJixTKhvIqA+EEHgBl6re8pivBMLLO1w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.4", + "@typescript-eslint/visitor-keys": "5.30.4", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/utils": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.5.tgz", + "integrity": "sha512-o4SSUH9IkuA7AYIfAvatldovurqTAHrfzPApOZvdUq01hHojZojCFXx06D/aFpKCgWbMPRdJBWAC3sWp3itwTA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.30.5", + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/typescript-estree": "5.30.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz", + "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/visitor-keys": "5.30.5" + } + }, + "@typescript-eslint/types": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz", + "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz", + "integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.5", + "@typescript-eslint/visitor-keys": "5.30.5", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.30.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz", + "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.5", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.30.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.4.tgz", + "integrity": "sha512-ulKGse3mruSc8x6l8ORSc6+1ORyJzKmZeIaRTu/WpaF/jx3vHvEn5XZUKF9XaVg2710mFmTAUlLcLYLPp/Zf/Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.30.4", + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } + } + }, "@vladmandic/human": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@vladmandic/human/-/human-2.6.5.tgz", @@ -34413,6 +35043,23 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index bb7ad930e..5ee0bd03d 100644 --- a/package.json +++ b/package.json @@ -153,6 +153,8 @@ "@types/react-native": "0.67.6", "@types/react-redux": "7.1.24", "@types/uuid": "8.3.4", + "@typescript-eslint/eslint-plugin": "5.30.5", + "@typescript-eslint/parser": "5.30.4", "babel-loader": "8.2.3", "babel-plugin-optional-require": "0.3.1", "circular-dependency-plugin": "5.2.0", @@ -188,9 +190,9 @@ }, "license": "Apache-2.0", "scripts": { - "lint": "eslint --max-warnings 0 .", + "lint": "eslint --ext .js,.ts,.tsx --max-warnings 0 .", "lang-sort": "./resources/lang-sort.sh", - "lint-fix": "eslint --max-warnings 0 --fix .", + "lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .", "postinstall": "patch-package --error-on-fail && jetify", "validate": "npm ls", "start": "make dev" diff --git a/react/.eslintrc.js b/react/.eslintrc.js index 5a696f9e7..ceb016626 100644 --- a/react/.eslintrc.js +++ b/react/.eslintrc.js @@ -6,6 +6,27 @@ module.exports = { '@jitsi/eslint-config/react', '.eslintrc-react-native.js' ], + 'overrides': [ + { + 'files': [ '*.ts', '*.tsx' ], + parser: '@typescript-eslint/parser', + rules: { + 'no-undef': 'off', + 'no-use-before-define': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + 'no-prototype-builtins': 'off' + }, + 'plugins': [ '@typescript-eslint' ], + 'extends': [ + 'eslint:recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended' + ] + } + ], 'rules': { 'flowtype/no-types-missing-file-annotation': 0, diff --git a/react/features/app/actions.native.js b/react/features/app/actions.native.js index af2584ced..6a997b112 100644 --- a/react/features/app/actions.native.js +++ b/react/features/app/actions.native.js @@ -44,7 +44,7 @@ export * from './actions.any'; * scheme, or a mere room name. * @returns {Function} */ -export function appNavigate(uri: ?string) { +export function appNavigate(uri?: string) { logger.info(`appNavigate to ${uri}`); return async (dispatch: Dispatch, getState: Function) => { diff --git a/react/features/app/types.ts b/react/features/app/types.ts index 96ba98158..7817178c7 100644 --- a/react/features/app/types.ts +++ b/react/features/app/types.ts @@ -1,10 +1,10 @@ -import { IAnalyticsState } from "../analytics/reducer" -import { IAuthenticationState } from "../authentication/reducer" -import { IAVModerationState } from "../av-moderation/reducer" -import { IAppState } from "../base/app/reducer" -import { IAudioOnlyState } from "../base/audio-only/reducer" -import { IConferenceState } from "../base/conference/reducer" -import { IConfig } from "../base/config/configType" +import { IAnalyticsState } from '../analytics/reducer'; +import { IAuthenticationState } from '../authentication/reducer'; +import { IAVModerationState } from '../av-moderation/reducer'; +import { IAppState } from '../base/app/reducer'; +import { IAudioOnlyState } from '../base/audio-only/reducer'; +import { IConferenceState } from '../base/conference/reducer'; +import { IConfig } from '../base/config/configType'; export interface IStore { getState: Function, diff --git a/react/features/authentication/reducer.ts b/react/features/authentication/reducer.ts index c3dd3d4c1..53641f9a9 100644 --- a/react/features/authentication/reducer.ts +++ b/react/features/authentication/reducer.ts @@ -1,6 +1,8 @@ +/* eslint-disable import/order */ +import ReducerRegistry from '../base/redux/ReducerRegistry'; + // @ts-ignore import { assign } from '../base/redux/functions'; -import ReducerRegistry from '../base/redux/ReducerRegistry'; import { CANCEL_LOGIN, diff --git a/react/features/av-moderation/constants.ts b/react/features/av-moderation/constants.ts index 18f0d6266..84134a664 100644 --- a/react/features/av-moderation/constants.ts +++ b/react/features/av-moderation/constants.ts @@ -1,4 +1,4 @@ -import { MEDIA_TYPE, type MediaType } from '../base/media/constants'; +import { MEDIA_TYPE } from '../base/media/constants'; /** * Mapping between a media type and the witelist reducer key. diff --git a/react/features/av-moderation/reducer.ts b/react/features/av-moderation/reducer.ts index a2696580a..959f905c5 100644 --- a/react/features/av-moderation/reducer.ts +++ b/react/features/av-moderation/reducer.ts @@ -3,6 +3,7 @@ import type { MediaType } from '../base/media/constants'; import { PARTICIPANT_LEFT, PARTICIPANT_UPDATED + // @ts-ignore } from '../base/participants'; import ReducerRegistry from '../base/redux/ReducerRegistry'; @@ -52,7 +53,7 @@ function _updatePendingParticipant(mediaType: MediaType, participant: any, state let arrayItemChanged = false; const storeKey = MEDIA_TYPE_TO_PENDING_STORE_KEY[mediaType]; const arr = state[storeKey]; - const newArr = arr.map((pending: { id: string} ) => { + const newArr = arr.map((pending: { id: string}) => { if (pending.id === participant.id) { arrayItemChanged = true; diff --git a/react/features/base/conference/reducer.ts b/react/features/base/conference/reducer.ts index 2400d5369..8b2fb39b4 100644 --- a/react/features/base/conference/reducer.ts +++ b/react/features/base/conference/reducer.ts @@ -1,9 +1,13 @@ +/* eslint-disable import/order */ // @ts-ignore import { LOCKED_LOCALLY, LOCKED_REMOTELY } from '../../room-lock'; + // @ts-ignore import { CONNECTION_WILL_CONNECT, SET_LOCATION_URL } from '../connection'; + // @ts-ignore import { JitsiConferenceErrors } from '../lib-jitsi-meet'; + // @ts-ignore import { assign, set } from '../redux'; import ReducerRegistry from '../redux/ReducerRegistry'; @@ -28,6 +32,7 @@ import { SET_START_MUTED_POLICY, SET_START_REACTIONS_MUTED } from './actionTypes'; + // @ts-ignore import { isRoomValid } from './functions'; @@ -376,7 +381,8 @@ function _p2pStatusChanged(state: any, action: any) { * @returns {Object} The new state of the feature base/conference after the * reduction of the specified action. */ -function _setPassword(state: any, { conference, method, password }: {conference: any, method: Object, password: string}) { +function _setPassword(state: any, { conference, method, password } + : {conference: any, method: Object, password: string}) { switch (method) { case conference.join: return assign(state, { diff --git a/react/features/base/config/configType.ts b/react/features/base/config/configType.ts index abdd15797..58f7ae63c 100644 --- a/react/features/base/config/configType.ts +++ b/react/features/base/config/configType.ts @@ -187,7 +187,7 @@ export interface IConfig { notifyAllParticipants?: boolean; }; transcribingEnabled?: boolean; - transcribeWithAppLanguage?: boolean; + transcribeWithAppLanguage?: boolean; preferredTranscribeLanguage?: string; autoCaptionOnRecord?: boolean; transcription?: { @@ -464,4 +464,4 @@ export interface IConfig { tileTime?: number; }; locationURL?: string; -} \ No newline at end of file +} diff --git a/react/features/base/config/reducer.ts b/react/features/base/config/reducer.ts index d0374a95a..f7f2b27c0 100644 --- a/react/features/base/config/reducer.ts +++ b/react/features/base/config/reducer.ts @@ -1,6 +1,8 @@ +/* eslint-disable import/order */ import _ from 'lodash'; import { CONFERENCE_INFO } from '../../conference/components/constants'; + // @ts-ignore import { equals } from '../redux'; import ReducerRegistry from '../redux/ReducerRegistry'; @@ -13,10 +15,11 @@ import { OVERWRITE_CONFIG } from './actionTypes'; import { IConfig } from './configType'; + // @ts-ignore import { _cleanupConfig } from './functions'; -declare var interfaceConfig: any; +declare let interfaceConfig: any; /** * The initial state of the feature base/config when executing in a @@ -307,15 +310,18 @@ function _translateLegacyConfig(oldValue: IConfig) { filteredConferenceInfo.forEach(key => { newValue.conferenceInfo = oldValue.conferenceInfo ?? {}; + // hideRecordingLabel does not mean not render it at all, but autoHide it if (key === 'hideRecordingLabel') { newValue.conferenceInfo.alwaysVisible - = (newValue.conferenceInfo?.alwaysVisible ?? []).filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c)); + = (newValue.conferenceInfo?.alwaysVisible ?? []) + .filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c)); newValue.conferenceInfo.autoHide = _.union(newValue.conferenceInfo.autoHide, CONFERENCE_HEADER_MAPPING[key]); } else { newValue.conferenceInfo.alwaysVisible - = (newValue.conferenceInfo.alwaysVisible ?? []).filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c)); + = (newValue.conferenceInfo.alwaysVisible ?? []) + .filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c)); newValue.conferenceInfo.autoHide = (newValue.conferenceInfo.autoHide ?? []).filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c)); } diff --git a/react/features/base/dialog/components/native/BottomSheetContainer.tsx b/react/features/base/dialog/components/native/BottomSheetContainer.tsx index 625fe7430..725ce88ca 100644 --- a/react/features/base/dialog/components/native/BottomSheetContainer.tsx +++ b/react/features/base/dialog/components/native/BottomSheetContainer.tsx @@ -15,6 +15,6 @@ const BottomSheetContainer: () => JSX.Element = () => { { React.createElement(sheet, sheetProps) } ); -} +}; export default BottomSheetContainer; diff --git a/react/features/base/media/middleware.web.ts b/react/features/base/media/middleware.web.ts index 8e3314e3c..74d40a8f5 100644 --- a/react/features/base/media/middleware.web.ts +++ b/react/features/base/media/middleware.web.ts @@ -1,16 +1,23 @@ +/* eslint-disable import/order */ import './middleware.any.js'; -// @ts-ignore -import { MiddlewareRegistry } from '../redux'; + import { IStore } from '../../app/types'; -import { SET_VIDEO_MUTED } from './actionTypes'; -import LocalRecordingManager from '../../recording/components/Recording/LocalRecordingManager.web'; -// @ts-ignore -import { openDialog } from '../dialog'; + // @ts-ignore import { NOTIFICATION_TIMEOUT_TYPE, showNotification } from '../../notifications'; +import LocalRecordingManager from '../../recording/components/Recording/LocalRecordingManager.web'; + // @ts-ignore import StopRecordingDialog from '../../recording/components/Recording/web/StopRecordingDialog'; +// @ts-ignore +import { openDialog } from '../dialog'; + +// @ts-ignore +import { MiddlewareRegistry } from '../redux'; + +import { SET_VIDEO_MUTED } from './actionTypes'; + /** * Implements the entry point of the middleware of the feature base/media. * @@ -19,22 +26,24 @@ import StopRecordingDialog from '../../recording/components/Recording/web/StopRe */ MiddlewareRegistry.register((store: IStore) => (next: Function) => (action: any) => { const { dispatch } = store; - switch(action.type) { - case SET_VIDEO_MUTED: { - if (LocalRecordingManager.isRecordingLocally() && LocalRecordingManager.selfRecording.on) { - if (action.muted && LocalRecordingManager.selfRecording.withVideo) { - dispatch(openDialog(StopRecordingDialog, { localRecordingVideoStop: true })); - return; - } else if (!action.muted && !LocalRecordingManager.selfRecording.withVideo) { - dispatch(showNotification({ - titleKey: 'recording.localRecordingNoVideo', - descriptionKey: 'recording.localRecordingVideoWarning', - uid: 'recording.localRecordingNoVideo' - }, NOTIFICATION_TIMEOUT_TYPE.MEDIUM)); - } + switch (action.type) { + case SET_VIDEO_MUTED: { + if (LocalRecordingManager.isRecordingLocally() && LocalRecordingManager.selfRecording.on) { + if (action.muted && LocalRecordingManager.selfRecording.withVideo) { + dispatch(openDialog(StopRecordingDialog, { localRecordingVideoStop: true })); + + return; + } else if (!action.muted && !LocalRecordingManager.selfRecording.withVideo) { + dispatch(showNotification({ + titleKey: 'recording.localRecordingNoVideo', + descriptionKey: 'recording.localRecordingVideoWarning', + uid: 'recording.localRecordingNoVideo' + }, NOTIFICATION_TIMEOUT_TYPE.MEDIUM)); } } } + } + return next(action); }); diff --git a/react/features/base/react/components/native/Button.tsx b/react/features/base/react/components/native/Button.tsx index 463774c22..08c5409ab 100644 --- a/react/features/base/react/components/native/Button.tsx +++ b/react/features/base/react/components/native/Button.tsx @@ -7,10 +7,11 @@ import { } from 'react-native-paper'; import BaseTheme from '../../../ui/components/BaseTheme.native'; -import styles from './styles'; import { BUTTON_MODES, BUTTON_TYPES } from '../../constants'; import { ButtonProps } from '../../types'; +import styles from './styles'; + const Button: React.FC = ({ accessibilityLabel, @@ -35,16 +36,16 @@ const Button: React.FC = ({ if (type === PRIMARY) { buttonLabelStyles = styles.buttonLabelPrimary; color = BaseTheme.palette.action01; - mode = CONTAINED + mode = CONTAINED; } else if (type === SECONDARY) { buttonLabelStyles = styles.buttonLabelSecondary; color = BaseTheme.palette.action02; - mode = CONTAINED + mode = CONTAINED; } else if (type === DESTRUCTIVE) { color = BaseTheme.palette.actionDanger; buttonLabelStyles = styles.buttonLabelDestructive; - mode = CONTAINED - } else { + mode = CONTAINED; + } else { color = buttonColor; buttonLabelStyles = styles.buttonLabel; } @@ -56,7 +57,7 @@ const Button: React.FC = ({ buttonStyles = styles.button; } - if ( type === TERTIARY) { + if (type === TERTIARY) { return ( = ({ ] }> { t(label) } + buttonLabelStyles, + labelStyle + ] }>{ t(label) } ); } diff --git a/react/features/base/react/components/native/IconButton.tsx b/react/features/base/react/components/native/IconButton.tsx index 2e6a07680..307d45935 100644 --- a/react/features/base/react/components/native/IconButton.tsx +++ b/react/features/base/react/components/native/IconButton.tsx @@ -3,10 +3,11 @@ import { TouchableRipple } from 'react-native-paper'; import { Icon } from '../../../icons'; import BaseTheme from '../../../ui/components/BaseTheme.native'; -import styles from './styles'; import { BUTTON_TYPES } from '../../constants'; import { IconButtonProps } from '../../types'; +import styles from './styles'; + const IconButton: React.FC = ({ accessibilityLabel, @@ -33,7 +34,7 @@ const IconButton: React.FC = ({ color = BaseTheme.palette.icon02; iconButtonContainerStyles = styles.iconButtonContainerSecondary; rippleColor = BaseTheme.palette.action02; - } else if ( type === TERTIARY) { + } else if (type === TERTIARY) { color = BaseTheme.palette.icon01; iconButtonContainerStyles = styles.iconButtonContainer; rippleColor = BaseTheme.palette.action03; diff --git a/react/features/base/redux/ReducerRegistry.ts b/react/features/base/redux/ReducerRegistry.ts index 7f40cb0c8..e05b15e4e 100644 --- a/react/features/base/redux/ReducerRegistry.ts +++ b/react/features/base/redux/ReducerRegistry.ts @@ -5,14 +5,14 @@ import type { Reducer } from 'redux'; * The type of the dictionary/map which associates a reducer (function) with the * name of he Redux state property managed by the reducer. */ -declare type NameReducerMap = { [name: string]: Reducer> }; +type NameReducerMap = { [name: string]: Reducer> }; /** * A registry for Redux reducers, allowing features to register themselves * without needing to create additional inter-feature dependencies. */ class ReducerRegistry { - _elements: NameReducerMap; + _elements: NameReducerMap; /** * Creates a ReducerRegistry instance. @@ -35,7 +35,7 @@ class ReducerRegistry { * included (such as reducers from third-party modules). * @returns {Function} */ - combineReducers(additional: NameReducerMap = {}) { + combineReducers(additional: NameReducerMap = {}) { // $FlowExpectedError return combineReducers({ ...this._elements, diff --git a/react/features/base/util/iframeUtils.ts b/react/features/base/util/iframeUtils.ts index 44616cb25..943c63116 100644 --- a/react/features/base/util/iframeUtils.ts +++ b/react/features/base/util/iframeUtils.ts @@ -1,7 +1,7 @@ /** * Checks whether we are loaded in iframe. * - * @returns Whether the current page is loaded in an iframe. + * @returns {boolean} Whether the current page is loaded in an iframe. */ export function inIframe(): boolean { if (navigator.product === 'ReactNative') { diff --git a/react/features/conference/components/native/carmode/AudioIcon.tsx b/react/features/conference/components/native/carmode/AudioIcon.tsx index 9781d31f7..a1b2cba5f 100644 --- a/react/features/conference/components/native/carmode/AudioIcon.tsx +++ b/react/features/conference/components/native/carmode/AudioIcon.tsx @@ -5,9 +5,9 @@ import BaseTheme from '../../../../base/ui/components/BaseTheme.native'; /** * React component for Audio icon. - * - * @returns {JSX.Element} - the Audio icon. - * + * + * @returns {JSX.Element} - The Audio icon. + * */ const AudioIcon = () : JSX.Element => ( ( { }, [ audioMuted, disabled ]); const onLongPress = useCallback(() => { - if ( !disabled && !audioMuted) { + if (!disabled && !audioMuted) { sendAnalytics(createShortcutEvent( 'push.to.talk', PRESSED, @@ -49,7 +48,7 @@ const MicrophoneButton = () : JSX.Element => { LONG_PRESS)); setLongPress(true); } - }, [audioMuted, disabled, setLongPress]); + }, [ audioMuted, disabled, setLongPress ]); const onPressOut = useCallback(() => { if (longPress) { @@ -62,13 +61,13 @@ const MicrophoneButton = () : JSX.Element => { )); dispatch(muteLocal(true, MEDIA_TYPE.AUDIO)); } - }, [longPress, setLongPress]); + }, [ longPress, setLongPress ]); return ( + onPressOut = { onPressOut } > { - const localParticipant = useSelector(getLocalParticipant); + const localParticipant = useSelector(getLocalParticipant); const localParticipantId = localParticipant?.id; return (<> + style = { styles.titleBarWrapper as StyleProp }> - + style = { styles.roomNameWrapper as StyleProp }> + }> - + iconStyle = { styles.connectionIndicatorIcon } + participantId = { localParticipantId } /> + }> { props._meetingNameEnabled - && + && }> @@ -70,7 +70,7 @@ const TitleBar = (props: Props) : JSX.Element => { ); -} +}; /** * Maps part of the Redux store to the props of this component. diff --git a/react/features/conference/components/web/ToggleTopPanelLabel.tsx b/react/features/conference/components/web/ToggleTopPanelLabel.tsx index f19e2c885..9426cd36e 100644 --- a/react/features/conference/components/web/ToggleTopPanelLabel.tsx +++ b/react/features/conference/components/web/ToggleTopPanelLabel.tsx @@ -1,13 +1,17 @@ +/* eslint-disable import/order */ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; // @ts-ignore import { IconMenuDown } from '../../../base/icons'; + // @ts-ignore import { Label } from '../../../base/label'; + // @ts-ignore import { Tooltip } from '../../../base/tooltip'; + // @ts-ignore import { setTopPanelVisible } from '../../../filmstrip/actions.web'; @@ -20,11 +24,11 @@ const ToggleTopPanelLabel = () => { }, []); return topPanelHidden && ( ); }; diff --git a/react/features/dynamic-branding/components/native/BrandingImageBackground.tsx b/react/features/dynamic-branding/components/native/BrandingImageBackground.tsx index edc99a0c2..3eb57866a 100644 --- a/react/features/dynamic-branding/components/native/BrandingImageBackground.tsx +++ b/react/features/dynamic-branding/components/native/BrandingImageBackground.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Image } from 'react-native'; +import { Image, ImageStyle, StyleProp, ViewStyle } from 'react-native'; import { SvgUri } from 'react-native-svg'; // @ts-ignore @@ -40,7 +40,7 @@ const BrandingImageBackground: React.FC = ({ uri }:Props) => { // Align the of the element's viewBox // with the smallest Y value of the viewport. preserveAspectRatio = 'xMinYMin' - style = { styles.brandingImageBackgroundSvg } + style = { styles.brandingImageBackgroundSvg as StyleProp } uri = { imgSrc } viewBox = '0 0 400 650' width = '100%' /> @@ -50,7 +50,7 @@ const BrandingImageBackground: React.FC = ({ uri }:Props) => { = ( + style = { styles.brandingImageBackground as StyleProp } /> ); } diff --git a/react/features/dynamic-branding/components/native/styles.ts b/react/features/dynamic-branding/components/native/styles.ts index 1fa161a84..8776bc4b4 100644 --- a/react/features/dynamic-branding/components/native/styles.ts +++ b/react/features/dynamic-branding/components/native/styles.ts @@ -4,12 +4,12 @@ export default { * {@code BrandingImageBackground} Style. */ brandingImageBackgroundSvg: { - position: 'absolute' as 'absolute' + position: 'absolute' }, brandingImageBackground: { height: '100%', - position: 'absolute' as 'absolute', + position: 'absolute', width: '100%' } }; diff --git a/react/features/face-landmarks/FaceLandmarksHelper.ts b/react/features/face-landmarks/FaceLandmarksHelper.ts index 9ca0cee4b..08797e146 100644 --- a/react/features/face-landmarks/FaceLandmarksHelper.ts +++ b/react/features/face-landmarks/FaceLandmarksHelper.ts @@ -36,7 +36,7 @@ export interface FaceLandmarksHelper { } /** - * Helper class for human library + * Helper class for human library. */ export class HumanHelper implements FaceLandmarksHelper { protected human: Human | undefined; @@ -44,6 +44,7 @@ export class HumanHelper implements FaceLandmarksHelper { protected baseUrl: string; private detectionInProgress = false; private lastValidFaceBox: FaceBox | undefined; + /** * Configuration for human. */ @@ -66,7 +67,7 @@ export class HumanHelper implements FaceLandmarksHelper { }, mesh: { enabled: false }, iris: { enabled: false }, - emotion: { + emotion: { enabled: false, modelPath: 'emotion.json' }, @@ -78,12 +79,23 @@ export class HumanHelper implements FaceLandmarksHelper { segmentation: { enabled: false } }; + /** + * Constructor function for the helper which initialize the helper. + * + * @param {InitInput} input - The input for the helper. + * @returns {void} + */ constructor({ baseUrl, detectionTypes }: InitInput) { this.faceDetectionTypes = detectionTypes; this.baseUrl = baseUrl; this.init(); } + /** + * Initializes the human helper with the available tfjs backend for the given detection types. + * + * @returns {Promise} + */ async init(): Promise { if (!this.human) { @@ -95,7 +107,7 @@ export class HumanHelper implements FaceLandmarksHelper { } if (this.faceDetectionTypes.length > 0 && this.config.face) { - this.config.face.enabled = true + this.config.face.enabled = true; } if (this.faceDetectionTypes.includes(DETECTION_TYPES.FACE_BOX) && this.config.face?.detector) { @@ -107,16 +119,24 @@ export class HumanHelper implements FaceLandmarksHelper { } const initialHuman = new Human(this.config); + try { await initialHuman.load(); } catch (err) { console.error(err); } - + this.human = initialHuman; } } + /** + * Gets the face box from the detections, if there is no valid detections it will return undefined.. + * + * @param {Array} detections - The array with the detections. + * @param {number} threshold - Face box position change threshold. + * @returns {FaceBox | undefined} + */ getFaceBox(detections: Array, threshold: number): FaceBox | undefined { if (this.getFaceCount(detections) !== 1) { return; @@ -127,18 +147,24 @@ export class HumanHelper implements FaceLandmarksHelper { left: Math.round(detections[0].boxRaw[0] * 100), right: Math.round((detections[0].boxRaw[0] + detections[0].boxRaw[2]) * 100) }; - + faceBox.width = Math.round(faceBox.right - faceBox.left); - + if (this.lastValidFaceBox && threshold && Math.abs(this.lastValidFaceBox.left - faceBox.left) < threshold) { return; } - + this.lastValidFaceBox = faceBox; - + return faceBox; } + /** + * Gets the face expression from the detections, if there is no valid detections it will return undefined. + * + * @param {Array} detections - The array with the detections. + * @returns {string | undefined} + */ getFaceExpression(detections: Array): string | undefined { if (this.getFaceCount(detections) !== 1) { return; @@ -149,6 +175,12 @@ export class HumanHelper implements FaceLandmarksHelper { } } + /** + * Gets the face count from the detections, which is the number of detections. + * + * @param {Array} detections - The array with the detections. + * @returns {number} + */ getFaceCount(detections: Array | undefined): number { if (detections) { return detections.length; @@ -157,44 +189,56 @@ export class HumanHelper implements FaceLandmarksHelper { return 0; } + /** + * Gets the detections from the image captured from the track. + * + * @param {ImageBitmap | ImageData} image - The image captured from the track, + * if OffscreenCanvas available it will be ImageBitmap, otherwise it will be ImageData. + * @returns {Promise>} + */ async getDetections(image: ImageBitmap | ImageData): Promise> { if (!this.human || !this.faceDetectionTypes.length) { return []; } this.human.tf.engine().startScope(); - + const imageTensor = this.human.tf.browser.fromPixels(image); const { face: detections } = await this.human.detect(imageTensor, this.config); this.human.tf.engine().endScope(); - - return detections.filter(detection => detection.score > FACE_DETECTION_SCORE_THRESHOLD); - } + return detections.filter(detection => detection.score > FACE_DETECTION_SCORE_THRESHOLD); + } + + /** + * Gathers together all the data from the detections, it's the function that will be called in the worker. + * + * @param {DetectInput} input - The input for the detections. + * @returns {Promise} + */ public async detect({ image, threshold } : DetectInput): Promise { - let detections; let faceExpression; let faceBox; this.detectionInProgress = true; - detections = await this.getDetections(image); + const detections = await this.getDetections(image); if (this.faceDetectionTypes.includes(DETECTION_TYPES.FACE_EXPRESSIONS)) { faceExpression = this.getFaceExpression(detections); } if (this.faceDetectionTypes.includes(DETECTION_TYPES.FACE_BOX)) { - //if more than one face is detected the face centering will be disabled. - if (this.getFaceCount(detections) > 1 ) { + // if more than one face is detected the face centering will be disabled. + if (this.getFaceCount(detections) > 1) { this.faceDetectionTypes.splice(this.faceDetectionTypes.indexOf(DETECTION_TYPES.FACE_BOX), 1); - //face-box for re-centering + // face-box for re-centering faceBox = { left: 0, right: 100, - width: 100, + width: 100 }; } else { faceBox = this.getFaceBox(detections, threshold); @@ -204,14 +248,19 @@ export class HumanHelper implements FaceLandmarksHelper { this.detectionInProgress = false; - return { - faceExpression, + return { + faceExpression, faceBox, faceCount: this.getFaceCount(detections) - } + }; } + /** + * Returns the detection state. + * + * @returns {boolean} + */ public getDetectionInProgress(): boolean { return this.detectionInProgress; } -} \ No newline at end of file +} diff --git a/react/features/face-landmarks/constants.ts b/react/features/face-landmarks/constants.ts index 36ae27ca5..bf5c6fc08 100644 --- a/react/features/face-landmarks/constants.ts +++ b/react/features/face-landmarks/constants.ts @@ -59,4 +59,4 @@ export const DETECTION_TYPES = { /** * Threshold for detection score of face. */ -export const FACE_DETECTION_SCORE_THRESHOLD = 0.6; \ No newline at end of file +export const FACE_DETECTION_SCORE_THRESHOLD = 0.6; diff --git a/react/features/face-landmarks/faceLandmarksWorker.ts b/react/features/face-landmarks/faceLandmarksWorker.ts index aaa7d7158..aeab6f8df 100644 --- a/react/features/face-landmarks/faceLandmarksWorker.ts +++ b/react/features/face-landmarks/faceLandmarksWorker.ts @@ -1,5 +1,5 @@ +import { FaceLandmarksHelper, HumanHelper } from './FaceLandmarksHelper'; import { DETECT_FACE, INIT_WORKER } from './constants'; -import { FaceLandmarksHelper, HumanHelper }from './FaceLandmarksHelper'; let helper: FaceLandmarksHelper; diff --git a/react/features/gifs/components/native/GifsMenuFooter.tsx b/react/features/gifs/components/native/GifsMenuFooter.tsx index e37d817c9..e62f43719 100644 --- a/react/features/gifs/components/native/GifsMenuFooter.tsx +++ b/react/features/gifs/components/native/GifsMenuFooter.tsx @@ -13,14 +13,14 @@ import styles from './styles'; const GifsMenuFooter = (): JSX.Element => { const { t } = useTranslation(); - return( - + return ( + { t('poweredby') } + style = { styles.creditText }>{ t('poweredby') } - ) + ); }; export default GifsMenuFooter; diff --git a/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.tsx b/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.tsx index e34feb8a4..102d0e25f 100644 --- a/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.tsx +++ b/react/features/mobile/navigation/components/conference/components/ConferenceNavigationContainer.tsx @@ -5,7 +5,6 @@ import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { Chat, ChatAndPolls } from '../../../../../chat'; - import Conference from '../../../../../conference/components/native/Conference'; import CarMode from '../../../../../conference/components/native/carmode/CarMode'; import { getDisablePolls } from '../../../../../conference/functions'; diff --git a/react/features/mobile/navigation/rootNavigationContainerRef.js b/react/features/mobile/navigation/rootNavigationContainerRef.js index a2667092b..bec3ecafc 100644 --- a/react/features/mobile/navigation/rootNavigationContainerRef.js +++ b/react/features/mobile/navigation/rootNavigationContainerRef.js @@ -16,7 +16,7 @@ export const rootNavigationRef = React.createRef(); * @param {Object} params - Params to pass to the destination route. * @returns {Function} */ -export function navigateRoot(name: string, params: Object) { +export function navigateRoot(name: string, params?: Object) { return rootNavigationRef.current?.navigate(name, params); } diff --git a/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx b/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx index fcb16fa49..38b3b0e71 100644 --- a/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx +++ b/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx @@ -1,3 +1,4 @@ +/* eslint-disable import/order */ import { makeStyles } from '@material-ui/core'; import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -5,16 +6,22 @@ import { useSelector } from 'react-redux'; // @ts-ignore import { Avatar } from '../../../../../base/avatar'; + // @ts-ignore import { ContextMenu, ContextMenuItemGroup } from '../../../../../base/components'; + // @ts-ignore import { isLocalParticipantModerator } from '../../../../../base/participants'; + // @ts-ignore import { getBreakoutRooms } from '../../../../../breakout-rooms/functions'; + // @ts-ignore import { showOverflowDrawer } from '../../../../../toolbox/functions.web'; + // @ts-ignore import SendToRoomButton from '../../../../../video-menu/components/web/SendToRoomButton'; + // @ts-ignore import { AVATAR_SIZE } from '../../../../constants'; @@ -74,7 +81,7 @@ export const RoomParticipantContextMenu = ({ const styles = useStyles(); const { t } = useTranslation(); const isLocalModerator = useSelector(isLocalParticipantModerator); - const lowerMenu = useCallback(() => onSelect(true), [onSelect]); + const lowerMenu = useCallback(() => onSelect(true), [ onSelect ]); const rooms: Object = useSelector(getBreakoutRooms); const overflowDrawer = useSelector(showOverflowDrawer); @@ -88,7 +95,8 @@ export const RoomParticipantContextMenu = ({ } return null; - }).filter(Boolean), [ entity, rooms ]); + }) +.filter(Boolean), [ entity, rooms ]); return isLocalModerator && ( { const showMoreActions = useSelector(isMoreActionsVisible); const showMuteAll = useSelector(isMuteAllVisible); - return( + return ( { showMuteAll && ( @@ -49,7 +49,7 @@ const ParticipantsPaneFooter = (): JSX.Element => { ) } - ) + ); }; export default ParticipantsPaneFooter; diff --git a/react/features/participants-pane/components/native/RoomParticipantMenu.tsx b/react/features/participants-pane/components/native/RoomParticipantMenu.tsx index d7a893b88..662dfaa1e 100644 --- a/react/features/participants-pane/components/native/RoomParticipantMenu.tsx +++ b/react/features/participants-pane/components/native/RoomParticipantMenu.tsx @@ -1,16 +1,18 @@ +/* eslint-disable import/order */ import React, { PureComponent } from 'react'; import { Text, View } from 'react-native'; // @ts-ignore import { Avatar } from '../../../base/avatar'; + // @ts-ignore import { BottomSheet, hideSheet } from '../../../base/dialog'; +import { bottomSheetStyles } from '../../../base/dialog/components/native/styles'; import { translate } from '../../../base/i18n'; import { connect } from '../../../base/redux'; import { getBreakoutRooms } from '../../../breakout-rooms/functions'; import SendToBreakoutRoom from '../../../video-menu/components/native/SendToBreakoutRoom'; import styles from '../../../video-menu/components/native/styles'; -import { bottomSheetStyles } from '../../../base/dialog/components/native/styles'; /** * Size of the rendered avatar in the menu. diff --git a/react/features/participants-pane/middleware.ts b/react/features/participants-pane/middleware.ts index f2c91157c..bd1d03848 100644 --- a/react/features/participants-pane/middleware.ts +++ b/react/features/participants-pane/middleware.ts @@ -1,11 +1,12 @@ -// @ts-ignore -import { IStore } from '../app/types'; +/* eslint-disable import/order */ + // @ts-ignore import { MiddlewareRegistry } from '../base/redux'; + import { PARTICIPANTS_PANE_CLOSE, PARTICIPANTS_PANE_OPEN } from './actionTypes'; -declare var APP: any; +declare let APP: any; /** * Middleware which intercepts participants pane actions. @@ -13,18 +14,19 @@ declare var APP: any; * @param {IStore} store - The redux store. * @returns {Function} */ -MiddlewareRegistry.register((store: IStore) => (next:Function) => (action:any) => { - switch(action.type) { - case PARTICIPANTS_PANE_OPEN: - if (typeof APP !== 'undefined') { - APP.API.notifyParticipantsPaneToggled(true); - } - break; - case PARTICIPANTS_PANE_CLOSE: - if (typeof APP !== 'undefined') { - APP.API.notifyParticipantsPaneToggled(false); - } - break; +MiddlewareRegistry.register(() => (next:Function) => (action:any) => { + switch (action.type) { + case PARTICIPANTS_PANE_OPEN: + if (typeof APP !== 'undefined') { + APP.API.notifyParticipantsPaneToggled(true); + } + break; + case PARTICIPANTS_PANE_CLOSE: + if (typeof APP !== 'undefined') { + APP.API.notifyParticipantsPaneToggled(false); + } + break; } + return next(action); }); diff --git a/react/features/prejoin/components/Prejoin.native.tsx b/react/features/prejoin/components/Prejoin.native.tsx index 137e098e7..16f7a496d 100644 --- a/react/features/prejoin/components/Prejoin.native.tsx +++ b/react/features/prejoin/components/Prejoin.native.tsx @@ -4,7 +4,10 @@ import { BackHandler, View, TextInput, - Platform + Platform, + StyleProp, + TextStyle, + ViewStyle } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; @@ -29,6 +32,7 @@ import AudioMuteButton from '../../toolbox/components/AudioMuteButton'; import VideoMuteButton from '../../toolbox/components/VideoMuteButton'; import { isDisplayNameRequired } from '../functions'; import { PrejoinProps } from '../types'; + import styles from './styles'; @@ -92,7 +96,7 @@ const Prejoin: React.FC = ({ navigation }: PrejoinProps) => { return () => BackHandler.removeEventListener('hardwareBackPress', goBack); - }, [ ]); + }, []); useLayoutEffect(() => { navigation.setOptions({ @@ -127,12 +131,12 @@ const Prejoin: React.FC = ({ navigation }: PrejoinProps) => { - + }> } value = { displayName } />