mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
detail page adapted to css modules
This commit is contained in:
parent
56bf9daf38
commit
1a7bea2e42
9 changed files with 132 additions and 131 deletions
|
|
@ -5,51 +5,41 @@ const VideosList = require('./VideosList');
|
|||
const StreamsList = require('./StreamsList');
|
||||
const useMetaItem = require('./useMetaItem');
|
||||
const useInLibrary = require('./useInLibrary');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const Detail = ({ urlParams }) => {
|
||||
const metaItem = useMetaItem(urlParams.type, urlParams.id, urlParams.videoId);
|
||||
const [inLibrary, addToLibrary, removeFromLibrary, toggleInLibrary] = useInLibrary(urlParams.id);
|
||||
return (
|
||||
<div className={'detail-container'}>
|
||||
<div className={styles['detail-container']}>
|
||||
<NavBar
|
||||
className={'nav-bar'}
|
||||
className={styles['nav-bar']}
|
||||
backButton={true}
|
||||
title={metaItem !== null ? metaItem.name : null}
|
||||
/>
|
||||
<div className={'detail-content'}>
|
||||
<div className={'background-image-layer'}>
|
||||
<img
|
||||
className={'background-image'}
|
||||
src={metaItem !== null ? metaItem.background : null}
|
||||
alt={' '}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['detail-content']}>
|
||||
{
|
||||
metaItem !== null ?
|
||||
<MetaPreview
|
||||
{...metaItem}
|
||||
className={'meta-preview'}
|
||||
background={null}
|
||||
inLibrary={inLibrary}
|
||||
toggleInLibrary={toggleInLibrary}
|
||||
/>
|
||||
<React.Fragment>
|
||||
<div className={styles['background-image-layer']}>
|
||||
<img className={styles['background-image']} src={metaItem.background} alt={' '} />
|
||||
</div>
|
||||
<MetaPreview
|
||||
{...metaItem}
|
||||
className={styles['meta-preview']}
|
||||
background={null}
|
||||
inLibrary={inLibrary}
|
||||
toggleInLibrary={toggleInLibrary}
|
||||
/>
|
||||
</React.Fragment>
|
||||
:
|
||||
<MetaPreviewPlaceholder
|
||||
className={classnames('meta-preview', placeholderStyles['placeholder-container'])}
|
||||
/>
|
||||
<MetaPreviewPlaceholder className={classnames(styles['meta-preview'], placeholderStyles['placeholder-container'])} />
|
||||
}
|
||||
{
|
||||
typeof urlParams.videoId === 'string' && urlParams.videoId.length > 0 ?
|
||||
<StreamsList
|
||||
className={'streams-list'}
|
||||
metaItem={metaItem}
|
||||
/>
|
||||
<StreamsList className={styles['streams-list']} metaItem={metaItem} />
|
||||
:
|
||||
<VideosList
|
||||
className={'videos-list'}
|
||||
metaItem={metaItem}
|
||||
/>
|
||||
<VideosList className={styles['videos-list']} metaItem={metaItem} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,26 +3,31 @@ const PropTypes = require('prop-types');
|
|||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const { Button } = require('stremio/common');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const Stream = ({ className, id, addon, description, progress, onClick }) => {
|
||||
return (
|
||||
<Button className={classnames(className, 'stream-container')} title={typeof description === 'string' && description.length > 0 ? description : id} data-id={id} onClick={onClick}>
|
||||
<div className={'addon-container'}>
|
||||
<div className={'addon-name'}>{addon}</div>
|
||||
</div>
|
||||
<div className={'info-container'}>
|
||||
<div className={'description-label'}>
|
||||
<Button className={classnames(className, styles['stream-container'])} title={typeof description === 'string' && description.length > 0 ? description : id} data-id={id} onClick={onClick}>
|
||||
{
|
||||
typeof addon === 'string' && addon.length > 0 ?
|
||||
<div className={styles['addon-container']}>
|
||||
<div className={styles['addon-name']}>{addon}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
<div className={styles['info-container']}>
|
||||
<div className={styles['description-label']}>
|
||||
{typeof description === 'string' && description.length > 0 ? description : id}
|
||||
</div>
|
||||
</div>
|
||||
<div className={'play-icon-container'}>
|
||||
<Icon className={'play-icon'} icon={'ic_play'} />
|
||||
<div className={styles['play-icon-container']}>
|
||||
<Icon className={styles['play-icon']} icon={'ic_play'} />
|
||||
</div>
|
||||
{
|
||||
progress !== null && !isNaN(progress) && progress > 0 ?
|
||||
<div className={'progress-bar-container'}>
|
||||
<div className={'progress-bar'} style={{ width: `${Math.min(progress, 1) * 100}%` }} />
|
||||
<div className={styles['progress-bar-container']}>
|
||||
<div className={styles['progress-bar']} style={{ width: `${Math.min(progress, 1) * 100}%` }} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
|
|
@ -33,8 +38,8 @@ const Stream = ({ className, id, addon, description, progress, onClick }) => {
|
|||
|
||||
Stream.propTypes = {
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string.isRequired,
|
||||
addon: PropTypes.string.isRequired,
|
||||
id: PropTypes.string,
|
||||
addon: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
progress: PropTypes.number,
|
||||
onClick: PropTypes.func
|
||||
|
|
|
|||
|
|
@ -2,20 +2,20 @@ const React = require('react');
|
|||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const StreamPlaceholder = ({ className }) => {
|
||||
return (
|
||||
<div className={classnames(className, 'stream-placeholder-container')}>
|
||||
<div className={'addon-container'}>
|
||||
<div className={'addon-name'} />
|
||||
<div className={classnames(className, styles['stream-placeholder-container'])}>
|
||||
<div className={styles['addon-container']}>
|
||||
<div className={styles['addon-name']} />
|
||||
</div>
|
||||
<div className={'info-container'}>
|
||||
<div className={'description-container'} />
|
||||
<div className={'description-container'} />
|
||||
<div className={styles['info-container']}>
|
||||
<div className={styles['description-container']} />
|
||||
<div className={styles['description-container']} />
|
||||
</div>
|
||||
<div className={'play-icon-container'}>
|
||||
<Icon className={'play-icon'} icon={'ic_play'} />
|
||||
<div className={styles['play-icon-container']}>
|
||||
<Icon className={styles['play-icon']} icon={'ic_play'} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,36 +6,32 @@ const { Button, placeholderStyles } = require('stremio/common');
|
|||
const Stream = require('./Stream');
|
||||
const StreamPlaceholder = require('./StreamPlaceholder');
|
||||
const useStreams = require('./useStreams');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const StreamsList = ({ className, metaItem }) => {
|
||||
const streams = useStreams(metaItem);
|
||||
return (
|
||||
<div className={classnames(className, 'streams-list-container')}>
|
||||
<div className={classnames('streams-scroll-container', { [placeholderStyles['placeholder-container']]: streams.length === 0 })}>
|
||||
<div className={classnames(className, styles['streams-list-container'])}>
|
||||
<div className={classnames(styles['streams-scroll-container'], { [placeholderStyles['placeholder-container']]: streams.length === 0 })}>
|
||||
{
|
||||
streams.length > 0 ?
|
||||
streams.map((stream) => (
|
||||
<Stream
|
||||
{...stream}
|
||||
key={stream.id}
|
||||
className={'stream'}
|
||||
/>
|
||||
<Stream {...stream} key={stream.id} className={styles['stream']} />
|
||||
))
|
||||
:
|
||||
<React.Fragment>
|
||||
<StreamPlaceholder className={'stream'} />
|
||||
<StreamPlaceholder className={'stream'} />
|
||||
<StreamPlaceholder className={'stream'} />
|
||||
<StreamPlaceholder className={'stream'} />
|
||||
<StreamPlaceholder className={'stream'} />
|
||||
<StreamPlaceholder className={'stream'} />
|
||||
<StreamPlaceholder className={styles['stream']} />
|
||||
<StreamPlaceholder className={styles['stream']} />
|
||||
<StreamPlaceholder className={styles['stream']} />
|
||||
<StreamPlaceholder className={styles['stream']} />
|
||||
<StreamPlaceholder className={styles['stream']} />
|
||||
<StreamPlaceholder className={styles['stream']} />
|
||||
</React.Fragment>
|
||||
}
|
||||
</div>
|
||||
<Button className={'install-addons-container'} title={'Install addons'} href={'#/addons'}>
|
||||
<Icon className={'icon'} icon={'ic_addons'} />
|
||||
<div className={'label'}>Install addons</div>
|
||||
<Button className={styles['install-addons-container']} title={'Install addons'} href={'#/addons'}>
|
||||
<Icon className={styles['icon']} icon={'ic_addons'} />
|
||||
<div className={styles['label']}>Install addons</div>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,22 +3,22 @@ const PropTypes = require('prop-types');
|
|||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
const { Button, Popup, useBinaryState } = require('stremio/common');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const SeasonsBar = ({ className, season, seasons, onSeasonChange }) => {
|
||||
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
|
||||
const setPrevSeason = React.useCallback(() => {
|
||||
if (Array.isArray(seasons)) {
|
||||
if (Array.isArray(seasons) && typeof onSeasonChange === 'function') {
|
||||
const seasonIndex = seasons.indexOf(season);
|
||||
if (seasonIndex > 0 && typeof onSeasonChange === 'function') {
|
||||
if (seasonIndex > 0) {
|
||||
onSeasonChange(seasons[seasonIndex - 1]);
|
||||
}
|
||||
}
|
||||
}, [season, seasons, onSeasonChange]);
|
||||
const setNextSeason = React.useCallback(() => {
|
||||
if (Array.isArray(seasons)) {
|
||||
if (Array.isArray(seasons) && typeof onSeasonChange === 'function') {
|
||||
const seasonIndex = seasons.indexOf(season);
|
||||
if (seasonIndex < seasons.length - 1 && typeof onSeasonChange === 'function') {
|
||||
if (seasonIndex < seasons.length - 1) {
|
||||
onSeasonChange(seasons[seasonIndex + 1]);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,28 +31,38 @@ const SeasonsBar = ({ className, season, seasons, onSeasonChange }) => {
|
|||
}
|
||||
}, [onSeasonChange]);
|
||||
return (
|
||||
<div className={classnames(className, 'seasons-bar-container')}>
|
||||
<Button className={'prev-season-button'} onClick={setPrevSeason}>
|
||||
<Icon className={'icon'} icon={'ic_arrow_left'} />
|
||||
<div className={classnames(className, styles['seasons-bar-container'])}>
|
||||
<Button className={styles['prev-season-button']} onClick={setPrevSeason}>
|
||||
<Icon className={styles['icon']} icon={'ic_arrow_left'} />
|
||||
</Button>
|
||||
<Popup
|
||||
open={menuOpen}
|
||||
menuMatchLabelWidth={true}
|
||||
onCloseRequest={closeMenu}
|
||||
renderLabel={(ref) => (
|
||||
<Button ref={ref} className={classnames('seasons-popup-label-container', { 'active': menuOpen })} title={`Season ${season}`} onClick={toggleMenu}>
|
||||
<div className={'season-label'}>Season</div>
|
||||
<div className={'number-label'}>{season}</div>
|
||||
<Button ref={ref} className={classnames(styles['seasons-popup-label-container'], { 'active': menuOpen })} title={season !== null && !isNaN(season) ? `Season ${season}` : 'Season'} onClick={toggleMenu}>
|
||||
<div className={styles['season-label']}>Season</div>
|
||||
{
|
||||
season !== null && !isNaN(season) ?
|
||||
<div className={styles['number-label']}>{season}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Button>
|
||||
)}
|
||||
renderMenu={() => (
|
||||
<div className={'seasons-menu-container'}>
|
||||
<div className={styles['seasons-menu-container']}>
|
||||
{
|
||||
Array.isArray(seasons) ?
|
||||
seasons.map((season) => (
|
||||
<Button key={season} className={'season-option-container'} data-season={season} title={`Season ${season}`} onClick={seasonOnClick}>
|
||||
<div className={'season-label'}>Season</div>
|
||||
<div className={'number-label'}>{season}</div>
|
||||
<Button key={season} className={styles['season-option-container']} data-season={season} title={season !== null && !isNaN(season) ? `Season ${season}` : 'Season'} onClick={seasonOnClick}>
|
||||
<div className={styles['season-label']}>Season</div>
|
||||
{
|
||||
season !== null && !isNaN(season) ?
|
||||
<div className={styles['number-label']}>{season}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</Button>
|
||||
))
|
||||
:
|
||||
|
|
@ -61,8 +71,8 @@ const SeasonsBar = ({ className, season, seasons, onSeasonChange }) => {
|
|||
</div>
|
||||
)}
|
||||
/>
|
||||
<Button className={'next-season-button'} onClick={setNextSeason}>
|
||||
<Icon className={'icon'} icon={'ic_arrow_right'} />
|
||||
<Button className={styles['next-season-button']} onClick={setNextSeason}>
|
||||
<Icon className={styles['icon']} icon={'ic_arrow_right'} />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,19 +2,19 @@ const React = require('react');
|
|||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const SeasonsBarPlaceholder = ({ className }) => {
|
||||
return (
|
||||
<div className={classnames(className, 'seasons-bar-placeholder-container')}>
|
||||
<div className={'prev-season-button'}>
|
||||
<Icon className={'icon'} icon={'ic_arrow_left'} />
|
||||
<div className={classnames(className, styles['seasons-bar-placeholder-container'])}>
|
||||
<div className={styles['prev-season-button']}>
|
||||
<Icon className={styles['icon']} icon={'ic_arrow_left'} />
|
||||
</div>
|
||||
<div className={'seasons-popup-label-container'}>
|
||||
<div className={'seasons-popup-label'} />
|
||||
<div className={styles['seasons-popup-label-container']}>
|
||||
<div className={styles['seasons-popup-label']} />
|
||||
</div>
|
||||
<div className={'next-season-button'}>
|
||||
<Icon className={'icon'} icon={'ic_arrow_right'} />
|
||||
<div className={styles['next-season-button']}>
|
||||
<Icon className={styles['icon']} icon={'ic_arrow_right'} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,27 +3,27 @@ const PropTypes = require('prop-types');
|
|||
const classnames = require('classnames');
|
||||
const { Button } = require('stremio/common');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const Video = ({ className, id, name, poster, episode, released, watched, upcoming, progress, onClick }) => {
|
||||
return (
|
||||
<Button className={classnames(className, 'video-container')} title={typeof name === 'string' && name.length > 0 ? name : id} data-id={id} onClick={onClick}>
|
||||
<Button className={classnames(className, styles['video-container'])} title={typeof name === 'string' && name.length > 0 ? name : id} data-id={id} onClick={onClick}>
|
||||
{
|
||||
typeof poster === 'string' && poster.length > 0 ?
|
||||
<div className={'poster-container'}>
|
||||
<img className={'poster'} src={poster} alt={' '} />
|
||||
<div className={styles['poster-container']}>
|
||||
<img className={styles['poster']} src={poster} alt={' '} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
<div className={'info-container'}>
|
||||
<div className={'name-container'}>
|
||||
<div className={styles['info-container']}>
|
||||
<div className={styles['name-container']}>
|
||||
{episode !== null && !isNaN(episode) ? `${episode}. ` : null}
|
||||
{typeof name === 'string' && name.length > 0 ? name : id}
|
||||
</div>
|
||||
{
|
||||
released instanceof Date && !isNaN(released.getFullYear()) ?
|
||||
<div className={'released-container'}>
|
||||
released instanceof Date && !isNaN(released.getTime()) ?
|
||||
<div className={styles['released-container']}>
|
||||
{released.toLocaleString(undefined, { year: '2-digit', month: 'short', day: 'numeric' })}
|
||||
</div>
|
||||
:
|
||||
|
|
@ -31,28 +31,28 @@ const Video = ({ className, id, name, poster, episode, released, watched, upcomi
|
|||
}
|
||||
{
|
||||
upcoming ?
|
||||
<div className={'upcoming-container'}>
|
||||
<div className={'flag-label'}>Upcoming</div>
|
||||
<div className={styles['upcoming-container']}>
|
||||
<div className={styles['flag-label']}>Upcoming</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
watched ?
|
||||
<div className={'watched-container'}>
|
||||
<div className={'flag-label'}>Watched</div>
|
||||
<div className={styles['watched-container']}>
|
||||
<div className={styles['flag-label']}>Watched</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
<div className={'next-icon-container'}>
|
||||
<Icon className={'next-icon'} icon={'ic_arrow_thin_right'} />
|
||||
<div className={styles['next-icon-container']}>
|
||||
<Icon className={styles['next-icon']} icon={'ic_arrow_thin_right'} />
|
||||
</div>
|
||||
{
|
||||
progress !== null && !isNaN(progress) && progress > 0 ?
|
||||
<div className={'progress-bar-container'}>
|
||||
<div className={'progress-bar'} style={{ width: `${Math.min(progress, 1) * 100}%` }} />
|
||||
<div className={styles['progress-bar-container']}>
|
||||
<div className={styles['progress-bar']} style={{ width: `${Math.min(progress, 1) * 100}%` }} />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
|
|
|
|||
|
|
@ -2,17 +2,17 @@ const React = require('react');
|
|||
const PropTypes = require('prop-types');
|
||||
const classnames = require('classnames');
|
||||
const Icon = require('stremio-icons/dom');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const VideoPlaceholder = ({ className }) => {
|
||||
return (
|
||||
<div className={classnames(className, 'video-placeholder-container')}>
|
||||
<div className={'info-container'}>
|
||||
<div className={'name-container'} />
|
||||
<div className={'released-container'} />
|
||||
<div className={classnames(className, styles['video-placeholder-container'])}>
|
||||
<div className={styles['info-container']}>
|
||||
<div className={styles['name-container']} />
|
||||
<div className={styles['released-container']} />
|
||||
</div>
|
||||
<div className={'next-icon-container'}>
|
||||
<Icon className={'next-icon'} icon={'ic_arrow_thin_right'} />
|
||||
<div className={styles['next-icon-container']}>
|
||||
<Icon className={styles['next-icon']} icon={'ic_arrow_thin_right'} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@ const SeasonsBarPlaceholder = require('./SeasonsBarPlaceholder');
|
|||
const Video = require('./Video');
|
||||
const VideoPlaceholder = require('./VideoPlaceholder');
|
||||
const useSeasons = require('./useSeasons');
|
||||
require('./styles');
|
||||
const styles = require('./styles');
|
||||
|
||||
const VideosList = ({ className, metaItem }) => {
|
||||
const [season, seasons, setSeason] = useSeasons(metaItem);
|
||||
return (
|
||||
<div className={classnames(className, 'videos-list-container', { [placeholderStyles['placeholder-container']]: metaItem === null })}>
|
||||
<div className={classnames(className, styles['videos-list-container'], { [placeholderStyles['placeholder-container']]: metaItem === null })}>
|
||||
{
|
||||
metaItem !== null ?
|
||||
<React.Fragment>
|
||||
{
|
||||
seasons.length > 1 ?
|
||||
<SeasonsBar
|
||||
className={'seasons-bar'}
|
||||
className={styles['seasons-bar']}
|
||||
season={season}
|
||||
seasons={seasons}
|
||||
onSeasonChange={setSeason}
|
||||
|
|
@ -27,7 +27,7 @@ const VideosList = ({ className, metaItem }) => {
|
|||
:
|
||||
null
|
||||
}
|
||||
<div className={'videos-scroll-container'}>
|
||||
<div className={styles['videos-scroll-container']}>
|
||||
{
|
||||
metaItem.videos
|
||||
.filter((video) => isNaN(season) || video.season === season)
|
||||
|
|
@ -35,7 +35,7 @@ const VideosList = ({ className, metaItem }) => {
|
|||
<Video
|
||||
{...video}
|
||||
key={video.id}
|
||||
className={'video'}
|
||||
className={styles['video']}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
|
@ -43,16 +43,16 @@ const VideosList = ({ className, metaItem }) => {
|
|||
</React.Fragment>
|
||||
:
|
||||
<React.Fragment>
|
||||
<SeasonsBarPlaceholder className={'seasons-bar'} />
|
||||
<div className={'videos-scroll-container'}>
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<VideoPlaceholder className={'video'} />
|
||||
<SeasonsBarPlaceholder className={styles['seasons-bar']} />
|
||||
<div className={styles['videos-scroll-container']}>
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
<VideoPlaceholder className={styles['video']} />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue