Search adapted to changes in core

This commit is contained in:
NikolaBorislavovHristov 2019-12-04 16:35:21 +02:00
parent f2607b2454
commit b6c1f142cc
5 changed files with 79 additions and 94 deletions

View file

@ -7,9 +7,8 @@ const MetaItem = require('stremio/common/MetaItem');
const MetaRowPlaceholder = require('./MetaRowPlaceholder');
const styles = require('./styles');
const MetaRow = ({ className, title, message, items, maximumItemsCount, itemMenuOptions, catalogHref }) => {
maximumItemsCount = maximumItemsCount !== null && isFinite(maximumItemsCount) ? maximumItemsCount : 20;
items = Array.isArray(items) ? items.slice(0, maximumItemsCount) : [];
const MetaRow = ({ className, title, message, items, limit, href }) => {
items = Array.isArray(items) ? items.slice(0, limit) : [];
return (
<div className={classnames(className, styles['meta-row-container'])}>
{
@ -28,17 +27,14 @@ const MetaRow = ({ className, title, message, items, maximumItemsCount, itemMenu
<MetaItem
{...item}
key={index}
data-id={item.id}
data-type={item.type}
className={classnames(styles['meta-item'], styles['poster-shape-poster'], styles[`poster-shape-${item.posterShape}`])}
menuOptions={itemMenuOptions}
/>
))}
{Array(Math.max(maximumItemsCount - items.length, 0)).fill(null).map((_, index) => (
{Array(limit - items.length).fill(null).map((_, index) => (
<div key={index} className={classnames(styles['meta-item'], styles['poster-shape-poster'])} />
))}
</div>
<Button className={styles['see-all-container']} title={'SEE ALL'} href={catalogHref}>
<Button className={styles['see-all-container']} title={'SEE ALL'} href={href}>
<div className={styles['label']}>SEE ALL</div>
<Icon className={styles['icon']} icon={'ic_arrow_thin_right'} />
</Button>
@ -57,9 +53,8 @@ MetaRow.propTypes = {
items: PropTypes.arrayOf(PropTypes.shape({
posterShape: PropTypes.string
})),
maximumItemsCount: PropTypes.number,
itemMenuOptions: PropTypes.any,
catalogHref: PropTypes.string
limit: PropTypes.number.isRequired,
href: PropTypes.string
};
module.exports = MetaRow;

View file

@ -3,13 +3,12 @@ const PropTypes = require('prop-types');
const classnames = require('classnames');
const styles = require('./styles');
const MetaRowPlaceholder = ({ className, title, maximumItemsCount }) => {
maximumItemsCount = maximumItemsCount !== null && isFinite(maximumItemsCount) ? maximumItemsCount : 20;
const MetaRowPlaceholder = ({ className, title, limit }) => {
return (
<div className={classnames(className, styles['meta-row-placeholder-container'])}>
<div className={styles['title-container']} title={title}>{title}</div>
<div className={styles['meta-items-container']}>
{Array(maximumItemsCount).fill(null).map((_, index) => (
{Array(limit).fill(null).map((_, index) => (
<div key={index} className={styles['meta-item']}>
<div className={styles['poster-container']} />
<div className={styles['title-bar-container']} />
@ -24,7 +23,7 @@ const MetaRowPlaceholder = ({ className, title, maximumItemsCount }) => {
MetaRowPlaceholder.propTypes = {
className: PropTypes.string,
title: PropTypes.string,
maximumItemsCount: PropTypes.number
limit: PropTypes.number.isRequired
};
module.exports = MetaRowPlaceholder;

View file

@ -5,62 +5,13 @@ const useSearch = require('./useSearch');
const styles = require('./styles');
const Search = ({ queryParams }) => {
const search = useSearch(queryParams);
const searchSelected = React.useMemo(() => {
return search.selected.some(([name, value]) => name === 'search' && value.length > 0)
}, [search.selected]);
const { selected, catalog_resources } = useSearch(queryParams);
return (
<div className={styles['search-container']}>
<MainNavBar className={styles['nav-bar']} />
<div className={styles['search-content']}>
{
searchSelected ?
search.items_groups && search.items_groups.length > 0 ?
search.items_groups.some(group => group.content.type !== 'Err') ?
search.items_groups.map(({ href, request, content }, index) => {
switch (content.type) {
case 'Ready':
return (
<MetaRow
key={`${index}${request.base}${content.type} Ready`}
className={styles['search-row']}
title={`${request.path.id} - ${request.path.type_name}`}
items={content.content}
catalogHref={href}
/>
);
case 'Err':
return (
<MetaRow
key={`${index}${request.base}${content.type}`}
className={styles['search-row']}
title={`${request.path.id} - ${request.path.type_name} Err`}
message={`${content.content.type} ${typeof content.content.content === 'string' ? content.content.content : ''}`}
/>
);
case 'Loading':
return (
<MetaRow.Placeholder
key={`${index}${request.base}${content.type} Loading`}
className={styles['search-row-placeholder']}
title={`${request.path.id} - ${request.path.type_name}`}
/>
);
}
})
:
<div className={styles['message-container']}>
<div className={styles['message-content']}>
<div className={styles['label']}>No metadata was found</div>
</div>
</div>
:
<div className={styles['message-container']}>
<div className={styles['message-content']}>
<div className={styles['label']}> No addons were requested for metadata</div>
</div>
</div>
:
selected === null || selected.extra.every(([name]) => name !== 'search') ?
<div className={styles['message-container']}>
<div className={styles['message-content']}>
<Icon className={styles['icon']} icon={'ic_movies'} />
@ -71,6 +22,48 @@ const Search = ({ queryParams }) => {
<div className={styles['label']}>Search for actors, directors and writers</div>
</div>
</div>
:
catalog_resources.length === 0 ?
<div className={styles['message-container']}>
<div className={styles['message-content']}>
<div className={styles['label']}> No addons were requested for catalogs</div>
</div>
</div>
:
catalog_resources.map((catalog, index) => {
switch (catalog.content.type) {
case 'Ready':
return (
<MetaRow
key={index}
className={styles['search-row']}
title={catalog.addon_name}
items={catalog.content.content}
href={catalog.href}
limit={10}
/>
);
case 'Err':
return (
<MetaRow
key={index}
className={styles['search-row']}
title={catalog.addon_name}
message={`Error(${catalog.content.content.type})${typeof catalog.content.content.content === 'string' ? ` - ${catalog.content.content.content}` : ''}`}
limit={10}
/>
);
case 'Loading':
return (
<MetaRow.Placeholder
key={index}
className={styles['search-row-placeholder']}
title={catalog.addon_name}
limit={10}
/>
);
}
})
}
</div>
</div>

View file

@ -42,6 +42,7 @@
flex-direction: row;
align-items: flex-start;
justify-content: center;
max-height: calc(100% - 10rem);
margin: 5rem;
.message-content {
@ -51,12 +52,16 @@
align-items: center;
justify-content: center;
&:not(:first-child) {
margin-left: 5rem;
}
.icon {
flex: none;
width: 6rem;
height: 6rem;
margin-bottom: 2rem;
fill: var(--color-surfacelighter40);
fill: var(--color-surfacelighter80);
}
.label {
@ -64,22 +69,18 @@
flex-shrink: 1;
flex-basis: auto;
font-size: 1.2rem;
color: var(--color-surfacelighter40);
color: var(--color-surfacelighter80);
text-align: center;
}
&:not(:last-child) {
margin-right: 5rem;;
}
}
}
}
}
@media only screen and (min-width: @large) {
.board-container {
.board-content {
.board-row, .board-row-placeholder {
.search-container {
.search-content {
.search-row, .search-row-placeholder {
.meta-item, .meta-item-placeholder {
&:nth-child(n+9) {
display: none;

View file

@ -2,46 +2,43 @@ const React = require('react');
const { useServices } = require('stremio/services');
const mapSearchState = (state) => {
const query = state.search.selected.reduceRight((query, [name, value]) => {
if (name === 'search') {
return value;
}
return query;
}, '');
const queryString = state.search.selected !== null ?
new URLSearchParams(state.search.selected.extra).toString()
:
'';
const selected = state.search.selected;
const items_groups = state.search.items_groups.map((group) => {
group.href = `#/discover/${encodeURIComponent(group.request.base)}/${encodeURIComponent(group.request.path.id)}/${encodeURIComponent(group.request.path.type_name)}?search=${query}`;
return group;
const catalog_resources = state.search.catalog_resources.map((catalog_resource) => {
catalog_resource.href = `#/discover/${encodeURIComponent(catalog_resource.request.base)}/${encodeURIComponent(catalog_resource.request.path.type_name)}/${encodeURIComponent(catalog_resource.request.path.id)}?${queryString}`;
return catalog_resource;
});
return { selected, items_groups };
return { selected, catalog_resources };
};
const useSearch = (queryParams) => {
const { core } = useServices();
const [search, setSearch] = React.useState(() => {
const state = core.getState();
const search = mapSearchState(state);
return search;
});
React.useEffect(() => {
const [search, setSearch] = React.useState(() => ({
selected: null,
catalog_resources: []
}));
React.useLayoutEffect(() => {
const onNewState = () => {
const state = core.getState();
const search = mapSearchState(state);
setSearch(search);
};
core.on('NewModel', onNewState);
if (queryParams.has('search')) {
if (queryParams.has('search') && queryParams.get('search').length > 0) {
core.dispatch({
action: 'Load',
args: {
load: 'CatalogsGrouped',
load: 'CatalogsWithExtra',
args: {
extra: [
['search', queryParams.get('search')]
]
}
}
});
}, 'Search');
}
return () => {
core.off('NewModel', onNewState);