diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..0c513bad1 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,85 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:react/recommended" + ], + "settings": { + "react": { + "version": "detect" + } + }, + "globals": { + "YT": "readonly", + "FB": "readonly" + }, + "env": { + "commonjs": true, + "browser": true, + "es6": true + }, + "parserOptions": { + "ecmaVersion": 9, + "ecmaFeatures": { + "jsx": true + } + }, + "ignorePatterns": [ + "/*", + "!/src", + "src/routes/Settings", + "src/routes/Player", + "src/video" + ], + "rules": { + "arrow-parens": "error", + "arrow-spacing": "error", + "block-spacing": "error", + "comma-spacing": "error", + "eol-last": "error", + "eqeqeq": "error", + "func-call-spacing": "error", + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-console": "error", + "no-extra-semi": "error", + "no-eq-null": "error", + "no-multi-spaces": "error", + "no-multiple-empty-lines": [ + "error", + { + "max": 1 + } + ], + "no-template-curly-in-string": "error", + "no-trailing-spaces": "error", + "no-useless-concat": "error", + "no-unreachable": "error", + "no-unused-vars": "error", + "prefer-const": "error", + "quotes": [ + "error", + "single" + ], + "quote-props": [ + "error", + "as-needed", + { + "unnecessary": false + } + ], + "semi": "error", + "semi-spacing": "error", + "space-before-blocks": "error", + "valid-typeof": [ + "error", + { + "requireStringLiterals": true + } + ] + } +} \ No newline at end of file diff --git a/package.json b/package.json index da4427714..9c26d2763 100755 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "start": "webpack-dev-server --mode development", "build": "webpack --mode production", "storybook": "start-storybook --ci --config-dir ./storybook --static-dir ./ --port 6060", - "test": "jest" + "test": "jest", + "lint": "eslint src" }, "dependencies": { "a-color-picker": "1.2.1", @@ -47,6 +48,8 @@ "css-loader": "3.2.1", "cssnano": "4.1.10", "cssnano-preset-advanced": "4.0.7", + "eslint": "6.7.2", + "eslint-plugin-react": "7.17.0", "html-webpack-plugin": "3.2.0", "jest": "24.9.0", "less": "3.10.3", diff --git a/src/common/Button/Button.js b/src/common/Button/Button.js index 21512b041..89d7d342d 100644 --- a/src/common/Button/Button.js +++ b/src/common/Button/Button.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const styles = require('./styles'); @@ -41,4 +42,13 @@ const Button = React.forwardRef(({ className, href, disabled, children, ...props Button.displayName = 'Button'; +Button.propTypes = { + className: PropTypes.string, + href: PropTypes.string, + disabled: PropTypes.bool, + children: PropTypes.node, + onKeyDown: PropTypes.func, + onMouseDown: PropTypes.func +}; + module.exports = Button; diff --git a/src/common/Checkbox/Checkbox.js b/src/common/Checkbox/Checkbox.js index 96c29f334..6fd3f3a72 100644 --- a/src/common/Checkbox/Checkbox.js +++ b/src/common/Checkbox/Checkbox.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); const Button = require('stremio/common/Button'); @@ -22,4 +23,10 @@ const Checkbox = React.forwardRef(({ className, checked, children, ...props }, r Checkbox.displayName = 'Checkbox'; +Checkbox.propTypes = { + className: PropTypes.string, + checked: PropTypes.bool, + children: PropTypes.node +}; + module.exports = Checkbox; diff --git a/src/common/ColorInput/ColorInput.js b/src/common/ColorInput/ColorInput.js index f493a11f1..7e846a4a8 100644 --- a/src/common/ColorInput/ColorInput.js +++ b/src/common/ColorInput/ColorInput.js @@ -16,9 +16,8 @@ const ColorInput = ({ className, value, dataset, onChange, ...props }) => { return parseColor(value); }); const labelButtonStyle = React.useMemo(() => ({ - ...props.style, backgroundColor: value - }), [props.style, value]); + }), [value]); const labelButtonOnClick = React.useCallback((event) => { if (typeof props.onClick === 'function') { props.onClick(event); @@ -76,9 +75,11 @@ const ColorInput = ({ className, value, dataset, onChange, ...props }) => { }; ColorInput.propTypes = { + className: PropTypes.string, value: PropTypes.string, - dataset: PropTypes.objectOf(String), - onChange: PropTypes.func + dataset: PropTypes.objectOf(PropTypes.string), + onChange: PropTypes.func, + onClick: PropTypes.func }; module.exports = ColorInput; diff --git a/src/common/Image/Image.js b/src/common/Image/Image.js index 520fade03..8091c2615 100644 --- a/src/common/Image/Image.js +++ b/src/common/Image/Image.js @@ -27,7 +27,8 @@ Image.propTypes = { src: PropTypes.string, alt: PropTypes.string, fallbackSrc: PropTypes.string, - renderFallback: PropTypes.func + renderFallback: PropTypes.func, + onError: PropTypes.func }; module.exports = Image; diff --git a/src/common/MainNavBar/MainNavBar.js b/src/common/MainNavBar/MainNavBar.js index c6920ce42..507f8d229 100644 --- a/src/common/MainNavBar/MainNavBar.js +++ b/src/common/MainNavBar/MainNavBar.js @@ -23,6 +23,8 @@ const MainNavBar = React.memo(({ className }) => { ); }); +MainNavBar.displayName = 'MainNavBar'; + MainNavBar.propTypes = { className: PropTypes.string }; diff --git a/src/common/MetaItem/MetaItem.js b/src/common/MetaItem/MetaItem.js index 5c130933a..4d4f6cb1f 100644 --- a/src/common/MetaItem/MetaItem.js +++ b/src/common/MetaItem/MetaItem.js @@ -121,8 +121,9 @@ MetaItem.propTypes = { playIcon: PropTypes.bool, progress: PropTypes.number, options: PropTypes.array, - dataset: PropTypes.objectOf(String), - optionOnSelect: PropTypes.func + dataset: PropTypes.objectOf(PropTypes.string), + optionOnSelect: PropTypes.func, + onClick: PropTypes.func }; module.exports = MetaItem; diff --git a/src/common/MetaPreview/MetaPreview.js b/src/common/MetaPreview/MetaPreview.js index 9cd1b7d8e..0aca83e9a 100644 --- a/src/common/MetaPreview/MetaPreview.js +++ b/src/common/MetaPreview/MetaPreview.js @@ -179,7 +179,7 @@ const MetaPreview = ({ className, compact, name, logo, background, runtime, rele null } { - linksGroups.hasOwnProperty(IMDB_LINK_CATEGORY) ? + typeof linksGroups[IMDB_LINK_CATEGORY] === 'object' ? { - const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false); + const [menuOpen, , closeMenu, toggleMenu] = useBinaryState(false); const options = React.useMemo(() => { return Array.isArray(props.options) ? props.options.filter((option) => { @@ -143,12 +143,13 @@ Multiselect.propTypes = { })), selected: PropTypes.arrayOf(PropTypes.string), disabled: PropTypes.bool, - dataset: PropTypes.objectOf(String), + dataset: PropTypes.objectOf(PropTypes.string), renderLabelContent: PropTypes.func, renderLabelText: PropTypes.func, onOpen: PropTypes.func, onClose: PropTypes.func, - onSelect: PropTypes.func + onSelect: PropTypes.func, + onClick: PropTypes.func }; module.exports = Multiselect; diff --git a/src/common/NavBar/NavMenu/NavMenu.js b/src/common/NavBar/NavMenu/NavMenu.js index 60871a0a2..2509185a2 100644 --- a/src/common/NavBar/NavMenu/NavMenu.js +++ b/src/common/NavBar/NavMenu/NavMenu.js @@ -10,7 +10,7 @@ const useUser = require('stremio/common/useUser'); const styles = require('./styles'); const NavMenu = ({ className }) => { - const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false); + const [menuOpen, , closeMenu, toggleMenu] = useBinaryState(false); const [fullscreen, requestFullscreen, exitFullscreen] = useFullscreen(); const [user, logout] = useUser(); const popupLabelOnClick = React.useCallback((event) => { @@ -41,7 +41,7 @@ const NavMenu = ({ className }) => { className={styles['avatar-container']} style={{ backgroundImage: user === null ? - `url('/images/anonymous.png')` + 'url(\'/images/anonymous.png\')' : `url('${user.avatar}'), url('/images/default_avatar.png')` }} diff --git a/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js b/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js index 53c7b0e81..8bba1d435 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsList/Notification/Notification.js @@ -80,7 +80,7 @@ const Notification = ({ className, id, type, name, poster, thumbnail, season, ep } ); -} +}; Notification.propTypes = { className: PropTypes.string, diff --git a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js index 3bbac1538..0ee602b64 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationPlaceholder/NotificationPlaceholder.js @@ -1,7 +1,6 @@ const React = require('react'); const PropTypes = require('prop-types'); const classnames = require('classnames'); -const Icon = require('stremio-icons/dom'); const styles = require('./styles'); const NotificationPlaceholder = ({ className }) => { @@ -20,6 +19,6 @@ const NotificationPlaceholder = ({ className }) => { NotificationPlaceholder.propTypes = { className: PropTypes.string -} +}; module.exports = NotificationPlaceholder; diff --git a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js index e54bacb68..3fca82728 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsList/NotificationsList.js @@ -57,7 +57,7 @@ const NotificationsList = ({ className, metaItems }) => { } ); -} +}; NotificationsList.propTypes = { className: PropTypes.string, diff --git a/src/common/NavBar/NotificationsMenu/NotificationsMenu.js b/src/common/NavBar/NotificationsMenu/NotificationsMenu.js index b0ea6d6d8..7e1a1d6e7 100644 --- a/src/common/NavBar/NotificationsMenu/NotificationsMenu.js +++ b/src/common/NavBar/NotificationsMenu/NotificationsMenu.js @@ -5,13 +5,13 @@ const Icon = require('stremio-icons/dom'); const Button = require('stremio/common/Button'); const Popup = require('stremio/common/Popup'); const NotificationsList = require('./NotificationsList'); -const useNotifications = require('./useNotifications'); +// const useNotifications = require('./useNotifications'); // const useCatalogs = require('stremio/routes/Board/useCatalogs'); const useBinaryState = require('stremio/common/useBinaryState'); const styles = require('./styles'); const NotificationsMenu = ({ className, onClearButtonClicked }) => { - const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false); + const [menuOpen, , closeMenu, toggleMenu] = useBinaryState(false); //TODO use useNotifications hook instead of useCatalogs const metaItems = []; //useCatalogs(); diff --git a/src/common/PaginationInput/PaginationInput.js b/src/common/PaginationInput/PaginationInput.js index 77bb38f5c..7358c55c7 100644 --- a/src/common/PaginationInput/PaginationInput.js +++ b/src/common/PaginationInput/PaginationInput.js @@ -35,6 +35,7 @@ const PaginationInput = ({ className, label, dataset, onSelect, ...props }) => { PaginationInput.propTypes = { className: PropTypes.string, label: PropTypes.string, + dataset: PropTypes.objectOf(PropTypes.string), onSelect: PropTypes.func }; diff --git a/src/common/PaginationInput/index.js b/src/common/PaginationInput/index.js index 99f9edf62..4500ec5a6 100644 --- a/src/common/PaginationInput/index.js +++ b/src/common/PaginationInput/index.js @@ -1,3 +1,3 @@ const PaginationInput = require('./PaginationInput'); -module.exports = PaginationInput; \ No newline at end of file +module.exports = PaginationInput; diff --git a/src/common/Popup/Popup.js b/src/common/Popup/Popup.js index d0b26fa03..59b89f26e 100644 --- a/src/common/Popup/Popup.js +++ b/src/common/Popup/Popup.js @@ -96,14 +96,14 @@ const Popup = ({ open, direction, renderLabel, renderMenu, dataset, onCloseReque : null }); -} +}; Popup.propTypes = { open: PropTypes.bool, direction: PropTypes.oneOf(['top-left', 'bottom-left', 'top-right', 'bottom-right']), renderLabel: PropTypes.func.isRequired, renderMenu: PropTypes.func.isRequired, - dataset: PropTypes.objectOf(String), + dataset: PropTypes.objectOf(PropTypes.string), onCloseRequest: PropTypes.func }; diff --git a/src/common/TextInput/TextInput.js b/src/common/TextInput/TextInput.js index 4f7db50f1..8b9606d6f 100644 --- a/src/common/TextInput/TextInput.js +++ b/src/common/TextInput/TextInput.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const styles = require('./styles'); @@ -30,4 +31,11 @@ const TextInput = React.forwardRef((props, ref) => { TextInput.displayName = 'TextInput'; +TextInput.propTypes = { + className: PropTypes.string, + disabled: PropTypes.bool, + onKeyDown: PropTypes.func, + onSubmit: PropTypes.func +}; + module.exports = TextInput; diff --git a/src/common/routesRegexp.js b/src/common/routesRegexp.js index df7f4e069..113497ec5 100644 --- a/src/common/routesRegexp.js +++ b/src/common/routesRegexp.js @@ -8,11 +8,11 @@ const routesRegexp = { urlParamsNames: [] }, discover: { - regexp: /^\/discover(?:\/([^\/]*)\/([^\/]*)\/([^\/]*))?$/, + regexp: /^\/discover(?:\/([^/]*)\/([^/]*)\/([^/]*))?$/, urlParamsNames: ['addonTransportUrl', 'type', 'catalogId'] }, library: { - regexp: /^\/library(?:\/([^\/]*))?$/, + regexp: /^\/library(?:\/([^/]*))?$/, urlParamsNames: ['type'] }, search: { @@ -20,11 +20,11 @@ const routesRegexp = { urlParamsNames: [] }, metadetails: { - regexp: /^\/metadetails\/([^\/]*)\/([^\/]*)(?:\/([^\/]*))?$/, + regexp: /^\/metadetails\/([^/]*)\/([^/]*)(?:\/([^/]*))?$/, urlParamsNames: ['type', 'id', 'videoId'] }, addons: { - regexp: /^\/addons(?:\/([^\/]*)\/([^\/]*)\/([^\/]*))?$/, + regexp: /^\/addons(?:\/([^/]*)\/([^/]*)\/([^/]*))?$/, urlParamsNames: ['addonTransportUrl', 'catalogId', 'type'] }, settings: { @@ -32,7 +32,7 @@ const routesRegexp = { urlParamsNames: [] }, player: { - regexp: /^\/player\/([^\/]*)\/([^\/]*)\/([^\/]*)\/([^\/]*)$/, + regexp: /^\/player\/([^/]*)\/([^/]*)\/([^/]*)\/([^/]*)$/, urlParamsNames: ['type', 'id', 'videoId', 'stream'] } }; diff --git a/src/router/Router/Router.js b/src/router/Router/Router.js index dd8321e70..60fc0334b 100644 --- a/src/router/Router/Router.js +++ b/src/router/Router/Router.js @@ -95,7 +95,7 @@ const Router = ({ className, onPathNotMatch, ...props }) => {
{ views - .filter(view => view !== null) + .filter((view) => view !== null) .map(({ key, component, urlParams, queryParams }, index, views) => ( diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index 083c16747..3f7874666 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const Icon = require('stremio-icons/dom'); const { Button, Multiselect, NavBar, TextInput, SharePrompt, ModalDialog, useBinaryState } = require('stremio/common'); const Addon = require('./Addon'); @@ -186,4 +187,13 @@ const Addons = ({ urlParams, queryParams }) => { ); }; +Addons.propTypes = { + urlParams: PropTypes.exact({ + addonTransportUrl: PropTypes.string, + catalogId: PropTypes.string, + type: PropTypes.string + }), + queryParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = Addons; diff --git a/src/routes/Board/Board.js b/src/routes/Board/Board.js index 33b6638ae..47f293f45 100644 --- a/src/routes/Board/Board.js +++ b/src/routes/Board/Board.js @@ -32,7 +32,7 @@ const Board = () => { {board.catalog_resources.map((catalog_resource, index) => { const title = `${catalog_resource.addon_name} - ${catalog_resource.request.path.id} ${catalog_resource.request.path.type_name}`; switch (catalog_resource.content.type) { - case 'Ready': + case 'Ready': { return ( { limit={10} /> ); - case 'Err': + } + case 'Err': { const message = `Error(${catalog_resource.content.content.type})${typeof catalog_resource.content.content.content === 'string' ? ` - ${catalog_resource.content.content.content}` : ''}`; return ( { limit={10} /> ); - case 'Loading': + } + case 'Loading': { return ( { limit={10} /> ); + } } })}
diff --git a/src/routes/Board/useItemOptions.js b/src/routes/Board/useItemOptions.js index 870c14936..b4da90921 100644 --- a/src/routes/Board/useItemOptions.js +++ b/src/routes/Board/useItemOptions.js @@ -10,7 +10,7 @@ const DISMISS_OPTION = { value: 'dismiss' }; -const onSelect = (event) => { +const onSelect = () => { // TODO {{event.value}} {{event.dataset}} }; diff --git a/src/routes/Discover/Discover.js b/src/routes/Discover/Discover.js index 0db14b05e..4f8358b32 100644 --- a/src/routes/Discover/Discover.js +++ b/src/routes/Discover/Discover.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); const { Button, MainNavBar, MetaItem, MetaPreview, Multiselect, ModalDialog, PaginationInput, useBinaryState } = require('stremio/common'); @@ -135,4 +136,13 @@ const Discover = ({ urlParams, queryParams }) => { ); }; +Discover.propTypes = { + urlParams: PropTypes.exact({ + addonTransportUrl: PropTypes.string, + type: PropTypes.string, + catalogId: PropTypes.string + }), + queryParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = Discover; diff --git a/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js b/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js index fe1898b4e..df05b7e60 100644 --- a/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js +++ b/src/routes/Intro/ConsentCheckbox/ConsentCheckbox.js @@ -4,16 +4,20 @@ const classnames = require('classnames'); const { Button, Checkbox } = require('stremio/common'); const styles = require('./styles'); -const ConsentCheckbox = React.forwardRef(({ className, checked, label, link, href, toggle, ...props }, ref) => { +const ConsentCheckbox = React.forwardRef(({ className, checked, label, link, href, onToggle, ...props }, ref) => { const checkboxOnClick = React.useCallback((event) => { if (typeof props.onClick === 'function') { props.onClick(event); } - if (!event.nativeEvent.togglePrevented && typeof toggle === 'function') { - toggle(event); + if (!event.nativeEvent.togglePrevented && typeof onToggle === 'function') { + onToggle({ + type: 'toggle', + reactEvent: event, + nativeEvent: event.nativeEvent + }); } - }, [toggle]); + }, [onToggle]); const linkOnClick = React.useCallback((event) => { event.nativeEvent.togglePrevented = true; }, []); @@ -42,7 +46,8 @@ ConsentCheckbox.propTypes = { label: PropTypes.string, link: PropTypes.string, href: PropTypes.string, - toggle: PropTypes.func + onToggle: PropTypes.func, + onClick: PropTypes.func }; module.exports = ConsentCheckbox; diff --git a/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js b/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js index d3c7696cf..43a2bb087 100644 --- a/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js +++ b/src/routes/Intro/CredentialsTextInput/CredentialsTextInput.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const { TextInput } = require('stremio/common'); const CredentialsTextInput = React.forwardRef((props, ref) => { @@ -23,4 +24,8 @@ const CredentialsTextInput = React.forwardRef((props, ref) => { CredentialsTextInput.displayName = 'CredentialsTextInput'; +CredentialsTextInput.propTypes = { + onKeyDown: PropTypes.func +}; + module.exports = CredentialsTextInput; diff --git a/src/routes/Intro/Intro.js b/src/routes/Intro/Intro.js index 6b05700ab..3e8347db0 100644 --- a/src/routes/Intro/Intro.js +++ b/src/routes/Intro/Intro.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const Icon = require('stremio-icons/dom'); const { useRouteFocused } = require('stremio-router'); @@ -73,14 +74,17 @@ const Intro = ({ queryParams }) => { React.useEffect(() => { const onEvent = ({ event, args }) => { switch (event) { - case 'CtxActionErr': - const [_action, error] = args; + case 'CtxActionErr': { + const [, error] = args; dispatch({ type: 'error', error: error.args.message }); - case 'CtxChanged': + break; + } + case 'CtxChanged': { const state = core.getState(); if (state.ctx.content.auth !== null) { window.location.replace('#/'); } + } } }; if (routeFocused) { @@ -113,9 +117,7 @@ const Intro = ({ queryParams }) => { } }); }) - .catch((err) => { - console.error(err); - }); + .catch(() => { }); } }); }, [state.email, state.password]); @@ -256,7 +258,7 @@ const Intro = ({ queryParams }) => {
Continue with Facebook
-
We won't post anything on your behalf
+
We won't post anything on your behalf
{ link={'Terms and conditions'} href={'https://www.stremio.com/tos'} checked={state.termsAccepted} - toggle={toggleTermsAccepted} + onToggle={toggleTermsAccepted} /> { link={'Privacy Policy'} href={'https://www.stremio.com/privacy'} checked={state.privacyPolicyAccepted} - toggle={togglePrivacyPolicyAccepted} + onToggle={togglePrivacyPolicyAccepted} /> : @@ -343,4 +345,8 @@ const Intro = ({ queryParams }) => { ); }; +Intro.propTypes = { + queryParams: PropTypes.instanceOf(URLSearchParams) +}; + module.exports = Intro; diff --git a/src/routes/Library/Library.js b/src/routes/Library/Library.js index 0f3013cfb..d3c081646 100644 --- a/src/routes/Library/Library.js +++ b/src/routes/Library/Library.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const classnames = require('classnames'); const { Button, Multiselect, MainNavBar, MetaItem } = require('stremio/common'); const useLibrary = require('./useLibrary'); @@ -67,6 +68,13 @@ const Library = ({ urlParams, queryParams }) => { ); -} +}; + +Library.propTypes = { + urlParams: PropTypes.exact({ + type: PropTypes.string, + }), + queryParams: PropTypes.instanceOf(URLSearchParams) +}; module.exports = Library; diff --git a/src/routes/Library/useItemOptions.js b/src/routes/Library/useItemOptions.js index 870c14936..b4da90921 100644 --- a/src/routes/Library/useItemOptions.js +++ b/src/routes/Library/useItemOptions.js @@ -10,7 +10,7 @@ const DISMISS_OPTION = { value: 'dismiss' }; -const onSelect = (event) => { +const onSelect = () => { // TODO {{event.value}} {{event.dataset}} }; diff --git a/src/routes/Library/useLibrary.js b/src/routes/Library/useLibrary.js index 4acaa6e78..b2426e055 100644 --- a/src/routes/Library/useLibrary.js +++ b/src/routes/Library/useLibrary.js @@ -90,6 +90,6 @@ const useLibrary = (urlParams, queryParams) => { init: initLibraryState, onNewState: onNewLibraryState }); -} +}; module.exports = useLibrary; diff --git a/src/routes/MetaDetails/MetaDetails.js b/src/routes/MetaDetails/MetaDetails.js index a800ea1a7..3cd804345 100644 --- a/src/routes/MetaDetails/MetaDetails.js +++ b/src/routes/MetaDetails/MetaDetails.js @@ -1,4 +1,5 @@ const React = require('react'); +const PropTypes = require('prop-types'); const { NavBar, MetaPreview, useInLibrary } = require('stremio/common'); const VideosList = require('./VideosList'); const StreamsList = require('./StreamsList'); @@ -111,4 +112,12 @@ const MetaDetails = ({ urlParams }) => { ); }; +MetaDetails.propTypes = { + urlParams: PropTypes.exact({ + type: PropTypes.string, + id: PropTypes.string, + videoId: PropTypes.string + }) +}; + module.exports = MetaDetails; diff --git a/src/routes/MetaDetails/StreamsList/StreamsList.js b/src/routes/MetaDetails/StreamsList/StreamsList.js index 01163b29a..2e0f8de86 100644 --- a/src/routes/MetaDetails/StreamsList/StreamsList.js +++ b/src/routes/MetaDetails/StreamsList/StreamsList.js @@ -44,7 +44,7 @@ const StreamsList = ({ className, streamsResources }) => { ); -} +}; StreamsList.propTypes = { className: PropTypes.string, diff --git a/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js b/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js index cfe24abe3..d830d710d 100644 --- a/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js +++ b/src/routes/MetaDetails/VideosList/SeasonsBar/SeasonsBar.js @@ -16,11 +16,9 @@ const SeasonsBar = ({ className, seasons, season, onSelect }) => { const selected = React.useMemo(() => { return [String(season)]; }, [season]); - const renderMultiselectLabelContent = React.useMemo(() => { - return () => ( -
Season {season}
- ); - }, [season]); + const renderMultiselectLabelContent = React.useMemo(() => () => ( +
Season {season}
+ ), [season]); const prevNextButtonOnClick = React.useCallback((event) => { if (typeof onSelect === 'function') { const seasonIndex = seasons.indexOf(season); diff --git a/src/routes/MetaDetails/VideosList/Video/Video.js b/src/routes/MetaDetails/VideosList/Video/Video.js index 2bcd22f27..4b13e30e6 100644 --- a/src/routes/MetaDetails/VideosList/Video/Video.js +++ b/src/routes/MetaDetails/VideosList/Video/Video.js @@ -6,7 +6,7 @@ const Icon = require('stremio-icons/dom'); const VideoPlaceholder = require('./VideoPlaceholder'); const styles = require('./styles'); -const Video = ({ className, title, thumbnail, episode, released, upcoming, watched, progress, ...props }) => { +const Video = ({ className, id, title, thumbnail, episode, released, upcoming, watched, progress, ...props }) => { return (