resetMonth func replaced with getMonthInfo; styles fixes (table used)

This commit is contained in:
svetlagasheva 2019-03-13 18:58:17 +02:00
parent 108e09e98c
commit 87fe0a1824
2 changed files with 216 additions and 176 deletions

View file

@ -11,8 +11,6 @@ class Calendar extends Component {
constructor(props) {
super(props);
this.resetMonth(new Date());
this.dateRef = React.createRef();
this.futureEpisodesRef = React.createRef();
@ -23,10 +21,37 @@ class Calendar extends Component {
};
}
componentDidMount() {
this.scrollTo();
}
shouldComponentUpdate(nextProps, nextState) {
return nextState.date !== this.state.date ||
nextState.episodeInfo !== this.state.episodeInfo ||
nextState.selectedDate !== this.state.selectedDate;
}
componentDidUpdate(prevProps, prevState) {
if (prevState.selectedDate !== this.state.selectedDate) {
this.scrollTo();
}
if (prevState.date.getMonth() !== this.state.date.getMonth()) {
this.setState({ selectedDate: new Date(this.state.date.getFullYear(), this.state.date.getMonth(), 1) });
}
}
scrollTo = () => {
if (this.dateRef.current !== null) {
var topPosition = this.dateRef.current.offsetTop;
this.futureEpisodesRef.current.scrollTop = topPosition - this.futureEpisodesRef.current.offsetTop;
} else {
this.setState({ episodeInfo: '' });
}
}
changeDate = (event) => {
const date = new Date(parseInt(event.currentTarget.dataset.date));
this.resetMonth(date);
this.setState({ date });
this.setState({ date: new Date(parseInt(event.currentTarget.dataset.date)) });
}
showEpisodeInfo = (event) => {
@ -52,51 +77,20 @@ class Calendar extends Component {
}
}
scrollTo = () => {
if (this.dateRef.current !== null) {
var topPosition = this.dateRef.current.offsetTop;
this.futureEpisodesRef.current.scrollTop = topPosition - this.futureEpisodesRef.current.offsetTop;
} else {
this.setState({ episodeInfo: '' });
}
}
getMonthInfo = (date) => {
const monthDate = new Date(date);
monthDate.setDate(1);
var padsCount = (monthDate.getDay() + 6) % 7;
monthDate.setMonth(monthDate.getMonth() + 1);
monthDate.setDate(0);
var daysCount = monthDate.getDate();
var rowsCount = Math.ceil((padsCount + daysCount) / 7);
resetMonth(newDate) {
this.monthDays = [];
this.monthStart = new Date(newDate.getFullYear(), newDate.getMonth());
this.monthEnd = new Date(this.monthStart.getFullYear(), this.monthStart.getMonth() + 1, 0);
this.pads = [];
var pad = (this.monthStart.getDay() + 6) % 7;
for (var i = 0; i != pad; i++) {
this.pads.push(i);
}
for (var i = 0; i != this.monthEnd.getDate(); i++) {
this.monthDays.push(i);
}
}
shouldComponentUpdate(nextProps, nextState) {
return nextState.date !== this.state.date ||
nextState.episodeInfo !== this.state.episodeInfo ||
nextState.selectedDate !== this.state.selectedDate;
}
componentDidMount() {
this.scrollTo();
}
componentDidUpdate(prevProps, prevState) {
if (prevState.selectedDate !== this.state.selectedDate) {
this.scrollTo();
}
if (prevState.date.getMonth() !== this.state.date.getMonth()) {
this.setState({ selectedDate: new Date(this.state.date.getFullYear(), this.state.date.getMonth(), 1) });
const newDate = this.state.date;
this.resetMonth(newDate);
}
return {
padsCount,
daysCount,
rowsCount
};
}
renderMonthButton(date) {
@ -106,6 +100,9 @@ class Calendar extends Component {
}
render() {
const { padsCount, daysCount, rowsCount } = this.getMonthInfo(this.state.date);
var currentDay = 0;
const videosDates = this.props.metaItems
.map((metaitem) => metaitem.videos
.filter((video) => video.released.getFullYear() === this.state.date.getFullYear() && video.released.getMonth() === this.state.date.getMonth()))
@ -120,42 +117,50 @@ class Calendar extends Component {
{this.renderMonthButton(new Date(this.state.date))}
{this.renderMonthButton(new Date((new Date(this.state.date)).setMonth(this.state.date.getMonth() + 1)))}
</div>
<div className={styles['week-days']}>
{days.map((day) => <div key={day} className={styles['day']}>{day}</div>)}
</div>
<div className={styles['month-days']}>
{this.pads.map((pad) =>
<div key={pad} className={styles['pad']} />
)}
{this.monthDays.map((day) =>
<div key={day}
className={classnames(styles['day'], { [styles['selected']]: this.state.selectedDate.getDate() === day + 1 })}
data-day={new Date(this.state.date.getFullYear(), this.state.date.getMonth(), day + 1)}
onClick={this.changeSelectedDate}
>
<div className={styles['date-container']}>
<div className={classnames(styles['date'], { [styles['selected']]: this.state.date.getFullYear() === new Date().getFullYear() && this.state.date.getMonth() === new Date().getMonth() && this.state.date.getDate() === day + 1 })}>{day + 1}</div>
</div>
<div className={styles['episodes']}>
{this.props.metaItems
.map((metaitem) => metaitem.videos
.filter((video) => video.released.getFullYear() === this.state.date.getFullYear() && video.released.getMonth() === this.state.date.getMonth() && video.released.getDate() === day + 1)
.map((video) =>
//////indicator for >3 posters?
//getTime()?
<div key={video.id}
style={{ backgroundImage: `url('${metaitem.background}')` }}
className={classnames(styles['poster'], { [styles['past']]: video.released.getDate() < new Date().getDate() && video.released.getMonth() <= new Date().getMonth() })}
data-video-name={video.name}
data-video-date={video.released}
onClick={this.showEpisodeInfo}
/>
)
)}
</div>
</div>
)}
</div>
<table className={styles['month-days']}>
<tr className={styles['week-days']}>
{days.map((day) => <td key={day} className={styles['day']}>{day}</td>)}
</tr>
{Array.apply(null, { length: rowsCount }).map((_, row) => (
<tr key={row} className={styles['row']}>
{Array.apply(null, { length: 7 }).map((_, day) => (
day < padsCount && row === 0
?
<td key={day} />
:
currentDay < daysCount
?
++currentDay &&
<td key={day}
className={classnames(styles['day'], { [styles['selected']]: this.state.selectedDate.getDate() === currentDay })}
data-day={new Date(this.state.date.getFullYear(), this.state.date.getMonth(), currentDay)}
onClick={this.changeSelectedDate}
>
<div className={styles['date-container']}>
<div className={classnames(styles['date'], { [styles['selected']]: this.state.date.getFullYear() === new Date().getFullYear() && this.state.date.getMonth() === new Date().getMonth() && this.state.date.getDate() === currentDay })}>{currentDay}</div>
</div>
<div className={classnames(styles['episodes'], { [styles['small']]: rowsCount === 6 }, { [styles['big']]: rowsCount === 4 })}>
{this.props.metaItems
.map((metaitem) => metaitem.videos
.filter((video) => video.released.getFullYear() === this.state.date.getFullYear() && video.released.getMonth() === this.state.date.getMonth() && video.released.getDate() === currentDay)
.map((video) =>
<div key={video.id}
style={{ backgroundImage: `url('${metaitem.background}')` }}
className={classnames(styles['poster'], { [styles['past']]: video.released.getDate() < new Date().getDate() && video.released.getMonth() <= new Date().getMonth() && video.released.getFullYear() <= new Date().getFullYear() })}
data-video-name={video.name}
data-video-date={video.released}
onClick={this.showEpisodeInfo}
/>
)
)}
</div>
</td>
:
null
))}
</tr>
))}
</table>
</div>
<div ref={this.futureEpisodesRef} className={styles['future-episodes']}>
{
@ -202,10 +207,10 @@ class Calendar extends Component {
<div className={styles['description']}>
{video.description}
</div>
<a className={styles['watch-button-container']} href={'#/detail'}>
<a className={styles['watch-button-container']} href={video.released.getDate() < new Date().getDate() && video.released.getMonth() <= new Date().getMonth() && video.released.getFullYear() <= new Date().getFullYear() ? '#/player' : '#/detail'}>
<div className={styles['watch-button']}>
<Icon className={styles['icon']} icon={'ic_play'} />
<div className={styles['label']}>WATCH NOW</div>
<div className={styles['label']}>{video.released.getDate() < new Date().getDate() && video.released.getMonth() <= new Date().getMonth() && video.released.getFullYear() <= new Date().getFullYear() ? 'WATCH NOW' : 'SHOW'}</div>
</div>
</a>
</div>

View file

@ -1,5 +1,7 @@
.calendar-container {
--spacing: 16px;
--episodes-height: 50px;
--future-episodes-width: 270px;
font-size: 14px;
}
@ -11,16 +13,22 @@
.calendar {
flex: 1;
padding-right: calc(var(--spacing) * 0.5);
.months {
padding: var(--spacing) 0 calc(var(--spacing) * 2) 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding-top: calc(var(--spacing) * 0.5);
height: 8%;
text-align: center;
.month {
width: 12%;
display: inline-block;
font-size: 1.7em;
line-height: 1.2em;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
vertical-align: middle;
color: var(--color-surfacelighter);
cursor: pointer;
@ -33,109 +41,109 @@
}
}
&:not(:last-child) {
margin-right: calc(var(--spacing) * 4);
&:not(:first-child):not(:last-child) {
margin: 0 var(--spacing);
}
}
}
.week-days {
margin-bottom: var(--spacing);
display: flex;
flex-direction: row;
.day {
margin-right: calc(var(--focusable-border-size) * 0.5);
width: 14%;
font-size: 1.2em;
color: var(--color-secondarylighter);
}
}
.month-days {
height: 100%;
width: 100%;
height: 92%;
table-layout: fixed;
.pad {
margin: 0 calc(var(--focusable-border-size) * 0.5) calc(var(--focusable-border-size) * 0.5) 0;
width: 14%;
height: 14%;
float: left;
.week-days {
.day {
padding: 0 calc(var(--spacing) * 0.5) calc(var(--spacing) * 0.5) 0;
font-size: 1.2em;
line-height: 1.2em;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--color-secondarylighter);
}
}
.day {
margin: 0 calc(var(--focusable-border-size) * 0.5) calc(var(--focusable-border-size) * 0.5) 0;
width: 14%;
height: 14%;
float: left;
font-size: 1.4em;
border: var(--focusable-border-size) solid transparent;
background-color: var(--color-backgroundlighter);
cursor: pointer;
.row {
.day {
border: var(--focusable-border-size) solid transparent;
background-color: var(--color-backgroundlighter);
cursor: pointer;
.date-container {
margin: calc(var(--spacing) * 0.5);
width: 30px;
height: 30px;
.date-container {
margin: calc(var(--spacing) * 0.5);
width: calc(var(--episodes-height) * 0.64);
height: calc(var(--episodes-height) * 0.64);
.date {
width: 100%;
height: 100%;
.date {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.4em;
color: var(--color-secondarylighter);
&.selected {
border-radius: 50%;
color: var(--color-surfacelighter);
background-color: var(--color-primary);
}
}
}
.episodes {
margin: var(--focusable-border-size);
height: var(--episodes-height);
display: flex;
align-items: center;
justify-content: center;
color: var(--color-secondarylighter);
flex-direction: row;
&.selected {
border-radius: 50%;
color: var(--color-surfacelighter);
background-color: var(--color-primary);
.poster {
margin-right: var(--focusable-border-size);
display: none;
width: 25%;
height: 100%;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
&.past {
opacity: 0.4;
}
&:nth-child(-n+4) {
display: block;
}
}
&.small {
height: calc(var(--episodes-height) * 0.64);
}
&.big {
height: calc(var(--episodes-height) * 1.54);
}
}
}
.episodes {
margin: 0 var(--focusable-border-size) var(--focusable-border-size) var(--focusable-border-size);
height: 34px;
display: flex;
flex-direction: row;
.poster {
margin-right: var(--focusable-border-size);
display: none;
width: 25%;
height: 100%;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
&.past {
opacity: 0.4;
}
&:nth-child(-n+4) {
display: inline-block;
}
&.selected {
border-color: var(--color-primary);
background-color: var(--color-backgroundlighter60);
}
}
&.selected {
border-color: var(--color-primary);
background-color: var(--color-backgroundlighter60);
}
}
}
}
.future-episodes {
padding-right: 10px;
width: 270px;
padding-right: calc(var(--spacing) * 0.5);
width: var(--future-episodes-width);
overflow-y: auto;
overflow-x: hidden;
scroll-behavior: smooth;
.episode-container {
margin-bottom: var(--spacing);
width: 252px;
margin-bottom: calc(var(--spacing) * 0.5);
border: var(--focusable-border-size) solid var(--color-background);
background-color: var(--color-backgroundlighter);
@ -147,9 +155,6 @@
.episode {
padding: var(--spacing);
display: flex;
flex-direction: column;
justify-content: space-between;
cursor: pointer;
.main-info {
@ -158,17 +163,28 @@
justify-content: space-between;
.serie-name {
margin-right: 5%;
width: 75%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--color-surface);
}
.episode-number {
width: 20%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--color-surface);
}
}
.name {
width: 100%;
display: none;
padding: calc(var(--spacing) * 0.5) 0 var(--spacing) 0;
overflow-wrap: break-word;
color: var(--color-surfacelighter);
}
@ -193,16 +209,21 @@
justify-content: center;
.icon {
margin-right: var(--spacing);
margin-right: 8%;
width: 8%;
fill: var(--color-surfacelight);
}
.label {
max-width: 84%;
word-break: break-all; //Firefox doesn't support { break-word }
word-break: break-word;
color: var(--color-surfacelight);
}
}
&:hover {
&:hover {
.watch-button {
.icon {
fill: var(--color-surfacelighter);
}
@ -219,16 +240,30 @@
background-color: var(--color-primarydark);
cursor: default;
.main-info {
.serie-name {
white-space: unset;
overflow: visible;
overflow-wrap: break-word;
}
.episode-number {
white-space: unset;
overflow: visible;
overflow-wrap: break-word;
}
}
.name {
display: inline-block;
display: block;
}
.description {
display: inline-block;
display: block;
}
.watch-button-container {
display: inline-block;
display: block;
}
&:hover {