Board hook refactored

This commit is contained in:
NikolaBorislavovHristov 2019-06-04 12:23:23 +03:00
parent eb72dfb266
commit 5c95f98345
5 changed files with 88 additions and 146 deletions

View file

@ -25,7 +25,7 @@ const MetaItem = React.memo(({ className, menuClassName, id, type, name, posterS
}, [menuOpen]);
const placeholderIcon = ICON_FOR_TYPE[type] || 'ic_movies';
return (
<Input className={classnames(className, styles['meta-item-container'], styles[`poster-shape-${posterShape}`])} title={name} type={'button'} data-meta-item-id={id} onClick={onClick} onContextMenu={onContextMenu}>
<Input className={classnames(className, styles['meta-item-container'], styles[`poster-shape-${posterShape}`])} title={name} type={'button'} data-id={id} onClick={onClick} onContextMenu={onContextMenu}>
<div className={styles['poster-image-container']}>
<div className={styles['placeholder-image-layer']}>
<Icon className={styles['placeholder-image']} icon={placeholderIcon} />
@ -79,7 +79,7 @@ const MetaItem = React.memo(({ className, menuClassName, id, type, name, posterS
<Popup.Menu className={classnames(menuClassName, styles['menu-container'])} tabIndex={-1}>
<div className={styles['menu-items-container']}>
{menuOptions.map(({ label, type }) => (
<Input key={type} className={styles['menu-item']} type={'button'} data-meta-item-id={id} data-menu-option-type={type} onClick={menuOptionOnSelect}>{label}</Input>
<Input key={type} className={styles['menu-item']} type={'button'} data-id={id} data-type={type} onClick={menuOptionOnSelect}>{label}</Input>
))}
</div>
</Popup.Menu>

View file

@ -3,7 +3,7 @@ const classnames = require('classnames');
const Icon = require('stremio-icons/dom');
const { Input } = require('stremio-navigation')
const { MetaItem, MainNavBar } = require('stremio-common');
const withGroups = require('./withGroups');
const useCatalogs = require('./useCatalogs');
const styles = require('./styles');
const CONTINUE_WATCHING_MENU = [
@ -17,86 +17,50 @@ const CONTINUE_WATCHING_MENU = [
}
];
class Board extends React.PureComponent {
onClick = (event) => {
console.log('onClick', {
id: event.currentTarget.dataset.metaItemId,
defaultPrevented: event.isDefaultPrevented(),
propagationStopped: event.isPropagationStopped()
});
}
menuOptionOnSelect = (event) => {
console.log('menuOptionOnSelect', {
id: event.currentTarget.dataset.metaItemId,
type: event.currentTarget.dataset.menuOptionType,
defaultPrevented: event.isDefaultPrevented(),
propagationStopped: event.isPropagationStopped()
});
}
render() {
return (
<div className={styles['board-container']}>
<MainNavBar className={styles['nav-bar']} />
<div className={styles['board-content']} tabIndex={-1}>
{
this.props.groups.length > 0 ?
<React.Fragment>
<div className={classnames(styles['board-row'], styles['continue-watching-row'])}>
<div className={styles['meta-items-container']}>
{this.props.groups[0].items.map((item) => (
<MetaItem
{...item}
key={item.id}
title={item.name}
className={classnames(styles['meta-item'], styles[`poster-shape-${item.posterShape === 'landscape' ? 'square' : item.posterShape}`])}
menuClassName={styles['menu-container']}
posterShape={item.posterShape === 'landscape' ? 'square' : item.posterShape}
menuOptions={CONTINUE_WATCHING_MENU}
menuOptionOnSelect={this.menuOptionOnSelect}
onClick={this.onClick}
/>
))}
</div>
<Input className={classnames(styles['show-more-container'], 'focusable-with-border')} type={'button'}>
<div className={styles['label']}>SEE ALL</div>
<Icon className={styles['icon']} icon={'ic_back_ios'} />
</Input>
</div>
{
this.props.groups.slice(1, this.props.groups.length).map((group) => {
return (
<div key={group.id} className={classnames(styles['board-row'], styles['addon-catalog-row'])}>
<div className={styles['meta-items-container']}>
{group.items.map((item, _, metaItems) => (
<MetaItem
{...item}
key={item.id}
title={item.name}
className={classnames(styles['meta-item'], styles[`poster-shape-${metaItems[0].posterShape}`])}
posterShape={metaItems[0].posterShape}
progress={0}
onClick={this.onClick}
/>
))}
</div>
<Input className={classnames(styles['show-more-container'], 'focusable-with-border')} type={'button'}>
<div className={styles['label']}>SEE ALL</div>
<Icon className={styles['icon']} icon={'ic_back_ios'} />
</Input>
</div>
);
})
}
</React.Fragment>
:
null
}
</div>
const BoardRow = ({ className, items }) => {
return (
<div className={classnames(styles['board-row'], className)}>
<div className={styles['meta-items-container']}>
{items.map((item) => (
<MetaItem
{...item}
key={item.id}
title={item.name}
className={classnames(styles['meta-item'], styles[`poster-shape-${item.posterShape === 'landscape' ? 'square' : item.posterShape}`])}
menuClassName={styles['menu-container']}
posterShape={item.posterShape === 'landscape' ? 'square' : item.posterShape}
menuOptions={CONTINUE_WATCHING_MENU}
/>
))}
</div>
);
}
}
<Input className={classnames(styles['show-more-container'], 'focusable-with-border')} type={'button'}>
<div className={styles['label']}>SEE ALL</div>
<Icon className={styles['icon']} icon={'ic_back_ios'} />
</Input>
</div>
);
};
module.exports = withGroups(Board);
const Board = () => {
const [resumeCatalog, ...addonCatalogs] = useCatalogs();
return (
<div className={styles['board-container']}>
<MainNavBar className={styles['nav-bar']} />
<div className={styles['board-content']} tabIndex={-1}>
{
resumeCatalog && Array.isArray(resumeCatalog.items) && resumeCatalog.items.length > 0 ?
<BoardRow className={styles['continue-watching-row']} items={resumeCatalog.items} />
:
null
}
{
addonCatalogs.map((catalog) => (
<BoardRow key={catalog.id} className={styles['addon-catalog-row']} items={catalog.items} />
))
}
</div>
</div>
);
};
module.exports = Board;

View file

@ -4,8 +4,6 @@
.board-row {
&.continue-watching-row {
.meta-item {
--play-icon-visibility: visible;
&:nth-child(n+7) {
display: none;
}
@ -14,10 +12,6 @@
&.notificatins-row {
.meta-item {
&:hover, &:focus {
--play-icon-visibility: visible;
}
&:nth-child(n+5) {
display: none;
}

View file

@ -0,0 +1,40 @@
const React = require('react');
const useCatalogs = () => {
const [catalogs, setCatalogs] = React.useState([]);
React.useEffect(() => {
const onNewState = () => {
const state = window.stateContainer.getState();
const catalogs = state.groups.reduce((catalogs, [request, response], index) => {
if (response.type === 'Ready') {
catalogs.push({
id: `${index}${request.transport_url}`,
items: response.content.map((item) => {
return {
...item,
posterShape: item.posterShape || 'poster'
};
})
});
}
return catalogs;
}, []);
setCatalogs(catalogs);
};
window.stateContainer.on('NewState', onNewState);
window.stateContainer.dispatch({
action: 'Load',
args: {
load: 'CatalogGrouped',
args: { extra: [] }
}
});
return () => {
window.stateContainer.off('NewState', onNewState);
};
}, []);
return catalogs;
};
module.exports = useCatalogs;

View file

@ -1,56 +0,0 @@
const React = require('react');
const withGroups = (Component) => {
return class withGroups extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
groups: []
};
}
componentDidMount() {
window.stateContainer.on('NewState', this.onUpdate);
window.stateContainer.dispatch({
action: 'Load',
args: {
load: 'CatalogGrouped',
args: { extra: [] }
}
});
}
componentWillUnmount() {
window.stateContainer.off('NewState', this.onUpdate);
}
onUpdate = (args) => {
const state = window.stateContainer.getState();
const groups = state.groups.reduce((groups, [request, response], index) => {
if (response.type === 'Ready') {
groups.push({
id: `${index}${request.transport_url}`,
items: response.content.map((item) => {
return {
...item,
posterShape: item.posterShape || 'poster'
};
})
});
}
return groups;
}, []);
this.setState({ groups });
}
render() {
return (
<Component {...this.props} {...this.state} />
);
}
}
}
module.exports = withGroups;