mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-08-14 01:15:18 +00:00
new design of stream and video
This commit is contained in:
parent
6cc4e3c258
commit
bfade83684
5 changed files with 233 additions and 249 deletions
|
|
@ -26,26 +26,7 @@ const renderTitle = (title) => {
|
|||
);
|
||||
}
|
||||
|
||||
const getClassName = (isFree, isSubscription, title, subtitle) => {
|
||||
if (isFree) return 'free-subtitle';
|
||||
if (title.length > 0 && subtitle.length === 0 && !isSubscription) return 'with-title';
|
||||
if (title.length === 0 && subtitle.length > 0) return 'with-subtitle';
|
||||
return 'text-container';
|
||||
}
|
||||
|
||||
const renderSubtitle = (isFree, isSubscription, subtitle) => {
|
||||
if (isFree) {
|
||||
return (
|
||||
<span className={styles['free-label']}>FREE</span>
|
||||
);
|
||||
}
|
||||
|
||||
if (isSubscription) {
|
||||
return (
|
||||
<span className={styles['subscription-label']}>SUBSCRIPTION</span>
|
||||
);
|
||||
}
|
||||
|
||||
const renderSubtitle = (subtitle) => {
|
||||
if (subtitle) {
|
||||
return (
|
||||
<div className={styles['subtitle']}>{subtitle}</div>
|
||||
|
|
@ -68,16 +49,18 @@ const renderProgress = (progress) => {
|
|||
|
||||
const Stream = (props) => {
|
||||
return (
|
||||
<div onClick={props.play} style={{ backgroundColor: props.progress ? colors.black40 : null }} className={styles['stream']}>
|
||||
{renderLogo(props.logo, props.sourceName)}
|
||||
<div className={styles[getClassName(props.isFree, props.isSubscription, props.title, props.subtitle)]}>
|
||||
{renderTitle(props.title)}
|
||||
{renderSubtitle(props.isFree, props.isSubscription, props.subtitle)}
|
||||
<div onClick={props.play} style={{ backgroundColor: props.progress ? colors.black40 : null }} className={styles['stream-container']}>
|
||||
<div className={styles['stream']}>
|
||||
{renderLogo(props.logo, props.sourceName)}
|
||||
<div className={styles['text-container']}>
|
||||
{renderTitle(props.title)}
|
||||
{renderSubtitle(props.subtitle)}
|
||||
</div>
|
||||
<div className={styles['play-container']}>
|
||||
<Icon style={{ width: props.progress ? '65%' : null, height: props.progress ? '65%' : null, fill: props.progress ? colors.white : null }} className={styles['play']} icon={'ic_play'} />
|
||||
</div>
|
||||
</div>
|
||||
{renderProgress(props.progress)}
|
||||
<div style={{ backgroundColor: props.progress ? colors.white : null }} className={styles['play-container']}>
|
||||
<Icon style={{ fill: props.progress ? colors.medium : null }} className={styles['play']} icon={'ic_play'} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -87,8 +70,6 @@ Stream.propTypes = {
|
|||
sourceName: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
subtitle: PropTypes.string.isRequired,
|
||||
isFree: PropTypes.bool.isRequired,
|
||||
isSubscription: PropTypes.bool.isRequired,
|
||||
progress: PropTypes.number.isRequired,
|
||||
play: PropTypes.func
|
||||
};
|
||||
|
|
@ -98,8 +79,6 @@ Stream.defaultProps = {
|
|||
sourceName: '',
|
||||
title: '',
|
||||
subtitle: '',
|
||||
isFree: false,
|
||||
isSubscription: false,
|
||||
progress: 0
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,110 +1,102 @@
|
|||
@import 'stremio-colors';
|
||||
.stream {
|
||||
width: 340px;
|
||||
display: grid;
|
||||
font-size: 11px;
|
||||
padding: 7px 20px;
|
||||
color: @colorwhite;
|
||||
align-items: center;
|
||||
|
||||
@stream-width: 340px;
|
||||
@play-width: ceil((@stream-width * 0.13));
|
||||
@progress-height: 3px;
|
||||
|
||||
.stream-container {
|
||||
width: @stream-width;
|
||||
|
||||
.stream {
|
||||
min-height: round((@stream-width * 0.2));
|
||||
|
||||
.source-name {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
line-height: 15px;
|
||||
|
||||
.title {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.play-container {
|
||||
height: @play-width;
|
||||
width: @play-width;
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: @progress-height;
|
||||
}
|
||||
}
|
||||
|
||||
.stream-container {
|
||||
margin: 10px; //remove
|
||||
background-color: @colorblack20;
|
||||
grid-template-columns: 74px 36px 120px 24px 46px;
|
||||
grid-template-rows: 40px 3px 3px;
|
||||
grid-template-areas:
|
||||
"logo . text . play"
|
||||
"progress progress progress . play"
|
||||
". . . . play";
|
||||
.logo {
|
||||
grid-area: logo;
|
||||
width: 74px;
|
||||
fill: @colorwhite;
|
||||
}
|
||||
.source-name {
|
||||
grid-area: logo;
|
||||
font-size: 13px;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.free-subtitle, .with-title, .with-subtitle, .text-container {
|
||||
grid-area: text;
|
||||
display: grid;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
grid-area: title;
|
||||
|
||||
.stream {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
.logo {
|
||||
width: 20%;
|
||||
fill: @colorwhite;
|
||||
}
|
||||
|
||||
.source-name {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 20%;
|
||||
color: @colorwhite;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
text-overflow: ellipsis;
|
||||
&:hover {
|
||||
margin-left: -180%;
|
||||
text-overflow: initial;
|
||||
transition: margin-left 3s linear;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
width: 45%;
|
||||
padding: 2% 0%;
|
||||
|
||||
.title {
|
||||
color: @colorwhite;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: @colorwhite;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
.subtitle, .subscription-label {
|
||||
grid-area: subtitle;
|
||||
}
|
||||
.free-label, .subscription-label {
|
||||
font-weight: 600;
|
||||
}
|
||||
.free-label {
|
||||
grid-area: free;
|
||||
padding: 0px 6px;
|
||||
border-radius: 2px;
|
||||
background-color: @colorprimlight;
|
||||
}
|
||||
.subscription-label {
|
||||
color: @colorsignal1;
|
||||
|
||||
.play-container {
|
||||
display: flex;
|
||||
|
||||
.play {
|
||||
width: 38%;
|
||||
height: 38%;
|
||||
margin: auto;
|
||||
fill: @colorwhite60;
|
||||
}
|
||||
}
|
||||
}
|
||||
.free-subtitle {
|
||||
grid-template-columns: 38px 82px;
|
||||
grid-template-rows: 18px 17px 1px;
|
||||
grid-template-areas:
|
||||
"title title"
|
||||
"free ."
|
||||
". .";
|
||||
}
|
||||
.with-title {
|
||||
grid-template-columns: 120px;
|
||||
grid-template-rows: 18px;
|
||||
grid-template-areas:
|
||||
"title";
|
||||
}
|
||||
.with-subtitle {
|
||||
grid-template-columns: 120px;
|
||||
grid-template-rows: 18px;
|
||||
grid-template-areas:
|
||||
"subtitle";
|
||||
}
|
||||
.text-container {
|
||||
grid-template-columns: 120px;
|
||||
grid-template-rows: 18px 18px;
|
||||
grid-template-areas:
|
||||
"title"
|
||||
"subtitle";
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
grid-area: progress;
|
||||
background-color: @colorneutral;
|
||||
|
||||
.progress {
|
||||
height: 3px;
|
||||
border-radius: 1px;
|
||||
height: @progress-height;
|
||||
background-color: @colorprimlight;
|
||||
}
|
||||
}
|
||||
.play-container {
|
||||
grid-area: play;
|
||||
height: 46px;
|
||||
display: flex;
|
||||
border-radius: 50%;
|
||||
.play {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: auto;
|
||||
margin-left: 16px;
|
||||
fill: @colorwhite60;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: @colorwhite20;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { dataUrl as iconDataUrl } from 'stremio-icons/dom';
|
||||
import Icon, { dataUrl as iconDataUrl } from 'stremio-icons/dom';
|
||||
import colors from 'stremio-colors';
|
||||
import styles from './styles';
|
||||
|
||||
|
|
@ -9,7 +9,8 @@ const renderPoster = (poster) => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const placeholderIconUrl = iconDataUrl({ icon: 'ic_channels', fill: colors.accent, width: 40, height: 36 });
|
||||
const videoWidth = 340;
|
||||
const placeholderIconUrl = iconDataUrl({ icon: 'ic_channels', fill: colors.accent, width: '20%', height: videoWidth * 0.13 });
|
||||
const imageStyle = {
|
||||
backgroundImage: `url('${poster}'), url('${placeholderIconUrl}')`
|
||||
};
|
||||
|
|
@ -19,33 +20,13 @@ const renderPoster = (poster) => {
|
|||
);
|
||||
}
|
||||
|
||||
const renderNumber = (number) => {
|
||||
if (number <= 0) {
|
||||
const renderTitle = (number, title) => {
|
||||
if (title.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={styles['number']}>{number + '.'}</span>
|
||||
);
|
||||
}
|
||||
|
||||
const renderName = (name) => {
|
||||
if (name.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={styles['name']}>{name}</span>
|
||||
);
|
||||
}
|
||||
|
||||
const renderDuration = (duration) => {
|
||||
if (duration <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={styles['duration']}>{duration + ' min'}</span>
|
||||
<div className={styles['title']}>{number + '.' + ' ' + title}</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -57,19 +38,27 @@ const renderReleasedDate = (released) => {
|
|||
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
|
||||
return (
|
||||
<span className={styles['released-date']}>{released.getDate() + ' ' + months[released.getMonth()]}</span>
|
||||
<div className={styles['released-date']}>{released.getDate() + ' ' + months[released.getMonth()]}</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderLabel = (isWatched, isUpcoming) => {
|
||||
if (!isWatched && !isUpcoming) {
|
||||
const renderUpcomingLabel = (isUpcoming) => {
|
||||
if(!isUpcoming) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['label-container']}>
|
||||
<span className={styles[isWatched ? 'watched-label' : 'upcoming-label']}>{isWatched ? 'WATCHED' : 'UPCOMING'}</span>
|
||||
</div>
|
||||
<div className={styles['upcoming-label']}>UPCOMING</div>
|
||||
);
|
||||
}
|
||||
|
||||
const renderWatchedLabel = (isWatched) => {
|
||||
if(!isWatched) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles['watched-label']}>WATCHED</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -85,22 +74,23 @@ const renderProgress = (progress) => {
|
|||
);
|
||||
}
|
||||
|
||||
const getClassName = (poster, progress) => {
|
||||
if (poster.length > 0 && !progress) return 'with-poster';
|
||||
if (progress && poster.length === 0) return 'with-progress';
|
||||
if (poster.length > 0 && progress) return 'with-poster-progress';
|
||||
return 'video';
|
||||
}
|
||||
|
||||
const Video = (props) => {
|
||||
return (
|
||||
<div onClick={props.onVideoClicked} style={{ padding: props.poster.length > 0 ? '10px 10px' : '10px 16px' }} className={styles[getClassName(props.poster, props.progress)]}>
|
||||
{renderPoster(props.poster)}
|
||||
{renderNumber(props.number)}
|
||||
{renderName(props.name)}
|
||||
{renderDuration(props.duration)}
|
||||
{renderReleasedDate(props.released)}
|
||||
{renderLabel(props.isWatched, props.isUpcoming)}
|
||||
<div onClick={props.onVideoClicked} style={{ backgroundColor: props.progress ? colors.black40 : null }} className={styles['video-container']}>
|
||||
<div className={styles['video']}>
|
||||
{renderPoster(props.poster)}
|
||||
<div style={{width: props.poster ? '50%' : '77%' }} className={styles['text-container']}>
|
||||
{renderTitle(props.number, props.title)}
|
||||
{renderReleasedDate(props.released)}
|
||||
<div className={styles['label-container']}>
|
||||
{renderUpcomingLabel(props.isUpcoming)}
|
||||
{renderWatchedLabel(props.isWatched)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles['play-container']}>
|
||||
<Icon style={{ width: props.progress ? '65%' : null, height: props.progress ? '65%' : null, fill: props.progress ? colors.white : null }} className={styles['play']} icon={'ic_arrow_left'} />
|
||||
</div>
|
||||
</div>
|
||||
{renderProgress(props.progress)}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -109,8 +99,7 @@ const Video = (props) => {
|
|||
Video.propTypes = {
|
||||
poster: PropTypes.string.isRequired,
|
||||
number: PropTypes.number.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
duration: PropTypes.number.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
released: PropTypes.instanceOf(Date).isRequired,
|
||||
isWatched: PropTypes.bool.isRequired,
|
||||
isUpcoming: PropTypes.bool.isRequired,
|
||||
|
|
@ -120,8 +109,7 @@ Video.propTypes = {
|
|||
Video.defaultProps = {
|
||||
poster: '',
|
||||
number: 0,
|
||||
name: '',
|
||||
duration: 0,
|
||||
title: '',
|
||||
released: new Date(''), //Invalid Date
|
||||
isWatched: false,
|
||||
isUpcoming: false,
|
||||
|
|
|
|||
|
|
@ -1,89 +1,114 @@
|
|||
@import 'stremio-colors';
|
||||
.with-poster, .with-progress, .with-poster-progress, .video {
|
||||
width: 340px;
|
||||
display: grid;
|
||||
font-size: 12px;
|
||||
color: @colorwhite;
|
||||
background-color: @colorblack20;
|
||||
.poster {
|
||||
grid-area: poster;
|
||||
background-position: center;
|
||||
background-size: cover, auto;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.number {
|
||||
grid-area: number;
|
||||
}
|
||||
.name {
|
||||
grid-area: name;
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.duration, .released-date {
|
||||
grid-area: time;
|
||||
font-size: 11px;
|
||||
color: @colorwhite60;
|
||||
}
|
||||
.label-container {
|
||||
grid-area: label;
|
||||
|
||||
@video-width: 340px;
|
||||
@play-width: ceil((@video-width * 0.13));
|
||||
@progress-height: 3px;
|
||||
|
||||
.video-container {
|
||||
width: @video-width;
|
||||
|
||||
.video {
|
||||
min-height: round((@video-width * 0.2));
|
||||
|
||||
.poster {
|
||||
height: round((@video-width * 0.14));
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.released-date {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.watched-label, .upcoming-label {
|
||||
grid-area: label;
|
||||
font-weight: 600;
|
||||
font-size: 10px;
|
||||
padding: 1px 6px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.watched-label {
|
||||
background-color: @colorprimlight;
|
||||
}
|
||||
.upcoming-label {
|
||||
background-color: @colorsignal5;
|
||||
|
||||
.play-container {
|
||||
height: @play-width;
|
||||
width: @play-width;
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: @progress-height;
|
||||
}
|
||||
}
|
||||
|
||||
.video-container {
|
||||
margin: 10px; //remove
|
||||
background-color: @colorblack20;
|
||||
|
||||
.video {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
.poster {
|
||||
width: 20%;
|
||||
background-position: center;
|
||||
background-size: cover, auto;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.text-container {
|
||||
padding: 2% 0%;
|
||||
|
||||
.title {
|
||||
color: @colorwhite;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.released-date {
|
||||
color: @colorwhite60;
|
||||
}
|
||||
|
||||
.label-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.watched-label, .upcoming-label {
|
||||
padding: 0% 3%;
|
||||
font-weight: 600;
|
||||
color: @colorwhite;
|
||||
}
|
||||
|
||||
.watched-label {
|
||||
background-color: @colorprimlight;
|
||||
}
|
||||
|
||||
.upcoming-label {
|
||||
background-color: @colorsignal5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.play-container {
|
||||
display: flex;
|
||||
transform: rotate(180deg);
|
||||
|
||||
.play {
|
||||
width: 38%;
|
||||
height: 38%;
|
||||
margin: auto;
|
||||
fill: @colorwhite60;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progress-container {
|
||||
grid-area: progress;
|
||||
background-color: @colorwhite20;
|
||||
|
||||
.progress {
|
||||
height: 3px;
|
||||
border-radius: 1px;
|
||||
background-color: @colorprimlight;
|
||||
}
|
||||
}
|
||||
&:hover, &:focus {
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: @colorwhite20;
|
||||
}
|
||||
}
|
||||
.with-poster {
|
||||
grid-template-columns: 70px 10px 1px 15px 28px 196px;
|
||||
grid-template-rows: 18px 24px;
|
||||
grid-template-areas:
|
||||
"poster . number number name name"
|
||||
"poster . . time time label";
|
||||
}
|
||||
.with-progress {
|
||||
background-color: @colorblack40;
|
||||
grid-template-columns: 1px 15px 278px 14px;
|
||||
grid-template-rows: 18px 19px 3px 2px;
|
||||
grid-template-areas:
|
||||
"number number name"
|
||||
". time time"
|
||||
"progress progress progress";
|
||||
}
|
||||
.with-poster-progress {
|
||||
background-color: @colorblack40;
|
||||
grid-template-columns: 70px 10px 1px 15px 204px 20px;
|
||||
grid-template-rows: 18px 19px 3px 2px;
|
||||
grid-template-areas:
|
||||
"poster . number number name"
|
||||
"poster . . time time"
|
||||
"poster . progress progress progress";
|
||||
}
|
||||
.video {
|
||||
grid-template-columns: 1px 15px 28px 264px;
|
||||
grid-template-rows: 18px 24px;
|
||||
grid-template-areas:
|
||||
"number number name name"
|
||||
". time time label";
|
||||
}
|
||||
|
|
@ -223,7 +223,7 @@ storiesOf('Video', module)
|
|||
<Video
|
||||
poster={'https://www.nationalgeographic.com/content/dam/photography/rights-exempt/pod-archive-grid-wide.adapt.945.1.jpg'}
|
||||
number={2}
|
||||
name={'The Bing Bran Hypothesis'}
|
||||
title={'The Bing Bran Hypothesis'}
|
||||
duration={23}
|
||||
isWatched={true}
|
||||
onVideoClicked={function() { alert(8) }}
|
||||
|
|
@ -234,7 +234,7 @@ storiesOf('Video', module)
|
|||
<div style={storyStyle} className={appStyles['app']}>
|
||||
<Video
|
||||
number={4}
|
||||
name={'The Luminous Fish Effect'}
|
||||
title={'The Luminous Fish Effect'}
|
||||
progress={50}
|
||||
duration={22}
|
||||
/>
|
||||
|
|
@ -245,7 +245,7 @@ storiesOf('Video', module)
|
|||
<Video
|
||||
poster={'5'}
|
||||
number={5}
|
||||
name={'The Dumpling Paradox'}
|
||||
title={'The Dumpling Paradox'}
|
||||
progress={50}
|
||||
duration={22}
|
||||
/>
|
||||
|
|
@ -255,7 +255,7 @@ storiesOf('Video', module)
|
|||
<div style={storyStyle} className={appStyles['app']}>
|
||||
<Video
|
||||
number={8}
|
||||
name={'The Loobendfeld Decay'}
|
||||
title={'The Loobendfeld Decay'}
|
||||
released={new Date(2018, 4, 23)}
|
||||
isUpcoming={true}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue