mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-19 13:52:12 +00:00
resetMonth func replaced with getMonthInfo; styles fixes (table used)
This commit is contained in:
parent
108e09e98c
commit
87fe0a1824
2 changed files with 216 additions and 176 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue