mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
deep linking integrated in Search and Board
This commit is contained in:
parent
80837a12c2
commit
c9076155a2
7 changed files with 49 additions and 26 deletions
|
|
@ -23,8 +23,23 @@ const ICON_FOR_TYPE = new Map([
|
||||||
['other', 'ic_movies'],
|
['other', 'ic_movies'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const MetaItem = React.memo(({ className, type, name, poster, posterShape, playIcon, progress, options, dataset, optionOnSelect, ...props }) => {
|
const MetaItem = React.memo(({ className, type, name, poster, posterShape, playIcon, progress, options, deepLinks, dataset, optionOnSelect, ...props }) => {
|
||||||
const [menuOpen, onMenuOpen, onMenuClose] = useBinaryState(false);
|
const [menuOpen, onMenuOpen, onMenuClose] = useBinaryState(false);
|
||||||
|
const href = React.useMemo(() => {
|
||||||
|
return deepLinks ?
|
||||||
|
typeof deepLinks.player === 'string' ?
|
||||||
|
deepLinks.player
|
||||||
|
:
|
||||||
|
typeof deepLinks.meta_details_streams === 'string' ?
|
||||||
|
deepLinks.meta_details_streams
|
||||||
|
:
|
||||||
|
typeof deepLinks.meta_details_videos === 'string' ?
|
||||||
|
deepLinks.meta_details_videos
|
||||||
|
:
|
||||||
|
null
|
||||||
|
:
|
||||||
|
null;
|
||||||
|
}, [deepLinks]);
|
||||||
const metaItemOnClick = React.useCallback((event) => {
|
const metaItemOnClick = React.useCallback((event) => {
|
||||||
if (typeof props.onClick === 'function') {
|
if (typeof props.onClick === 'function') {
|
||||||
props.onClick(event);
|
props.onClick(event);
|
||||||
|
|
@ -58,7 +73,7 @@ const MetaItem = React.memo(({ className, type, name, poster, posterShape, playI
|
||||||
<Icon className={styles['icon']} icon={'ic_more'} />
|
<Icon className={styles['icon']} icon={'ic_more'} />
|
||||||
), []);
|
), []);
|
||||||
return (
|
return (
|
||||||
<Button title={name} {...props} className={classnames(className, styles['meta-item-container'], styles['poster-shape-poster'], styles[`poster-shape-${posterShape}`], { 'active': menuOpen })} onClick={metaItemOnClick}>
|
<Button title={name} href={href} {...props} className={classnames(className, styles['meta-item-container'], styles['poster-shape-poster'], styles[`poster-shape-${posterShape}`], { 'active': menuOpen })} onClick={metaItemOnClick}>
|
||||||
<div className={styles['poster-container']}>
|
<div className={styles['poster-container']}>
|
||||||
<div className={styles['poster-image-layer']}>
|
<div className={styles['poster-image-layer']}>
|
||||||
<Image
|
<Image
|
||||||
|
|
@ -125,6 +140,11 @@ MetaItem.propTypes = {
|
||||||
playIcon: PropTypes.bool,
|
playIcon: PropTypes.bool,
|
||||||
progress: PropTypes.number,
|
progress: PropTypes.number,
|
||||||
options: PropTypes.array,
|
options: PropTypes.array,
|
||||||
|
deepLinks: PropTypes.shape({
|
||||||
|
meta_details_videos: PropTypes.string,
|
||||||
|
meta_details_streams: PropTypes.string,
|
||||||
|
player: PropTypes.string
|
||||||
|
}),
|
||||||
dataset: PropTypes.object,
|
dataset: PropTypes.object,
|
||||||
optionOnSelect: PropTypes.func,
|
optionOnSelect: PropTypes.func,
|
||||||
onClick: PropTypes.func
|
onClick: PropTypes.func
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ const CONSTANTS = require('stremio/common/CONSTANTS');
|
||||||
const MetaRowPlaceholder = require('./MetaRowPlaceholder');
|
const MetaRowPlaceholder = require('./MetaRowPlaceholder');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
const MetaRow = ({ className, title, message, items, itemComponent, href }) => {
|
const MetaRow = ({ className, title, message, items, itemComponent, deepLinks }) => {
|
||||||
return (
|
return (
|
||||||
<div className={classnames(className, styles['meta-row-container'])}>
|
<div className={classnames(className, styles['meta-row-container'])}>
|
||||||
{
|
{
|
||||||
(typeof title === 'string' && title.length > 0) || (typeof href === 'string' && href.length > 0) ?
|
(typeof title === 'string' && title.length > 0) || (deepLinks && typeof deepLinks.discover === 'string') ?
|
||||||
<div className={styles['header-container']}>
|
<div className={styles['header-container']}>
|
||||||
{
|
{
|
||||||
typeof title === 'string' && title.length > 0 ?
|
typeof title === 'string' && title.length > 0 ?
|
||||||
|
|
@ -21,8 +21,8 @@ const MetaRow = ({ className, title, message, items, itemComponent, href }) => {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typeof href === 'string' && href.length > 0 ?
|
deepLinks && typeof deepLinks.discover === 'string' ?
|
||||||
<Button className={styles['see-all-container']} title={'SEE ALL'} href={href}>
|
<Button className={styles['see-all-container']} title={'SEE ALL'} href={deepLinks.discover}>
|
||||||
<div className={styles['label']}>SEE ALL</div>
|
<div className={styles['label']}>SEE ALL</div>
|
||||||
<Icon className={styles['icon']} icon={'ic_arrow_thin_right'} />
|
<Icon className={styles['icon']} icon={'ic_arrow_thin_right'} />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -69,7 +69,9 @@ MetaRow.propTypes = {
|
||||||
posterShape: PropTypes.string
|
posterShape: PropTypes.string
|
||||||
})),
|
})),
|
||||||
itemComponent: PropTypes.elementType,
|
itemComponent: PropTypes.elementType,
|
||||||
href: PropTypes.string
|
deepLinks: PropTypes.shape({
|
||||||
|
discover: PropTypes.string
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = MetaRow;
|
module.exports = MetaRow;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const Button = require('stremio/common/Button');
|
||||||
const CONSTANTS = require('stremio/common/CONSTANTS');
|
const CONSTANTS = require('stremio/common/CONSTANTS');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
const MetaRowPlaceholder = ({ className, title, href }) => {
|
const MetaRowPlaceholder = ({ className, title, deepLinks }) => {
|
||||||
return (
|
return (
|
||||||
<div className={classnames(className, styles['meta-row-placeholder-container'])}>
|
<div className={classnames(className, styles['meta-row-placeholder-container'])}>
|
||||||
<div className={styles['header-container']}>
|
<div className={styles['header-container']}>
|
||||||
|
|
@ -14,8 +14,8 @@ const MetaRowPlaceholder = ({ className, title, href }) => {
|
||||||
{typeof title === 'string' && title.length > 0 ? title : null}
|
{typeof title === 'string' && title.length > 0 ? title : null}
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
typeof href === 'string' && href.length > 0 ?
|
deepLinks && typeof deepLinks.discover === 'string' ?
|
||||||
<Button className={styles['see-all-container']} title={'SEE ALL'} href={href}>
|
<Button className={styles['see-all-container']} title={'SEE ALL'} href={deepLinks.discover}>
|
||||||
<div className={styles['label']}>SEE ALL</div>
|
<div className={styles['label']}>SEE ALL</div>
|
||||||
<Icon className={styles['icon']} icon={'ic_arrow_thin_right'} />
|
<Icon className={styles['icon']} icon={'ic_arrow_thin_right'} />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -40,7 +40,9 @@ const MetaRowPlaceholder = ({ className, title, href }) => {
|
||||||
MetaRowPlaceholder.propTypes = {
|
MetaRowPlaceholder.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
title: PropTypes.string,
|
title: PropTypes.string,
|
||||||
href: PropTypes.string
|
deepLinks: PropTypes.shape({
|
||||||
|
discover: PropTypes.string
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = MetaRowPlaceholder;
|
module.exports = MetaRowPlaceholder;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ const Board = () => {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
{board.catalog_resources.map((catalog_resource, index) => {
|
{board.catalog_resources.map((catalog_resource, index) => {
|
||||||
const href = `#/discover/${encodeURIComponent(catalog_resource.request.base)}/${encodeURIComponent(catalog_resource.request.path.type_name)}/${encodeURIComponent(catalog_resource.request.path.id)}`;
|
|
||||||
const title = `${catalog_resource.origin} - ${catalog_resource.request.path.id} ${catalog_resource.request.path.type_name}`;
|
const title = `${catalog_resource.origin} - ${catalog_resource.request.path.id} ${catalog_resource.request.path.type_name}`;
|
||||||
switch (catalog_resource.content.type) {
|
switch (catalog_resource.content.type) {
|
||||||
case 'Ready': {
|
case 'Ready': {
|
||||||
|
|
@ -39,7 +38,7 @@ const Board = () => {
|
||||||
title={title}
|
title={title}
|
||||||
items={catalog_resource.content.content}
|
items={catalog_resource.content.content}
|
||||||
itemComponent={MetaItem}
|
itemComponent={MetaItem}
|
||||||
href={href}
|
deepLinks={catalog_resource.deepLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +50,7 @@ const Board = () => {
|
||||||
className={styles['board-row']}
|
className={styles['board-row']}
|
||||||
title={title}
|
title={title}
|
||||||
message={message}
|
message={message}
|
||||||
href={href}
|
deepLinks={catalog_resource.deepLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +60,7 @@ const Board = () => {
|
||||||
key={index}
|
key={index}
|
||||||
className={classnames(styles['board-row'], styles['board-row-poster'])}
|
className={classnames(styles['board-row'], styles['board-row-poster'])}
|
||||||
title={title}
|
title={title}
|
||||||
href={href}
|
deepLinks={catalog_resource.deepLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const { useModelState } = require('stremio/common');
|
const { deepLinking, useModelState } = require('stremio/common');
|
||||||
|
|
||||||
const initBoardState = () => ({
|
const initBoardState = () => ({
|
||||||
selected: null,
|
selected: null,
|
||||||
|
|
@ -18,7 +18,7 @@ const mapBoardStateWithCtx = (board, ctx) => {
|
||||||
name: metaItem.name,
|
name: metaItem.name,
|
||||||
poster: metaItem.poster,
|
poster: metaItem.poster,
|
||||||
posterShape: metaItems[0].posterShape,
|
posterShape: metaItems[0].posterShape,
|
||||||
href: `#/metadetails/${encodeURIComponent(metaItem.type)}/${encodeURIComponent(metaItem.id)}` // TODO this should redirect with videoId at some cases
|
deepLinks: deepLinking.withMetaItem({ metaItem })
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
|
|
@ -33,7 +33,8 @@ const mapBoardStateWithCtx = (board, ctx) => {
|
||||||
|
|
||||||
return origin;
|
return origin;
|
||||||
}, catalog_resource.request.base);
|
}, catalog_resource.request.base);
|
||||||
return { request, content, origin };
|
const deepLinks = deepLinking.withCatalog({ request });
|
||||||
|
return { request, content, origin, deepLinks };
|
||||||
});
|
});
|
||||||
return { selected, catalog_resources };
|
return { selected, catalog_resources };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,6 @@ const Search = ({ queryParams }) => {
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
search.catalog_resources.map((catalog_resource, index) => {
|
search.catalog_resources.map((catalog_resource, index) => {
|
||||||
const queryString = new URLSearchParams([['search', query]]).toString();
|
|
||||||
const href = `#/discover/${encodeURIComponent(catalog_resource.request.base)}/${encodeURIComponent(catalog_resource.request.path.type_name)}/${encodeURIComponent(catalog_resource.request.path.id)}?${queryString}`;
|
|
||||||
const title = `${catalog_resource.origin} - ${catalog_resource.request.path.id} ${catalog_resource.request.path.type_name}`;
|
const title = `${catalog_resource.origin} - ${catalog_resource.request.path.id} ${catalog_resource.request.path.type_name}`;
|
||||||
switch (catalog_resource.content.type) {
|
switch (catalog_resource.content.type) {
|
||||||
case 'Ready': {
|
case 'Ready': {
|
||||||
|
|
@ -63,7 +61,7 @@ const Search = ({ queryParams }) => {
|
||||||
title={title}
|
title={title}
|
||||||
items={catalog_resource.content.content}
|
items={catalog_resource.content.content}
|
||||||
itemComponent={MetaItem}
|
itemComponent={MetaItem}
|
||||||
href={href}
|
deepLinks={catalog_resource.deepLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +73,7 @@ const Search = ({ queryParams }) => {
|
||||||
className={styles['search-row']}
|
className={styles['search-row']}
|
||||||
title={title}
|
title={title}
|
||||||
message={message}
|
message={message}
|
||||||
href={href}
|
deepLinks={catalog_resource.deepLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +83,7 @@ const Search = ({ queryParams }) => {
|
||||||
key={index}
|
key={index}
|
||||||
className={classnames(styles['search-row'], styles['search-row-poster'])}
|
className={classnames(styles['search-row'], styles['search-row-poster'])}
|
||||||
title={title}
|
title={title}
|
||||||
href={href}
|
deepLinks={catalog_resource.deepLinks}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const { useModelState } = require('stremio/common');
|
const { deepLinking, useModelState } = require('stremio/common');
|
||||||
|
|
||||||
const initSearchState = () => ({
|
const initSearchState = () => ({
|
||||||
selected: null,
|
selected: null,
|
||||||
|
|
@ -18,7 +18,7 @@ const mapSearchStateWithCtx = (search, ctx) => {
|
||||||
name: metaItem.name,
|
name: metaItem.name,
|
||||||
poster: metaItem.poster,
|
poster: metaItem.poster,
|
||||||
posterShape: metaItems[0].posterShape,
|
posterShape: metaItems[0].posterShape,
|
||||||
href: `#/metadetails/${encodeURIComponent(metaItem.type)}/${encodeURIComponent(metaItem.id)}` // TODO this should redirect with videoId at some cases
|
deepLinks: deepLinking.withMetaItem({ metaItem })
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
:
|
:
|
||||||
|
|
@ -33,7 +33,8 @@ const mapSearchStateWithCtx = (search, ctx) => {
|
||||||
|
|
||||||
return origin;
|
return origin;
|
||||||
}, catalog_resource.request.base);
|
}, catalog_resource.request.base);
|
||||||
return { request, content, origin };
|
const deepLinks = deepLinking.withCatalog({ request });
|
||||||
|
return { request, content, origin, deepLinks };
|
||||||
});
|
});
|
||||||
return { selected, catalog_resources };
|
return { selected, catalog_resources };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue