parent
5fec72395c
commit
0a7f18e843
@ -0,0 +1,219 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import Label from 'Components/Label';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
|
||||
import EpisodeSearchCellConnector from 'Episode/EpisodeSearchCellConnector';
|
||||
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
|
||||
|
||||
import styles from './AlbumRow.css';
|
||||
|
||||
function getEpisodeCountKind(monitored, episodeFileCount, episodeCount) {
|
||||
if (episodeFileCount === episodeCount && episodeCount > 0) {
|
||||
return kinds.SUCCESS;
|
||||
}
|
||||
|
||||
if (!monitored) {
|
||||
return kinds.WARNING;
|
||||
}
|
||||
|
||||
return kinds.DANGER;
|
||||
}
|
||||
|
||||
class AlbumRow extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isDetailsModalOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onManualSearchPress = () => {
|
||||
this.setState({ isDetailsModalOpen: true });
|
||||
}
|
||||
|
||||
onDetailsModalClose = () => {
|
||||
this.setState({ isDetailsModalOpen: false });
|
||||
}
|
||||
|
||||
onMonitorAlbumPress = (monitored, options) => {
|
||||
this.props.onMonitorAlbumPress(this.props.id, monitored, options);
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
id,
|
||||
artistId,
|
||||
monitored,
|
||||
statistics,
|
||||
duration,
|
||||
releaseDate,
|
||||
title,
|
||||
isSaving,
|
||||
artistMonitored,
|
||||
path,
|
||||
columns
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
trackCount,
|
||||
trackFileCount,
|
||||
totalTrackCount
|
||||
} = statistics;
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
{
|
||||
columns.map((column) => {
|
||||
const {
|
||||
name,
|
||||
isVisible
|
||||
} = column;
|
||||
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name === 'monitored') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.monitored}
|
||||
>
|
||||
<MonitorToggleButton
|
||||
monitored={monitored}
|
||||
isDisabled={!artistMonitored}
|
||||
isSaving={isSaving}
|
||||
onPress={this.onMonitorAlbumPress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'title') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.title}
|
||||
>
|
||||
<EpisodeTitleLink
|
||||
episodeId={id}
|
||||
artistId={artistId}
|
||||
episodeTitle={title}
|
||||
showOpenSeriesButton={false}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'path') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
{
|
||||
path
|
||||
}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'trackCount') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
{
|
||||
statistics.trackCount
|
||||
}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'duration') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
{
|
||||
formatTimeSpan(duration)
|
||||
}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'releaseDate') {
|
||||
return (
|
||||
<RelativeDateCellConnector
|
||||
key={name}
|
||||
date={releaseDate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'status') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.status}
|
||||
>
|
||||
<Label
|
||||
title={`${totalTrackCount} tracks total. ${trackFileCount} tracks with files.`}
|
||||
kind={getEpisodeCountKind(monitored, trackFileCount, trackCount)}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
{
|
||||
<span>{trackFileCount} / {trackCount}</span>
|
||||
}
|
||||
</Label>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<EpisodeSearchCellConnector
|
||||
key={name}
|
||||
episodeId={id}
|
||||
artistId={artistId}
|
||||
episodeTitle={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AlbumRow.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
artistId: PropTypes.number.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
releaseDate: PropTypes.string.isRequired,
|
||||
duration: PropTypes.number.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
isSaving: PropTypes.bool,
|
||||
unverifiedSceneNumbering: PropTypes.bool,
|
||||
artistMonitored: PropTypes.bool.isRequired,
|
||||
statistics: PropTypes.object.isRequired,
|
||||
path: PropTypes.string,
|
||||
mediaInfo: PropTypes.object,
|
||||
alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onMonitorAlbumPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default AlbumRow;
|
@ -0,0 +1,36 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import Label from 'Components/Label';
|
||||
import Link from 'Components/Link/Link';
|
||||
import styles from './ArtistDetailsLinks.css';
|
||||
|
||||
function ArtistDetailsLinks(props) {
|
||||
const {
|
||||
foreignArtistId
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={styles.links}>
|
||||
<Link
|
||||
className={styles.link}
|
||||
to={`https://musicbrainz.org/artist/${foreignArtistId}`}
|
||||
>
|
||||
<Label
|
||||
className={styles.linkLabel}
|
||||
kind={kinds.INFO}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
Musicbrainz
|
||||
</Label>
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ArtistDetailsLinks.propTypes = {
|
||||
foreignArtistId: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default ArtistDetailsLinks;
|
@ -1,266 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import EpisodeSearchCellConnector from 'Episode/EpisodeSearchCellConnector';
|
||||
import EpisodeNumber from 'Episode/EpisodeNumber';
|
||||
import EpisodeTitleLink from 'Episode/EpisodeTitleLink';
|
||||
import EpisodeStatusConnector from 'Episode/EpisodeStatusConnector';
|
||||
import EpisodeFileLanguageConnector from 'EpisodeFile/EpisodeFileLanguageConnector';
|
||||
import MediaInfoConnector from 'EpisodeFile/MediaInfoConnector';
|
||||
import * as mediaInfoTypes from 'EpisodeFile/mediaInfoTypes';
|
||||
|
||||
import styles from './EpisodeRow.css';
|
||||
|
||||
class EpisodeRow extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isDetailsModalOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onManualSearchPress = () => {
|
||||
this.setState({ isDetailsModalOpen: true });
|
||||
}
|
||||
|
||||
onDetailsModalClose = () => {
|
||||
this.setState({ isDetailsModalOpen: false });
|
||||
}
|
||||
|
||||
onMonitorEpisodePress = (monitored, options) => {
|
||||
this.props.onMonitorEpisodePress(this.props.id, monitored, options);
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
id,
|
||||
artistId,
|
||||
episodeFileId,
|
||||
monitored,
|
||||
seasonNumber,
|
||||
episodeNumber,
|
||||
absoluteEpisodeNumber,
|
||||
sceneSeasonNumber,
|
||||
sceneEpisodeNumber,
|
||||
sceneAbsoluteEpisodeNumber,
|
||||
airDateUtc,
|
||||
title,
|
||||
unverifiedSceneNumbering,
|
||||
isSaving,
|
||||
seriesMonitored,
|
||||
seriesType,
|
||||
episodeFilePath,
|
||||
episodeFileRelativePath,
|
||||
alternateTitles,
|
||||
columns
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
{
|
||||
columns.map((column) => {
|
||||
const {
|
||||
name,
|
||||
isVisible
|
||||
} = column;
|
||||
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (name === 'monitored') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.monitored}
|
||||
>
|
||||
<MonitorToggleButton
|
||||
monitored={monitored}
|
||||
isDisabled={!seriesMonitored}
|
||||
isSaving={isSaving}
|
||||
onPress={this.onMonitorEpisodePress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'episodeNumber') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.episodeNumber}
|
||||
>
|
||||
<EpisodeNumber
|
||||
seasonNumber={seasonNumber}
|
||||
episodeNumber={episodeNumber}
|
||||
absoluteEpisodeNumber={absoluteEpisodeNumber}
|
||||
unverifiedSceneNumbering={unverifiedSceneNumbering}
|
||||
seriesType={seriesType}
|
||||
sceneSeasonNumber={sceneSeasonNumber}
|
||||
sceneEpisodeNumber={sceneEpisodeNumber}
|
||||
sceneAbsoluteEpisodeNumber={sceneAbsoluteEpisodeNumber}
|
||||
alternateTitles={alternateTitles}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'title') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.title}
|
||||
>
|
||||
<EpisodeTitleLink
|
||||
episodeId={id}
|
||||
artistId={artistId}
|
||||
episodeTitle={title}
|
||||
showOpenSeriesButton={false}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'path') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
{
|
||||
episodeFilePath
|
||||
}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'relativePath') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
{
|
||||
episodeFileRelativePath
|
||||
}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'airDateUtc') {
|
||||
return (
|
||||
<RelativeDateCellConnector
|
||||
key={name}
|
||||
date={airDateUtc}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'language') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.language}
|
||||
>
|
||||
<EpisodeFileLanguageConnector
|
||||
episodeFileId={episodeFileId}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'audioInfo') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.audio}
|
||||
>
|
||||
<MediaInfoConnector
|
||||
type={mediaInfoTypes.AUDIO}
|
||||
episodeFileId={episodeFileId}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'videoCodec') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.video}
|
||||
>
|
||||
<MediaInfoConnector
|
||||
type={mediaInfoTypes.VIDEO}
|
||||
episodeFileId={episodeFileId}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'status') {
|
||||
return (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.status}
|
||||
>
|
||||
<EpisodeStatusConnector
|
||||
episodeId={id}
|
||||
episodeFileId={episodeFileId}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<EpisodeSearchCellConnector
|
||||
key={name}
|
||||
episodeId={id}
|
||||
artistId={artistId}
|
||||
episodeTitle={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})
|
||||
}
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EpisodeRow.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
artistId: PropTypes.number.isRequired,
|
||||
episodeFileId: PropTypes.number,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
seasonNumber: PropTypes.number.isRequired,
|
||||
episodeNumber: PropTypes.number.isRequired,
|
||||
absoluteEpisodeNumber: PropTypes.number,
|
||||
sceneSeasonNumber: PropTypes.number,
|
||||
sceneEpisodeNumber: PropTypes.number,
|
||||
sceneAbsoluteEpisodeNumber: PropTypes.number,
|
||||
airDateUtc: PropTypes.string,
|
||||
title: PropTypes.string.isRequired,
|
||||
isSaving: PropTypes.bool,
|
||||
unverifiedSceneNumbering: PropTypes.bool,
|
||||
seriesMonitored: PropTypes.bool.isRequired,
|
||||
seriesType: PropTypes.string.isRequired,
|
||||
episodeFilePath: PropTypes.string,
|
||||
episodeFileRelativePath: PropTypes.string,
|
||||
mediaInfo: PropTypes.object,
|
||||
alternateTitles: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
onMonitorEpisodePress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default EpisodeRow;
|
@ -1,70 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import Label from 'Components/Label';
|
||||
import Link from 'Components/Link/Link';
|
||||
import styles from './SeriesDetailsLinks.css';
|
||||
|
||||
function SeriesDetailsLinks(props) {
|
||||
const {
|
||||
foreignArtistId,
|
||||
tvMazeId,
|
||||
imdbId
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={styles.links}>
|
||||
<Link
|
||||
className={styles.link}
|
||||
to={`https://musicbrainz.org/artist/${foreignArtistId}`}
|
||||
>
|
||||
<Label
|
||||
className={styles.linkLabel}
|
||||
kind={kinds.INFO}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
Musicbrainz
|
||||
</Label>
|
||||
</Link>
|
||||
{
|
||||
!!tvMazeId &&
|
||||
<Link
|
||||
className={styles.link}
|
||||
to={`http://www.tvmaze.com/shows/${tvMazeId}/_`}
|
||||
>
|
||||
<Label
|
||||
className={styles.linkLabel}
|
||||
kind={kinds.INFO}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
TV Maze
|
||||
</Label>
|
||||
</Link>
|
||||
}
|
||||
|
||||
{
|
||||
!!imdbId &&
|
||||
<Link
|
||||
className={styles.link}
|
||||
to={`http://imdb.com/title/${imdbId}/`}
|
||||
>
|
||||
<Label
|
||||
className={styles.linkLabel}
|
||||
kind={kinds.INFO}
|
||||
size={sizes.LARGE}
|
||||
>
|
||||
IMDB
|
||||
</Label>
|
||||
</Link>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
SeriesDetailsLinks.propTypes = {
|
||||
foreignArtistId: PropTypes.string.isRequired,
|
||||
tvMazeId: PropTypes.number,
|
||||
imdbId: PropTypes.string
|
||||
};
|
||||
|
||||
export default SeriesDetailsLinks;
|
Loading…
Reference in new issue