parent
b2c1dbf3ab
commit
5a5e896eb4
@ -1,87 +0,0 @@
|
||||
.eventGroup {
|
||||
overflow-x: hidden;
|
||||
margin: 4px 2px;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid $borderColor;
|
||||
border-left: 4px solid $borderColor;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.info,
|
||||
.airingInfo {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.seriesTitle {
|
||||
@add-mixin truncate;
|
||||
flex: 1 0 1px;
|
||||
margin-right: 10px;
|
||||
color: #3a3f51;
|
||||
font-size: $defaultFontSize;
|
||||
}
|
||||
|
||||
.airTime {
|
||||
flex: 1 0 1px;
|
||||
color: $calendarTextDim;
|
||||
}
|
||||
|
||||
.episodeInfo {
|
||||
margin-left: 10px;
|
||||
color: $calendarTextDim;
|
||||
}
|
||||
|
||||
.absoluteEpisodeNumber {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.expandContainerInline {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
flex: 1 0 20px;
|
||||
}
|
||||
|
||||
.expandContainer,
|
||||
.collapseContainer {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.collapseContainer {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.statusIcon {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
|
||||
.downloaded {
|
||||
composes: downloaded from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.downloading {
|
||||
composes: downloading from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.unmonitored {
|
||||
composes: unmonitored from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.onAir {
|
||||
composes: onAir from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.missing {
|
||||
composes: missing from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.premiere {
|
||||
composes: premiere from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
||||
|
||||
.unaired {
|
||||
composes: unaired from '~Calendar/Events/CalendarEvent.css';
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
import moment from 'moment';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { icons, kinds } from 'Helpers/Props';
|
||||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import getStatusStyle from 'Calendar/getStatusStyle';
|
||||
import CalendarEventConnector from 'Calendar/Events/CalendarEventConnector';
|
||||
import styles from './CalendarEventGroup.css';
|
||||
|
||||
function getEventsInfo(events) {
|
||||
let files = 0;
|
||||
let queued = 0;
|
||||
let monitored = 0;
|
||||
let absoluteEpisodeNumbers = 0;
|
||||
|
||||
events.forEach((event) => {
|
||||
if (event.episodeFileId) {
|
||||
files++;
|
||||
}
|
||||
|
||||
if (event.queued) {
|
||||
queued++;
|
||||
}
|
||||
|
||||
if (event.monitored) {
|
||||
monitored++;
|
||||
}
|
||||
|
||||
if (event.absoluteEpisodeNumber) {
|
||||
absoluteEpisodeNumbers++;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
allDownloaded: files === events.length,
|
||||
anyQueued: queued > 0,
|
||||
anyMonitored: monitored > 0,
|
||||
allAbsoluteEpisodeNumbers: absoluteEpisodeNumbers === events.length
|
||||
};
|
||||
}
|
||||
|
||||
class CalendarEventGroup extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isExpanded: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onExpandPress = () => {
|
||||
this.setState({ isExpanded: !this.state.isExpanded });
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
series,
|
||||
events,
|
||||
isDownloading,
|
||||
showEpisodeInformation,
|
||||
showFinaleIcon,
|
||||
colorImpairedMode,
|
||||
onEventModalOpenToggle
|
||||
} = this.props;
|
||||
|
||||
const { isExpanded } = this.state;
|
||||
const {
|
||||
allDownloaded,
|
||||
anyQueued,
|
||||
anyMonitored
|
||||
} = getEventsInfo(events);
|
||||
const anyDownloading = isDownloading || anyQueued;
|
||||
const firstEpisode = events[0];
|
||||
const lastEpisode = events[events.length -1];
|
||||
const airDateUtc = firstEpisode.airDateUtc;
|
||||
const startTime = moment(airDateUtc);
|
||||
const endTime = moment(lastEpisode.airDateUtc).add(series.runtime, 'minutes');
|
||||
const seasonNumber = firstEpisode.seasonNumber;
|
||||
const statusStyle = getStatusStyle(allDownloaded, anyDownloading, startTime, endTime, anyMonitored);
|
||||
|
||||
if (isExpanded) {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
events.map((event) => {
|
||||
if (event.isGroup) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<CalendarEventConnector
|
||||
key={event.id}
|
||||
episodeId={event.id}
|
||||
{...event}
|
||||
onEventModalOpenToggle={onEventModalOpenToggle}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
<Link
|
||||
className={styles.collapseContainer}
|
||||
component="div"
|
||||
onPress={this.onExpandPress}
|
||||
>
|
||||
<Icon
|
||||
name={icons.COLLAPSE}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
styles.eventGroup,
|
||||
styles[statusStyle],
|
||||
colorImpairedMode && 'colorImpaired'
|
||||
)}
|
||||
>
|
||||
<div className={styles.info}>
|
||||
<div className={styles.seriesTitle}>
|
||||
{series.title}
|
||||
</div>
|
||||
|
||||
{
|
||||
anyDownloading &&
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.DOWNLOADING}
|
||||
title="An episode is downloading"
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
firstEpisode.episodeNumber === 1 && seasonNumber > 0 &&
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.INFO}
|
||||
kind={kinds.INFO}
|
||||
title={seasonNumber === 1 ? 'Series Premiere' : 'Season Premiere'}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
showFinaleIcon &&
|
||||
lastEpisode.episodeNumber !== 1 &&
|
||||
seasonNumber > 0 &&
|
||||
lastEpisode.episodeNumber === series.seasons.find((season) => season.seasonNumber === seasonNumber).statistics.totalEpisodeCount &&
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.INFO}
|
||||
kind={kinds.WARNING}
|
||||
title={series.status === 'ended' ? 'Series finale' : 'Season finale'}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
{
|
||||
showEpisodeInformation &&
|
||||
<Link
|
||||
className={styles.expandContainer}
|
||||
component="div"
|
||||
onPress={this.onExpandPress}
|
||||
>
|
||||
<Icon
|
||||
name={icons.EXPAND}
|
||||
/>
|
||||
</Link>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CalendarEventGroup.propTypes = {
|
||||
series: PropTypes.object.isRequired,
|
||||
events: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isDownloading: PropTypes.bool.isRequired,
|
||||
showEpisodeInformation: PropTypes.bool.isRequired,
|
||||
showFinaleIcon: PropTypes.bool.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired,
|
||||
colorImpairedMode: PropTypes.bool.isRequired,
|
||||
onEventModalOpenToggle: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default CalendarEventGroup;
|
@ -1,37 +0,0 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createMovieSelector from 'Store/Selectors/createMovieSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import CalendarEventGroup from './CalendarEventGroup';
|
||||
|
||||
function createIsDownloadingSelector() {
|
||||
return createSelector(
|
||||
(state, { movieIds }) => movieIds,
|
||||
(state) => state.queue.details,
|
||||
(movieIds, details) => {
|
||||
return details.items.some((item) => {
|
||||
return item.movie && movieIds.includes(item.movie.id);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.calendar.options,
|
||||
createMovieSelector(),
|
||||
createIsDownloadingSelector(),
|
||||
createUISettingsSelector(),
|
||||
(calendarOptions, movie, isDownloading, uiSettings) => {
|
||||
return {
|
||||
movie,
|
||||
isDownloading,
|
||||
...calendarOptions,
|
||||
timeFormat: uiSettings.timeFormat,
|
||||
colorImpairedMode: uiSettings.enableColorImpairedMode
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps)(CalendarEventGroup);
|
Loading…
Reference in new issue