From 6703b9771baf43b9f55a0ab6618d5f8a91898adb Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 16 Feb 2022 23:09:38 +0100 Subject: [PATCH] refactor: move filters code to a new component and use it on routes --- src/common/Filters/Filters.js | 32 +++++++++++++++ src/common/Filters/index.js | 2 + src/common/Filters/styles.less | 45 +++++++++++++++++++++ src/common/index.js | 2 + src/routes/Addons/Addons.js | 16 ++------ src/routes/Addons/styles.less | 55 +++++-------------------- src/routes/Discover/Discover.js | 16 ++------ src/routes/Discover/styles.less | 54 ++++--------------------- src/routes/Library/Library.js | 13 +++++- src/routes/Library/styles.less | 72 ++++++++++++++++++++++++++++----- 10 files changed, 180 insertions(+), 127 deletions(-) create mode 100644 src/common/Filters/Filters.js create mode 100644 src/common/Filters/index.js create mode 100644 src/common/Filters/styles.less diff --git a/src/common/Filters/Filters.js b/src/common/Filters/Filters.js new file mode 100644 index 000000000..11a49a300 --- /dev/null +++ b/src/common/Filters/Filters.js @@ -0,0 +1,32 @@ +const React = require('react'); +const PropTypes = require('prop-types'); +const classnames = require('classnames'); +const Button = require('stremio/common/Button'); +const styles = require('./styles'); +const Icon = require('@stremio/stremio-icons/dom'); + +const Filters = ({ className, children }) => { + const [filtersMenuOpen, setFiltersMenuOpen] = React.useState(false); + return ( +
+ + { + filtersMenuOpen ? +
+ { children } +
+ : + null + } +
+ ); +}; + +Filters.propTypes = { + className: PropTypes.string, + children: PropTypes.node +}; + +module.exports = Filters; diff --git a/src/common/Filters/index.js b/src/common/Filters/index.js new file mode 100644 index 000000000..fa8335b4d --- /dev/null +++ b/src/common/Filters/index.js @@ -0,0 +1,2 @@ +const Filters = require('./Filters'); +module.exports = Filters; diff --git a/src/common/Filters/styles.less b/src/common/Filters/styles.less new file mode 100644 index 000000000..c7efba64b --- /dev/null +++ b/src/common/Filters/styles.less @@ -0,0 +1,45 @@ +@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less'; + +.filters-container { + flex: 0 0 auto; + + .filters-button-container { + display: flex; + flex: none; + flex-direction: row; + align-items: center; + justify-content: center; + height: 3.5rem; + padding: 0 1rem; + background-color: @color-background; + + .icon { + flex: none; + width: 1.2rem; + height: 1.2rem; + fill: @color-secondaryvariant1-90; + } + } + + .filters-menu-container { + z-index: 99; + flex: auto; + display: flex; + position: absolute; + top: 5em; + left: 0; + right: 0; + flex-direction: column; + gap: 1em; + padding: 1.5em; + background-color: @color-background-dark2; + box-shadow: 0 1.35rem 2.7rem @color-background-dark5-40, + 0 1.1rem 0.85rem @color-background-dark5-20; + overflow: visible; + + .select-input-container { + flex-basis: 3.5em; + margin-right: 0; + } + } +} \ No newline at end of file diff --git a/src/common/index.js b/src/common/index.js index 19fa9bafd..38a361fff 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -4,6 +4,7 @@ const AddonDetailsModal = require('./AddonDetailsModal'); const Button = require('./Button'); const Checkbox = require('./Checkbox'); const ColorInput = require('./ColorInput'); +const Filters = require('./Filters'); const Image = require('./Image'); const LibItem = require('./LibItem'); const MainNavBars = require('./MainNavBars'); @@ -43,6 +44,7 @@ module.exports = { Button, Checkbox, ColorInput, + Filters, Image, LibItem, MainNavBars, diff --git a/src/routes/Addons/Addons.js b/src/routes/Addons/Addons.js index d2abaeabf..01e7ff319 100644 --- a/src/routes/Addons/Addons.js +++ b/src/routes/Addons/Addons.js @@ -10,6 +10,7 @@ const useRemoteAddons = require('./useRemoteAddons'); const useAddonDetailsTransportUrl = require('./useAddonDetailsTransportUrl'); const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); +const { Filters } = require('stremio/common'); const Addons = ({ urlParams, queryParams }) => { const installedAddons = useInstalledAddons(urlParams); @@ -40,7 +41,6 @@ const Addons = ({ urlParams, queryParams }) => { } ]; }, [addAddonOnSubmit]); - const [filtersMenuOpen, setFiltersMenuOpen] = React.useState(false); const [search, setSearch] = React.useState(''); const searchInputOnChange = React.useCallback((event) => { setSearch(event.currentTarget.value); @@ -100,17 +100,9 @@ const Addons = ({ urlParams, queryParams }) => { value={search} onChange={searchInputOnChange} /> - - { - filtersMenuOpen ? -
- { renderMultiselectsInputs() } -
- : - null - } + + { renderMultiselectsInputs() } + { installedAddons.selected !== null ? diff --git a/src/routes/Addons/styles.less b/src/routes/Addons/styles.less index c3992c4b8..dfb608498 100644 --- a/src/routes/Addons/styles.less +++ b/src/routes/Addons/styles.less @@ -71,45 +71,6 @@ } } - .filter-button-container { - display: none; - flex: none; - flex-direction: row; - align-items: center; - justify-content: center; - height: 3.5rem; - padding: 0 1rem; - background-color: @color-background; - - .icon { - flex: none; - width: 1.2rem; - height: 1.2rem; - fill: @color-secondaryvariant1-90; - } - } - - .filters-menu-container { - flex: auto; - display: flex; - position: absolute; - top: 5em; - left: 0; - right: 0; - flex-direction: column; - gap: 1em; - padding: 1.5em; - background-color: @color-background-dark2; - box-shadow: 0 1.35rem 2.7rem @color-background-dark5-40, - 0 1.1rem 0.85rem @color-background-dark5-20; - overflow: visible; - - .select-input-container { - flex-basis: 3.5em; - margin-right: 0; - } - } - .multiselect-inputs-container { flex: auto; display: flex; @@ -139,6 +100,10 @@ flex-shrink: 1; flex-basis: 18rem; } + + .filters { + display: none; + } } .message-container { @@ -270,8 +235,6 @@ .addons-container { .addons-content { .selectable-inputs-container { - position: relative; - flex-direction: row; gap: 1em; .add-button-container { @@ -281,9 +244,9 @@ box-shadow: 0 1.35rem 2.7rem @color-background-dark5-40, 0 1.1rem 0.85rem @color-background-dark5-20; } - - .filter-button-container { - display: flex; + + .select-input-container { + flex: 0 1 3.5em; } .multiselect-inputs-container { @@ -297,6 +260,10 @@ .search-bar { flex-basis: 100%; } + + .filters { + display: block; + } } } } diff --git a/src/routes/Discover/Discover.js b/src/routes/Discover/Discover.js index 8507cdc23..100bb40c6 100644 --- a/src/routes/Discover/Discover.js +++ b/src/routes/Discover/Discover.js @@ -9,12 +9,12 @@ const { AddonDetailsModal, Button, MainNavBars, MetaItem, Image, MetaPreview, Mu const useDiscover = require('./useDiscover'); const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); +const { Filters } = require('stremio/common'); const Discover = ({ urlParams, queryParams }) => { const { core } = useServices(); const discover = useDiscover(urlParams, queryParams); const [selectInputs, paginationInput] = useSelectableInputs(discover); - const [filtersMenuOpen, setFiltersMenuOpen] = React.useState(false); const [inputsModalOpen, openInputsModal, closeInputsModal] = useBinaryState(false); const [addonModalOpen, openAddonModal, closeAddonModal] = useBinaryState(false); const [selectedMetaItemIndex, setSelectedMetaItemIndex] = React.useState(0); @@ -107,17 +107,9 @@ const Discover = ({ urlParams, queryParams }) => { : } - - { - filtersMenuOpen ? -
- { renderMultiselectsInputs() } -
- : - null - } + + { renderMultiselectsInputs() } + : null diff --git a/src/routes/Discover/styles.less b/src/routes/Discover/styles.less index 928436a7d..cbce005c8 100644 --- a/src/routes/Discover/styles.less +++ b/src/routes/Discover/styles.less @@ -43,46 +43,6 @@ padding: 1.5rem; overflow: visible; - .filter-button-container { - display: none; - flex: none; - flex-direction: row; - align-items: center; - justify-content: center; - height: 3.5rem; - padding: 0 1rem; - background-color: @color-background; - - .icon { - flex: none; - width: 1.2rem; - height: 1.2rem; - fill: @color-secondaryvariant1-90; - } - } - - .filters-menu-container { - z-index: 99; - flex: auto; - display: flex; - position: absolute; - top: 5em; - left: 0; - right: 0; - flex-direction: column; - gap: 1em; - padding: 1.5em; - background-color: @color-background-dark2; - box-shadow: 0 1.35rem 2.7rem @color-background-dark5-40, - 0 1.1rem 0.85rem @color-background-dark5-20; - overflow: visible; - - .select-input-container { - flex-basis: 3.5em; - margin-right: 0; - } - } - .multiselect-inputs-container { flex: auto; display: flex; @@ -167,6 +127,10 @@ width: 3rem; } } + + .filters { + display: none; + } } .missing-addon-warning-container { @@ -491,8 +455,6 @@ .discover-content { .catalog-container { .selectable-inputs-container { - position: relative; - flex-direction: row; justify-content: space-between; gap: 1em; @@ -504,10 +466,6 @@ } } - .filter-button-container { - display: flex; - } - .multiselect-inputs-container { display: none; } @@ -519,6 +477,10 @@ .pagination-input { margin-left: 0; } + + .filters { + display: block; + } } .meta-items-container { diff --git a/src/routes/Library/Library.js b/src/routes/Library/Library.js index a088e245c..f154d75e9 100644 --- a/src/routes/Library/Library.js +++ b/src/routes/Library/Library.js @@ -8,6 +8,7 @@ const { Button, Multiselect, MainNavBars, LibItem, Image, PaginationInput, usePr const useLibrary = require('./useLibrary'); const useSelectableInputs = require('./useSelectableInputs'); const styles = require('./styles'); +const { Filters } = require('stremio/common'); function withModel(Library) { const withModel = ({ urlParams, queryParams }) => { @@ -46,14 +47,19 @@ const Library = ({ model, urlParams, queryParams }) => { const profile = useProfile(); const library = useLibrary(model, urlParams, queryParams); const [typeSelect, sortSelect, paginationInput] = useSelectableInputs(library); + const multiselectInputs = <> + + + ; return (
{ model === 'continue_watching' || profile.auth !== null ?
- - +
+ { multiselectInputs } +
{ paginationInput !== null ? @@ -61,6 +67,9 @@ const Library = ({ model, urlParams, queryParams }) => { : } + + { multiselectInputs } +
: null diff --git a/src/routes/Library/styles.less b/src/routes/Library/styles.less index 2b09a2149..ded44c5a5 100644 --- a/src/routes/Library/styles.less +++ b/src/routes/Library/styles.less @@ -33,19 +33,26 @@ padding: 1.5rem; overflow: visible; - .select-input-container { - flex-grow: 0; - flex-shrink: 1; - flex-basis: 15rem; - height: 3.5rem; + .multiselect-inputs-container { + flex: auto; + display: flex; + flex-direction: row; + overflow: visible; - &:not(:last-child) { - margin-right: 1.5rem; - } + .select-input-container { + flex-grow: 0; + flex-shrink: 1; + flex-basis: 15rem; + height: 3.5rem; - .multiselect-menu-container { - max-height: calc(3.2rem * 7); - overflow: auto; + &:not(:last-child) { + margin-right: 1.5rem; + } + + .multiselect-menu-container { + max-height: calc(3.2rem * 7); + overflow: auto; + } } } @@ -86,6 +93,10 @@ width: 3rem; } } + + .filters { + display: none; + } } .message-container { @@ -230,4 +241,43 @@ } } } +} + +@media only screen and (max-width: @minimum) { + .library-container { + .library-content { + .selectable-inputs-container { + justify-content: space-between; + gap: 1em; + + .select-input-container { + flex-basis: 3.5em; + + &:not(:last-child) { + margin-right: 0; + } + } + + .multiselect-inputs-container { + display: none; + } + + .spacing { + display: none; + } + + .pagination-input { + margin-left: 0; + } + + .filters { + display: block; + } + } + + .meta-items-container { + grid-template-columns: repeat(3, 1fr); + } + } + } } \ No newline at end of file