diff --git a/frontend/src/AlbumStudio/AlbumStudioAlbum.js b/frontend/src/AlbumStudio/AlbumStudioAlbum.js
index 4e4be3ac1..d1c9e393d 100644
--- a/frontend/src/AlbumStudio/AlbumStudioAlbum.js
+++ b/frontend/src/AlbumStudio/AlbumStudioAlbum.js
@@ -10,13 +10,13 @@ class AlbumStudioAlbum extends Component {
//
// Listeners
- onSeasonMonitoredPress = () => {
+ onAlbumMonitoredPress = () => {
const {
id,
monitored
} = this.props;
- this.props.onSeasonMonitoredPress(id, !monitored);
+ this.props.onAlbumMonitoredPress(id, !monitored);
}
//
@@ -43,7 +43,7 @@ class AlbumStudioAlbum extends Component {
@@ -75,7 +75,7 @@ AlbumStudioAlbum.propTypes = {
monitored: PropTypes.bool.isRequired,
statistics: PropTypes.object.isRequired,
isSaving: PropTypes.bool.isRequired,
- onSeasonMonitoredPress: PropTypes.func.isRequired
+ onAlbumMonitoredPress: PropTypes.func.isRequired
};
AlbumStudioAlbum.defaultProps = {
diff --git a/frontend/src/AlbumStudio/AlbumStudioRow.js b/frontend/src/AlbumStudio/AlbumStudioRow.js
index 0f0711335..d63dc83ee 100644
--- a/frontend/src/AlbumStudio/AlbumStudioRow.js
+++ b/frontend/src/AlbumStudio/AlbumStudioRow.js
@@ -26,8 +26,8 @@ class AlbumStudioRow extends Component {
isSaving,
isSelected,
onSelectedChange,
- onSeriesMonitoredPress,
- onSeasonMonitoredPress
+ onArtistMonitoredPress,
+ onAlbumMonitoredPress
} = this.props;
return (
@@ -41,7 +41,7 @@ class AlbumStudioRow extends Component {
@@ -58,7 +58,7 @@ class AlbumStudioRow extends Component {
@@ -69,7 +69,7 @@ class AlbumStudioRow extends Component {
);
})
@@ -90,8 +90,8 @@ AlbumStudioRow.propTypes = {
isSaving: PropTypes.bool.isRequired,
isSelected: PropTypes.bool,
onSelectedChange: PropTypes.func.isRequired,
- onSeriesMonitoredPress: PropTypes.func.isRequired,
- onSeasonMonitoredPress: PropTypes.func.isRequired
+ onArtistMonitoredPress: PropTypes.func.isRequired,
+ onAlbumMonitoredPress: PropTypes.func.isRequired
};
AlbumStudioRow.defaultProps = {
diff --git a/frontend/src/AlbumStudio/AlbumStudioRowConnector.js b/frontend/src/AlbumStudio/AlbumStudioRowConnector.js
index ac7b79927..1a0ae45ad 100644
--- a/frontend/src/AlbumStudio/AlbumStudioRowConnector.js
+++ b/frontend/src/AlbumStudio/AlbumStudioRowConnector.js
@@ -5,6 +5,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import { toggleSeriesMonitored, toggleSeasonMonitored } from 'Store/Actions/artistActions';
+import { toggleEpisodeMonitored } from 'Store/Actions/episodeActions';
import AlbumStudioRow from './AlbumStudioRow';
function createMapStateToProps() {
@@ -25,7 +26,8 @@ function createMapStateToProps() {
const mapDispatchToProps = {
toggleSeriesMonitored,
- toggleSeasonMonitored
+ toggleSeasonMonitored,
+ toggleEpisodeMonitored
};
class AlbumStudioRowConnector extends Component {
@@ -33,7 +35,7 @@ class AlbumStudioRowConnector extends Component {
//
// Listeners
- onSeriesMonitoredPress = () => {
+ onArtistMonitoredPress = () => {
const {
artistId,
monitored
@@ -45,11 +47,10 @@ class AlbumStudioRowConnector extends Component {
});
}
- onSeasonMonitoredPress = (seasonNumber, monitored) => {
- this.props.toggleSeasonMonitored({
- artistId: this.props.artistId,
- seasonNumber,
- monitored
+ onAlbumMonitoredPress = (episodeId, monitored) => {
+ this.props.toggleEpisodeMonitored({
+ episodeId,
+ monitored: !monitored
});
}
@@ -60,8 +61,8 @@ class AlbumStudioRowConnector extends Component {
return (
);
}
@@ -71,7 +72,8 @@ AlbumStudioRowConnector.propTypes = {
artistId: PropTypes.number.isRequired,
monitored: PropTypes.bool.isRequired,
toggleSeriesMonitored: PropTypes.func.isRequired,
- toggleSeasonMonitored: PropTypes.func.isRequired
+ toggleSeasonMonitored: PropTypes.func.isRequired,
+ toggleEpisodeMonitored: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(AlbumStudioRowConnector);
diff --git a/frontend/src/App/App.js b/frontend/src/App/App.js
index 4295ab2af..5a8d6a95c 100644
--- a/frontend/src/App/App.js
+++ b/frontend/src/App/App.js
@@ -13,7 +13,7 @@ import AddNewArtistConnector from 'AddArtist/AddNewArtist/AddNewArtistConnector'
import ImportArtist from 'AddArtist/ImportArtist/ImportArtist';
import ArtistEditorConnector from 'Artist/Editor/ArtistEditorConnector';
import AlbumStudioConnector from 'AlbumStudio/AlbumStudioConnector';
-import SeriesDetailsPageConnector from 'Artist/Details/SeriesDetailsPageConnector';
+import ArtistDetailsPageConnector from 'Artist/Details/ArtistDetailsPageConnector';
import CalendarPageConnector from 'Calendar/CalendarPageConnector';
import HistoryConnector from 'Activity/History/HistoryConnector';
import QueueConnector from 'Activity/Queue/QueueConnector';
@@ -93,7 +93,7 @@ function App({ store, history }) {
{/*
diff --git a/frontend/src/Artist/Details/EpisodeRow.css b/frontend/src/Artist/Details/AlbumRow.css
similarity index 69%
rename from frontend/src/Artist/Details/EpisodeRow.css
rename to frontend/src/Artist/Details/AlbumRow.css
index fc7bf0397..255ee76c9 100644
--- a/frontend/src/Artist/Details/EpisodeRow.css
+++ b/frontend/src/Artist/Details/AlbumRow.css
@@ -10,15 +10,6 @@
width: 42px;
}
-.episodeNumber {
- composes: cell from 'Components/Table/Cells/TableRowCell.css';
-
- width: 50px;
-}
-
-.language,
-.audio,
-.video,
.status {
composes: cell from 'Components/Table/Cells/TableRowCell.css';
diff --git a/frontend/src/Artist/Details/AlbumRow.js b/frontend/src/Artist/Details/AlbumRow.js
new file mode 100644
index 000000000..8c0e2b804
--- /dev/null
+++ b/frontend/src/Artist/Details/AlbumRow.js
@@ -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 (
+
+ {
+ columns.map((column) => {
+ const {
+ name,
+ isVisible
+ } = column;
+
+ if (!isVisible) {
+ return null;
+ }
+
+ if (name === 'monitored') {
+ return (
+
+
+
+ );
+ }
+
+ if (name === 'title') {
+ return (
+
+
+
+ );
+ }
+
+ if (name === 'path') {
+ return (
+
+ {
+ path
+ }
+
+ );
+ }
+
+ if (name === 'trackCount') {
+ return (
+
+ {
+ statistics.trackCount
+ }
+
+ );
+ }
+
+ if (name === 'duration') {
+ return (
+
+ {
+ formatTimeSpan(duration)
+ }
+
+ );
+ }
+
+ if (name === 'releaseDate') {
+ return (
+
+ );
+ }
+
+ if (name === 'status') {
+ return (
+
+
+
+ );
+ }
+
+ if (name === 'actions') {
+ return (
+
+ );
+ }
+
+ return null;
+ })
+ }
+
+ );
+ }
+}
+
+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;
diff --git a/frontend/src/Artist/Details/EpisodeRowConnector.js b/frontend/src/Artist/Details/AlbumRowConnector.js
similarity index 87%
rename from frontend/src/Artist/Details/EpisodeRowConnector.js
rename to frontend/src/Artist/Details/AlbumRowConnector.js
index e827c17b5..eba950ab3 100644
--- a/frontend/src/Artist/Details/EpisodeRowConnector.js
+++ b/frontend/src/Artist/Details/AlbumRowConnector.js
@@ -4,7 +4,7 @@ import { createSelector } from 'reselect';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createEpisodeFileSelector from 'Store/Selectors/createEpisodeFileSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
-import EpisodeRow from './EpisodeRow';
+import AlbumRow from './AlbumRow';
function createMapStateToProps() {
return createSelector(
@@ -17,7 +17,7 @@ function createMapStateToProps() {
const alternateTitles = sceneSeasonNumber ? _.filter(series.alternateTitles, { sceneSeasonNumber }) : [];
return {
- seriesMonitored: series.monitored,
+ artistMonitored: series.monitored,
seriesType: series.seriesType,
episodeFilePath: episodeFile ? episodeFile.path : null,
episodeFileRelativePath: episodeFile ? episodeFile.relativePath : null,
@@ -26,4 +26,4 @@ function createMapStateToProps() {
}
);
}
-export default connect(createMapStateToProps)(EpisodeRow);
+export default connect(createMapStateToProps)(AlbumRow);
diff --git a/frontend/src/Artist/Details/SeriesAlternateTitles.css b/frontend/src/Artist/Details/ArtistAlternateTitles.css
similarity index 100%
rename from frontend/src/Artist/Details/SeriesAlternateTitles.css
rename to frontend/src/Artist/Details/ArtistAlternateTitles.css
diff --git a/frontend/src/Artist/Details/SeriesAlternateTitles.js b/frontend/src/Artist/Details/ArtistAlternateTitles.js
similarity index 71%
rename from frontend/src/Artist/Details/SeriesAlternateTitles.js
rename to frontend/src/Artist/Details/ArtistAlternateTitles.js
index 18d016579..e1fde52e6 100644
--- a/frontend/src/Artist/Details/SeriesAlternateTitles.js
+++ b/frontend/src/Artist/Details/ArtistAlternateTitles.js
@@ -1,8 +1,8 @@
import PropTypes from 'prop-types';
import React from 'react';
-import styles from './SeriesAlternateTitles.css';
+import styles from './ArtistAlternateTitles.css';
-function SeriesAlternateTitles({ alternateTitles }) {
+function ArtistAlternateTitles({ alternateTitles }) {
return (
{
@@ -21,8 +21,8 @@ function SeriesAlternateTitles({ alternateTitles }) {
);
}
-SeriesAlternateTitles.propTypes = {
+ArtistAlternateTitles.propTypes = {
alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired
};
-export default SeriesAlternateTitles;
+export default ArtistAlternateTitles;
diff --git a/frontend/src/Artist/Details/SeriesDetails.css b/frontend/src/Artist/Details/ArtistDetails.css
similarity index 96%
rename from frontend/src/Artist/Details/SeriesDetails.css
rename to frontend/src/Artist/Details/ArtistDetails.css
index 7a2daccb2..20b8d911f 100644
--- a/frontend/src/Artist/Details/SeriesDetails.css
+++ b/frontend/src/Artist/Details/ArtistDetails.css
@@ -61,11 +61,11 @@
line-height: 50px;
}
-.seriesNavigationButtons {
+.artistNavigationButtons {
white-space: no-wrap;
}
-.seriesNavigationButton {
+.artistNavigationButton {
composes: button from 'Components/Link/IconButton.css';
margin-left: 5px;
@@ -90,7 +90,6 @@
.sizeOnDisk,
.qualityProfileName,
-.network,
.links,
.tags {
margin-left: 8px;
diff --git a/frontend/src/Artist/Details/SeriesDetails.js b/frontend/src/Artist/Details/ArtistDetails.js
similarity index 84%
rename from frontend/src/Artist/Details/SeriesDetails.js
rename to frontend/src/Artist/Details/ArtistDetails.js
index f9b33cb42..14a1e6b3e 100644
--- a/frontend/src/Artist/Details/SeriesDetails.js
+++ b/frontend/src/Artist/Details/ArtistDetails.js
@@ -24,11 +24,29 @@ import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfil
import ArtistPoster from 'Artist/ArtistPoster';
import EditArtistModalConnector from 'Artist/Edit/EditArtistModalConnector';
import DeleteArtistModal from 'Artist/Delete/DeleteArtistModal';
-import SeriesAlternateTitles from './SeriesAlternateTitles';
-import SeriesDetailsSeasonConnector from './SeriesDetailsSeasonConnector';
-import SeriesTagsConnector from './SeriesTagsConnector';
-import SeriesDetailsLinks from './SeriesDetailsLinks';
-import styles from './SeriesDetails.css';
+import ArtistAlternateTitles from './ArtistAlternateTitles';
+import ArtistDetailsSeasonConnector from './ArtistDetailsSeasonConnector';
+import ArtistTagsConnector from './ArtistTagsConnector';
+import ArtistDetailsLinks from './ArtistDetailsLinks';
+import styles from './ArtistDetails.css';
+
+const albumTypes = [
+ {
+ name: 'album',
+ label: 'Album',
+ isVisible: true
+ },
+ {
+ name: 'single',
+ label: 'Single',
+ isVisible: true
+ },
+ {
+ name: 'ep',
+ label: 'EP',
+ isVisible: true
+ }
+];
function getFanartUrl(images) {
const fanartImage = _.find(images, { coverType: 'fanart' });
@@ -46,7 +64,7 @@ function getExpandedState(newState) {
};
}
-class SeriesDetails extends Component {
+class ArtistDetails extends Component {
//
// Lifecycle
@@ -133,8 +151,6 @@ class SeriesDetails extends Component {
const {
id,
foreignArtistId,
- tvMazeId,
- imdbId,
artistName,
ratings,
sizeOnDisk,
@@ -142,7 +158,6 @@ class SeriesDetails extends Component {
qualityProfileId,
monitored,
status,
- network,
overview,
images,
albums,
@@ -154,8 +169,8 @@ class SeriesDetails extends Component {
isPopulated,
episodesError,
episodeFilesError,
- previousSeries,
- nextSeries,
+ previousArtist,
+ nextArtist,
onRefreshPress,
onSearchPress
} = this.props;
@@ -172,12 +187,12 @@ class SeriesDetails extends Component {
const continuing = status === 'continuing';
- let episodeFilesCountMessage = 'No episode files';
+ let episodeFilesCountMessage = 'No track files';
if (trackFileCount === 1) {
- episodeFilesCountMessage = '1 episode file';
+ episodeFilesCountMessage = '1 track file';
} else if (trackFileCount > 1) {
- episodeFilesCountMessage = `${trackFileCount} episode files`;
+ episodeFilesCountMessage = `${trackFileCount} track files`;
}
let expandIcon = icons.EXPAND_INDETERMINATE;
@@ -217,7 +232,7 @@ class SeriesDetails extends Component {
/>
@@ -281,28 +296,28 @@ class SeriesDetails extends Component {
/>
}
title="Alternate Titles"
- body={}
+ body={}
position={tooltipPositions.BOTTOM}
/>
}
-
@@ -369,11 +384,11 @@ class SeriesDetails extends Component {
- {
- !!network &&
-
- }
-
}
tooltip={
-
}
kind={kinds.INVERSE}
@@ -445,7 +440,7 @@ class SeriesDetails extends Component {
}
- tooltip={}
+ tooltip={}
kind={kinds.INVERSE}
position={tooltipPositions.BOTTOM}
/>
@@ -477,18 +472,17 @@ class SeriesDetails extends Component {
}
{
- isPopulated && !!albums.length &&
+ isPopulated && !!albumTypes.length &&
{
- albums.slice(0).reverse().map((season) => {
+ albumTypes.slice(0).map((season) => {
return (
-
);
@@ -536,11 +530,9 @@ class SeriesDetails extends Component {
}
}
-SeriesDetails.propTypes = {
+ArtistDetails.propTypes = {
id: PropTypes.number.isRequired,
foreignArtistId: PropTypes.string.isRequired,
- tvMazeId: PropTypes.number,
- imdbId: PropTypes.string,
artistName: PropTypes.string.isRequired,
ratings: PropTypes.object.isRequired,
sizeOnDisk: PropTypes.number.isRequired,
@@ -548,7 +540,6 @@ SeriesDetails.propTypes = {
qualityProfileId: PropTypes.number.isRequired,
monitored: PropTypes.bool.isRequired,
status: PropTypes.string.isRequired,
- network: PropTypes.string,
overview: PropTypes.string.isRequired,
images: PropTypes.arrayOf(PropTypes.object).isRequired,
albums: PropTypes.arrayOf(PropTypes.object).isRequired,
@@ -560,10 +551,10 @@ SeriesDetails.propTypes = {
isPopulated: PropTypes.bool.isRequired,
episodesError: PropTypes.object,
episodeFilesError: PropTypes.object,
- previousSeries: PropTypes.object.isRequired,
- nextSeries: PropTypes.object.isRequired,
+ previousArtist: PropTypes.object.isRequired,
+ nextArtist: PropTypes.object.isRequired,
onRefreshPress: PropTypes.func.isRequired,
onSearchPress: PropTypes.func.isRequired
};
-export default SeriesDetails;
+export default ArtistDetails;
diff --git a/frontend/src/Artist/Details/SeriesDetailsConnector.js b/frontend/src/Artist/Details/ArtistDetailsConnector.js
similarity index 83%
rename from frontend/src/Artist/Details/SeriesDetailsConnector.js
rename to frontend/src/Artist/Details/ArtistDetailsConnector.js
index 7ec84f95e..d223ea1d7 100644
--- a/frontend/src/Artist/Details/SeriesDetailsConnector.js
+++ b/frontend/src/Artist/Details/ArtistDetailsConnector.js
@@ -11,7 +11,7 @@ import { fetchEpisodeFiles, clearEpisodeFiles } from 'Store/Actions/episodeFileA
import { fetchQueueDetails, clearQueueDetails } from 'Store/Actions/queueActions';
import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames';
-import SeriesDetails from './SeriesDetails';
+import ArtistDetails from './ArtistDetails';
function createMapStateToProps() {
return createSelector(
@@ -21,7 +21,7 @@ function createMapStateToProps() {
createAllArtistSelector(),
createCommandsSelector(),
(nameSlug, episodes, episodeFiles, allSeries, commands) => {
- const sortedArtist = _.orderBy(allSeries, 'sortTitle');
+ const sortedArtist = _.orderBy(allSeries, 'sortName');
const seriesIndex = _.findIndex(sortedArtist, { nameSlug });
const series = sortedArtist[seriesIndex];
@@ -29,15 +29,15 @@ function createMapStateToProps() {
return {};
}
- const previousSeries = sortedArtist[seriesIndex - 1] || _.last(sortedArtist);
- const nextSeries = sortedArtist[seriesIndex + 1] || _.first(sortedArtist);
- const isSeriesRefreshing = !!findCommand(commands, { name: commandNames.REFRESH_ARTIST, artistId: series.id });
- const allSeriesRefreshing = _.some(commands, (command) => command.name === commandNames.REFRESH_ARTIST && !command.body.artistId);
- const isRefreshing = isSeriesRefreshing || allSeriesRefreshing;
+ const previousArtist = sortedArtist[seriesIndex - 1] || _.last(sortedArtist);
+ const nextArtist = sortedArtist[seriesIndex + 1] || _.first(sortedArtist);
+ const isArtistRefreshing = !!findCommand(commands, { name: commandNames.REFRESH_ARTIST, artistId: series.id });
+ const allArtistRefreshing = _.some(commands, (command) => command.name === commandNames.REFRESH_ARTIST && !command.body.artistId);
+ const isRefreshing = isArtistRefreshing || allArtistRefreshing;
const isSearching = !!findCommand(commands, { name: commandNames.ARTIST_SEARCH, artistId: series.id });
const isRenamingFiles = !!findCommand(commands, { name: commandNames.RENAME_FILES, artistId: series.id });
- const isRenamingSeriesCommand = findCommand(commands, { name: commandNames.RENAME_ARTIST });
- const isRenamingSeries = !!(isRenamingSeriesCommand && isRenamingSeriesCommand.body.artistId.indexOf(series.id) > -1);
+ const isRenamingArtistCommand = findCommand(commands, { name: commandNames.RENAME_ARTIST });
+ const isRenamingArtist = !!(isRenamingArtistCommand && isRenamingArtistCommand.body.artistId.indexOf(series.id) > -1);
const isFetching = episodes.isFetching || episodeFiles.isFetching;
const isPopulated = episodes.isPopulated && episodeFiles.isPopulated;
@@ -58,13 +58,13 @@ function createMapStateToProps() {
isRefreshing,
isSearching,
isRenamingFiles,
- isRenamingSeries,
+ isRenamingArtist,
isFetching,
isPopulated,
episodesError,
episodeFilesError,
- previousSeries,
- nextSeries
+ previousArtist,
+ nextArtist
};
}
);
@@ -80,7 +80,7 @@ const mapDispatchToProps = {
executeCommand
};
-class SeriesDetailsConnector extends Component {
+class ArtistDetailsConnector extends Component {
//
// Lifecycle
@@ -94,13 +94,13 @@ class SeriesDetailsConnector extends Component {
id,
isRefreshing,
isRenamingFiles,
- isRenamingSeries
+ isRenamingArtist
} = this.props;
if (
(prevProps.isRefreshing && !isRefreshing) ||
(prevProps.isRenamingFiles && !isRenamingFiles) ||
- (prevProps.isRenamingSeries && !isRenamingSeries)
+ (prevProps.isRenamingArtist && !isRenamingArtist)
) {
this._populate();
}
@@ -157,7 +157,7 @@ class SeriesDetailsConnector extends Component {
render() {
return (
-
+
+
+
+
+
+ );
+}
+
+ArtistDetailsLinks.propTypes = {
+ foreignArtistId: PropTypes.string.isRequired
+};
+
+export default ArtistDetailsLinks;
diff --git a/frontend/src/Artist/Details/SeriesDetailsPageConnector.js b/frontend/src/Artist/Details/ArtistDetailsPageConnector.js
similarity index 87%
rename from frontend/src/Artist/Details/SeriesDetailsPageConnector.js
rename to frontend/src/Artist/Details/ArtistDetailsPageConnector.js
index aa6f29f5d..29817c512 100644
--- a/frontend/src/Artist/Details/SeriesDetailsPageConnector.js
+++ b/frontend/src/Artist/Details/ArtistDetailsPageConnector.js
@@ -6,7 +6,7 @@ import { createSelector } from 'reselect';
import { push } from 'react-router-redux';
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
import NotFound from 'Components/NotFound';
-import SeriesDetailsConnector from './SeriesDetailsConnector';
+import ArtistDetailsConnector from './ArtistDetailsConnector';
function createMapStateToProps() {
return createSelector(
@@ -31,7 +31,7 @@ const mapDispatchToProps = {
push
};
-class SeriesDetailsPageConnector extends Component {
+class ArtistDetailsPageConnector extends Component {
//
// Lifecycle
@@ -60,17 +60,17 @@ class SeriesDetailsPageConnector extends Component {
}
return (
-
);
}
}
-SeriesDetailsPageConnector.propTypes = {
+ArtistDetailsPageConnector.propTypes = {
nameSlug: PropTypes.string,
match: PropTypes.shape({ params: PropTypes.shape({ nameSlug: PropTypes.string.isRequired }).isRequired }).isRequired,
push: PropTypes.func.isRequired
};
-export default connect(createMapStateToProps, mapDispatchToProps)(SeriesDetailsPageConnector);
+export default connect(createMapStateToProps, mapDispatchToProps)(ArtistDetailsPageConnector);
diff --git a/frontend/src/Artist/Details/SeriesDetailsSeason.css b/frontend/src/Artist/Details/ArtistDetailsSeason.css
similarity index 91%
rename from frontend/src/Artist/Details/SeriesDetailsSeason.css
rename to frontend/src/Artist/Details/ArtistDetailsSeason.css
index 31a9da431..4cb0065e9 100644
--- a/frontend/src/Artist/Details/SeriesDetailsSeason.css
+++ b/frontend/src/Artist/Details/ArtistDetailsSeason.css
@@ -1,4 +1,4 @@
-.season {
+.albumType {
margin-bottom: 20px;
border: 1px solid $borderColor;
border-radius: 4px;
@@ -17,11 +17,17 @@
font-size: 24px;
}
-.seasonNumber {
- margin-right: 10px;
+.albumTypeLabel {
+ margin-right: 5px;
margin-left: 5px;
}
+.albumCount {
+ font-size: 18px;
+ font-style: italic;
+ color: #8895aa;
+}
+
.episodeCountContainer {
margin-left: 10px;
vertical-align: text-bottom;
@@ -38,7 +44,7 @@
.left {
display: flex;
align-items: center;
- flex: 0 1 600px;
+ flex: 0 1 300px;
}
.left,
diff --git a/frontend/src/Artist/Details/SeriesDetailsSeason.js b/frontend/src/Artist/Details/ArtistDetailsSeason.js
similarity index 66%
rename from frontend/src/Artist/Details/SeriesDetailsSeason.js
rename to frontend/src/Artist/Details/ArtistDetailsSeason.js
index 77858f53f..224d6d442 100644
--- a/frontend/src/Artist/Details/SeriesDetailsSeason.js
+++ b/frontend/src/Artist/Details/ArtistDetailsSeason.js
@@ -7,9 +7,7 @@ import getToggledRange from 'Utilities/Table/getToggledRange';
import { align, icons, kinds, sizes } from 'Helpers/Props';
import Icon from 'Components/Icon';
import IconButton from 'Components/Link/IconButton';
-import Label from 'Components/Label';
import Link from 'Components/Link/Link';
-import MonitorToggleButton from 'Components/MonitorToggleButton';
import SpinnerIcon from 'Components/SpinnerIcon';
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
import Menu from 'Components/Menu/Menu';
@@ -20,22 +18,10 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import EpisodeFileEditorModal from 'EpisodeFile/Editor/EpisodeFileEditorModal';
import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector';
-import EpisodeRowConnector from './EpisodeRowConnector';
-import styles from './SeriesDetailsSeason.css';
+import AlbumRowConnector from './AlbumRowConnector';
+import styles from './ArtistDetailsSeason.css';
-function getEpisodeCountKind(monitored, episodeFileCount, episodeCount) {
- if (episodeFileCount === episodeCount && episodeCount > 0) {
- return kinds.SUCCESS;
- }
-
- if (!monitored) {
- return kinds.WARNING;
- }
-
- return kinds.DANGER;
-}
-
-class SeriesDetailsSeason extends Component {
+class ArtistDetailsSeason extends Component {
//
// Lifecycle
@@ -65,7 +51,7 @@ class SeriesDetailsSeason extends Component {
_expandByDefault() {
const {
- albumId,
+ name,
onExpandPress,
items
} = this.props;
@@ -75,7 +61,7 @@ class SeriesDetailsSeason extends Component {
isAfter(item.airDateUtc, { days: -30 });
});
- onExpandPress(albumId, expand && albumId > 0);
+ onExpandPress(name, expand && name > 0);
}
//
@@ -99,29 +85,29 @@ class SeriesDetailsSeason extends Component {
onExpandPress = () => {
const {
- albumId,
+ name,
isExpanded
} = this.props;
- this.props.onExpandPress(albumId, !isExpanded);
+ this.props.onExpandPress(name, !isExpanded);
}
- onMonitorEpisodePress = (episodeId, monitored, { shiftKey }) => {
+ onMonitorAlbumPress = (albumId, monitored, { shiftKey }) => {
const lastToggled = this.state.lastToggledEpisode;
- const episodeIds = [episodeId];
+ const albumIds = [albumId];
if (shiftKey && lastToggled) {
- const { lower, upper } = getToggledRange(this.props.items, episodeId, lastToggled);
+ const { lower, upper } = getToggledRange(this.props.items, albumId, lastToggled);
const items = this.props.items;
for (let i = lower; i < upper; i++) {
- episodeIds.push(items[i].id);
+ albumIds.push(items[i].id);
}
}
- this.setState({ lastToggledEpisode: episodeId });
+ this.setState({ lastToggledEpisode: albumId });
- this.props.onMonitorEpisodePress(_.uniq(episodeIds), monitored);
+ this.props.onMonitorAlbumPress(_.uniq(albumIds), monitored);
}
//
@@ -130,29 +116,19 @@ class SeriesDetailsSeason extends Component {
render() {
const {
artistId,
- monitored,
- title,
- releaseDate,
- albumId,
- statistics,
+ label,
items,
columns,
isSaving,
isExpanded,
isSearching,
- seriesMonitored,
+ artistMonitored,
isSmallScreen,
onTableOptionChange,
onMonitorSeasonPress,
onSearchPress
} = this.props;
- const {
- trackCount,
- trackFileCount,
- totalTrackCount
- } = statistics;
-
const {
isOrganizeModalOpen,
isManageEpisodesOpen
@@ -160,37 +136,22 @@ class SeriesDetailsSeason extends Component {
return (
-
-
{
- albumId === 0 ?
-
- Specials
- :
-
- {title}
+
+
+ {label}
+
+
+ ({items.length} Releases)
+
+
}
-
+
+
{
!isSmallScreen &&
@@ -266,37 +234,62 @@ class SeriesDetailsSeason extends Component {
onPress={onSearchPress}
/>
-
-
-
}
+
+ {
+ isExpanded &&
+
+ {
+ items.length ?
+
+
+ {
+ items.map((item) => {
+ return (
+
+ );
+ })
+ }
+
+
:
+
+
+ No albums in this group
+
+ }
+
+
+
+
+ }
+
+
@@ -304,33 +297,22 @@ class SeriesDetailsSeason extends Component {
}
}
-SeriesDetailsSeason.propTypes = {
+ArtistDetailsSeason.propTypes = {
artistId: PropTypes.number.isRequired,
- monitored: PropTypes.bool.isRequired,
- title: PropTypes.string.isRequired,
- releaseDate: PropTypes.string.isRequired,
- albumId: PropTypes.number.isRequired,
- statistics: PropTypes.object.isRequired,
+ name: PropTypes.string.isRequired,
+ label: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
isSaving: PropTypes.bool,
isExpanded: PropTypes.bool,
isSearching: PropTypes.bool.isRequired,
- seriesMonitored: PropTypes.bool.isRequired,
+ artistMonitored: PropTypes.bool.isRequired,
isSmallScreen: PropTypes.bool.isRequired,
onTableOptionChange: PropTypes.func.isRequired,
onMonitorSeasonPress: PropTypes.func.isRequired,
onExpandPress: PropTypes.func.isRequired,
- onMonitorEpisodePress: PropTypes.func.isRequired,
+ onMonitorAlbumPress: PropTypes.func.isRequired,
onSearchPress: PropTypes.func.isRequired
};
-SeriesDetailsSeason.defaultProps = {
- statistics: {
- trackFileCount: 0,
- totalTrackCount: 0,
- percentOfTracks: 0
- }
-};
-
-export default SeriesDetailsSeason;
+export default ArtistDetailsSeason;
diff --git a/frontend/src/Artist/Details/SeriesDetailsSeasonConnector.js b/frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js
similarity index 74%
rename from frontend/src/Artist/Details/SeriesDetailsSeasonConnector.js
rename to frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js
index 6035eb73e..f24fc8fc6 100644
--- a/frontend/src/Artist/Details/SeriesDetailsSeasonConnector.js
+++ b/frontend/src/Artist/Details/ArtistDetailsSeasonConnector.js
@@ -11,30 +11,30 @@ import { toggleSeasonMonitored } from 'Store/Actions/artistActions';
import { toggleEpisodesMonitored, setEpisodesTableOption } from 'Store/Actions/episodeActions';
import { executeCommand } from 'Store/Actions/commandActions';
import * as commandNames from 'Commands/commandNames';
-import SeriesDetailsSeason from './SeriesDetailsSeason';
+import ArtistDetailsSeason from './ArtistDetailsSeason';
function createMapStateToProps() {
return createSelector(
- (state, { seasonNumber }) => seasonNumber,
+ (state, { label }) => label,
(state) => state.episodes,
createArtistSelector(),
createCommandsSelector(),
createDimensionsSelector(),
- (seasonNumber, episodes, series, commands, dimensions) => {
+ (label, episodes, series, commands, dimensions) => {
const isSearching = !!findCommand(commands, {
name: commandNames.SEASON_SEARCH,
artistId: series.id,
- seasonNumber
+ label
});
- const episodesInSeason = _.filter(episodes.items, { seasonNumber });
- const sortedEpisodes = _.orderBy(episodesInSeason, 'episodeNumber', 'desc');
+ const episodesInSeason = _.filter(episodes.items, { albumType: label });
+ const sortedEpisodes = _.orderBy(episodesInSeason, 'releaseDate', 'desc');
return {
items: sortedEpisodes,
columns: episodes.columns,
isSearching,
- seriesMonitored: series.monitored,
+ artistMonitored: series.monitored,
isSmallScreen: dimensions.isSmallScreen
};
}
@@ -48,7 +48,7 @@ const mapDispatchToProps = {
executeCommand
};
-class SeriesDetailsSeasonConnector extends Component {
+class ArtistDetailsSeasonConnector extends Component {
//
// Listeners
@@ -59,33 +59,29 @@ class SeriesDetailsSeasonConnector extends Component {
onMonitorSeasonPress = (monitored) => {
const {
- artistId,
- albumId
+ artistId
} = this.props;
this.props.toggleSeasonMonitored({
artistId,
- albumId,
monitored
});
}
onSearchPress = () => {
const {
- artistId,
- albumId
+ artistId
} = this.props;
this.props.executeCommand({
name: commandNames.SEASON_SEARCH,
- artistId,
- albumIds: [albumId]
+ artistId
});
}
- onMonitorEpisodePress = (episodeIds, monitored) => {
+ onMonitorAlbumPress = (albumIds, monitored) => {
this.props.toggleEpisodesMonitored({
- episodeIds,
+ albumIds,
monitored
});
}
@@ -95,24 +91,23 @@ class SeriesDetailsSeasonConnector extends Component {
render() {
return (
-
);
}
}
-SeriesDetailsSeasonConnector.propTypes = {
+ArtistDetailsSeasonConnector.propTypes = {
artistId: PropTypes.number.isRequired,
- albumId: PropTypes.number.isRequired,
toggleSeasonMonitored: PropTypes.func.isRequired,
toggleEpisodesMonitored: PropTypes.func.isRequired,
setEpisodesTableOption: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired
};
-export default connect(createMapStateToProps, mapDispatchToProps)(SeriesDetailsSeasonConnector);
+export default connect(createMapStateToProps, mapDispatchToProps)(ArtistDetailsSeasonConnector);
diff --git a/frontend/src/Artist/Details/SeriesTags.css b/frontend/src/Artist/Details/ArtistTags.css
similarity index 100%
rename from frontend/src/Artist/Details/SeriesTags.css
rename to frontend/src/Artist/Details/ArtistTags.css
diff --git a/frontend/src/Artist/Details/SeriesTags.js b/frontend/src/Artist/Details/ArtistTags.js
similarity index 80%
rename from frontend/src/Artist/Details/SeriesTags.js
rename to frontend/src/Artist/Details/ArtistTags.js
index 4897937dd..efac57d65 100644
--- a/frontend/src/Artist/Details/SeriesTags.js
+++ b/frontend/src/Artist/Details/ArtistTags.js
@@ -2,9 +2,9 @@ import PropTypes from 'prop-types';
import React from 'react';
import { kinds, sizes } from 'Helpers/Props';
import Label from 'Components/Label';
-import styles from './SeriesTags.css';
+import styles from './ArtistTags.css';
-function SeriesTags({ tags }) {
+function ArtistTags({ tags }) {
return (
{
@@ -24,8 +24,8 @@ function SeriesTags({ tags }) {
);
}
-SeriesTags.propTypes = {
+ArtistTags.propTypes = {
tags: PropTypes.arrayOf(PropTypes.string).isRequired
};
-export default SeriesTags;
+export default ArtistTags;
diff --git a/frontend/src/Artist/Details/SeriesTagsConnector.js b/frontend/src/Artist/Details/ArtistTagsConnector.js
similarity index 87%
rename from frontend/src/Artist/Details/SeriesTagsConnector.js
rename to frontend/src/Artist/Details/ArtistTagsConnector.js
index 354b2cec2..8c8b035ea 100644
--- a/frontend/src/Artist/Details/SeriesTagsConnector.js
+++ b/frontend/src/Artist/Details/ArtistTagsConnector.js
@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createArtistSelector from 'Store/Selectors/createArtistSelector';
import createTagsSelector from 'Store/Selectors/createTagsSelector';
-import SeriesTags from './SeriesTags';
+import ArtistTags from './ArtistTags';
function createMapStateToProps() {
return createSelector(
@@ -27,4 +27,4 @@ function createMapStateToProps() {
);
}
-export default connect(createMapStateToProps)(SeriesTags);
+export default connect(createMapStateToProps)(ArtistTags);
diff --git a/frontend/src/Artist/Details/EpisodeRow.js b/frontend/src/Artist/Details/EpisodeRow.js
deleted file mode 100644
index 5063db63b..000000000
--- a/frontend/src/Artist/Details/EpisodeRow.js
+++ /dev/null
@@ -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 (
-
- {
- columns.map((column) => {
- const {
- name,
- isVisible
- } = column;
-
- if (!isVisible) {
- return null;
- }
-
- if (name === 'monitored') {
- return (
-
-
-
- );
- }
-
- if (name === 'episodeNumber') {
- return (
-
-
-
- );
- }
-
- if (name === 'title') {
- return (
-
-
-
- );
- }
-
- if (name === 'path') {
- return (
-
- {
- episodeFilePath
- }
-
- );
- }
-
- if (name === 'relativePath') {
- return (
-
- {
- episodeFileRelativePath
- }
-
- );
- }
-
- if (name === 'airDateUtc') {
- return (
-
- );
- }
-
- if (name === 'language') {
- return (
-
-
-
- );
- }
-
- if (name === 'audioInfo') {
- return (
-
-
-
- );
- }
-
- if (name === 'videoCodec') {
- return (
-
-
-
- );
- }
-
- if (name === 'status') {
- return (
-
-
-
- );
- }
-
- if (name === 'actions') {
- return (
-
- );
- }
-
- return null;
- })
- }
-
- );
- }
-}
-
-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;
diff --git a/frontend/src/Artist/Details/SeriesDetailsLinks.js b/frontend/src/Artist/Details/SeriesDetailsLinks.js
deleted file mode 100644
index d1be3d409..000000000
--- a/frontend/src/Artist/Details/SeriesDetailsLinks.js
+++ /dev/null
@@ -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 (
-
-
-
-
- {
- !!tvMazeId &&
-
-
-
- }
-
- {
- !!imdbId &&
-
-
-
- }
-
- );
-}
-
-SeriesDetailsLinks.propTypes = {
- foreignArtistId: PropTypes.string.isRequired,
- tvMazeId: PropTypes.number,
- imdbId: PropTypes.string
-};
-
-export default SeriesDetailsLinks;
diff --git a/frontend/src/Artist/Index/Table/ArtistStatusCell.js b/frontend/src/Artist/Index/Table/ArtistStatusCell.js
index 734e50722..ab3042a10 100644
--- a/frontend/src/Artist/Index/Table/ArtistStatusCell.js
+++ b/frontend/src/Artist/Index/Table/ArtistStatusCell.js
@@ -27,7 +27,7 @@ function ArtistStatusCell(props) {
diff --git a/frontend/src/Commands/commandNames.js b/frontend/src/Commands/commandNames.js
index 47b273248..4d564afb4 100644
--- a/frontend/src/Commands/commandNames.js
+++ b/frontend/src/Commands/commandNames.js
@@ -7,9 +7,9 @@ export const CUTOFF_UNMET_EPISODE_SEARCH = 'CutoffUnmetEpisodeSearch';
export const DELETE_LOG_FILES = 'DeleteLogFiles';
export const DELETE_UPDATE_LOG_FILES = 'DeleteUpdateLogFiles';
export const DOWNLOADED_EPSIODES_SCAN = 'DownloadedEpisodesScan';
-export const EPISODE_SEARCH = 'EpisodeSearch';
+export const EPISODE_SEARCH = 'AlbumSearch';
export const INTERACTIVE_IMPORT = 'ManualImport';
-export const MISSING_EPISODE_SEARCH = 'MissingEpisodeSearch';
+export const MISSING_ALBUM_SEARCH = 'MissingAlbumSearch';
export const REFRESH_ARTIST = 'RefreshArtist';
export const RENAME_FILES = 'RenameFiles';
export const RENAME_ARTIST = 'RenameArtist';
diff --git a/frontend/src/Components/Page/Sidebar/PageSidebar.js b/frontend/src/Components/Page/Sidebar/PageSidebar.js
index 4d616dfd0..965f7d4d6 100644
--- a/frontend/src/Components/Page/Sidebar/PageSidebar.js
+++ b/frontend/src/Components/Page/Sidebar/PageSidebar.js
@@ -19,7 +19,7 @@ const SIDEBAR_WIDTH = parseInt(dimensions.sidebarWidth);
const links = [
{
- iconName: icons.SERIES_CONTINUING,
+ iconName: icons.ARTIST_CONTINUING,
title: 'Artist',
to: '/',
alias: '/series',
diff --git a/frontend/src/Episode/EpisodeDetailsModalContent.js b/frontend/src/Episode/EpisodeDetailsModalContent.js
index 60e5d6d81..24ca04c16 100644
--- a/frontend/src/Episode/EpisodeDetailsModalContent.js
+++ b/frontend/src/Episode/EpisodeDetailsModalContent.js
@@ -11,7 +11,6 @@ import MonitorToggleButton from 'Components/MonitorToggleButton';
import EpisodeSummaryConnector from './Summary/EpisodeSummaryConnector';
import EpisodeHistoryConnector from './History/EpisodeHistoryConnector';
import EpisodeSearchConnector from './Search/EpisodeSearchConnector';
-import SeasonEpisodeNumber from './SeasonEpisodeNumber';
import styles from './EpisodeDetailsModalContent.css';
const tabs = [
@@ -47,26 +46,22 @@ class EpisodeDetailsModalContent extends Component {
const {
episodeId,
episodeEntity,
- episodeFileId,
artistId,
seriesTitle,
- titleSlug,
- seriesMonitored,
- seriesType,
- seasonNumber,
- episodeNumber,
- absoluteEpisodeNumber,
+ nameSlug,
+ albumLabel,
+ artistMonitored,
episodeTitle,
- airDate,
+ releaseDate,
monitored,
isSaving,
showOpenSeriesButton,
startInteractiveSearch,
- onMonitorEpisodePress,
+ onMonitorAlbumPress,
onModalClose
} = this.props;
- const seriesLink = `/artist/${titleSlug}`;
+ const seriesLink = `/artist/${nameSlug}`;
return (
@@ -89,16 +84,6 @@ class EpisodeDetailsModalContent extends Component {
-
-
-
- -
-
{episodeTitle}
@@ -137,7 +122,8 @@ class EpisodeDetailsModalContent extends Component {
@@ -150,7 +136,7 @@ class EpisodeDetailsModalContent extends Component {
@@ -166,7 +152,7 @@ class EpisodeDetailsModalContent extends Component {
to={seriesLink}
onPress={onModalClose}
>
- Open Series
+ Open Artist
}
@@ -184,28 +170,25 @@ class EpisodeDetailsModalContent extends Component {
EpisodeDetailsModalContent.propTypes = {
episodeId: PropTypes.number.isRequired,
episodeEntity: PropTypes.string.isRequired,
- episodeFileId: PropTypes.number,
artistId: PropTypes.number.isRequired,
seriesTitle: PropTypes.string.isRequired,
- titleSlug: PropTypes.string.isRequired,
- seriesMonitored: PropTypes.bool.isRequired,
- seriesType: PropTypes.string.isRequired,
- seasonNumber: PropTypes.number.isRequired,
- episodeNumber: PropTypes.number.isRequired,
- absoluteEpisodeNumber: PropTypes.number,
- airDate: PropTypes.string.isRequired,
+ nameSlug: PropTypes.string.isRequired,
+ artistMonitored: PropTypes.bool.isRequired,
+ releaseDate: PropTypes.string.isRequired,
+ albumLabel: PropTypes.string.isRequired,
episodeTitle: PropTypes.string.isRequired,
monitored: PropTypes.bool.isRequired,
isSaving: PropTypes.bool,
showOpenSeriesButton: PropTypes.bool,
selectedTab: PropTypes.string.isRequired,
startInteractiveSearch: PropTypes.bool.isRequired,
- onMonitorEpisodePress: PropTypes.func.isRequired,
+ onMonitorAlbumPress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
EpisodeDetailsModalContent.defaultProps = {
selectedTab: 'details',
+ albumLabel: 'Unknown',
episodeEntity: episodeEntities.EPISODES,
startInteractiveSearch: false
};
diff --git a/frontend/src/Episode/EpisodeDetailsModalContentConnector.js b/frontend/src/Episode/EpisodeDetailsModalContentConnector.js
index 59129e142..f32da84fe 100644
--- a/frontend/src/Episode/EpisodeDetailsModalContentConnector.js
+++ b/frontend/src/Episode/EpisodeDetailsModalContentConnector.js
@@ -15,16 +15,16 @@ function createMapStateToProps() {
createArtistSelector(),
(episode, series) => {
const {
- title: seriesTitle,
- titleSlug,
- monitored: seriesMonitored,
+ artistName: seriesTitle,
+ nameSlug,
+ monitored: artistMonitored,
seriesType
} = series;
return {
seriesTitle,
- titleSlug,
- seriesMonitored,
+ nameSlug,
+ artistMonitored,
seriesType,
...episode
};
@@ -52,7 +52,7 @@ class EpisodeDetailsModalContentConnector extends Component {
//
// Listeners
- onMonitorEpisodePress = (monitored) => {
+ onMonitorAlbumPress = (monitored) => {
const {
episodeId,
episodeEntity
@@ -72,7 +72,7 @@ class EpisodeDetailsModalContentConnector extends Component {
return (
);
}
diff --git a/frontend/src/Episode/EpisodeSearchCellConnector.js b/frontend/src/Episode/EpisodeSearchCellConnector.js
index cc4cce8ee..89fdd9925 100644
--- a/frontend/src/Episode/EpisodeSearchCellConnector.js
+++ b/frontend/src/Episode/EpisodeSearchCellConnector.js
@@ -21,11 +21,11 @@ function createMapStateToProps() {
return false;
}
- return command.body.episodeIds.indexOf(episodeId) > -1;
+ return command.body.albumIds.indexOf(episodeId) > -1;
});
return {
- seriesMonitored: series.monitored,
+ artistMonitored: series.monitored,
seriesType: series.seriesType,
isSearching
};
@@ -38,7 +38,7 @@ function createMapDispatchToProps(dispatch, props) {
onSearchPress(name, path) {
dispatch(executeCommand({
name: commandNames.EPISODE_SEARCH,
- episodeIds: [props.episodeId]
+ albumIds: [props.episodeId]
}));
}
};
diff --git a/frontend/src/Episode/History/EpisodeHistory.js b/frontend/src/Episode/History/EpisodeHistory.js
index fc284096e..c2690275d 100644
--- a/frontend/src/Episode/History/EpisodeHistory.js
+++ b/frontend/src/Episode/History/EpisodeHistory.js
@@ -61,13 +61,13 @@ class EpisodeHistory extends Component {
if (!isFetching && !!error) {
return (
- Unable to load episode history.
+ Unable to load album history.
);
}
if (isPopulated && !hasItems && !error) {
return (
- No episode history.
+ No album history.
);
}
diff --git a/frontend/src/Episode/Search/EpisodeSearchConnector.js b/frontend/src/Episode/Search/EpisodeSearchConnector.js
index 748cb9660..8f511bfa0 100644
--- a/frontend/src/Episode/Search/EpisodeSearchConnector.js
+++ b/frontend/src/Episode/Search/EpisodeSearchConnector.js
@@ -47,7 +47,7 @@ class EpisodeSearchConnector extends Component {
onQuickSearchPress = () => {
this.props.executeCommand({
name: commandNames.EPISODE_SEARCH,
- episodeIds: [this.props.episodeId]
+ albumIds: [this.props.albumId]
});
this.props.onModalClose();
@@ -80,7 +80,7 @@ class EpisodeSearchConnector extends Component {
}
EpisodeSearchConnector.propTypes = {
- episodeId: PropTypes.number.isRequired,
+ albumId: PropTypes.number.isRequired,
isPopulated: PropTypes.bool.isRequired,
startInteractiveSearch: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired,
diff --git a/frontend/src/Episode/Search/InteractiveEpisodeSearchConnector.js b/frontend/src/Episode/Search/InteractiveEpisodeSearchConnector.js
index 20c93813c..cff2595c8 100644
--- a/frontend/src/Episode/Search/InteractiveEpisodeSearchConnector.js
+++ b/frontend/src/Episode/Search/InteractiveEpisodeSearchConnector.js
@@ -34,7 +34,7 @@ class InteractiveEpisodeSearchConnector extends Component {
componentDidMount() {
const {
- episodeId,
+ albumId,
isPopulated
} = this.props;
@@ -43,7 +43,7 @@ class InteractiveEpisodeSearchConnector extends Component {
if (!isPopulated) {
this.props.fetchReleases({
- episodeId
+ albumId
});
}
}
@@ -74,7 +74,7 @@ class InteractiveEpisodeSearchConnector extends Component {
}
InteractiveEpisodeSearchConnector.propTypes = {
- episodeId: PropTypes.number.isRequired,
+ albumId: PropTypes.number.isRequired,
isPopulated: PropTypes.bool.isRequired,
fetchReleases: PropTypes.func.isRequired,
setReleasesSort: PropTypes.func.isRequired,
diff --git a/frontend/src/Episode/Summary/EpisodeAiring.js b/frontend/src/Episode/Summary/EpisodeAiring.js
index 54ca64325..6ec8d887b 100644
--- a/frontend/src/Episode/Summary/EpisodeAiring.js
+++ b/frontend/src/Episode/Summary/EpisodeAiring.js
@@ -10,8 +10,8 @@ import Label from 'Components/Label';
function EpisodeAiring(props) {
const {
- airDateUtc,
- network,
+ releaseDate,
+ albumLabel,
shortDateFormat,
showRelativeDates,
timeFormat
@@ -22,11 +22,11 @@ function EpisodeAiring(props) {
kind={kinds.INFO}
size={sizes.MEDIUM}
>
- {network}
+ {albumLabel}
);
- if (!airDateUtc) {
+ if (!releaseDate) {
return (
TBA on {networkLabel}
@@ -34,50 +34,48 @@ function EpisodeAiring(props) {
);
}
- const time = formatTime(airDateUtc, timeFormat);
-
if (!showRelativeDates) {
return (
- {moment(airDateUtc).format(shortDateFormat)} at {time} on {networkLabel}
+ {moment(releaseDate).format(shortDateFormat)} on {networkLabel}
);
}
- if (isToday(airDateUtc)) {
+ if (isToday(releaseDate)) {
return (
- {time} on {networkLabel}
+ Today on {networkLabel}
);
}
- if (isTomorrow(airDateUtc)) {
+ if (isTomorrow(releaseDate)) {
return (
- Tomorrow at {time} on {networkLabel}
+ Tomorrow on {networkLabel}
);
}
- if (isInNextWeek(airDateUtc)) {
+ if (isInNextWeek(releaseDate)) {
return (
- {moment(airDateUtc).format('dddd')} at {time} on {networkLabel}
+ {moment(releaseDate).format('dddd')} on {networkLabel}
);
}
return (
- {moment(airDateUtc).format(shortDateFormat)} at {time} on {networkLabel}
+ {moment(releaseDate).format(shortDateFormat)} on {networkLabel}
);
}
EpisodeAiring.propTypes = {
- airDateUtc: PropTypes.string.isRequired,
- network: PropTypes.string.isRequired,
+ releaseDate: PropTypes.string.isRequired,
+ albumLabel: PropTypes.string.isRequired,
shortDateFormat: PropTypes.string.isRequired,
showRelativeDates: PropTypes.bool.isRequired,
timeFormat: PropTypes.string.isRequired
diff --git a/frontend/src/Episode/Summary/EpisodeSummary.js b/frontend/src/Episode/Summary/EpisodeSummary.js
index 8b8388744..f6ce4d747 100644
--- a/frontend/src/Episode/Summary/EpisodeSummary.js
+++ b/frontend/src/Episode/Summary/EpisodeSummary.js
@@ -45,9 +45,9 @@ class EpisodeSummary extends Component {
render() {
const {
qualityProfileId,
- network,
overview,
- airDateUtc,
+ releaseDate,
+ albumLabel,
path,
size,
quality,
@@ -59,11 +59,11 @@ class EpisodeSummary extends Component {
return (
- Airs
+ Releases
@@ -84,7 +84,7 @@ class EpisodeSummary extends Component {
{
hasOverview ?
overview :
- 'No episode overview.'
+ 'No album overview.'
}
@@ -151,11 +151,10 @@ class EpisodeSummary extends Component {
}
EpisodeSummary.propTypes = {
- episodeFileId: PropTypes.number.isRequired,
qualityProfileId: PropTypes.number.isRequired,
- network: PropTypes.string.isRequired,
overview: PropTypes.string,
- airDateUtc: PropTypes.string.isRequired,
+ albumLabel: PropTypes.string,
+ releaseDate: PropTypes.string.isRequired,
path: PropTypes.string,
size: PropTypes.number,
quality: PropTypes.object,
diff --git a/frontend/src/Helpers/Props/icons.js b/frontend/src/Helpers/Props/icons.js
index fbd0b8c6d..1ca253a4b 100644
--- a/frontend/src/Helpers/Props/icons.js
+++ b/frontend/src/Helpers/Props/icons.js
@@ -67,8 +67,8 @@ export const RSS = 'fa fa-rss';
export const SAVE = 'fa fa-floppy-o';
export const SCHEDULED = 'fa fa-clock-o';
export const SEARCH = 'fa fa-search';
-export const SERIES_CONTINUING = 'fa fa-play';
-export const SERIES_ENDED = 'fa fa-stop';
+export const ARTIST_CONTINUING = 'fa fa-play';
+export const ARTIST_ENDED = 'fa fa-stop';
export const SETTINGS = 'fa fa-cogs';
export const SHUTDOWN = 'fa fa-power-off';
export const SORT = 'fa fa-sort';
diff --git a/frontend/src/Store/Actions/episodeActionHandlers.js b/frontend/src/Store/Actions/episodeActionHandlers.js
index 1fa8034bd..52a441321 100644
--- a/frontend/src/Store/Actions/episodeActionHandlers.js
+++ b/frontend/src/Store/Actions/episodeActionHandlers.js
@@ -9,7 +9,7 @@ import { updateItem } from './baseActions';
const section = 'episodes';
const episodeActionHandlers = {
- [types.FETCH_EPISODES]: createFetchHandler(section, '/track'),
+ [types.FETCH_EPISODES]: createFetchHandler(section, '/album'),
[types.TOGGLE_EPISODE_MONITORED]: function(payload) {
return function(dispatch, getState) {
@@ -28,7 +28,7 @@ const episodeActionHandlers = {
}));
const promise = $.ajax({
- url: `/episode/${id}`,
+ url: `/album/${id}`,
method: 'PUT',
data: JSON.stringify({ monitored }),
dataType: 'json'
@@ -56,7 +56,7 @@ const episodeActionHandlers = {
[types.TOGGLE_EPISODES_MONITORED]: function(payload) {
return function(dispatch, getState) {
const {
- episodeIds,
+ albumIds,
episodeEntity = episodeEntities.EPISODES,
monitored
} = payload;
@@ -64,7 +64,7 @@ const episodeActionHandlers = {
const episodeSection = _.last(episodeEntity.split('.'));
dispatch(batchActions(
- episodeIds.map((episodeId) => {
+ albumIds.map((episodeId) => {
return updateItem({
id: episodeId,
section: episodeSection,
@@ -74,15 +74,15 @@ const episodeActionHandlers = {
));
const promise = $.ajax({
- url: '/episode/monitor',
+ url: '/album/monitor',
method: 'PUT',
- data: JSON.stringify({ episodeIds, monitored }),
+ data: JSON.stringify({ albumIds, monitored }),
dataType: 'json'
});
promise.done((data) => {
dispatch(batchActions(
- episodeIds.map((episodeId) => {
+ albumIds.map((episodeId) => {
return updateItem({
id: episodeId,
section: episodeSection,
@@ -95,7 +95,7 @@ const episodeActionHandlers = {
promise.fail((xhr) => {
dispatch(batchActions(
- episodeIds.map((episodeId) => {
+ albumIds.map((episodeId) => {
return updateItem({
id: episodeId,
section: episodeSection,
diff --git a/frontend/src/Store/Reducers/episodeReducers.js b/frontend/src/Store/Reducers/episodeReducers.js
index 4c21e4fc3..479ea3fe0 100644
--- a/frontend/src/Store/Reducers/episodeReducers.js
+++ b/frontend/src/Store/Reducers/episodeReducers.js
@@ -11,7 +11,7 @@ export const defaultState = {
isFetching: false,
isPopulated: false,
error: null,
- sortKey: 'episodeNumber',
+ sortKey: 'releaseDate',
sortDirection: sortDirections.DESCENDING,
items: [],
@@ -22,11 +22,6 @@ export const defaultState = {
isVisible: true,
isModifiable: false
},
- {
- name: 'episodeNumber',
- label: '#',
- isVisible: true
- },
{
name: 'title',
label: 'Title',
@@ -38,28 +33,18 @@ export const defaultState = {
isVisible: false
},
{
- name: 'relativePath',
- label: 'Relative Path',
- isVisible: false
- },
- {
- name: 'airDateUtc',
- label: 'Air Date',
+ name: 'releaseDate',
+ label: 'Release Date',
isVisible: true
},
{
- name: 'language',
- label: 'Language',
+ name: 'trackCount',
+ label: 'Track Count',
isVisible: false
},
{
- name: 'audioInfo',
- label: 'Audio Info',
- isVisible: false
- },
- {
- name: 'videoCodec',
- label: 'Video Codec',
+ name: 'duration',
+ label: 'Duration',
isVisible: false
},
{
diff --git a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js
index 473c041e9..8a03e366d 100644
--- a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js
+++ b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js
@@ -110,7 +110,7 @@ class CutoffUnmetConnector extends Component {
onSearchSelectedPress = (selected) => {
this.props.executeCommand({
name: commandNames.EPISODE_SEARCH,
- episodeIds: selected
+ albumIds: selected
});
}
diff --git a/frontend/src/Wanted/Missing/MissingConnector.js b/frontend/src/Wanted/Missing/MissingConnector.js
index 9142ad001..be74f4f12 100644
--- a/frontend/src/Wanted/Missing/MissingConnector.js
+++ b/frontend/src/Wanted/Missing/MissingConnector.js
@@ -18,7 +18,7 @@ function createMapStateToProps() {
createCommandsSelector(),
(missing, commands) => {
const isSearchingForAlbums = _.some(commands, { name: commandNames.EPISODE_SEARCH });
- const isSearchingForMissingAlbums = _.some(commands, { name: commandNames.MISSING_EPISODE_SEARCH });
+ const isSearchingForMissingAlbums = _.some(commands, { name: commandNames.MISSING_ALBUM_SEARCH });
return {
isSearchingForAlbums,
@@ -100,7 +100,7 @@ class MissingConnector extends Component {
onSearchSelectedPress = (selected) => {
this.props.executeCommand({
name: commandNames.EPISODE_SEARCH,
- episodeIds: selected
+ albumIds: selected
});
}
@@ -118,7 +118,7 @@ class MissingConnector extends Component {
onSearchAllMissingPress = () => {
this.props.executeCommand({
- name: commandNames.MISSING_EPISODE_SEARCH
+ name: commandNames.MISSING_ALBUM_SEARCH
});
}