new design of stream and video

This commit is contained in:
svetlagasheva 2018-11-20 14:39:52 +02:00
parent 6cc4e3c258
commit bfade83684
5 changed files with 233 additions and 249 deletions

View file

@ -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
};

View file

@ -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;

View file

@ -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,

View file

@ -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";
}

View file

@ -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}
/>