New: Show detailed queue status on Calendar and Series Details
Closes #3775
This commit is contained in:
parent
ca61efa57f
commit
8fff59ff10
|
@ -0,0 +1,5 @@
|
||||||
|
.progressBarContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
|
@ -1,115 +1,70 @@
|
||||||
import moment from 'moment';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
|
import { icons, tooltipPositions } from 'Helpers/Props';
|
||||||
|
import QueueStatus from './QueueStatus';
|
||||||
|
import styles from './QueueDetails.css';
|
||||||
|
|
||||||
function QueueDetails(props) {
|
function QueueDetails(props) {
|
||||||
const {
|
const {
|
||||||
title,
|
title,
|
||||||
size,
|
size,
|
||||||
sizeleft,
|
sizeleft,
|
||||||
estimatedCompletionTime,
|
|
||||||
status,
|
status,
|
||||||
trackedDownloadState,
|
trackedDownloadState,
|
||||||
trackedDownloadStatus,
|
trackedDownloadStatus,
|
||||||
|
statusMessages,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
progressBar
|
progressBar
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const progress = (100 - sizeleft / size * 100);
|
const progress = (100 - sizeleft / size * 100);
|
||||||
|
const isDownloading = status === 'downloading';
|
||||||
|
const isPaused = status === 'paused';
|
||||||
|
const hasWarning = trackedDownloadStatus === 'warning';
|
||||||
|
const hasError = trackedDownloadStatus === 'error';
|
||||||
|
|
||||||
if (status === 'pending') {
|
if (
|
||||||
return (
|
(isDownloading || isPaused) &&
|
||||||
<Icon
|
!hasWarning &&
|
||||||
name={icons.PENDING}
|
!hasError
|
||||||
title={`Release will be processed ${moment(estimatedCompletionTime).fromNow()}`}
|
) {
|
||||||
/>
|
const state = isPaused ? 'Paused' : 'Downloading';
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'completed') {
|
|
||||||
if (errorMessage) {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOAD}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title={`Import failed: ${errorMessage}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadStatus === 'warning') {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOAD}
|
|
||||||
kind={kinds.WARNING}
|
|
||||||
title={'Downloaded - Unable to Import: check logs for details'}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'importPending') {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOAD}
|
|
||||||
kind={kinds.PURPLE}
|
|
||||||
title={'Downloaded - Waiting to Import'}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'importing') {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOAD}
|
|
||||||
kind={kinds.PURPLE}
|
|
||||||
title={'Downloaded - Importing'}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorMessage) {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOADING}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title={`Download failed: ${errorMessage}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'failed') {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOADING}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title="Download failed: check download client for more details"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'warning') {
|
|
||||||
return (
|
|
||||||
<Icon
|
|
||||||
name={icons.DOWNLOADING}
|
|
||||||
kind={kinds.WARNING}
|
|
||||||
title="Download warning: check download client for more details"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress < 5) {
|
if (progress < 5) {
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
name={icons.DOWNLOADING}
|
name={icons.DOWNLOADING}
|
||||||
title={`Episode is downloading - ${progress.toFixed(1)}% ${title}`}
|
title={`${state} - ${progress.toFixed(1)}% ${title}`}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return progressBar;
|
return (
|
||||||
|
<Popover
|
||||||
|
className={styles.progressBarContainer}
|
||||||
|
anchor={progressBar}
|
||||||
|
title={`${state} - ${progress.toFixed(1)}%`}
|
||||||
|
body={
|
||||||
|
<div>{title}</div>
|
||||||
|
}
|
||||||
|
position={tooltipPositions.LEFT}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<QueueStatus
|
||||||
|
sourceTitle={title}
|
||||||
|
status={status}
|
||||||
|
trackedDownloadStatus={trackedDownloadStatus}
|
||||||
|
trackedDownloadState={trackedDownloadState}
|
||||||
|
statusMessages={statusMessages}
|
||||||
|
errorMessage={errorMessage}
|
||||||
|
position={tooltipPositions.LEFT}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueDetails.propTypes = {
|
QueueDetails.propTypes = {
|
||||||
|
@ -120,6 +75,7 @@ QueueDetails.propTypes = {
|
||||||
status: PropTypes.string.isRequired,
|
status: PropTypes.string.isRequired,
|
||||||
trackedDownloadState: PropTypes.string.isRequired,
|
trackedDownloadState: PropTypes.string.isRequired,
|
||||||
trackedDownloadStatus: PropTypes.string.isRequired,
|
trackedDownloadStatus: PropTypes.string.isRequired,
|
||||||
|
statusMessages: PropTypes.arrayOf(PropTypes.object),
|
||||||
errorMessage: PropTypes.string,
|
errorMessage: PropTypes.string,
|
||||||
progressBar: PropTypes.node.isRequired
|
progressBar: PropTypes.node.isRequired
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
.noMessages {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import Icon from 'Components/Icon';
|
||||||
|
import Popover from 'Components/Tooltip/Popover';
|
||||||
|
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||||
|
import styles from './QueueStatus.css';
|
||||||
|
|
||||||
|
function getDetailedPopoverBody(statusMessages) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
statusMessages.map(({ title, messages }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={title}
|
||||||
|
className={messages.length ? undefined: styles.noMessages}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
messages.map((message) => {
|
||||||
|
return (
|
||||||
|
<li key={message}>
|
||||||
|
{message}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function QueueStatus(props) {
|
||||||
|
const {
|
||||||
|
sourceTitle,
|
||||||
|
status,
|
||||||
|
trackedDownloadStatus,
|
||||||
|
trackedDownloadState,
|
||||||
|
statusMessages,
|
||||||
|
errorMessage,
|
||||||
|
position,
|
||||||
|
canFlip
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const hasWarning = trackedDownloadStatus === 'warning';
|
||||||
|
const hasError = trackedDownloadStatus === 'error';
|
||||||
|
|
||||||
|
// status === 'downloading'
|
||||||
|
let iconName = icons.DOWNLOADING;
|
||||||
|
let iconKind = kinds.DEFAULT;
|
||||||
|
let title = 'Downloading';
|
||||||
|
|
||||||
|
if (status === 'paused') {
|
||||||
|
iconName = icons.PAUSED;
|
||||||
|
title = 'Paused';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'queued') {
|
||||||
|
iconName = icons.QUEUED;
|
||||||
|
title = 'Queued';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'completed') {
|
||||||
|
iconName = icons.DOWNLOADED;
|
||||||
|
title = 'Downloaded';
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'importPending') {
|
||||||
|
title += ' - Waiting to Import';
|
||||||
|
iconKind = kinds.PURPLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'importing') {
|
||||||
|
title += ' - Importing';
|
||||||
|
iconKind = kinds.PURPLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trackedDownloadState === 'failedPending') {
|
||||||
|
title += ' - Waiting to Process';
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasWarning) {
|
||||||
|
iconKind = kinds.WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'delay') {
|
||||||
|
iconName = icons.PENDING;
|
||||||
|
title = 'Pending';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'downloadClientUnavailable') {
|
||||||
|
iconName = icons.PENDING;
|
||||||
|
iconKind = kinds.WARNING;
|
||||||
|
title = 'Pending - Download client is unavailable';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'failed') {
|
||||||
|
iconName = icons.DOWNLOADING;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
title = 'Download failed';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === 'warning') {
|
||||||
|
iconName = icons.DOWNLOADING;
|
||||||
|
iconKind = kinds.WARNING;
|
||||||
|
title = `Download warning: ${errorMessage || 'check download client for more details'}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
if (status === 'completed') {
|
||||||
|
iconName = icons.DOWNLOAD;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
title = `Import failed: ${sourceTitle}`;
|
||||||
|
} else {
|
||||||
|
iconName = icons.DOWNLOADING;
|
||||||
|
iconKind = kinds.DANGER;
|
||||||
|
title = 'Download failed';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
anchor={
|
||||||
|
<Icon
|
||||||
|
name={iconName}
|
||||||
|
kind={iconKind}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
title={title}
|
||||||
|
body={hasWarning || hasError ? getDetailedPopoverBody(statusMessages) : sourceTitle}
|
||||||
|
position={position}
|
||||||
|
canFlip={canFlip}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QueueStatus.propTypes = {
|
||||||
|
sourceTitle: PropTypes.string.isRequired,
|
||||||
|
status: PropTypes.string.isRequired,
|
||||||
|
trackedDownloadStatus: PropTypes.string.isRequired,
|
||||||
|
trackedDownloadState: PropTypes.string.isRequired,
|
||||||
|
statusMessages: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
errorMessage: PropTypes.string,
|
||||||
|
position: PropTypes.oneOf(tooltipPositions.all).isRequired,
|
||||||
|
canFlip: PropTypes.bool.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
QueueStatus.defaultProps = {
|
||||||
|
trackedDownloadStatus: 'Ok',
|
||||||
|
trackedDownloadState: 'Downloading',
|
||||||
|
canFlip: false
|
||||||
|
};
|
||||||
|
|
||||||
|
export default QueueStatus;
|
|
@ -1,41 +1,10 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import Popover from 'Components/Tooltip/Popover';
|
import { tooltipPositions } from 'Helpers/Props';
|
||||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
import QueueStatus from './QueueStatus';
|
||||||
import styles from './QueueStatusCell.css';
|
import styles from './QueueStatusCell.css';
|
||||||
|
|
||||||
function getDetailedPopoverBody(statusMessages) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
statusMessages.map(({ title, messages }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={title}
|
|
||||||
className={messages.length ? undefined: styles.noMessages}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
<ul>
|
|
||||||
{
|
|
||||||
messages.map((message) => {
|
|
||||||
return (
|
|
||||||
<li key={message}>
|
|
||||||
{message}
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function QueueStatusCell(props) {
|
function QueueStatusCell(props) {
|
||||||
const {
|
const {
|
||||||
sourceTitle,
|
sourceTitle,
|
||||||
|
@ -46,96 +15,16 @@ function QueueStatusCell(props) {
|
||||||
errorMessage
|
errorMessage
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const hasWarning = trackedDownloadStatus === 'warning';
|
|
||||||
const hasError = trackedDownloadStatus === 'error';
|
|
||||||
|
|
||||||
// status === 'downloading'
|
|
||||||
let iconName = icons.DOWNLOADING;
|
|
||||||
let iconKind = kinds.DEFAULT;
|
|
||||||
let title = 'Downloading';
|
|
||||||
|
|
||||||
if (status === 'paused') {
|
|
||||||
iconName = icons.PAUSED;
|
|
||||||
title = 'Paused';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'queued') {
|
|
||||||
iconName = icons.QUEUED;
|
|
||||||
title = 'Queued';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'completed') {
|
|
||||||
iconName = icons.DOWNLOADED;
|
|
||||||
title = 'Downloaded';
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'importPending') {
|
|
||||||
title += ' - Waiting to Import';
|
|
||||||
iconKind = kinds.PURPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'importing') {
|
|
||||||
title += ' - Importing';
|
|
||||||
iconKind = kinds.PURPLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trackedDownloadState === 'failedPending') {
|
|
||||||
title += ' - Waiting to Process';
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasWarning) {
|
|
||||||
iconKind = kinds.WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'delay') {
|
|
||||||
iconName = icons.PENDING;
|
|
||||||
title = 'Pending';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'downloadClientUnavailable') {
|
|
||||||
iconName = icons.PENDING;
|
|
||||||
iconKind = kinds.WARNING;
|
|
||||||
title = 'Pending - Download client is unavailable';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'failed') {
|
|
||||||
iconName = icons.DOWNLOADING;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
title = 'Download failed';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === 'warning') {
|
|
||||||
iconName = icons.DOWNLOADING;
|
|
||||||
iconKind = kinds.WARNING;
|
|
||||||
title = `Download warning: ${errorMessage || 'check download client for more details'}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasError) {
|
|
||||||
if (status === 'completed') {
|
|
||||||
iconName = icons.DOWNLOAD;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
title = `Import failed: ${sourceTitle}`;
|
|
||||||
} else {
|
|
||||||
iconName = icons.DOWNLOADING;
|
|
||||||
iconKind = kinds.DANGER;
|
|
||||||
title = 'Download failed';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRowCell className={styles.status}>
|
<TableRowCell className={styles.status}>
|
||||||
<Popover
|
<QueueStatus
|
||||||
anchor={
|
sourceTitle={sourceTitle}
|
||||||
<Icon
|
status={status}
|
||||||
name={iconName}
|
trackedDownloadStatus={trackedDownloadStatus}
|
||||||
kind={iconKind}
|
trackedDownloadState={trackedDownloadState}
|
||||||
/>
|
statusMessages={statusMessages}
|
||||||
}
|
errorMessage={errorMessage}
|
||||||
title={title}
|
|
||||||
body={hasWarning || hasError ? getDetailedPopoverBody(statusMessages) : sourceTitle}
|
|
||||||
position={tooltipPositions.RIGHT}
|
position={tooltipPositions.RIGHT}
|
||||||
canFlip={false}
|
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,15 +1,30 @@
|
||||||
.event {
|
.event {
|
||||||
display: flex;
|
position: relative;
|
||||||
overflow-x: hidden;
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-bottom: 1px solid var(--borderColor);
|
border-bottom: 1px solid var(--borderColor);
|
||||||
font-size: $defaultFontSize;
|
}
|
||||||
|
|
||||||
|
.underlay {
|
||||||
|
@add-mixin cover;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--tableRowHoverBackgroundColor);
|
background-color: var(--tableRowHoverBackgroundColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
@add-mixin linkOverlay;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
overflow-x: hidden;
|
||||||
|
font-size: $defaultFontSize;
|
||||||
|
|
||||||
|
&:global(.colorImpaired) {
|
||||||
|
border-left-width: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.eventWrapper {
|
.eventWrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 0 1px;
|
flex: 1 0 1px;
|
||||||
|
@ -56,6 +71,8 @@
|
||||||
|
|
||||||
.statusIcon {
|
.statusIcon {
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -74,12 +74,13 @@ class AgendaEvent extends Component {
|
||||||
const seasonStatistics = season?.statistics || {};
|
const seasonStatistics = season?.statistics || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={styles.event}>
|
||||||
<Link
|
<Link
|
||||||
className={styles.event}
|
className={styles.underlay}
|
||||||
component="div"
|
|
||||||
onPress={this.onPress}
|
onPress={this.onPress}
|
||||||
>
|
/>
|
||||||
|
|
||||||
|
<div className={styles.overlay}>
|
||||||
<div className={styles.date}>
|
<div className={styles.date}>
|
||||||
{
|
{
|
||||||
showDate &&
|
showDate &&
|
||||||
|
@ -209,7 +210,7 @@ class AgendaEvent extends Component {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</div>
|
||||||
|
|
||||||
<EpisodeDetailsModal
|
<EpisodeDetailsModal
|
||||||
isOpen={this.state.isDetailsModalOpen}
|
isOpen={this.state.isDetailsModalOpen}
|
||||||
|
|
|
@ -1,11 +1,22 @@
|
||||||
$fullColorGradient: rgba(244, 245, 246, 0.2);
|
$fullColorGradient: rgba(244, 245, 246, 0.2);
|
||||||
|
|
||||||
.event {
|
.event {
|
||||||
overflow-x: hidden;
|
position: relative;
|
||||||
margin: 4px 2px;
|
margin: 4px 2px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-bottom: 1px solid var(--calendarBorderColor);
|
border-bottom: 1px solid var(--calendarBorderColor);
|
||||||
border-left: 4px solid var(--calendarBorderColor);
|
border-left: 4px solid var(--calendarBorderColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
.underlay {
|
||||||
|
@add-mixin cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
@add-mixin linkOverlay;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
overflow-x: hidden;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
&:global(.colorImpaired) {
|
&:global(.colorImpaired) {
|
||||||
|
@ -45,6 +56,8 @@ $fullColorGradient: rgba(244, 245, 246, 0.2);
|
||||||
|
|
||||||
.statusIcon {
|
.statusIcon {
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.airTime {
|
.airTime {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component } from 'react';
|
||||||
import getStatusStyle from 'Calendar/getStatusStyle';
|
import getStatusStyle from 'Calendar/getStatusStyle';
|
||||||
import Icon from 'Components/Icon';
|
import Icon from 'Components/Icon';
|
||||||
import Link from 'Components/Link/Link';
|
import Link from 'Components/Link/Link';
|
||||||
|
@ -82,17 +82,20 @@ class CalendarEvent extends Component {
|
||||||
const seasonStatistics = season?.statistics || {};
|
const seasonStatistics = season?.statistics || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<div
|
||||||
<Link
|
|
||||||
className={classNames(
|
className={classNames(
|
||||||
styles.event,
|
styles.event,
|
||||||
styles[statusStyle],
|
styles[statusStyle],
|
||||||
colorImpairedMode && 'colorImpaired',
|
colorImpairedMode && 'colorImpaired',
|
||||||
fullColorEvents && 'fullColor'
|
fullColorEvents && 'fullColor'
|
||||||
)}
|
)}
|
||||||
component="div"
|
|
||||||
onPress={this.onPress}
|
|
||||||
>
|
>
|
||||||
|
<Link
|
||||||
|
className={styles.underlay}
|
||||||
|
onPress={this.onPress}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className={styles.overlay} >
|
||||||
<div className={styles.info}>
|
<div className={styles.info}>
|
||||||
<div className={styles.seriesTitle}>
|
<div className={styles.seriesTitle}>
|
||||||
{series.title}
|
{series.title}
|
||||||
|
@ -215,7 +218,7 @@ class CalendarEvent extends Component {
|
||||||
<div className={styles.airTime}>
|
<div className={styles.airTime}>
|
||||||
{formatTime(airDateUtc, timeFormat)} - {formatTime(endTime.toISOString(), timeFormat, { includeMinuteZero: true })}
|
{formatTime(airDateUtc, timeFormat)} - {formatTime(endTime.toISOString(), timeFormat, { includeMinuteZero: true })}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</div>
|
||||||
|
|
||||||
<EpisodeDetailsModal
|
<EpisodeDetailsModal
|
||||||
isOpen={this.state.isDetailsModalOpen}
|
isOpen={this.state.isDetailsModalOpen}
|
||||||
|
@ -226,7 +229,7 @@ class CalendarEvent extends Component {
|
||||||
showOpenSeriesButton={true}
|
showOpenSeriesButton={true}
|
||||||
onModalClose={this.onDetailsModalClose}
|
onModalClose={this.onDetailsModalClose}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ function CalendarEventQueueDetails(props) {
|
||||||
status,
|
status,
|
||||||
trackedDownloadState,
|
trackedDownloadState,
|
||||||
trackedDownloadStatus,
|
trackedDownloadStatus,
|
||||||
|
statusMessages,
|
||||||
errorMessage
|
errorMessage
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -26,16 +27,15 @@ function CalendarEventQueueDetails(props) {
|
||||||
status={status}
|
status={status}
|
||||||
trackedDownloadState={trackedDownloadState}
|
trackedDownloadState={trackedDownloadState}
|
||||||
trackedDownloadStatus={trackedDownloadStatus}
|
trackedDownloadStatus={trackedDownloadStatus}
|
||||||
|
statusMessages={statusMessages}
|
||||||
errorMessage={errorMessage}
|
errorMessage={errorMessage}
|
||||||
progressBar={
|
progressBar={
|
||||||
<div title={`Episode is downloading - ${progress.toFixed(1)}% ${title}`}>
|
|
||||||
<CircularProgressBar
|
<CircularProgressBar
|
||||||
progress={progress}
|
progress={progress}
|
||||||
size={20}
|
size={20}
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
strokeColor={'#7a43b6'}
|
strokeColor={'#7a43b6'}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -49,6 +49,7 @@ CalendarEventQueueDetails.propTypes = {
|
||||||
status: PropTypes.string.isRequired,
|
status: PropTypes.string.isRequired,
|
||||||
trackedDownloadState: PropTypes.string.isRequired,
|
trackedDownloadState: PropTypes.string.isRequired,
|
||||||
trackedDownloadStatus: PropTypes.string.isRequired,
|
trackedDownloadStatus: PropTypes.string.isRequired,
|
||||||
|
statusMessages: PropTypes.arrayOf(PropTypes.object),
|
||||||
errorMessage: PropTypes.string
|
errorMessage: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ function EpisodeStatus(props) {
|
||||||
{...queueItem}
|
{...queueItem}
|
||||||
progressBar={
|
progressBar={
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
title={`Episode is downloading - ${progress.toFixed(1)}% ${queueItem.title}`}
|
|
||||||
progress={progress}
|
progress={progress}
|
||||||
kind={kinds.PURPLE}
|
kind={kinds.PURPLE}
|
||||||
size={sizes.MEDIUM}
|
size={sizes.MEDIUM}
|
||||||
|
|
Loading…
Reference in New Issue