fix(lint) make sure eslint also runs on TypeScript files (#11777)
Co-authored-by: robertpin <robert.pin9@gmail.com> Co-authored-by: Gabriel Borlea <gabriel.borlea@8x8.com>
This commit is contained in:
parent
61a6ce2a2e
commit
b0deb9ec0c
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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<any>, getState: Function) => {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ const BottomSheetContainer: () => JSX.Element = () => {
|
|||
{ React.createElement(sheet, sheetProps) }
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default BottomSheetContainer;
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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<ButtonProps> = ({
|
||||
accessibilityLabel,
|
||||
|
@ -35,16 +36,16 @@ const Button: React.FC<ButtonProps> = ({
|
|||
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<ButtonProps> = ({
|
|||
buttonStyles = styles.button;
|
||||
}
|
||||
|
||||
if ( type === TERTIARY) {
|
||||
if (type === TERTIARY) {
|
||||
return (
|
||||
<TouchableRipple
|
||||
accessibilityLabel = { accessibilityLabel }
|
||||
|
@ -69,9 +70,9 @@ const Button: React.FC<ButtonProps> = ({
|
|||
] }>
|
||||
<Text
|
||||
style = { [
|
||||
buttonLabelStyles,
|
||||
labelStyle
|
||||
] }>{ t(label) }</Text>
|
||||
buttonLabelStyles,
|
||||
labelStyle
|
||||
] }>{ t(label) }</Text>
|
||||
</TouchableRipple>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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<IconButtonProps> = ({
|
||||
accessibilityLabel,
|
||||
|
@ -33,7 +34,7 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|||
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;
|
||||
|
|
|
@ -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<S, A> = { [name: string]: Reducer<S, Action<any>> };
|
||||
type NameReducerMap<S> = { [name: string]: Reducer<S, Action<any>> };
|
||||
|
||||
/**
|
||||
* A registry for Redux reducers, allowing features to register themselves
|
||||
* without needing to create additional inter-feature dependencies.
|
||||
*/
|
||||
class ReducerRegistry {
|
||||
_elements: NameReducerMap<any, any>;
|
||||
_elements: NameReducerMap<any>;
|
||||
|
||||
/**
|
||||
* Creates a ReducerRegistry instance.
|
||||
|
@ -35,7 +35,7 @@ class ReducerRegistry {
|
|||
* included (such as reducers from third-party modules).
|
||||
* @returns {Function}
|
||||
*/
|
||||
combineReducers(additional: NameReducerMap<any, any> = {}) {
|
||||
combineReducers(additional: NameReducerMap<any> = {}) {
|
||||
// $FlowExpectedError
|
||||
return combineReducers({
|
||||
...this._elements,
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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 => (<Icon
|
||||
color = { BaseTheme.palette.text06 }
|
||||
|
|
|
@ -5,8 +5,8 @@ import BaseTheme from '../../../../base/ui/components/BaseTheme.native';
|
|||
|
||||
/**
|
||||
* Implements an end meeting icon.
|
||||
*
|
||||
* @returns {JSX.Element} - the end meeting icon.
|
||||
*
|
||||
* @returns {JSX.Element} - The end meeting icon.
|
||||
*/
|
||||
const EndMeetingIcon = () : JSX.Element => (<Icon
|
||||
color = { BaseTheme.palette.icon01 }
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useState } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { View, TouchableOpacity } from 'react-native';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
createShortcutEvent,
|
||||
sendAnalytics,
|
||||
ACTION_SHORTCUT_PRESSED as PRESSED,
|
||||
ACTION_SHORTCUT_RELEASED as RELEASED
|
||||
} from '../../../../analytics';
|
||||
|
||||
import { getFeatureFlag, AUDIO_MUTE_BUTTON_ENABLED } from '../../../../base/flags';
|
||||
import { Icon, IconMicrophone, IconMicrophoneEmptySlash } from '../../../../base/icons';
|
||||
import { MEDIA_TYPE } from '../../../../base/media';
|
||||
|
@ -41,7 +40,7 @@ const MicrophoneButton = () : 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 (
|
||||
<TouchableOpacity
|
||||
onLongPress = { onLongPress }
|
||||
onPressIn = { onPressIn }
|
||||
onLongPress={ onLongPress }
|
||||
onPressOut={ onPressOut } >
|
||||
onPressOut = { onPressOut } >
|
||||
<View
|
||||
style = { [
|
||||
styles.microphoneStyles.container,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import React from 'react';
|
||||
import { StyleProp, Text, View, ViewStyle } from 'react-native';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Text, View } from 'react-native';
|
||||
|
||||
import { getConferenceName } from '../../../../base/conference/functions';
|
||||
import { ConnectionIndicator } from '../../../../connection-indicator';
|
||||
import { getFeatureFlag, MEETING_NAME_ENABLED } from '../../../../base/flags';
|
||||
import { JitsiRecordingConstants } from '../../../../base/lib-jitsi-meet';
|
||||
import { connect } from '../../../../base/redux';;
|
||||
import { RecordingLabel } from '../../../../recording';
|
||||
import { getLocalParticipant } from '../../../../base/participants';
|
||||
import { connect } from '../../../../base/redux';
|
||||
import ConnectionIndicator from '../../../../connection-indicator/components/native/ConnectionIndicator';
|
||||
import RecordingLabel from '../../../../recording/components/native/RecordingLabel';
|
||||
import { VideoQualityLabel } from '../../../../video-quality';
|
||||
|
||||
import { getLocalParticipant } from '../../../../base/participants';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
|
@ -36,30 +36,30 @@ type Props = {
|
|||
* @returns {JSX.Element}
|
||||
*/
|
||||
const TitleBar = (props: Props) : JSX.Element => {
|
||||
const localParticipant = useSelector(getLocalParticipant);
|
||||
const localParticipant = useSelector(getLocalParticipant);
|
||||
const localParticipantId = localParticipant?.id;
|
||||
|
||||
return (<>
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.titleBarWrapper }>
|
||||
style = { styles.titleBarWrapper as StyleProp<ViewStyle> }>
|
||||
<View
|
||||
pointerEvents = 'box-none'
|
||||
style = { styles.roomNameWrapper }>
|
||||
<View style = { styles.qualityLabelContainer }>
|
||||
style = { styles.roomNameWrapper as StyleProp<ViewStyle> }>
|
||||
<View style = { styles.qualityLabelContainer as StyleProp<ViewStyle> }>
|
||||
<VideoQualityLabel />
|
||||
</View>
|
||||
<ConnectionIndicator
|
||||
participantId = { localParticipantId }
|
||||
iconStyle = { styles.connectionIndicatorIcon } />
|
||||
<View style = { styles.headerLabels }>
|
||||
iconStyle = { styles.connectionIndicatorIcon }
|
||||
participantId = { localParticipantId } />
|
||||
<View style = { styles.headerLabels as StyleProp<ViewStyle> }>
|
||||
<RecordingLabel mode = { JitsiRecordingConstants.mode.FILE } />
|
||||
<RecordingLabel mode = { JitsiRecordingConstants.mode.STREAM } />
|
||||
</View>
|
||||
|
||||
{
|
||||
props._meetingNameEnabled
|
||||
&& <View style = { styles.roomNameView }>
|
||||
&& <View style = { styles.roomNameView as StyleProp<ViewStyle> }>
|
||||
<Text
|
||||
numberOfLines = { 1 }
|
||||
style = { styles.roomName }>
|
||||
|
@ -70,7 +70,7 @@ const TitleBar = (props: Props) : JSX.Element => {
|
|||
</View>
|
||||
</View>
|
||||
</>);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps part of the Redux store to the props of this component.
|
||||
|
|
|
@ -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 && (<Tooltip
|
||||
content={t('toggleTopPanelLabel') }
|
||||
content = { t('toggleTopPanelLabel') }
|
||||
position = { 'bottom' }>
|
||||
<Label
|
||||
icon={IconMenuDown}
|
||||
onClick = { onClick }/>
|
||||
icon = { IconMenuDown }
|
||||
onClick = { onClick } />
|
||||
</Tooltip>);
|
||||
};
|
||||
|
||||
|
|
|
@ -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<Props> = ({ uri }:Props) => {
|
|||
// Align the <min-y> of the element's viewBox
|
||||
// with the smallest Y value of the viewport.
|
||||
preserveAspectRatio = 'xMinYMin'
|
||||
style = { styles.brandingImageBackgroundSvg }
|
||||
style = { styles.brandingImageBackgroundSvg as StyleProp<ViewStyle> }
|
||||
uri = { imgSrc }
|
||||
viewBox = '0 0 400 650'
|
||||
width = '100%' />
|
||||
|
@ -50,7 +50,7 @@ const BrandingImageBackground: React.FC<Props> = ({ uri }:Props) => {
|
|||
= (
|
||||
<Image
|
||||
source = {{ uri: imgSrc }}
|
||||
style = { styles.brandingImageBackground } />
|
||||
style = { styles.brandingImageBackground as StyleProp<ImageStyle> } />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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%'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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<void>}
|
||||
*/
|
||||
async init(): Promise<void> {
|
||||
|
||||
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<FaceResult>} detections - The array with the detections.
|
||||
* @param {number} threshold - Face box position change threshold.
|
||||
* @returns {FaceBox | undefined}
|
||||
*/
|
||||
getFaceBox(detections: Array<FaceResult>, 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<FaceResult>} detections - The array with the detections.
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
getFaceExpression(detections: Array<FaceResult>): 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<FaceResult>} detections - The array with the detections.
|
||||
* @returns {number}
|
||||
*/
|
||||
getFaceCount(detections: Array<FaceResult> | 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<Array<FaceResult>>}
|
||||
*/
|
||||
async getDetections(image: ImageBitmap | ImageData): Promise<Array<FaceResult>> {
|
||||
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<DetectOutput>}
|
||||
*/
|
||||
public async detect({ image, threshold } : DetectInput): Promise<DetectOutput> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,4 +59,4 @@ export const DETECTION_TYPES = {
|
|||
/**
|
||||
* Threshold for detection score of face.
|
||||
*/
|
||||
export const FACE_DETECTION_SCORE_THRESHOLD = 0.6;
|
||||
export const FACE_DETECTION_SCORE_THRESHOLD = 0.6;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { FaceLandmarksHelper, HumanHelper } from './FaceLandmarksHelper';
|
||||
import { DETECT_FACE, INIT_WORKER } from './constants';
|
||||
import { FaceLandmarksHelper, HumanHelper }from './FaceLandmarksHelper';
|
||||
|
||||
|
||||
let helper: FaceLandmarksHelper;
|
||||
|
|
|
@ -13,14 +13,14 @@ import styles from './styles';
|
|||
const GifsMenuFooter = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return(
|
||||
<View style={ styles.credit }>
|
||||
return (
|
||||
<View style = { styles.credit }>
|
||||
<Text
|
||||
style={ styles.creditText }>{ t('poweredby') }</Text>
|
||||
style = { styles.creditText }>{ t('poweredby') }</Text>
|
||||
<Image
|
||||
source = { require('../../../../../images/GIPHY_logo.png') } />
|
||||
</View>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default GifsMenuFooter;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 && (
|
||||
<ContextMenu
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useDispatch, useSelector} from "react-redux";
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { openDialog, openSheet } from '../../../base/dialog';
|
||||
import { IconHorizontalPoints } from '../../../base/icons';
|
||||
|
@ -28,7 +28,7 @@ const ParticipantsPaneFooter = (): JSX.Element => {
|
|||
const showMoreActions = useSelector(isMoreActionsVisible);
|
||||
const showMuteAll = useSelector(isMuteAllVisible);
|
||||
|
||||
return(
|
||||
return (
|
||||
<View style = { styles.participantsPaneFooter }>
|
||||
{
|
||||
showMuteAll && (
|
||||
|
@ -49,7 +49,7 @@ const ParticipantsPaneFooter = (): JSX.Element => {
|
|||
)
|
||||
}
|
||||
</View>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default ParticipantsPaneFooter;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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<PrejoinProps> = ({ navigation }: PrejoinProps) => {
|
|||
|
||||
return () => BackHandler.removeEventListener('hardwareBackPress', goBack);
|
||||
|
||||
}, [ ]);
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
navigation.setOptions({
|
||||
|
@ -127,12 +131,12 @@ const Prejoin: React.FC<PrejoinProps> = ({ navigation }: PrejoinProps) => {
|
|||
<LargeVideo />
|
||||
</View>
|
||||
<View style = { contentContainerStyles }>
|
||||
<View style = { styles.formWrapper }>
|
||||
<View style = { styles.formWrapper as StyleProp<ViewStyle> }>
|
||||
<TextInput
|
||||
onChangeText = { onChangeDisplayName }
|
||||
placeholder = { t('dialog.enterDisplayName') }
|
||||
placeholderTextColor = { BaseTheme.palette.text03 }
|
||||
style = { styles.field }
|
||||
style = { styles.field as StyleProp<TextStyle> }
|
||||
value = { displayName } />
|
||||
<Button
|
||||
accessibilityLabel = 'prejoin.joinMeeting'
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
interface PrejoinProps {
|
||||
navigation: Object;
|
||||
export interface PrejoinProps {
|
||||
navigation: any;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import { ReactionsAction } from './reducer';
|
|||
* Sets the reaction queue.
|
||||
*
|
||||
* @param {Array} queue - The new queue.
|
||||
* @returns {ReactionsAction}
|
||||
*/
|
||||
export function setReactionQueue(queue: Array<ReactionEmojiProps>): ReactionsAction {
|
||||
return {
|
||||
|
@ -26,6 +27,7 @@ export function setReactionQueue(queue: Array<ReactionEmojiProps>): ReactionsAct
|
|||
* Removes a reaction from the queue.
|
||||
*
|
||||
* @param {string} uid - Id of the reaction to be removed.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function removeReaction(uid: string): Function {
|
||||
return (dispatch: Function, getState: Function) => {
|
||||
|
@ -38,6 +40,8 @@ export function removeReaction(uid: string): Function {
|
|||
|
||||
/**
|
||||
* Sends the reactions buffer to everyone in the conference.
|
||||
*
|
||||
* @returns {ReactionsAction}
|
||||
*/
|
||||
export function sendReactions(): ReactionsAction {
|
||||
return {
|
||||
|
@ -49,6 +53,7 @@ export function sendReactions(): ReactionsAction {
|
|||
* Adds a reaction to the local buffer.
|
||||
*
|
||||
* @param {string} reaction - The reaction to be added.
|
||||
* @returns {ReactionsAction}
|
||||
*/
|
||||
export function addReactionToBuffer(reaction: string): ReactionsAction {
|
||||
return {
|
||||
|
@ -59,6 +64,8 @@ export function addReactionToBuffer(reaction: string): ReactionsAction {
|
|||
|
||||
/**
|
||||
* Clears the reaction buffer.
|
||||
*
|
||||
* @returns {ReactionsAction}
|
||||
*/
|
||||
export function flushReactionBuffer(): ReactionsAction {
|
||||
return {
|
||||
|
@ -70,6 +77,7 @@ export function flushReactionBuffer(): ReactionsAction {
|
|||
* Adds a reaction message to the chat.
|
||||
*
|
||||
* @param {string} message - The reaction message.
|
||||
* @returns {ReactionsAction}
|
||||
*/
|
||||
export function addReactionsToChat(message: string): ReactionsAction {
|
||||
return {
|
||||
|
@ -82,6 +90,7 @@ export function addReactionsToChat(message: string): ReactionsAction {
|
|||
* Adds reactions to the animation queue.
|
||||
*
|
||||
* @param {Array} reactions - The reactions to be animated.
|
||||
* @returns {ReactionsAction}
|
||||
*/
|
||||
export function pushReactions(reactions: Array<string>): ReactionsAction {
|
||||
return {
|
||||
|
|
|
@ -6,6 +6,8 @@ import { ReactionsAction } from './reducer';
|
|||
|
||||
/**
|
||||
* Toggles the visibility of the reactions menu.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function toggleReactionsMenuVisibility(): ReactionsAction {
|
||||
return {
|
||||
|
@ -15,6 +17,8 @@ export function toggleReactionsMenuVisibility(): ReactionsAction {
|
|||
|
||||
/**
|
||||
* Displays the disable sounds notification.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function displayReactionSoundsNotification(): ReactionsAction {
|
||||
return {
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
/* eslint-disable import/order */
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// @ts-ignore
|
||||
import { IStore } from '../../../app/types';
|
||||
|
||||
// @ts-ignore
|
||||
import { connect } from '../../../base/redux';
|
||||
import { removeReaction } from '../../actions.any';
|
||||
import { REACTIONS } from '../../constants';
|
||||
import { IStore } from '../../../app/types';
|
||||
|
||||
type Props = {
|
||||
|
||||
|
@ -86,8 +89,10 @@ class ReactionEmoji extends Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = (dispatch: IStore['dispatch']) => ({
|
||||
reactionRemove: (uid: string) => dispatch(removeReaction(uid))
|
||||
});
|
||||
const mapDispatchToProps = (dispatch: IStore['dispatch']) => {
|
||||
return {
|
||||
reactionRemove: (uid: string) => dispatch(removeReaction(uid))
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(null, mapDispatchToProps)(ReactionEmoji);
|
||||
export default connect(undefined, mapDispatchToProps)(ReactionEmoji);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable import/order */
|
||||
import { withStyles } from '@material-ui/styles';
|
||||
import clsx from 'clsx';
|
||||
import React, { Component } from 'react';
|
||||
|
@ -7,21 +8,29 @@ import {
|
|||
createReactionMenuEvent,
|
||||
createToolbarEvent,
|
||||
sendAnalytics
|
||||
|
||||
// @ts-ignore
|
||||
} from '../../../analytics';
|
||||
import { IStore } from '../../../app/types';
|
||||
|
||||
// @ts-ignore
|
||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||
|
||||
// @ts-ignore
|
||||
import { translate } from '../../../base/i18n';
|
||||
|
||||
// @ts-ignore
|
||||
import { getLocalParticipant, hasRaisedHand, raiseHand } from '../../../base/participants';
|
||||
|
||||
// @ts-ignore
|
||||
import { connect } from '../../../base/redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { GifsMenu, GifsMenuButton } from '../../../gifs/components';
|
||||
|
||||
// @ts-ignore
|
||||
import { isGifEnabled, isGifsMenuOpen } from '../../../gifs/functions';
|
||||
|
||||
// @ts-ignore
|
||||
import { dockToolbox } from '../../../toolbox/actions.web';
|
||||
import { addReactionToBuffer } from '../../actions.any';
|
||||
|
@ -88,8 +97,6 @@ type Props = {
|
|||
t: Function
|
||||
};
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
const styles = (theme: any) => {
|
||||
return {
|
||||
overflow: {
|
||||
|
@ -201,6 +208,7 @@ class ReactionsMenu extends Component<Props> {
|
|||
accessibilityLabel = { t(`toolbar.accessibilityLabel.${key}`) }
|
||||
icon = { REACTIONS[key].emoji }
|
||||
key = { key }
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick = { doSendReaction }
|
||||
toggled = { false }
|
||||
tooltip = { `${t(`toolbar.${key}`)} (${modifierKey} + ${REACTIONS[key].shortcutChar})` } />);
|
||||
|
@ -274,6 +282,7 @@ function mapDispatchToProps(dispatch: IStore['dispatch']) {
|
|||
...bindActionCreators(
|
||||
{
|
||||
_dockToolbox: dockToolbox
|
||||
|
||||
// @ts-ignore
|
||||
}, dispatch)
|
||||
};
|
||||
|
@ -282,5 +291,6 @@ function mapDispatchToProps(dispatch: IStore['dispatch']) {
|
|||
export default translate(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
|
||||
// @ts-ignore
|
||||
)(withStyles(styles)(ReactionsMenu)));
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable import/order */
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
// @ts-ignore
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { isMobileBrowser } from '../../../base/environment/utils';
|
||||
|
||||
// @ts-ignore
|
||||
import { translate } from '../../../base/i18n';
|
||||
|
||||
// @ts-ignore
|
||||
import { IconArrowUp } from '../../../base/icons';
|
||||
|
||||
// @ts-ignore
|
||||
import { connect } from '../../../base/redux';
|
||||
|
||||
// @ts-ignore
|
||||
import ToolboxButtonWithIconPopup from '../../../base/toolbox/components/web/ToolboxButtonWithIconPopup';
|
||||
import { toggleReactionsMenuVisibility } from '../../actions.web';
|
||||
|
@ -73,9 +77,6 @@ type Props = {
|
|||
t: Function
|
||||
};
|
||||
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Button used for the reactions menu.
|
||||
*
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
/* eslint-disable import/order */
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
// @ts-ignore
|
||||
import { getFeatureFlag, REACTIONS_ENABLED } from '../base/flags';
|
||||
|
||||
// @ts-ignore
|
||||
import { getLocalParticipant } from '../base/participants';
|
||||
|
||||
// @ts-ignore
|
||||
import { extractFqnFromPath } from '../dynamic-branding/functions.any';
|
||||
|
||||
|
@ -14,6 +17,7 @@ import logger from './logger';
|
|||
* Returns the queue of reactions.
|
||||
*
|
||||
* @param {Object} state - The state of the application.
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function getReactionsQueue(state: any): Array<ReactionEmojiProps> {
|
||||
return state['features/reactions'].queue;
|
||||
|
@ -23,6 +27,7 @@ export function getReactionsQueue(state: any): Array<ReactionEmojiProps> {
|
|||
* Returns chat message from reactions buffer.
|
||||
*
|
||||
* @param {Array} buffer - The reactions buffer.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getReactionMessageFromBuffer(buffer: Array<string>): string {
|
||||
return buffer.map<string>(reaction => REACTIONS[reaction].message).reduce((acc, val) => `${acc}${val}`);
|
||||
|
@ -32,6 +37,7 @@ export function getReactionMessageFromBuffer(buffer: Array<string>): string {
|
|||
* Returns reactions array with uid.
|
||||
*
|
||||
* @param {Array} buffer - The reactions buffer.
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function getReactionsWithId(buffer: Array<string>): Array<ReactionEmojiProps> {
|
||||
return buffer.map<ReactionEmojiProps>(reaction => {
|
||||
|
@ -47,6 +53,7 @@ export function getReactionsWithId(buffer: Array<string>): Array<ReactionEmojiPr
|
|||
*
|
||||
* @param {Object} state - The redux state object.
|
||||
* @param {Array} reactions - Reactions array to be sent.
|
||||
* @returns {void}
|
||||
*/
|
||||
export async function sendReactionsWebhook(state: any, reactions: Array<string>) {
|
||||
const { webhookProxyUrl: url } = state['features/base/config'];
|
||||
|
@ -93,6 +100,7 @@ export async function sendReactionsWebhook(state: any, reactions: Array<string>)
|
|||
* Returns unique reactions from the reactions buffer.
|
||||
*
|
||||
* @param {Array} reactions - The reactions buffer.
|
||||
* @returns {Array}
|
||||
*/
|
||||
function getUniqueReactions(reactions: Array<string>): Array<string> {
|
||||
return [ ...new Set(reactions) ];
|
||||
|
@ -103,6 +111,7 @@ function getUniqueReactions(reactions: Array<string>): Array<string> {
|
|||
*
|
||||
* @param {Array} reactions - Array of reactions.
|
||||
* @param {string} reaction - Reaction to get frequency for.
|
||||
* @returns {number}
|
||||
*/
|
||||
function getReactionFrequency(reactions: Array<string>, reaction: string): number {
|
||||
return reactions.filter(r => r === reaction).length;
|
||||
|
@ -112,6 +121,7 @@ function getReactionFrequency(reactions: Array<string>, reaction: string): numbe
|
|||
* Returns the threshold number for a given frequency.
|
||||
*
|
||||
* @param {number} frequency - Frequency of reaction.
|
||||
* @returns {number}
|
||||
*/
|
||||
function getSoundThresholdByFrequency(frequency: number): number {
|
||||
for (const i of SOUNDS_THRESHOLDS) {
|
||||
|
@ -127,6 +137,7 @@ function getSoundThresholdByFrequency(frequency: number): number {
|
|||
* Returns unique reactions with threshold.
|
||||
*
|
||||
* @param {Array} reactions - The reactions buffer.
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function getReactionsSoundsThresholds(reactions: Array<string>): Array<ReactionThreshold> {
|
||||
const unique = getUniqueReactions(reactions);
|
||||
|
@ -143,6 +154,7 @@ export function getReactionsSoundsThresholds(reactions: Array<string>): Array<Re
|
|||
* Whether or not the reactions are enabled.
|
||||
*
|
||||
* @param {Object} state - The Redux state object.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isReactionsEnabled(state: any): boolean {
|
||||
const { disableReactions } = state['features/base/config'];
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Returns the visibility state of the reactions menu.
|
||||
*
|
||||
* @param {Object} state - The state of the application.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function getReactionsMenuVisibility(state: any): boolean {
|
||||
return state['features/reactions'].visible;
|
||||
|
|
|
@ -1,30 +1,41 @@
|
|||
/* eslint-disable import/order */
|
||||
// @ts-ignore
|
||||
import { batch } from 'react-redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { createReactionSoundsDisabledEvent, sendAnalytics } from '../analytics';
|
||||
|
||||
// @ts-ignore
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
|
||||
import { IStore } from '../app/types';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
|
||||
import {
|
||||
CONFERENCE_JOIN_IN_PROGRESS,
|
||||
SET_START_REACTIONS_MUTED,
|
||||
setStartReactionsMuted
|
||||
|
||||
// @ts-ignore
|
||||
} from '../base/conference';
|
||||
import {
|
||||
getParticipantById,
|
||||
getParticipantCount,
|
||||
isLocalParticipantModerator
|
||||
|
||||
// @ts-ignore
|
||||
} from '../base/participants';
|
||||
|
||||
// @ts-ignore
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { SETTINGS_UPDATED } from '../base/settings/actionTypes';
|
||||
|
||||
// @ts-ignore
|
||||
import { updateSettings } from '../base/settings/actions';
|
||||
|
||||
// @ts-ignore
|
||||
import { playSound, registerSound, unregisterSound } from '../base/sounds';
|
||||
|
||||
// @ts-ignore
|
||||
import { getDisabledSounds } from '../base/sounds/functions.any';
|
||||
|
||||
// @ts-ignore
|
||||
import { NOTIFICATION_TIMEOUT_TYPE, showNotification } from '../notifications';
|
||||
|
||||
|
@ -60,7 +71,6 @@ import {
|
|||
} from './functions.any';
|
||||
import logger from './logger';
|
||||
import { RAISE_HAND_SOUND_FILE } from './sounds';
|
||||
import { IStore } from '../app/types';
|
||||
|
||||
/**
|
||||
* Middleware which intercepts Reactions actions to handle changes to the
|
||||
|
@ -241,6 +251,7 @@ MiddlewareRegistry.register((store: IStore) => (next: Function) => (action:any)
|
|||
* @param {Object} store - The redux store. Used to calculate and dispatch
|
||||
* updates.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _onMuteReactionsCommand(attributes: MuteCommandAttributes = {}, id: string, store: IStore) {
|
||||
const state = store.getState();
|
||||
|
@ -267,6 +278,7 @@ function _onMuteReactionsCommand(attributes: MuteCommandAttributes = {}, id: str
|
|||
}
|
||||
|
||||
const oldState = Boolean(state['features/base/conference'].startReactionsMuted);
|
||||
|
||||
// @ts-ignore
|
||||
const newState = attributes.startReactionsMuted === 'true';
|
||||
|
||||
|
|
|
@ -10,20 +10,24 @@ import {
|
|||
} from './actionTypes';
|
||||
import { ReactionEmojiProps } from './constants';
|
||||
|
||||
interface State {
|
||||
interface IReactionsState {
|
||||
|
||||
/**
|
||||
* The indicator that determines whether the reactions menu is visible.
|
||||
*/
|
||||
visible: boolean,
|
||||
|
||||
/**
|
||||
* An array that contains the reactions buffer to be sent.
|
||||
*/
|
||||
buffer: Array<string>,
|
||||
|
||||
/**
|
||||
* A number, non-zero value which identifies the timer created by a call
|
||||
* to setTimeout().
|
||||
*/
|
||||
timeoutID: number|null,
|
||||
|
||||
/**
|
||||
* The array of reactions to animate.
|
||||
*/
|
||||
|
@ -35,19 +39,23 @@ interface State {
|
|||
notificationDisplayed: boolean
|
||||
}
|
||||
|
||||
export interface ReactionsAction extends Partial<State> {
|
||||
export interface ReactionsAction extends Partial<IReactionsState> {
|
||||
|
||||
/**
|
||||
* The message to be added to the chat.
|
||||
*/
|
||||
message?: string,
|
||||
|
||||
/**
|
||||
* The reaction to be added to buffer.
|
||||
*/
|
||||
reaction?: string,
|
||||
|
||||
/**
|
||||
* The reactions to be added to the animation queue.
|
||||
*/
|
||||
reactions?: Array<string>,
|
||||
|
||||
/**
|
||||
* The action type.
|
||||
*/
|
||||
|
@ -58,8 +66,9 @@ export interface ReactionsAction extends Partial<State> {
|
|||
* Returns initial state for reactions' part of Redux store.
|
||||
*
|
||||
* @private
|
||||
* @returns {IReactionsState}
|
||||
*/
|
||||
function _getInitialState(): State {
|
||||
function _getInitialState(): IReactionsState {
|
||||
return {
|
||||
visible: false,
|
||||
buffer: [],
|
||||
|
@ -71,7 +80,7 @@ function _getInitialState(): State {
|
|||
|
||||
ReducerRegistry.register(
|
||||
'features/reactions',
|
||||
(state: State = _getInitialState(), action: ReactionsAction) => {
|
||||
(state: IReactionsState = _getInitialState(), action: ReactionsAction) => {
|
||||
switch (action.type) {
|
||||
|
||||
case TOGGLE_REACTIONS_VISIBLE:
|
||||
|
|
|
@ -1,36 +1,40 @@
|
|||
interface IReduxStore {
|
||||
dispatch: Function;
|
||||
getState: Function;
|
||||
}
|
||||
import { IStore } from '../../../app/types';
|
||||
|
||||
interface ILocalRecordingManager {
|
||||
addAudioTrackToLocalRecording: (track: MediaStreamTrack) => void;
|
||||
stopLocalRecording: () => void;
|
||||
startLocalRecording: (store: IReduxStore) => void;
|
||||
startLocalRecording: (store: IStore) => void;
|
||||
isRecordingLocally: () => boolean;
|
||||
}
|
||||
|
||||
const LocalRecordingManager: ILocalRecordingManager = {
|
||||
/**
|
||||
* Adds audio track to the recording stream.
|
||||
*
|
||||
* @param {MediaStreamTrack} track - Track to be added,.
|
||||
* @returns {void}
|
||||
*/
|
||||
addAudioTrackToLocalRecording(track) {
|
||||
},
|
||||
addAudioTrackToLocalRecording() { },
|
||||
|
||||
/**
|
||||
* Stops local recording.
|
||||
*
|
||||
* @returns {void}
|
||||
* */
|
||||
stopLocalRecording() {
|
||||
},
|
||||
stopLocalRecording() { },
|
||||
|
||||
/**
|
||||
* Starts a local recording.
|
||||
*
|
||||
* @param {IStore} store - The Redux store.
|
||||
* @returns {void}
|
||||
*/
|
||||
async startLocalRecording(store) {
|
||||
},
|
||||
async startLocalRecording() { },
|
||||
|
||||
/**
|
||||
* Whether or not we're currently recording locally.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isRecordingLocally() {
|
||||
return false;
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
/* eslint-disable import/order */
|
||||
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
import fixWebmDuration from 'webm-duration-fix';
|
||||
|
||||
import { IStore } from '../../../app/types';
|
||||
|
||||
// @ts-ignore
|
||||
import { getRoomName } from '../../../base/conference';
|
||||
|
||||
// @ts-ignore
|
||||
import { MEDIA_TYPE } from '../../../base/media';
|
||||
|
||||
// @ts-ignore
|
||||
import { getTrackState, getLocalTrack } from '../../../base/tracks';
|
||||
import { inIframe } from '../../../base/util/iframeUtils';
|
||||
|
||||
// @ts-ignore
|
||||
import { stopLocalVideoRecording } from '../../actions.any';
|
||||
|
||||
declare var APP: any;
|
||||
|
||||
interface IReduxStore {
|
||||
dispatch: Function;
|
||||
getState: Function;
|
||||
}
|
||||
declare let APP: any;
|
||||
|
||||
interface SelfRecording {
|
||||
on: boolean;
|
||||
|
@ -37,7 +39,7 @@ interface ILocalRecordingManager {
|
|||
getFilename: () => string;
|
||||
saveRecording: (recordingData: Blob[], filename: string) => void;
|
||||
stopLocalRecording: () => void;
|
||||
startLocalRecording: (store: IReduxStore, onlySelf: boolean) => void;
|
||||
startLocalRecording: (store: IStore, onlySelf: boolean) => void;
|
||||
isRecordingLocally: () => boolean;
|
||||
totalSize: number;
|
||||
selfRecording: SelfRecording;
|
||||
|
@ -48,15 +50,16 @@ const getMimeType = (): string => {
|
|||
'video/mp4;codecs=h264',
|
||||
'video/webm;codecs=h264',
|
||||
'video/webm;codecs=vp9',
|
||||
'video/webm;codecs=vp8',
|
||||
'video/webm;codecs=vp8'
|
||||
];
|
||||
for(let type of possibleTypes) {
|
||||
if(MediaRecorder.isTypeSupported(type)) {
|
||||
|
||||
for (const type of possibleTypes) {
|
||||
if (MediaRecorder.isTypeSupported(type)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
throw new Error("No MIME Type supported by MediaRecorder");
|
||||
}
|
||||
throw new Error('No MIME Type supported by MediaRecorder');
|
||||
};
|
||||
|
||||
const VIDEO_BIT_RATE = 2500000; // 2.5Mbps in bits
|
||||
|
||||
|
@ -86,6 +89,8 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Initializes audio context used for mixing audio tracks.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
initializeAudioMixer() {
|
||||
this.audioContext = new AudioContext();
|
||||
|
@ -94,6 +99,9 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Mixes multiple audio tracks to the destination media stream.
|
||||
*
|
||||
* @param {MediaStream} stream - The stream to mix.
|
||||
* @returns {void}
|
||||
* */
|
||||
mixAudioStream(stream) {
|
||||
if (stream.getAudioTracks().length > 0 && this.audioDestination) {
|
||||
|
@ -103,9 +111,12 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Adds audio track to the recording stream.
|
||||
*
|
||||
* @param {MediaStreamTrack} track - The track to be added.
|
||||
* @returns {void}
|
||||
*/
|
||||
addAudioTrackToLocalRecording(track) {
|
||||
if(this.selfRecording.on) {
|
||||
if (this.selfRecording.on) {
|
||||
return;
|
||||
}
|
||||
if (track) {
|
||||
|
@ -117,6 +128,8 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Returns a filename based ono the Jitsi room name in the URL and timestamp.
|
||||
*
|
||||
* @returns {string}
|
||||
* */
|
||||
getFilename() {
|
||||
const now = new Date();
|
||||
|
@ -127,15 +140,21 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Saves local recording to file.
|
||||
*
|
||||
* @param {Array} recordingData - The recording data.
|
||||
* @param {string} filename - The name of the file.
|
||||
* @returns {void}
|
||||
* */
|
||||
async saveRecording(recordingData, filename) {
|
||||
// @ts-ignore
|
||||
const blob = await fixWebmDuration(new Blob(recordingData, { type: this.mediaType }));
|
||||
|
||||
// @ts-ignore
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
|
||||
const extension = this.mediaType.slice(this.mediaType.indexOf('/') + 1, this.mediaType.indexOf(';'))
|
||||
const extension = this.mediaType.slice(this.mediaType.indexOf('/') + 1, this.mediaType.indexOf(';'));
|
||||
|
||||
a.style.display = 'none';
|
||||
a.href = url;
|
||||
a.download = `${filename}.${extension}`;
|
||||
|
@ -144,6 +163,8 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Stops local recording.
|
||||
*
|
||||
* @returns {void}
|
||||
* */
|
||||
stopLocalRecording() {
|
||||
if (this.recorder) {
|
||||
|
@ -157,9 +178,14 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Starts a local recording.
|
||||
*
|
||||
* @param {IStore} store - The redux store.
|
||||
* @param {boolean} onlySelf - Whether to record only self streams.
|
||||
* @returns {void}
|
||||
*/
|
||||
async startLocalRecording(store, onlySelf) {
|
||||
const { dispatch, getState } = store;
|
||||
|
||||
// @ts-ignore
|
||||
const supportsCaptureHandle = Boolean(navigator.mediaDevices.setCaptureHandleConfig) && !inIframe();
|
||||
const tabId = uuidV4();
|
||||
|
@ -170,25 +196,27 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
let gdmStream: MediaStream = new MediaStream();
|
||||
const tracks = getTrackState(getState());
|
||||
|
||||
if(onlySelf) {
|
||||
if (onlySelf) {
|
||||
let audioTrack: MediaStreamTrack | undefined = getLocalTrack(tracks, MEDIA_TYPE.AUDIO)?.jitsiTrack?.track;
|
||||
let videoTrack: MediaStreamTrack | undefined = getLocalTrack(tracks, MEDIA_TYPE.VIDEO)?.jitsiTrack?.track;
|
||||
if(!audioTrack) {
|
||||
|
||||
if (!audioTrack) {
|
||||
APP.conference.muteAudio(false);
|
||||
setTimeout(() => APP.conference.muteAudio(true), 100);
|
||||
await new Promise((resolve) => {
|
||||
await new Promise(resolve => {
|
||||
setTimeout(resolve, 100);
|
||||
});
|
||||
}
|
||||
if(videoTrack && videoTrack.readyState !== 'live') {
|
||||
if (videoTrack && videoTrack.readyState !== 'live') {
|
||||
videoTrack = undefined;
|
||||
}
|
||||
audioTrack = getLocalTrack(getTrackState(getState()), MEDIA_TYPE.AUDIO)?.jitsiTrack?.track;
|
||||
if(!audioTrack && !videoTrack) {
|
||||
throw new Error('NoLocalStreams')
|
||||
if (!audioTrack && !videoTrack) {
|
||||
throw new Error('NoLocalStreams');
|
||||
}
|
||||
this.selfRecording.withVideo = Boolean(videoTrack);
|
||||
const localTracks = [];
|
||||
|
||||
audioTrack && localTracks.push(audioTrack);
|
||||
videoTrack && localTracks.push(videoTrack);
|
||||
this.stream = new MediaStream(localTracks);
|
||||
|
@ -204,7 +232,8 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
// @ts-ignore
|
||||
gdmStream = await navigator.mediaDevices.getDisplayMedia({
|
||||
// @ts-ignore
|
||||
video: { displaySurface: 'browser', frameRate: 30 },
|
||||
video: { displaySurface: 'browser',
|
||||
frameRate: 30 },
|
||||
audio: {
|
||||
autoGainControl: false,
|
||||
channelCount: 2,
|
||||
|
@ -212,6 +241,7 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
noiseSuppression: false
|
||||
}
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
const isBrowser = gdmStream.getVideoTracks()[0].getSettings().displaySurface === 'browser';
|
||||
|
||||
|
@ -232,7 +262,7 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
}
|
||||
});
|
||||
this.stream = new MediaStream([
|
||||
...(this.audioDestination?.stream.getAudioTracks() || []),
|
||||
...this.audioDestination?.stream.getAudioTracks() || [],
|
||||
gdmStream.getVideoTracks()[0]
|
||||
]);
|
||||
}
|
||||
|
@ -251,7 +281,7 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
}
|
||||
});
|
||||
|
||||
if(!onlySelf) {
|
||||
if (!onlySelf) {
|
||||
this.recorder.addEventListener('stop', () => {
|
||||
this.stream?.getTracks().forEach((track: MediaStreamTrack) => track.stop());
|
||||
gdmStream?.getTracks().forEach((track: MediaStreamTrack) => track.stop());
|
||||
|
@ -271,6 +301,8 @@ const LocalRecordingManager: ILocalRecordingManager = {
|
|||
|
||||
/**
|
||||
* Whether or not we're currently recording locally.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isRecordingLocally() {
|
||||
return Boolean(this.recorder);
|
||||
|
|
|
@ -34,7 +34,7 @@ class OpenCarmodeButton extends AbstractButton<AbstractButtonProps, any, any> {
|
|||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
function _mapStateToProps(state: Object, ownProps: AbstractButtonProps): Object {
|
||||
function _mapStateToProps(state: Object, ownProps: AbstractButtonProps): Object {
|
||||
const enabled = getFeatureFlag(state, CAR_MODE_ENABLED, true);
|
||||
const { visible = enabled } = ownProps;
|
||||
|
||||
|
|
|
@ -22,8 +22,9 @@ const ScreenSharingButton = props => (
|
|||
* Maps (parts of) the redux state to the associated props for the
|
||||
* {@code ScreenSharingButton} component.
|
||||
*
|
||||
* @param state - The Redux state.
|
||||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
function _mapStateToProps(state: object): object {
|
||||
return {
|
||||
|
|
Loading…
Reference in New Issue