mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-08-18 21:57:46 +00:00
addons screen implemented
This commit is contained in:
parent
785ed4601c
commit
f126f8d789
2 changed files with 244 additions and 1 deletions
|
|
@ -1,11 +1,148 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import Addon from './Addon';
|
||||
import styles from './styles';
|
||||
|
||||
const ADDON_CATEGORIES = {
|
||||
OFFICIAL: 1,
|
||||
COMMUNITY: 2,
|
||||
MY: 3
|
||||
};
|
||||
|
||||
const ADDON_TYPES = {
|
||||
All: -1,
|
||||
Movies: 0,
|
||||
Series: 1,
|
||||
Channels: 2,
|
||||
Others: 3
|
||||
};
|
||||
|
||||
const DEFAULT_TYPE = 'All';
|
||||
|
||||
class Addons extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
selectedCategory: ADDON_CATEGORIES.OFFICIAL,
|
||||
selectedAddonType: DEFAULT_TYPE
|
||||
};
|
||||
}
|
||||
|
||||
changeSelectedCategory = (event) => {
|
||||
this.setState({ selectedCategory: ADDON_CATEGORIES[event.currentTarget.dataset.category] });
|
||||
}
|
||||
|
||||
changeSelectedAddonType = (event) => {
|
||||
this.setState({ selectedAddonType: event.currentTarget.dataset.type })
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return nextState.selectedCategory !== this.state.selectedCategory ||
|
||||
nextState.selectedAddonType !== this.state.selectedAddonType;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
if (this.state.selectedCategory !== prevState.selectedCategory || !this.getAddonTypes().includes(this.state.selectedAddonType)) {
|
||||
this.setState({ selectedAddonType: DEFAULT_TYPE })
|
||||
}
|
||||
}
|
||||
|
||||
getAddonTypes() {
|
||||
const addonTypes = this.props.addons
|
||||
.filter((addon) => {
|
||||
if (this.state.selectedCategory === ADDON_CATEGORIES.OFFICIAL) return addon.isOfficial === true;
|
||||
if (this.state.selectedCategory === ADDON_CATEGORIES.COMMUNITY) return addon.isOfficial === false;
|
||||
if (this.state.selectedCategory === ADDON_CATEGORIES.MY) return addon.isInstalled === true;
|
||||
})
|
||||
.map((addon) => addon.types)
|
||||
.join()
|
||||
.split(',')
|
||||
.filter((type, index, types) => types.indexOf(type) === index)
|
||||
.sort(function(a, b) {
|
||||
const valueA = ADDON_TYPES[a];
|
||||
const valueB = ADDON_TYPES[b];
|
||||
if (!isNaN(valueA) && !isNaN(valueB)) return valueA - valueB;
|
||||
if (!isNaN(valueA)) return -1;
|
||||
if (!isNaN(valueB)) return 1;
|
||||
return a - b;
|
||||
});
|
||||
|
||||
return addonTypes;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={{ color: 'pink', paddingTop: 40 }}>You're on the Addons Tab</div>
|
||||
<div className={styles['addons-container']}>
|
||||
<div className={styles['side-menu']}>
|
||||
{Object.keys(ADDON_CATEGORIES).map((category) =>
|
||||
<div className={classnames(styles['label-container'], { [styles['selected']]: this.state.selectedCategory === ADDON_CATEGORIES[category] })} tabIndex={this.state.selectedCategory === ADDON_CATEGORIES[category] ? null : '0'} key={category} data-category={category} onClick={this.changeSelectedCategory}>
|
||||
<div className={styles['label']}>
|
||||
{category}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={classnames(styles['label-container'], { [styles['selected']]: this.state.selectedAddonType === DEFAULT_TYPE })} tabIndex={this.state.selectedAddonType === DEFAULT_TYPE ? null : '0'} data-type={DEFAULT_TYPE} onClick={this.changeSelectedAddonType}>
|
||||
<div className={styles['label-']}>All</div>
|
||||
</div>
|
||||
{this.getAddonTypes().map((type) =>
|
||||
<div className={classnames(styles['label-container'], { [styles['selected']]: this.state.selectedAddonType === type })} tabIndex={this.state.selectedAddonType === type ? null : '0'} key={type} data-type={type} onClick={this.changeSelectedAddonType}>
|
||||
<div className={styles['label']}>{type}</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles['scroll-container']}>
|
||||
{this.props.addons
|
||||
.filter((addon) => {
|
||||
if (this.state.selectedCategory === ADDON_CATEGORIES.OFFICIAL) return addon.isOfficial === true;
|
||||
if (this.state.selectedCategory === ADDON_CATEGORIES.COMMUNITY) return addon.isOfficial === false;
|
||||
if (this.state.selectedCategory === ADDON_CATEGORIES.MY) return addon.isInstalled === true;
|
||||
})
|
||||
.filter((addon) => {
|
||||
return this.state.selectedAddonType === DEFAULT_TYPE ||
|
||||
addon.types.indexOf(this.state.selectedAddonType) !== -1;
|
||||
})
|
||||
.map((addon) =>
|
||||
<Addon key={addon.name}
|
||||
className={styles['addon']}
|
||||
logo={addon.logo}
|
||||
name={addon.name}
|
||||
version={addon.version}
|
||||
isOfficial={addon.isOfficial}
|
||||
isInstalled={addon.isInstalled}
|
||||
types={addon.types}
|
||||
description={addon.description}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Addons.propTypes = {
|
||||
addons: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||
};
|
||||
Addons.defaultProps = {
|
||||
addons: [
|
||||
{ logo: 'ic_series', name: 'Watch Hub', version: '1.3.0', isOfficial: true, isInstalled: false, types: ['ovies', 'Series'], description: 'Find where to stream your favourite movies and shows amongst iTunes, Hulu, Amazon and other UK/US services.' },
|
||||
{ name: 'Cinemeta', version: '2.4.0', isOfficial: false, isInstalled: true, types: ['Moies', 'Series'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_youtube_small', name: 'YouTube', version: '1.3.0', isOfficial: false, isInstalled: true, types: ['Channels', 'Videos'], description: 'Watch your favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ name: 'OpenSubtitles', version: '1.3.0', isOfficial: false, isInstalled: false, types: ['Movie', 'Seies'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_series', name: 'Zooqle', version: '1.3.0', isOfficial: true, isInstalled: false, types: ['Movies', 'Series'], description: 'Find where to stream your favourite movies and shows amongst iTunes, Hulu, Amazon and other UK/US services.' },
|
||||
{ name: 'PirateBay Addon', version: '2.4.0', isOfficial: false, isInstalled: true, types: ['Movies', 'eries'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_youtube_small', name: 'Popcorn Time', version: '1.3.0', isOfficial: false, isInstalled: true, types: ['Channels', 'Videos'], description: 'Watch your favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ name: 'IBERIAN', version: '1.3.0', isOfficial: false, isInstalled: true, types: ['Movies', 'Other'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_series', name: 'Ex Addon', version: '1.3.0', isOfficial: false, isInstalled: false, types: ['Movies', 'Series'], description: 'Find where to stream your favourite movies and shows amongst iTunes, Hulu, Amazon and other UK/US services.' },
|
||||
{ name: 'Juan Carlos', version: '2.4.0', isOfficial: false, isInstalled: true, types: ['Movies', 'Seris', 'Channels'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_youtube_small', name: 'Juan Carlos Torrents', version: '1.3.0', isOfficial: false, isInstalled: true, types: ['Channels', 'Videos'], description: 'Watch your favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ name: 'Juan Carlos 2', version: '1.3.0', isOfficial: false, isInstalled: false, types: ['Moes', 'Serie'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_series', name: 'Netflix', version: '1.3.0', isOfficial: true, isInstalled: false, types: ['Movies', 'Series'], description: 'Find where to stream your favourite movies and shows amongst iTunes, Hulu, Amazon and other UK/US services.' },
|
||||
{ name: 'Anime Addon', version: '2.4.0', isOfficial: false, isInstalled: true, types: ['Movies', 'Series'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ logo: 'ic_youtube_small', name: 'DTube', version: '1.3.0', isOfficial: true, isInstalled: true, types: ['hannels', 'Videos'], description: 'Watch your favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiourfavourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notiour favourite YouTube channels ad-free and get notified when they upload new videos.' },
|
||||
{ name: 'Mixer', version: '1.3.0', isOfficial: false, isInstalled: true, types: ['Movies', 'Series'], description: 'Watch your favourite YouTube channels ad-free and get notified when they upload new videos.' }
|
||||
]
|
||||
};
|
||||
|
||||
export default Addons;
|
||||
|
|
|
|||
106
src/routes/Addons/styles.less
Normal file
106
src/routes/Addons/styles.less
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
.addons-container {
|
||||
--addon-width: 960px;
|
||||
--label-width: 196px;
|
||||
--spacing: 8px;
|
||||
--button-border-width: 2px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.addons-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.side-menu {
|
||||
width: calc(var(--addon-width) * 0.25);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 calc(var(--spacing) * 2.5 + var(--button-border-width));
|
||||
margin: calc(var(--spacing) * 2.5 + var(--button-border-width)) calc(var(--spacing) * 4.5) calc(var(--spacing) * 2.5 + var(--button-border-width)) 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
.label-container {
|
||||
width: var(--label-width);
|
||||
cursor: pointer;
|
||||
margin-top: var(--button-border-width);
|
||||
padding: calc(var(--spacing) * 1.5);
|
||||
font-size: 1.2em;
|
||||
color: var(--color-surfacelight);
|
||||
|
||||
.label {
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
color: var(--color-surfacelighter);
|
||||
background: var(--color-primarydark);
|
||||
|
||||
&:hover {
|
||||
background: var(--color-primarydark);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--color-surfacelighter);
|
||||
background: var(--color-backgroundlighter);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: var(--button-border-width) solid var(--color-surfacelighter);
|
||||
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
margin-bottom: calc(var(--spacing) * 2.5 + var(--button-border-width));
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: var(--button-border-width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.side-menu::-webkit-scrollbar {
|
||||
width: var(--spacing) !important;
|
||||
}
|
||||
|
||||
.side-menu::-webkit-scrollbar-thumb {
|
||||
background-color: var(--color-secondarylighter);
|
||||
}
|
||||
|
||||
.side-menu::-webkit-scrollbar-track {
|
||||
background-color: var(--color-backgroundlighter);
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
flex: 1;
|
||||
align-self: stretch;
|
||||
margin: calc(var(--spacing) * 2.5 + var(--button-border-width)) calc(var(--spacing) * 2.5 + var(--button-border-width)) calc(var(--spacing) * 2.5 + var(--button-border-width)) 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
>:not(:first-child) {
|
||||
margin-top: calc(var(--spacing) * 2.5 + var(--button-border-width));
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-container::-webkit-scrollbar {
|
||||
width: var(--spacing) !important;
|
||||
}
|
||||
|
||||
.scroll-container::-webkit-scrollbar-thumb {
|
||||
background-color: var(--color-secondarylighter);
|
||||
}
|
||||
|
||||
.scroll-container::-webkit-scrollbar-track {
|
||||
background-color: var(--color-backgroundlighter);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue