mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-03 21:19:06 +00:00
videos list implemented
This commit is contained in:
parent
f863b5a0b9
commit
8fd7d8e60c
3 changed files with 174 additions and 0 deletions
86
src/routes/Detail/VideosList/VideosList.js
Normal file
86
src/routes/Detail/VideosList/VideosList.js
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import Icon from 'stremio-icons/dom';
|
||||||
|
import Video from './Video';
|
||||||
|
import styles from './styles';
|
||||||
|
|
||||||
|
class VideosList extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.seasons = this.props.videos.map((video) => video.season)
|
||||||
|
.filter((season, index, seasons) => seasons.indexOf(season) === index);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
selectedSeason: this.seasons[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeSeason = (event) => {
|
||||||
|
this.setState({ selectedSeason: parseInt(event.target.value) });
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
return nextState.selectedSeason !== this.state.selectedSeason;
|
||||||
|
}
|
||||||
|
|
||||||
|
onPrevButtonClicked = () => {
|
||||||
|
const prevSeasonIndex = Math.max(this.seasons.indexOf(this.state.selectedSeason) - 1, 0);
|
||||||
|
this.setState({ selectedSeason: this.seasons[prevSeasonIndex] });
|
||||||
|
}
|
||||||
|
|
||||||
|
onNextButtonClicked = () => {
|
||||||
|
const nextSeasonIndex = Math.min(this.seasons.indexOf(this.state.selectedSeason) + 1, this.seasons.length - 1);
|
||||||
|
this.setState({ selectedSeason: this.seasons[nextSeasonIndex] });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={styles['videos-list-container']}>
|
||||||
|
<div className={styles['seasons-bar']}>
|
||||||
|
<div className={styles['button-container']} onClick={this.onPrevButtonClicked}>
|
||||||
|
<Icon className={styles['button-icon']} icon={'ic_arrow_left'} />
|
||||||
|
</div>
|
||||||
|
<select value={this.state.selectedSeason} onChange={this.changeSeason}>
|
||||||
|
{this.seasons.map((season) =>
|
||||||
|
<option key={season} value={season}>
|
||||||
|
{season}
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
</select>
|
||||||
|
<div className={styles['button-container']} onClick={this.onNextButtonClicked} >
|
||||||
|
<Icon className={styles['button-icon']} icon={'ic_arrow_left'} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles['scroll-container']}>
|
||||||
|
<div className={classnames(styles['videos-list'])}>
|
||||||
|
{this.props.videos
|
||||||
|
.filter((video) => video.season === this.state.selectedSeason)
|
||||||
|
.map((video) =>
|
||||||
|
<Video key={video.id}
|
||||||
|
className={styles['video']}
|
||||||
|
poster={video.poster}
|
||||||
|
episode={video.episode}
|
||||||
|
title={video.name}
|
||||||
|
released={video.released}
|
||||||
|
isWatched={video.isWatched}
|
||||||
|
isUpcoming={video.isUpcoming}
|
||||||
|
progress={video.progress}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VideosList.propTypes = {
|
||||||
|
videos: PropTypes.arrayOf(PropTypes.object).isRequired
|
||||||
|
};
|
||||||
|
VideosList.defaultProps = {
|
||||||
|
videos: []
|
||||||
|
};
|
||||||
|
|
||||||
|
export default VideosList;
|
||||||
3
src/routes/Detail/VideosList/index.js
Normal file
3
src/routes/Detail/VideosList/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import VideosList from './VideosList';
|
||||||
|
|
||||||
|
export default VideosList;
|
||||||
85
src/routes/Detail/VideosList/styles.less
Normal file
85
src/routes/Detail/VideosList/styles.less
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
@import 'stremio-colors';
|
||||||
|
|
||||||
|
@scroll-container-width: 392px;
|
||||||
|
@seasons-bar-height: 50px;
|
||||||
|
@spacing: 8px;
|
||||||
|
|
||||||
|
.videos-list-container {
|
||||||
|
.seasons-bar {
|
||||||
|
height: @seasons-bar-height;
|
||||||
|
margin-bottom: @spacing;
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
width: (@seasons-bar-height * 1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container {
|
||||||
|
width: @scroll-container-width;
|
||||||
|
margin: 0 @spacing;
|
||||||
|
|
||||||
|
.videos-list {
|
||||||
|
padding: 0 (2 * @spacing);
|
||||||
|
|
||||||
|
>:not(:first-child) {
|
||||||
|
margin-top: @spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container::-webkit-scrollbar {
|
||||||
|
width: @spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.videos-list-container {
|
||||||
|
height: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: @colordarkest;
|
||||||
|
|
||||||
|
.seasons-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.button-icon {
|
||||||
|
width: 60%;
|
||||||
|
height: 60%;
|
||||||
|
fill: @colorwhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: @colorwhite20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
.videos-list {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container::-webkit-scrollbar-thumb {
|
||||||
|
background-color: @coloraccent80;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container::-webkit-scrollbar-track {
|
||||||
|
background-color: @colorglass;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue