mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
useSort hook implemented
This commit is contained in:
parent
2a12457be3
commit
0f5e6e6798
4 changed files with 63 additions and 49 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
35
src/routes/Library/useSort.js
Normal file
35
src/routes/Library/useSort.js
Normal 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;
|
||||
Loading…
Reference in a new issue