feat(StreamsList): add multiselect to filter streams by addons

This commit is contained in:
Tim 2022-10-26 01:14:10 +02:00
parent c89072e329
commit 704af55ccb
2 changed files with 86 additions and 16 deletions

View file

@ -4,13 +4,19 @@ const React = require('react');
const PropTypes = require('prop-types');
const classnames = require('classnames');
const Icon = require('@stremio/stremio-icons/dom');
const { Button, Image } = require('stremio/common');
const { Button, Image, Multiselect } = require('stremio/common');
const { useServices } = require('stremio/services');
const Stream = require('./Stream');
const styles = require('./styles');
const ALL_ADDONS_KEY = 'ALL';
const StreamsList = ({ className, ...props }) => {
const { core } = useServices();
const [selectedAddon, setSelectedAddon] = React.useState(ALL_ADDONS_KEY);
const onAddonSelected = React.useCallback((event) => {
setSelectedAddon(event.value);
}, []);
const streams = React.useMemo(() => {
return props.streams
.filter((streams) => streams.content.type === 'Ready')
@ -25,11 +31,39 @@ const StreamsList = ({ className, ...props }) => {
}
});
},
transportUrl: streams.addon.transportUrl,
addonName: streams.addon.manifest.name
}));
})
.flat(1);
}, [props.streams]);
const filteredStreams = React.useMemo(() => {
return selectedAddon === ALL_ADDONS_KEY ?
streams
:
streams.filter((stream) => stream.transportUrl === selectedAddon);
}, [streams, selectedAddon]);
const selectableOptions = React.useMemo(() => {
const transportUrls = [...new Set(streams.map(({ transportUrl }) => transportUrl))];
const sortedStreams = transportUrls.map((transportUrl) => streams.filter((stream) => stream.transportUrl === transportUrl));
return {
title: 'Select Addon',
options: [
{
value: ALL_ADDONS_KEY,
label: 'All',
title: 'All'
},
...sortedStreams.map((streams) => ({
value: streams[0].transportUrl,
label: streams[0].addonName,
title: streams[0].addonName
}))
],
selected: [selectedAddon],
onSelect: onAddonSelected
};
}, [streams, selectedAddon]);
return (
<div className={classnames(className, styles['streams-list-container'])}>
{
@ -45,26 +79,32 @@ const StreamsList = ({ className, ...props }) => {
<div className={styles['label']}>No streams were found!</div>
</div>
:
streams.length === 0 ?
filteredStreams.length === 0 ?
<div className={styles['streams-container']}>
<Stream.Placeholder />
<Stream.Placeholder />
</div>
:
<div className={styles['streams-container']}>
{streams.map((stream, index) => (
<Stream
key={index}
addonName={stream.addonName}
name={stream.name}
description={stream.description}
thumbnail={stream.thumbnail}
progress={stream.progress}
deepLinks={stream.deepLinks}
onClick={stream.onClick}
/>
))}
</div>
<React.Fragment>
<Multiselect
{...selectableOptions}
className={styles['select-input-container']}
/>
<div className={styles['streams-container']}>
{filteredStreams.map((stream, index) => (
<Stream
key={index}
addonName={stream.addonName}
name={stream.name}
description={stream.description}
thumbnail={stream.thumbnail}
progress={stream.progress}
deepLinks={stream.deepLinks}
onClick={stream.onClick}
/>
))}
</div>
</React.Fragment>
}
<Button className={styles['install-button-container']} title={'Install Addons'} href={'#/addons'}>
<Icon className={styles['icon']} icon={'ic_addons'} />

View file

@ -3,6 +3,12 @@
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
@import (reference) '~stremio/common/screen-sizes.less';
:import('~stremio/common/Multiselect/styles.less') {
multiselect-menu-container: menu-container;
multiselect-label: label;
multiselect-icon: icon;
}
.streams-list-container {
display: flex;
flex-direction: column;
@ -35,6 +41,30 @@
}
}
.select-input-container {
flex: 0 0 auto;
height: 3.5rem;
margin: 1em 1em 0 1em;
background: none;
&:hover, &:focus, &:global(.active) {
background-color: @color-background;
}
& >.multiselect-label {
color: @color-surface-light5-90;
}
& >.multiselect-icon {
fill: @color-surface-light5-90;
}
.multiselect-menu-container {
max-height: calc(3.2rem * 7);
overflow: auto;
}
}
.streams-container {
flex: 0 1 auto;
align-self: stretch;