New: Album Status on Cutoff/Wanted/Artist Page

fix-album-status-ui
Qstick 5 years ago
parent 9f082c849a
commit 533919ccdd

@ -0,0 +1,125 @@
import PropTypes from 'prop-types';
import React from 'react';
import isBefore from 'Utilities/Date/isBefore';
import { icons, kinds, sizes } from 'Helpers/Props';
import Icon from 'Components/Icon';
import ProgressBar from 'Components/ProgressBar';
import QueueDetails from 'Activity/Queue/QueueDetails';
// import TrackQuality from './TrackQuality';
import styles from './AlbumStatus.css';
function AlbumStatus(props) {
const {
releaseDate,
monitored,
grabbed,
queueItem
} = props;
// const hasTrackFile = !!trackFile;
const isQueued = !!queueItem;
const hasReleased = isBefore(releaseDate);
if (isQueued) {
const {
sizeleft,
size
} = queueItem;
const progress = (100 - sizeleft / size * 100);
return (
<div className={styles.center}>
<QueueDetails
{...queueItem}
progressBar={
<ProgressBar
title={`Album is downloading - ${progress.toFixed(1)}% ${queueItem.title}`}
progress={progress}
kind={kinds.PURPLE}
size={sizes.MEDIUM}
/>
}
/>
</div>
);
}
if (grabbed) {
return (
<div className={styles.center}>
<Icon
name={icons.DOWNLOADING}
title="Album is downloading"
/>
</div>
);
}
// if (hasTrackFile) {
// const quality = trackFile.quality;
// const isCutoffNotMet = trackFile.qualityCutoffNotMet;
// return (
// <div className={styles.center}>
// <TrackQuality
// quality={quality}
// size={trackFile.size}
// isCutoffNotMet={isCutoffNotMet}
// title="Track Downloaded"
// />
// </div>
// );
// }
if (!releaseDate) {
return (
<div className={styles.center}>
<Icon
name={icons.TBA}
title="TBA"
/>
</div>
);
}
if (!monitored) {
return (
<div className={styles.center}>
<Icon
name={icons.UNMONITORED}
title="Album is not monitored"
/>
</div>
);
}
if (hasReleased) {
return (
<div className={styles.center}>
<Icon
name={icons.MISSING}
title="Album missing from disk"
/>
</div>
);
}
return (
<div className={styles.center}>
<Icon
name={icons.NOT_AIRED}
title="Album has not released"
/>
</div>
);
}
AlbumStatus.propTypes = {
releaseDate: PropTypes.string,
monitored: PropTypes.bool,
grabbed: PropTypes.bool,
queueItem: PropTypes.object
};
export default AlbumStatus;

@ -0,0 +1,50 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createQueueItemSelector from 'Store/Selectors/createQueueItemSelector';
// import createTrackFileSelector from 'Store/Selectors/createTrackFileSelector';
import AlbumStatus from './AlbumStatus';
function createMapStateToProps() {
return createSelector(
createAlbumSelector(),
createQueueItemSelector(),
(album, queueItem) => {
const result = _.pick(album, [
'releaseDate',
'monitored',
'grabbed'
]);
result.queueItem = queueItem;
return result;
}
);
}
const mapDispatchToProps = {
};
class AlbumStatusConnector extends Component {
//
// Render
render() {
return (
<AlbumStatus
{...this.props}
/>
);
}
}
AlbumStatusConnector.propTypes = {
albumId: PropTypes.number.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AlbumStatusConnector);

