useSort hook implemented

This commit is contained in:
svetlagasheva 2019-11-14 18:16:10 +02:00
parent 2a12457be3
commit 0f5e6e6798
4 changed files with 63 additions and 49 deletions

View file

@ -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 (
<div className={styles['library-container']}>
<MainNavBar className={styles['nav-bar']} />
<div className={styles['library-content']}>
<div className={styles['dropdowns-container']}>
{dropdowns.map((dropdown, index) => (
<Multiselect {...dropdown} key={index} className={styles['dropdown']} />
))}
<div className={styles['controls-container']}>
<Multiselect {...selectTypeInput} className={styles['select-input-container']} />
<Multiselect {...selectSortInput} className={styles['select-input-container']} />
</div>
<div className={styles['meta-items-container']}>
{metaItems
.sort(sortFunction)
.map((metaItem, index) => (
<MetaItem
{...metaItem}
key={index}
/>
))}
))
}
</div>
</div>
</div>

View file

@ -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;

View file

@ -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;
}

View file

@ -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;