Library refactored to use new model schema

This commit is contained in:
nklhrstv 2020-10-19 22:14:44 +03:00
parent 2cf0bfa4b1
commit 3252b8e829
3 changed files with 60 additions and 85 deletions

View file

@ -9,18 +9,15 @@ const useLibrary = require('./useLibrary');
const useSelectableInputs = require('./useSelectableInputs');
const styles = require('./styles');
const Library = ({ model, route, urlParams, queryParams }) => {
const Library = ({ model, urlParams, queryParams }) => {
const profile = useProfile();
const library = useLibrary(model, urlParams, queryParams);
const [typeSelect, sortSelect] = useSelectableInputs(route, library);
const available = React.useMemo(() => {
return route === 'continuewatching' || profile.auth !== null;
}, []);
const [typeSelect, sortSelect] = useSelectableInputs(library);
return (
<MainNavBars className={styles['library-container']} route={route}>
<MainNavBars className={styles['library-container']} route={model}>
<div className={styles['library-content']}>
{
available && library.type_names.length > 0 ?
model === 'continue_watching' || profile.auth !== null ?
<div className={styles['selectable-inputs-container']}>
<Multiselect {...typeSelect} className={styles['select-input-container']} />
<Multiselect {...sortSelect} className={styles['select-input-container']} />
@ -29,7 +26,7 @@ const Library = ({ model, route, urlParams, queryParams }) => {
null
}
{
!available ?
model === 'library' && profile.auth === null ?
<div className={classnames(styles['message-container'], styles['no-user-message-container'])}>
<Image
className={styles['image']}
@ -42,41 +39,31 @@ const Library = ({ model, route, urlParams, queryParams }) => {
<div className={styles['message-label']}>Library is only available for logged in users!</div>
</div>
:
library.type_names.length === 0 ?
library.selected === null ?
<div className={styles['message-container']}>
<Image
className={styles['image']}
src={'/images/empty.png'}
alt={' '}
/>
<div className={styles['message-label']}>Empty {route === 'continuewatching' ? 'Continue Watching' : 'Library'}</div>
<div className={styles['message-label']}>{model === 'library' ? 'Library' : 'Continue Watching'} not loaded!</div>
</div>
:
library.selected === null ?
library.catalog.length === 0 ?
<div className={styles['message-container']}>
<Image
className={styles['image']}
src={'/images/empty.png'}
alt={' '}
/>
<div className={styles['message-label']}>{route === 'continuewatching' ? 'Continue Watching' : 'Library'} not loaded!</div>
<div className={styles['message-label']}>Empty {model === 'library' ? 'Library' : 'Continue Watching'}</div>
</div>
:
library.library_items.length === 0 ?
<div className={styles['message-container']}>
<Image
className={styles['image']}
src={'/images/empty.png'}
alt={' '}
/>
<div className={styles['message-label']}>There are no items for the selected type!</div>
</div>
:
<div className={styles['meta-items-container']}>
{library.library_items.map((libItem, index) => (
<LibItem {...libItem} key={index} />
))}
</div>
<div className={styles['meta-items-container']}>
{library.catalog.map((libItem, index) => (
<LibItem {...libItem} key={index} />
))}
</div>
}
</div>
</MainNavBars>
@ -85,7 +72,6 @@ const Library = ({ model, route, urlParams, queryParams }) => {
Library.propTypes = {
model: PropTypes.oneOf(['library', 'continue_watching']),
route: PropTypes.oneOf(['library', 'continuewatching']),
urlParams: PropTypes.shape({
type: PropTypes.string
}),
@ -93,24 +79,23 @@ Library.propTypes = {
};
module.exports = ({ urlParams, queryParams }) => {
const [model, route] = React.useMemo(() => {
const model = React.useMemo(() => {
return typeof urlParams.path === 'string' ?
urlParams.path.match(routesRegexp.library.regexp) ?
['library', 'library']
'library'
:
urlParams.path.match(routesRegexp.continuewatching.regexp) ?
['continue_watching', 'continuewatching']
'continue_watching'
:
[null, null]
null
:
[null, null];
null;
}, [urlParams.path]);
if (typeof model === 'string') {
return (
<Library
key={model}
model={model}
route={route}
urlParams={urlParams}
queryParams={queryParams}
/>

View file

@ -1,18 +1,20 @@
// Copyright (C) 2017-2020 Smart code 203358507
const React = require('react');
const { CONSTANTS, deepLinking, useModelState, comparatorWithPriorities } = require('stremio/common');
const { useModelState } = require('stremio/common');
const initLibraryState = () => ({
const init = () => ({
selected: null,
type_names: [],
library_items: []
selectable: {
types: [],
sorts: []
},
catalog: []
});
const mapLibraryState = (library) => {
const selected = library.selected;
const type_names = library.type_names.sort(comparatorWithPriorities(CONSTANTS.TYPE_PRIORITIES));
const library_items = library.library_items.map((libItem) => ({
const map = (library) => ({
...library,
catalog: library.catalog.map((libItem) => ({
id: libItem._id,
type: libItem.type,
name: libItem.name,
@ -22,28 +24,24 @@ const mapLibraryState = (library) => {
libItem.state.timeOffset / libItem.state.duration
:
null,
deepLinks: deepLinking.withLibItem({ libItem })
}));
return { selected, type_names, library_items };
};
deepLinks: libItem.deepLinks
}))
});
const useLibrary = (libraryModel, urlParams, queryParams) => {
const loadLibraryAction = React.useMemo(() => ({
const useLibrary = (model, urlParams, queryParams) => {
const action = React.useMemo(() => ({
action: 'Load',
args: {
model: 'LibraryWithFilters',
args: {
type_name: typeof urlParams.type === 'string' ? urlParams.type : null,
sort: queryParams.has('sort') ? queryParams.get('sort') : 'lastwatched'
request: {
type: typeof urlParams.type === 'string' ? urlParams.type : null,
sort: queryParams.has('sort') ? queryParams.get('sort') : undefined
}
}
}
}), [urlParams, queryParams]);
return useModelState({
model: libraryModel,
action: loadLibraryAction,
map: mapLibraryState,
init: initLibraryState
});
return useModelState({ model, action, map, init });
};
module.exports = useLibrary;

View file

@ -2,49 +2,41 @@
const React = require('react');
const SORT_OPTIONS = [
{ label: 'Recent', value: 'lastwatched' },
{ label: 'A-Z', value: 'name' },
{ label: 'Watched', value: 'timeswatched' },
];
const mapSelectableInputs = (route, library) => {
const mapSelectableInputs = (library) => {
const typeSelect = {
title: 'Select type',
selected: library.selected !== null ?
[JSON.stringify(library.selected.type_name)]
:
[],
options: [{ label: 'All', value: JSON.stringify(null) }]
.concat(library.type_names.map((type) => ({ label: type, value: JSON.stringify(type) }))),
renderLabelText: () => {
return library.selected.type_name === null ? 'All' : library.selected.type_name;
},
options: library.selectable.types
.map(({ type, deep_links }) => ({
value: deep_links.library,
label: type === null ? 'All' : type
})),
selected: library.selectable.types
.filter(({ selected }) => selected)
.map(({ deep_links }) => deep_links.library),
onSelect: (event) => {
const type = JSON.parse(event.value);
const queryParams = new URLSearchParams(library.selected !== null ? [['sort', library.selected.sort]] : []);
window.location = `#/${route}${type !== null ? `/${encodeURIComponent(type)}` : ''}?${queryParams.toString()}`;
window.location = event.value;
}
};
const sortSelect = {
title: 'Select sort',
selected: library.selected !== null ?
[library.selected.sort]
:
[],
options: SORT_OPTIONS,
options: library.selectable.sorts
.map(({ sort, deep_links }) => ({
value: deep_links.library,
label: sort
})),
selected: library.selectable.sorts
.filter(({ selected }) => selected)
.map(({ deep_links }) => deep_links.library),
onSelect: (event) => {
const type = library.selected !== null ? library.selected.type_name : null;
const queryParams = new URLSearchParams([['sort', event.value]]);
window.location = `#/${route}${type !== null ? `/${encodeURIComponent(type)}` : ''}?${queryParams.toString()}`;
window.location = event.value;
}
};
return [typeSelect, sortSelect];
};
const useSelectableInputs = (route, library) => {
const useSelectableInputs = (library) => {
const selectableInputs = React.useMemo(() => {
return mapSelectableInputs(route, library);
return mapSelectableInputs(library);
}, [library]);
return selectableInputs;
};