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;