@ -3,7 +3,7 @@ import React, { Component } from 'react';
import TableRow from 'Components/Table/TableRow'; import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableRowCell from 'Components/Table/Cells/TableRowCell';
import formatTimeSpan from 'Utilities/Date/formatTimeSpan'; import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
import EpisodeStatusConnector from 'Album/EpisodeStatusConnector'; import TrackStatusConnector from './TrackStatusConnector';
import MediaInfoConnector from 'TrackFile/MediaInfoConnector'; import MediaInfoConnector from 'TrackFile/MediaInfoConnector';
import TrackActionsCell from './TrackActionsCell'; import TrackActionsCell from './TrackActionsCell';
import * as mediaInfoTypes from 'TrackFile/mediaInfoTypes'; import * as mediaInfoTypes from 'TrackFile/mediaInfoTypes';
@ -129,7 +129,7 @@ class TrackRow extends Component {
key={name} key={name}
className={styles.status} className={styles.status}
> >
<EpisodeStatusConnector <TrackStatusConnector
albumId={id} albumId={id}
trackFileId={trackFileId} trackFileId={trackFileId}
/> />

@ -0,0 +1,4 @@
.center {
display: flex;
justify-content: center;
}

@ -5,12 +5,12 @@ import { icons, kinds, sizes } from 'Helpers/Props';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import ProgressBar from 'Components/ProgressBar'; import ProgressBar from 'Components/ProgressBar';
import QueueDetails from 'Activity/Queue/QueueDetails'; import QueueDetails from 'Activity/Queue/QueueDetails';
import TrackQuality from './TrackQuality'; import TrackQuality from 'Album/TrackQuality';
import styles from './EpisodeStatus.css'; import styles from './TrackStatus.css';
function EpisodeStatus(props) { function TrackStatus(props) {
const { const {
airDateUtc, releaseDate,
monitored, monitored,
grabbed, grabbed,
queueItem, queueItem,
@ -19,7 +19,7 @@ function EpisodeStatus(props) {
const hasTrackFile = !!trackFile; const hasTrackFile = !!trackFile;
const isQueued = !!queueItem; const isQueued = !!queueItem;
const hasAired = isBefore(airDateUtc); const hasReleased = isBefore(releaseDate);
if (isQueued) { if (isQueued) {
const { const {
@ -73,7 +73,7 @@ function EpisodeStatus(props) {
); );
} }
if (!airDateUtc) { if (!releaseDate) {
return ( return (
<div className={styles.center}> <div className={styles.center}>
<Icon <Icon
@ -95,7 +95,7 @@ function EpisodeStatus(props) {
); );
} }
if (hasAired) { if (hasReleased) {
return ( return (
<div className={styles.center}> <div className={styles.center}>
<Icon <Icon
@ -110,18 +110,18 @@ function EpisodeStatus(props) {
<div className={styles.center}> <div className={styles.center}>
<Icon <Icon
name={icons.NOT_AIRED} name={icons.NOT_AIRED}
title="Album has not aired" title="Album has not released"
/> />
</div> </div>
); );
} }
EpisodeStatus.propTypes = { TrackStatus.propTypes = {
airDateUtc: PropTypes.string, releaseDate: PropTypes.string,
monitored: PropTypes.bool, monitored: PropTypes.bool,
grabbed: PropTypes.bool, grabbed: PropTypes.bool,
queueItem: PropTypes.object, queueItem: PropTypes.object,
trackFile: PropTypes.object trackFile: PropTypes.object
}; };
export default EpisodeStatus; export default TrackStatus;

@ -6,7 +6,7 @@ import { createSelector } from 'reselect';
import createAlbumSelector from 'Store/Selectors/createAlbumSelector'; import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
import createQueueItemSelector from 'Store/Selectors/createQueueItemSelector'; import createQueueItemSelector from 'Store/Selectors/createQueueItemSelector';
import createTrackFileSelector from 'Store/Selectors/createTrackFileSelector'; import createTrackFileSelector from 'Store/Selectors/createTrackFileSelector';
import EpisodeStatus from './EpisodeStatus'; import TrackStatus from './TrackStatus';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
@ -15,7 +15,7 @@ function createMapStateToProps() {
createTrackFileSelector(), createTrackFileSelector(),
(album, queueItem, trackFile) => { (album, queueItem, trackFile) => {
const result = _.pick(album, [ const result = _.pick(album, [
'airDateUtc', 'releaseDate',
'monitored', 'monitored',
'grabbed' 'grabbed'
]); ]);
@ -31,23 +31,23 @@ function createMapStateToProps() {
const mapDispatchToProps = { const mapDispatchToProps = {
}; };
class EpisodeStatusConnector extends Component { class TrackStatusConnector extends Component {
// //
// Render // Render
render() { render() {
return ( return (
<EpisodeStatus <TrackStatus
{...this.props} {...this.props}
/> />
); );
} }
} }
EpisodeStatusConnector.propTypes = { TrackStatusConnector.propTypes = {
albumId: PropTypes.number.isRequired, albumId: PropTypes.number.isRequired,
trackFileId: PropTypes.number.isRequired trackFileId: PropTypes.number.isRequired
}; };
export default connect(createMapStateToProps, mapDispatchToProps)(EpisodeStatusConnector); export default connect(createMapStateToProps, mapDispatchToProps)(TrackStatusConnector);

@ -0,0 +1,13 @@
import { createSelector } from 'reselect';
function createAlbumTrackFilesSelector() {
return createSelector(
(state, { albumId }) => albumId,
(state) => state.trackFiles(),
(albumId, trackFiles) => {
return trackFiles.find((trackFile) => trackFile.albumId === albumId );
}
);
}
export default createAlbumTrackFilesSelector;

@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import albumEntities from 'Album/albumEntities'; import albumEntities from 'Album/albumEntities';
import AlbumTitleLink from 'Album/AlbumTitleLink'; import AlbumTitleLink from 'Album/AlbumTitleLink';
import EpisodeStatusConnector from 'Album/EpisodeStatusConnector'; import AlbumStatusConnector from 'Album/AlbumStatusConnector';
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector'; import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
import ArtistNameLink from 'Artist/ArtistNameLink'; import ArtistNameLink from 'Artist/ArtistNameLink';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector'; import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
@ -14,8 +14,8 @@ import styles from './CutoffUnmetRow.css';
function CutoffUnmetRow(props) { function CutoffUnmetRow(props) {
const { const {
id, id,
trackFileId,
artist, artist,
trackFiles,
releaseDate, releaseDate,
foreignAlbumId, foreignAlbumId,
albumType, albumType,
@ -95,9 +95,9 @@ function CutoffUnmetRow(props) {
key={name} key={name}
className={styles.status} className={styles.status}
> >
<EpisodeStatusConnector <AlbumStatusConnector
albumId={id} albumId={id}
trackFileId={trackFileId} trackFiles={trackFiles}
albumEntity={albumEntities.WANTED_CUTOFF_UNMET} albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
/> />
</TableRowCell> </TableRowCell>
@ -126,8 +126,8 @@ function CutoffUnmetRow(props) {
CutoffUnmetRow.propTypes = { CutoffUnmetRow.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
trackFileId: PropTypes.number,
artist: PropTypes.object.isRequired, artist: PropTypes.object.isRequired,
trackFiles: PropTypes.arrayOf(PropTypes.object),
releaseDate: PropTypes.string.isRequired, releaseDate: PropTypes.string.isRequired,
foreignAlbumId: PropTypes.string.isRequired, foreignAlbumId: PropTypes.string.isRequired,
albumType: PropTypes.string.isRequired, albumType: PropTypes.string.isRequired,

@ -1,14 +1,17 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import createArtistSelector from 'Store/Selectors/createArtistSelector'; import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createAlbumTrackFilesSelector from 'Store/Selectors/createAlbumTrackFilesSelector';
import CutoffUnmetRow from './CutoffUnmetRow'; import CutoffUnmetRow from './CutoffUnmetRow';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
createArtistSelector(), createArtistSelector(),
(artist) => { createAlbumTrackFilesSelector(),
(artist, trackFiles) => {
return { return {
artist artist,
trackFiles
}; };
} }
); );

Loading…
Cancel
Save