mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-21 03:22:11 +00:00
Merge branch 'development' of github.com:Stremio/stremio-web into nav-bars
This commit is contained in:
commit
b420d236a3
6 changed files with 50 additions and 48 deletions
|
|
@ -12,7 +12,7 @@ const routesRegexp = {
|
||||||
urlParamsNames: ['transportUrl', 'type', 'catalogId']
|
urlParamsNames: ['transportUrl', 'type', 'catalogId']
|
||||||
},
|
},
|
||||||
library: {
|
library: {
|
||||||
regexp: /^\/library(?:\/([^/]*)\/([^/]*))?$/,
|
regexp: /^\/library(?:\/([^/]*))?(?:\/([^/]*))?$/,
|
||||||
urlParamsNames: ['type', 'sort']
|
urlParamsNames: ['type', 'sort']
|
||||||
},
|
},
|
||||||
search: {
|
search: {
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@ const LOGIN_FORM = 'login';
|
||||||
const Intro = ({ queryParams }) => {
|
const Intro = ({ queryParams }) => {
|
||||||
const { core } = useServices();
|
const { core } = useServices();
|
||||||
const routeFocused = useRouteFocused();
|
const routeFocused = useRouteFocused();
|
||||||
const emailRef = React.useRef();
|
const emailRef = React.useRef(null);
|
||||||
const passwordRef = React.useRef();
|
const passwordRef = React.useRef(null);
|
||||||
const confirmPasswordRef = React.useRef();
|
const confirmPasswordRef = React.useRef(null);
|
||||||
const termsRef = React.useRef();
|
const termsRef = React.useRef(null);
|
||||||
const privacyPolicyRef = React.useRef();
|
const privacyPolicyRef = React.useRef(null);
|
||||||
const marketingRef = React.useRef();
|
const marketingRef = React.useRef(null);
|
||||||
const errorRef = React.useRef();
|
const errorRef = React.useRef(null);
|
||||||
const [passwordRestModalOpen, openPasswordRestModal, closePasswordResetModal] = useBinaryState(false);
|
const [passwordRestModalOpen, openPasswordRestModal, closePasswordResetModal] = useBinaryState(false);
|
||||||
const [loaderModalOpen, openLoaderModal, closeLoaderModal] = useBinaryState(false);
|
const [loaderModalOpen, openLoaderModal, closeLoaderModal] = useBinaryState(false);
|
||||||
const [state, dispatch] = React.useReducer(
|
const [state, dispatch] = React.useReducer(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const PropTypes = require('prop-types');
|
const PropTypes = require('prop-types');
|
||||||
const classnames = require('classnames');
|
const classnames = require('classnames');
|
||||||
const { Button, Multiselect, MainNavBar, MetaItem } = require('stremio/common');
|
const { Button, Multiselect, MainNavBar, MetaItem, useProfile } = require('stremio/common');
|
||||||
const useLibrary = require('./useLibrary');
|
const useLibrary = require('./useLibrary');
|
||||||
const useSelectableInputs = require('./useSelectableInputs');
|
const useSelectableInputs = require('./useSelectableInputs');
|
||||||
const useItemOptions = require('./useItemOptions');
|
const useItemOptions = require('./useItemOptions');
|
||||||
|
|
@ -9,6 +9,7 @@ const styles = require('./styles');
|
||||||
|
|
||||||
const Library = ({ urlParams }) => {
|
const Library = ({ urlParams }) => {
|
||||||
const library = useLibrary(urlParams);
|
const library = useLibrary(urlParams);
|
||||||
|
const profile = useProfile();
|
||||||
const [typeSelect, sortPropSelect] = useSelectableInputs(library);
|
const [typeSelect, sortPropSelect] = useSelectableInputs(library);
|
||||||
const [options, optionOnSelect] = useItemOptions();
|
const [options, optionOnSelect] = useItemOptions();
|
||||||
return (
|
return (
|
||||||
|
|
@ -16,7 +17,7 @@ const Library = ({ urlParams }) => {
|
||||||
<MainNavBar className={styles['nav-bar']} route={'library'} />
|
<MainNavBar className={styles['nav-bar']} route={'library'} />
|
||||||
<div className={styles['library-content']}>
|
<div className={styles['library-content']}>
|
||||||
{
|
{
|
||||||
library.library_state.type === 'Ready' && library.library_state.content.uid !== null && library.type_names.length > 0 ?
|
profile.auth !== null && library.type_names.length > 0 ?
|
||||||
<div className={styles['selectable-inputs-container']}>
|
<div className={styles['selectable-inputs-container']}>
|
||||||
<Multiselect {...typeSelect} className={styles['select-input-container']} />
|
<Multiselect {...typeSelect} className={styles['select-input-container']} />
|
||||||
<Multiselect {...sortPropSelect} className={styles['select-input-container']} />
|
<Multiselect {...sortPropSelect} className={styles['select-input-container']} />
|
||||||
|
|
@ -25,7 +26,7 @@ const Library = ({ urlParams }) => {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
library.library_state.type === 'Ready' && library.library_state.content.uid === null ?
|
profile.auth === null ?
|
||||||
<div className={classnames(styles['message-container'], styles['no-user-message-container'])}>
|
<div className={classnames(styles['message-container'], styles['no-user-message-container'])}>
|
||||||
<div className={styles['message-label']}>Library is only availavle for logged in users</div>
|
<div className={styles['message-label']}>Library is only availavle for logged in users</div>
|
||||||
<Button className={styles['login-button-container']} href={'#/intro'}>
|
<Button className={styles['login-button-container']} href={'#/intro'}>
|
||||||
|
|
@ -33,37 +34,32 @@ const Library = ({ urlParams }) => {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
library.library_state.type !== 'Ready' ?
|
library.type_names.length === 0 ?
|
||||||
<div className={styles['message-container']}>
|
<div className={styles['message-container']}>
|
||||||
<div className={styles['message-label']}>Loading</div>
|
<div className={styles['message-label']}>Empty library</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
library.type_names.length === 0 ?
|
library.selected === null ?
|
||||||
<div className={styles['message-container']}>
|
<div className={styles['message-container']}>
|
||||||
<div className={styles['message-label']}>Empty library</div>
|
<div className={styles['message-label']}>Please select a type</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
library.selected === null ?
|
library.lib_items.length === 0 ?
|
||||||
<div className={styles['message-container']}>
|
<div className={styles['message-container']}>
|
||||||
<div className={styles['message-label']}>Please select a type</div>
|
<div className={styles['message-label']}>There are no items for the selected type</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
library.lib_items.length === 0 ?
|
<div className={styles['meta-items-container']}>
|
||||||
<div className={styles['message-container']}>
|
{library.lib_items.map(({ id, videoId, ...libItem }, index) => (
|
||||||
<div className={styles['message-label']}>There are no items for the selected type</div>
|
<MetaItem
|
||||||
</div>
|
{...libItem}
|
||||||
:
|
key={index}
|
||||||
<div className={styles['meta-items-container']}>
|
dataset={{ id, videoId, type: libItem.type }}
|
||||||
{library.lib_items.map(({ id, videoId, ...libItem }, index) => (
|
options={options}
|
||||||
<MetaItem
|
optionOnSelect={optionOnSelect}
|
||||||
{...libItem}
|
/>
|
||||||
key={index}
|
))}
|
||||||
dataset={{ id, videoId, type: libItem.type }}
|
</div>
|
||||||
options={options}
|
|
||||||
optionOnSelect={optionOnSelect}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,12 @@ const { useServices } = require('stremio/services');
|
||||||
const { useModelState } = require('stremio/common');
|
const { useModelState } = require('stremio/common');
|
||||||
|
|
||||||
const initLibraryState = () => ({
|
const initLibraryState = () => ({
|
||||||
library_state: {
|
|
||||||
type: 'NotLoaded'
|
|
||||||
},
|
|
||||||
selected: null,
|
selected: null,
|
||||||
type_names: [],
|
type_names: [],
|
||||||
lib_items: []
|
lib_items: []
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapLibraryState = (library) => {
|
const mapLibraryState = (library) => {
|
||||||
const library_state = library.library_state;
|
|
||||||
const selected = library.selected;
|
const selected = library.selected;
|
||||||
const type_names = library.type_names;
|
const type_names = library.type_names;
|
||||||
const lib_items = library.lib_items.map((lib_item) => ({
|
const lib_items = library.lib_items.map((lib_item) => ({
|
||||||
|
|
@ -28,7 +24,7 @@ const mapLibraryState = (library) => {
|
||||||
videoId: lib_item.state.video_id,
|
videoId: lib_item.state.video_id,
|
||||||
href: `#/metadetails/${encodeURIComponent(lib_item.type)}/${encodeURIComponent(lib_item._id)}${lib_item.state.video_id !== null ? `/${encodeURIComponent(lib_item.state.video_id)}` : ''}`
|
href: `#/metadetails/${encodeURIComponent(lib_item.type)}/${encodeURIComponent(lib_item._id)}${lib_item.state.video_id !== null ? `/${encodeURIComponent(lib_item.state.video_id)}` : ''}`
|
||||||
}));
|
}));
|
||||||
return { library_state, selected, type_names, lib_items };
|
return { selected, type_names, lib_items };
|
||||||
};
|
};
|
||||||
|
|
||||||
const onNewLibraryState = (library) => {
|
const onNewLibraryState = (library) => {
|
||||||
|
|
@ -36,10 +32,9 @@ const onNewLibraryState = (library) => {
|
||||||
return {
|
return {
|
||||||
action: 'Load',
|
action: 'Load',
|
||||||
args: {
|
args: {
|
||||||
load: 'LibraryFiltered',
|
model: 'LibraryWithFilters',
|
||||||
args: {
|
args: {
|
||||||
type_name: library.type_names[0],
|
type_name: library.type_names[0]
|
||||||
sort_prop: null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -53,23 +48,32 @@ const useLibrary = (urlParams) => {
|
||||||
return {
|
return {
|
||||||
action: 'Load',
|
action: 'Load',
|
||||||
args: {
|
args: {
|
||||||
load: 'LibraryFiltered',
|
model: 'LibraryWithFilters',
|
||||||
args: {
|
args: {
|
||||||
type_name: urlParams.type,
|
type_name: urlParams.type,
|
||||||
sort_prop: urlParams.sort
|
sort_prop: urlParams.sort
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
} else if (typeof urlParams.type === 'string') {
|
||||||
|
return {
|
||||||
|
action: 'Load',
|
||||||
|
args: {
|
||||||
|
model: 'LibraryWithFilters',
|
||||||
|
args: {
|
||||||
|
type_name: urlParams.type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
const library = core.getState('library');
|
const library = core.getState('library');
|
||||||
if (library.type_names.length > 0) {
|
if (library.type_names.length > 0) {
|
||||||
return {
|
return {
|
||||||
action: 'Load',
|
action: 'Load',
|
||||||
args: {
|
args: {
|
||||||
load: 'LibraryFiltered',
|
model: 'LibraryWithFilters',
|
||||||
args: {
|
args: {
|
||||||
type_name: library.type_names[0],
|
type_name: library.type_names[0]
|
||||||
sort_prop: null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
|
|
||||||
const SORT_PROP_OPTIONS = [
|
const SORT_PROP_OPTIONS = [
|
||||||
{ label: 'Recent', value: '_ctime' },
|
{ label: 'Recent', value: 'ctime' },
|
||||||
{ label: 'A-Z', value: 'name' },
|
{ label: 'A-Z', value: 'name' },
|
||||||
{ label: 'Year', value: 'year' },
|
{ label: 'Year', value: 'year' },
|
||||||
];
|
];
|
||||||
|
|
@ -16,7 +16,7 @@ const mapSelectableInputs = (library) => {
|
||||||
options: library.type_names
|
options: library.type_names
|
||||||
.map((type) => ({ label: type, value: type })),
|
.map((type) => ({ label: type, value: type })),
|
||||||
onSelect: (event) => {
|
onSelect: (event) => {
|
||||||
window.location.replace(`#/library/${encodeURIComponent(event.value)}/${encodeURIComponent(library.selected.sort_prop)}`);
|
window.location.replace(`#/library/${encodeURIComponent(event.value)}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const sortPropSelect = {
|
const sortPropSelect = {
|
||||||
|
|
@ -29,6 +29,8 @@ const mapSelectableInputs = (library) => {
|
||||||
onSelect: (event) => {
|
onSelect: (event) => {
|
||||||
if (library.selected !== null) {
|
if (library.selected !== null) {
|
||||||
window.location.replace(`#/library/${encodeURIComponent(library.selected.type_name)}/${encodeURIComponent(event.value)}`);
|
window.location.replace(`#/library/${encodeURIComponent(library.selected.type_name)}/${encodeURIComponent(event.value)}`);
|
||||||
|
} else if (library.type_names.length > 0) {
|
||||||
|
window.location.replace(`#/library/${encodeURIComponent(library.type_names[0])}/${encodeURIComponent(event.value)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ function Core() {
|
||||||
events.off(name, listener);
|
events.off(name, listener);
|
||||||
}
|
}
|
||||||
function dispatch(action, model) {
|
function dispatch(action, model) {
|
||||||
if (!active) {
|
if (!active || typeof action === 'undefined') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue