From 0f5e6e67984f9025dd55cc7e3495745cafcc3b6c Mon Sep 17 00:00:00 2001 From: svetlagasheva Date: Thu, 14 Nov 2019 18:16:10 +0200 Subject: [PATCH] useSort hook implemented --- src/routes/Library/Library.js | 15 +++++---- src/routes/Library/styles.less | 4 +-- src/routes/Library/useLibrary.js | 58 ++++++++++---------------------- src/routes/Library/useSort.js | 35 +++++++++++++++++++ 4 files changed, 63 insertions(+), 49 deletions(-) create mode 100644 src/routes/Library/useSort.js diff --git a/src/routes/Library/Library.js b/src/routes/Library/Library.js index 95ed7eb93..8ece37d85 100644 --- a/src/routes/Library/Library.js +++ b/src/routes/Library/Library.js @@ -1,27 +1,30 @@ const React = require('react'); const { Multiselect, MainNavBar, MetaItem } = require('stremio/common'); const useLibrary = require('./useLibrary'); +const useSort = require('./useSort'); const styles = require('./styles'); const Library = ({ urlParams, queryParams }) => { - const [metaItems, dropdowns] = useLibrary(urlParams, queryParams); + const [metaItems, selectTypeInput] = useLibrary(urlParams); + const [selectSortInput, sortFunction] = useSort(urlParams, queryParams); return (
-
- {dropdowns.map((dropdown, index) => ( - - ))} +
+ +
{metaItems + .sort(sortFunction) .map((metaItem, index) => ( - ))} + )) + }
diff --git a/src/routes/Library/styles.less b/src/routes/Library/styles.less index 44eaa213e..8f4417f89 100644 --- a/src/routes/Library/styles.less +++ b/src/routes/Library/styles.less @@ -22,14 +22,14 @@ "dropdowns-area switch-view-area" "meta-items-area meta-items-area"; - .dropdowns-container { + .controls-container { grid-area: dropdowns-area; display: flex; flex-direction: row; margin: 2rem; overflow: visible; - .dropdown { + .select-input-container { flex-grow: 0; flex-shrink: 1; flex-basis: 15rem; diff --git a/src/routes/Library/useLibrary.js b/src/routes/Library/useLibrary.js index 73291f847..f102d8f84 100644 --- a/src/routes/Library/useLibrary.js +++ b/src/routes/Library/useLibrary.js @@ -1,55 +1,31 @@ const React = require('react'); +const UrlUtils = require('url'); const { useServices } = require('stremio/services'); const DEFAULT_TYPE = 'movie'; -const DEFAULT_SORT = 'recent'; -const useLibrary = (urlParams, queryParams) => { +const useLibrary = (urlParams) => { const { core } = useServices(); const [library, setLibrary] = React.useState([[], []]); - React.useEffect(() => { const type = typeof urlParams.type === 'string' && urlParams.type.length > 0 ? urlParams.type : DEFAULT_TYPE; - const sort = typeof queryParams.get('sort') === 'string' && queryParams.get('sort').length > 0 ? queryParams.get('sort') : DEFAULT_SORT; const onNewState = () => { const state = core.getState(); - const sortItems = (items, prop) => { - return items - .filter(item => !item.removed) - .sort((a, b) => { - if (a[prop] < b[prop]) return -1; - if (a[prop] > b[prop]) return 1; - return 0; - }); - } - const selectInputs = [ - { - selected: [type], - options: state.library.types - .map((type) => ({ - label: type, - value: type - })), - onSelect: (event) => { - const value = event.value; - const nextQuery = new URLSearchParams({ sort: typeof sort === 'string' ? sort : '' }); - const nextType = typeof value === 'string' ? value : ''; - window.location.replace(`#/library/${nextType}?${nextQuery}`); - } - }, - { - selected: [sort], - options: [{ label: 'A-Z', value: 'a-z' }, { label: 'Recent', value: 'recent' }], - onSelect: (event) => { - const value = event.value; - const nextQuery = new URLSearchParams({ sort: typeof value === 'string' ? value : '' }); - const nextType = typeof type === 'string' ? type : ''; - window.location.replace(`#/library/${nextType}?${nextQuery}`); - } + const selectInput = { + selected: [type], + options: state.library.types + .map((type) => ({ + label: type, + value: type + })), + onSelect: (event) => { + const { search } = UrlUtils.parse(window.location.hash.slice(1)); + const queryParams = new URLSearchParams(search || { sort: 'recent' }); + window.location.replace(`#/library/${event.value}?${queryParams}`); } - ]; - const items = sort === 'recent' ? sortItems(state.library.items, '_ctime') : sortItems(state.library.items, 'name'); - setLibrary([items, selectInputs]); + }; + const items = state.library.items.filter(item => !item.removed); + setLibrary([items, selectInput]); } core.on('NewModel', onNewState); core.dispatch({ @@ -62,7 +38,7 @@ const useLibrary = (urlParams, queryParams) => { return () => { core.off('NewModel', onNewState); }; - }, [urlParams, queryParams]); + }, [urlParams]); return library; } diff --git a/src/routes/Library/useSort.js b/src/routes/Library/useSort.js new file mode 100644 index 000000000..078e68e65 --- /dev/null +++ b/src/routes/Library/useSort.js @@ -0,0 +1,35 @@ +const React = require('react'); + +const DEFAULT_TYPE = 'movie'; +const DEFAULT_SORT = 'recent'; +const SORTS = [DEFAULT_SORT, 'year', 'a-z']; +const SORT_PROPS = { + 'recent': '_ctime', + 'a-z': 'name', + 'year': 'year' +}; + +const useSort = (urlParams, queryParams) => { + const [sort, setSort] = React.useState([null, () => { }]); + React.useEffect(() => { + const sort = queryParams.has('sort') && SORTS.includes(queryParams.get('sort')) ? queryParams.get('sort') : DEFAULT_SORT; + const sortProp = SORT_PROPS[sort]; + const sortItems = (a, b) => { + if (a[sortProp] < b[sortProp]) return -1; + if (a[sortProp] > b[sortProp]) return 1; + return 0; + }; + selectInput = { + selected: [sort], + options: [{ label: 'A-Z', value: 'a-z' }, { label: 'Recent', value: 'recent' }, { label: 'Year', value: 'year' }], + onSelect: (event) => { + const nextQuery = new URLSearchParams({ sort: typeof event.value === 'string' ? event.value : '' }); + window.location.replace(`#/library/${urlParams.type || DEFAULT_TYPE}?${nextQuery}`); + } + }; + setSort([selectInput, sortItems]); + }, [urlParams, queryParams]); + return sort; +}; + +module.exports = useSort;