mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 10:42:12 +00:00
Board hook refactored
This commit is contained in:
parent
eb72dfb266
commit
5c95f98345
5 changed files with 88 additions and 146 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
40
src/routes/Board/useCatalogs.js
Normal file
40
src/routes/Board/useCatalogs.js
Normal 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;
|
||||
|
|
@ -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;
|
||||
Loading…
Reference in a new issue