mirror of https://github.com/lidarr/Lidarr
Refactor Episode section naming to Album in UI
This commit is contained in:
parent
0e7a22dc95
commit
b1a016289c
|
@ -54,7 +54,7 @@ class History extends Component {
|
|||
totalRecords,
|
||||
isAlbumsFetching,
|
||||
isAlbumsPopulated,
|
||||
episodesError,
|
||||
albumsError,
|
||||
onFilterSelect,
|
||||
onFirstPagePress,
|
||||
...otherProps
|
||||
|
@ -62,7 +62,7 @@ class History extends Component {
|
|||
|
||||
const isFetchingAny = isFetching || isAlbumsFetching;
|
||||
const isAllPopulated = isPopulated && (isAlbumsPopulated || !items.length);
|
||||
const hasError = error || episodesError;
|
||||
const hasError = error || albumsError;
|
||||
|
||||
return (
|
||||
<PageContent title="History">
|
||||
|
@ -209,7 +209,7 @@ History.propTypes = {
|
|||
totalRecords: PropTypes.number,
|
||||
isAlbumsFetching: PropTypes.bool.isRequired,
|
||||
isAlbumsPopulated: PropTypes.bool.isRequired,
|
||||
episodesError: PropTypes.object,
|
||||
albumsError: PropTypes.object,
|
||||
onFilterSelect: PropTypes.func.isRequired,
|
||||
onFirstPagePress: PropTypes.func.isRequired
|
||||
};
|
||||
|
|
|
@ -6,20 +6,20 @@ import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePo
|
|||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
|
||||
import * as historyActions from 'Store/Actions/historyActions';
|
||||
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
|
||||
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
|
||||
import { fetchTracks, clearTracks } from 'Store/Actions/trackActions';
|
||||
import History from './History';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.history,
|
||||
(state) => state.episodes,
|
||||
(state) => state.albums,
|
||||
(state) => state.tracks,
|
||||
(history, episodes, tracks) => {
|
||||
(history, albums, tracks) => {
|
||||
return {
|
||||
isAlbumsFetching: episodes.isFetching,
|
||||
isAlbumsPopulated: episodes.isPopulated,
|
||||
episodesError: episodes.error,
|
||||
isAlbumsFetching: albums.isFetching,
|
||||
isAlbumsPopulated: albums.isPopulated,
|
||||
albumsError: albums.error,
|
||||
isTracksFetching: tracks.isFetching,
|
||||
isTracksPopulated: tracks.isPopulated,
|
||||
tracksError: tracks.error,
|
||||
|
@ -31,8 +31,8 @@ function createMapStateToProps() {
|
|||
|
||||
const mapDispatchToProps = {
|
||||
...historyActions,
|
||||
fetchEpisodes,
|
||||
clearEpisodes,
|
||||
fetchAlbums,
|
||||
clearAlbums,
|
||||
fetchTracks,
|
||||
clearTracks
|
||||
};
|
||||
|
@ -52,9 +52,9 @@ class HistoryConnector extends Component {
|
|||
const albumIds = selectUniqueIds(this.props.items, 'albumId');
|
||||
const trackIds = selectUniqueIds(this.props.items, 'trackId');
|
||||
if (albumIds.length) {
|
||||
this.props.fetchEpisodes({ albumIds });
|
||||
this.props.fetchAlbums({ albumIds });
|
||||
} else {
|
||||
this.props.clearEpisodes();
|
||||
this.props.clearAlbums();
|
||||
}
|
||||
if (trackIds.length) {
|
||||
this.props.fetchTracks({ trackIds });
|
||||
|
@ -67,7 +67,7 @@ class HistoryConnector extends Component {
|
|||
componentWillUnmount() {
|
||||
unregisterPagePopulator(this.repopulate);
|
||||
this.props.clearHistory();
|
||||
this.props.clearEpisodes();
|
||||
this.props.clearAlbums();
|
||||
this.props.clearTracks();
|
||||
}
|
||||
|
||||
|
@ -149,8 +149,8 @@ HistoryConnector.propTypes = {
|
|||
setHistoryFilter: PropTypes.func.isRequired,
|
||||
setHistoryTableOption: PropTypes.func.isRequired,
|
||||
clearHistory: PropTypes.func.isRequired,
|
||||
fetchEpisodes: PropTypes.func.isRequired,
|
||||
clearEpisodes: PropTypes.func.isRequired,
|
||||
fetchAlbums: PropTypes.func.isRequired,
|
||||
clearAlbums: PropTypes.func.isRequired,
|
||||
fetchTracks: PropTypes.func.isRequired,
|
||||
clearTracks: PropTypes.func.isRequired
|
||||
};
|
||||
|
|
|
@ -5,8 +5,8 @@ import IconButton from 'Components/Link/IconButton';
|
|||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import AlbumTitleLink from 'Album/AlbumTitleLink';
|
||||
import EpisodeLanguage from 'Album/EpisodeLanguage';
|
||||
import EpisodeQuality from 'Album/EpisodeQuality';
|
||||
import ArtistNameLink from 'Artist/ArtistNameLink';
|
||||
|
@ -110,14 +110,14 @@ class HistoryRow extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
if (name === 'episodeTitle') {
|
||||
if (name === 'albumTitle') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
<EpisodeTitleLink
|
||||
<AlbumTitleLink
|
||||
albumId={albumId}
|
||||
episodeEntity={episodeEntities.EPISODES}
|
||||
albumEntity={albumEntities.ALBUMS}
|
||||
artistId={artist.id}
|
||||
episodeTitle={album.title}
|
||||
albumTitle={album.title}
|
||||
showOpenArtistButton={true}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { connect } from 'react-redux';
|
|||
import { createSelector } from 'reselect';
|
||||
import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
|
||||
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
|
||||
import createTrackSelector from 'Store/Selectors/createTrackSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import HistoryRow from './HistoryRow';
|
||||
|
@ -12,7 +12,7 @@ import HistoryRow from './HistoryRow';
|
|||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createArtistSelector(),
|
||||
createEpisodeSelector(),
|
||||
createAlbumSelector(),
|
||||
createTrackSelector(),
|
||||
createUISettingsSelector(),
|
||||
(artist, album, track, uiSettings) => {
|
||||
|
|
|
@ -119,7 +119,7 @@ class Queue extends Component {
|
|||
items,
|
||||
isAlbumsFetching,
|
||||
isAlbumsPopulated,
|
||||
episodesError,
|
||||
albumsError,
|
||||
columns,
|
||||
totalRecords,
|
||||
isGrabbing,
|
||||
|
@ -139,7 +139,7 @@ class Queue extends Component {
|
|||
|
||||
const isRefreshing = isFetching || isAlbumsFetching || isCheckForFinishedDownloadExecuting;
|
||||
const isAllPopulated = isPopulated && (isAlbumsPopulated || !items.length);
|
||||
const hasError = error || episodesError;
|
||||
const hasError = error || albumsError;
|
||||
const selectedCount = this.getSelectedIds().length;
|
||||
const disableSelectedActions = selectedCount === 0;
|
||||
|
||||
|
@ -250,7 +250,7 @@ Queue.propTypes = {
|
|||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isAlbumsFetching: PropTypes.bool.isRequired,
|
||||
isAlbumsPopulated: PropTypes.bool.isRequired,
|
||||
episodesError: PropTypes.object,
|
||||
albumsError: PropTypes.object,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
totalRecords: PropTypes.number,
|
||||
isGrabbing: PropTypes.bool.isRequired,
|
||||
|
|
|
@ -9,22 +9,22 @@ import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
|
|||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import * as queueActions from 'Store/Actions/queueActions';
|
||||
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
|
||||
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import Queue from './Queue';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.episodes,
|
||||
(state) => state.albums,
|
||||
(state) => state.queue.paged,
|
||||
createCommandsSelector(),
|
||||
(episodes, queue, commands) => {
|
||||
(albums, queue, commands) => {
|
||||
const isCheckForFinishedDownloadExecuting = _.some(commands, { name: commandNames.CHECK_FOR_FINISHED_DOWNLOAD });
|
||||
|
||||
return {
|
||||
isAlbumsFetching: episodes.isFetching,
|
||||
isAlbumsPopulated: episodes.isPopulated,
|
||||
episodesError: episodes.error,
|
||||
isAlbumsFetching: albums.isFetching,
|
||||
isAlbumsPopulated: albums.isPopulated,
|
||||
albumsError: albums.error,
|
||||
isCheckForFinishedDownloadExecuting,
|
||||
...queue
|
||||
};
|
||||
|
@ -34,8 +34,8 @@ function createMapStateToProps() {
|
|||
|
||||
const mapDispatchToProps = {
|
||||
...queueActions,
|
||||
fetchEpisodes,
|
||||
clearEpisodes,
|
||||
fetchAlbums,
|
||||
clearAlbums,
|
||||
executeCommand
|
||||
};
|
||||
|
||||
|
@ -53,9 +53,9 @@ class QueueConnector extends Component {
|
|||
if (hasDifferentItems(prevProps.items, this.props.items)) {
|
||||
const albumIds = selectUniqueIds(this.props.items, 'albumId');
|
||||
if (albumIds.length) {
|
||||
this.props.fetchEpisodes({ albumIds });
|
||||
this.props.fetchAlbums({ albumIds });
|
||||
} else {
|
||||
this.props.clearEpisodes();
|
||||
this.props.clearAlbums();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class QueueConnector extends Component {
|
|||
componentWillUnmount() {
|
||||
unregisterPagePopulator(this.repopulate);
|
||||
this.props.clearQueue();
|
||||
this.props.clearEpisodes();
|
||||
this.props.clearAlbums();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -158,8 +158,8 @@ QueueConnector.propTypes = {
|
|||
clearQueue: PropTypes.func.isRequired,
|
||||
grabQueueItems: PropTypes.func.isRequired,
|
||||
removeQueueItems: PropTypes.func.isRequired,
|
||||
fetchEpisodes: PropTypes.func.isRequired,
|
||||
clearEpisodes: PropTypes.func.isRequired,
|
||||
fetchAlbums: PropTypes.func.isRequired,
|
||||
clearAlbums: PropTypes.func.isRequired,
|
||||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ function QueueDetails(props) {
|
|||
return (
|
||||
<Icon
|
||||
name={icons.DOWNLOADING}
|
||||
title={`Episode is downloading - ${progress.toFixed(1)}% ${title}`}
|
||||
title={`Album is downloading - ${progress.toFixed(1)}% ${title}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import TableRow from 'Components/Table/TableRow';
|
|||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||
import ProtocolLabel from 'Activity/Queue/ProtocolLabel';
|
||||
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
|
||||
import AlbumTitleLink from 'Album/AlbumTitleLink';
|
||||
import EpisodeQuality from 'Album/EpisodeQuality';
|
||||
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
|
||||
import ArtistNameLink from 'Artist/ArtistNameLink';
|
||||
|
@ -68,7 +68,7 @@ class QueueRow extends Component {
|
|||
statusMessages,
|
||||
errorMessage,
|
||||
artist,
|
||||
episode,
|
||||
album,
|
||||
quality,
|
||||
protocol,
|
||||
indexer,
|
||||
|
@ -152,14 +152,14 @@ class QueueRow extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
if (name === 'episodeTitle') {
|
||||
if (name === 'albumTitle') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
<EpisodeTitleLink
|
||||
albumId={episode.id}
|
||||
<AlbumTitleLink
|
||||
albumId={album.id}
|
||||
artistId={artist.id}
|
||||
trackFileId={episode.trackFileId}
|
||||
episodeTitle={episode.title}
|
||||
trackFileId={album.trackFileId}
|
||||
albumTitle={album.title}
|
||||
showOpenArtistButton={true}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
@ -300,7 +300,7 @@ QueueRow.propTypes = {
|
|||
statusMessages: PropTypes.arrayOf(PropTypes.object),
|
||||
errorMessage: PropTypes.string,
|
||||
artist: PropTypes.object.isRequired,
|
||||
episode: PropTypes.object.isRequired,
|
||||
album: PropTypes.object.isRequired,
|
||||
quality: PropTypes.object.isRequired,
|
||||
protocol: PropTypes.string.isRequired,
|
||||
indexer: PropTypes.string,
|
||||
|
|
|
@ -5,16 +5,16 @@ import { connect } from 'react-redux';
|
|||
import { createSelector } from 'reselect';
|
||||
import { grabQueueItem, removeQueueItem } from 'Store/Actions/queueActions';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
|
||||
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import QueueRow from './QueueRow';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createArtistSelector(),
|
||||
createEpisodeSelector(),
|
||||
createAlbumSelector(),
|
||||
createUISettingsSelector(),
|
||||
(artist, episode, uiSettings) => {
|
||||
(artist, album, uiSettings) => {
|
||||
const result = _.pick(uiSettings, [
|
||||
'showRelativeDates',
|
||||
'shortDateFormat',
|
||||
|
@ -22,7 +22,7 @@ function createMapStateToProps() {
|
|||
]);
|
||||
|
||||
result.artist = artist;
|
||||
result.episode = episode;
|
||||
result.album = album;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class QueueRowConnector extends Component {
|
|||
// Render
|
||||
|
||||
render() {
|
||||
if (!this.props.episode) {
|
||||
if (!this.props.album) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ class QueueRowConnector extends Component {
|
|||
|
||||
QueueRowConnector.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
episode: PropTypes.object,
|
||||
album: PropTypes.object,
|
||||
grabQueueItem: PropTypes.func.isRequired,
|
||||
removeQueueItem: PropTypes.func.isRequired
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Modal from 'Components/Modal/Modal';
|
||||
import EpisodeDetailsModalContentConnector from './EpisodeDetailsModalContentConnector';
|
||||
import AlbumDetailsModalContentConnector from './AlbumDetailsModalContentConnector';
|
||||
|
||||
class EpisodeDetailsModal extends Component {
|
||||
class AlbumDetailsModal extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
|
@ -20,7 +20,7 @@ class EpisodeDetailsModal extends Component {
|
|||
isOpen={isOpen}
|
||||
onModalClose={onModalClose}
|
||||
>
|
||||
<EpisodeDetailsModalContentConnector
|
||||
<AlbumDetailsModalContentConnector
|
||||
{...otherProps}
|
||||
onModalClose={onModalClose}
|
||||
/>
|
||||
|
@ -29,9 +29,9 @@ class EpisodeDetailsModal extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
EpisodeDetailsModal.propTypes = {
|
||||
AlbumDetailsModal.propTypes = {
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default EpisodeDetailsModal;
|
||||
export default AlbumDetailsModal;
|
|
@ -1,17 +1,17 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import Button from 'Components/Link/Button';
|
||||
import ModalContent from 'Components/Modal/ModalContent';
|
||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||
import ModalBody from 'Components/Modal/ModalBody';
|
||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import EpisodeSummaryConnector from './Summary/EpisodeSummaryConnector';
|
||||
import AlbumSummaryConnector from './Summary/AlbumSummaryConnector';
|
||||
import AlbumHistoryConnector from './History/AlbumHistoryConnector';
|
||||
import EpisodeSearchConnector from './Search/EpisodeSearchConnector';
|
||||
import styles from './EpisodeDetailsModalContent.css';
|
||||
import AlbumSearchConnector from './Search/AlbumSearchConnector';
|
||||
import styles from './AlbumDetailsModalContent.css';
|
||||
|
||||
const tabs = [
|
||||
'details',
|
||||
|
@ -19,7 +19,7 @@ const tabs = [
|
|||
'search'
|
||||
];
|
||||
|
||||
class EpisodeDetailsModalContent extends Component {
|
||||
class AlbumDetailsModalContent extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -45,13 +45,13 @@ class EpisodeDetailsModalContent extends Component {
|
|||
render() {
|
||||
const {
|
||||
albumId,
|
||||
episodeEntity,
|
||||
albumEntity,
|
||||
artistId,
|
||||
artistName,
|
||||
nameSlug,
|
||||
albumLabel,
|
||||
artistMonitored,
|
||||
episodeTitle,
|
||||
albumTitle,
|
||||
releaseDate,
|
||||
monitored,
|
||||
isSaving,
|
||||
|
@ -84,7 +84,7 @@ class EpisodeDetailsModalContent extends Component {
|
|||
|
||||
<span className={styles.separator}>-</span>
|
||||
|
||||
{episodeTitle}
|
||||
{albumTitle}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
|
@ -119,9 +119,9 @@ class EpisodeDetailsModalContent extends Component {
|
|||
</TabList>
|
||||
|
||||
<TabPanel className={styles.tabPanel}>
|
||||
<EpisodeSummaryConnector
|
||||
<AlbumSummaryConnector
|
||||
albumId={albumId}
|
||||
episodeEntity={episodeEntity}
|
||||
albumEntity={albumEntity}
|
||||
releaseDate={releaseDate}
|
||||
albumLabel={albumLabel}
|
||||
artistId={artistId}
|
||||
|
@ -135,7 +135,7 @@ class EpisodeDetailsModalContent extends Component {
|
|||
</TabPanel>
|
||||
|
||||
<TabPanel className={styles.tabPanel}>
|
||||
<EpisodeSearchConnector
|
||||
<AlbumSearchConnector
|
||||
albumId={albumId}
|
||||
startInteractiveSearch={startInteractiveSearch}
|
||||
onModalClose={onModalClose}
|
||||
|
@ -167,16 +167,16 @@ class EpisodeDetailsModalContent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
EpisodeDetailsModalContent.propTypes = {
|
||||
AlbumDetailsModalContent.propTypes = {
|
||||
albumId: PropTypes.number.isRequired,
|
||||
episodeEntity: PropTypes.string.isRequired,
|
||||
albumEntity: PropTypes.string.isRequired,
|
||||
artistId: PropTypes.number.isRequired,
|
||||
artistName: PropTypes.string.isRequired,
|
||||
nameSlug: PropTypes.string.isRequired,
|
||||
artistMonitored: PropTypes.bool.isRequired,
|
||||
releaseDate: PropTypes.string.isRequired,
|
||||
albumLabel: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
episodeTitle: PropTypes.string.isRequired,
|
||||
albumTitle: PropTypes.string.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
isSaving: PropTypes.bool,
|
||||
showOpenArtistButton: PropTypes.bool,
|
||||
|
@ -186,11 +186,11 @@ EpisodeDetailsModalContent.propTypes = {
|
|||
onModalClose: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
EpisodeDetailsModalContent.defaultProps = {
|
||||
AlbumDetailsModalContent.defaultProps = {
|
||||
selectedTab: 'details',
|
||||
albumLabel: ['Unknown'],
|
||||
episodeEntity: episodeEntities.EPISODES,
|
||||
albumEntity: albumEntities.ALBUMS,
|
||||
startInteractiveSearch: false
|
||||
};
|
||||
|
||||
export default EpisodeDetailsModalContent;
|
||||
export default AlbumDetailsModalContent;
|
|
@ -3,16 +3,16 @@ import React, { Component } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions';
|
||||
import { toggleEpisodeMonitored } from 'Store/Actions/episodeActions';
|
||||
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
|
||||
import { toggleAlbumMonitored } from 'Store/Actions/albumActions';
|
||||
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import { fetchTracks, clearTracks } from 'Store/Actions/trackActions';
|
||||
import EpisodeDetailsModalContent from './EpisodeDetailsModalContent';
|
||||
import AlbumDetailsModalContent from './AlbumDetailsModalContent';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createEpisodeSelector(),
|
||||
createAlbumSelector(),
|
||||
createArtistSelector(),
|
||||
(album, artist) => {
|
||||
const {
|
||||
|
@ -52,11 +52,11 @@ function createMapDispatchToProps(dispatch, props) {
|
|||
onMonitorAlbumPress(monitored) {
|
||||
const {
|
||||
albumId,
|
||||
episodeEntity
|
||||
albumEntity
|
||||
} = this.props;
|
||||
|
||||
dispatch(toggleEpisodeMonitored({
|
||||
episodeEntity,
|
||||
dispatch(toggleAlbumMonitored({
|
||||
albumEntity,
|
||||
albumId,
|
||||
monitored
|
||||
}));
|
||||
|
@ -64,7 +64,7 @@ function createMapDispatchToProps(dispatch, props) {
|
|||
};
|
||||
}
|
||||
|
||||
class EpisodeDetailsModalContentConnector extends Component {
|
||||
class AlbumDetailsModalContentConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -103,14 +103,14 @@ class EpisodeDetailsModalContentConnector extends Component {
|
|||
} = this.props;
|
||||
|
||||
return (
|
||||
<EpisodeDetailsModalContent {...otherProps} />
|
||||
<AlbumDetailsModalContent {...otherProps} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EpisodeDetailsModalContentConnector.propTypes = {
|
||||
AlbumDetailsModalContentConnector.propTypes = {
|
||||
albumId: PropTypes.number.isRequired,
|
||||
episodeEntity: PropTypes.string.isRequired,
|
||||
albumEntity: PropTypes.string.isRequired,
|
||||
artistId: PropTypes.number.isRequired,
|
||||
dispatchFetchTracks: PropTypes.func.isRequired,
|
||||
dispatchClearTracks: PropTypes.func.isRequired,
|
||||
|
@ -118,8 +118,8 @@ EpisodeDetailsModalContentConnector.propTypes = {
|
|||
dispatchClearReleases: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
EpisodeDetailsModalContentConnector.defaultProps = {
|
||||
episodeEntity: episodeEntities.EPISODES
|
||||
AlbumDetailsModalContentConnector.defaultProps = {
|
||||
albumEntity: albumEntities.ALBUMS
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(EpisodeDetailsModalContentConnector);
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(AlbumDetailsModalContentConnector);
|
|
@ -1,4 +1,4 @@
|
|||
.episodeSearchCell {
|
||||
.AlbumSearchCell {
|
||||
composes: cell from 'Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
width: 70px;
|
|
@ -4,10 +4,10 @@ import { icons } from 'Helpers/Props';
|
|||
import IconButton from 'Components/Link/IconButton';
|
||||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import EpisodeDetailsModal from './EpisodeDetailsModal';
|
||||
import styles from './EpisodeSearchCell.css';
|
||||
import AlbumDetailsModal from './AlbumDetailsModal';
|
||||
import styles from './AlbumSearchCell.css';
|
||||
|
||||
class EpisodeSearchCell extends Component {
|
||||
class AlbumSearchCell extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -38,14 +38,14 @@ class EpisodeSearchCell extends Component {
|
|||
const {
|
||||
albumId,
|
||||
artistId,
|
||||
episodeTitle,
|
||||
albumTitle,
|
||||
isSearching,
|
||||
onSearchPress,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<TableRowCell className={styles.episodeSearchCell}>
|
||||
<TableRowCell className={styles.AlbumSearchCell}>
|
||||
<SpinnerIconButton
|
||||
name={icons.SEARCH}
|
||||
isSpinning={isSearching}
|
||||
|
@ -57,11 +57,11 @@ class EpisodeSearchCell extends Component {
|
|||
onPress={this.onManualSearchPress}
|
||||
/>
|
||||
|
||||
<EpisodeDetailsModal
|
||||
<AlbumDetailsModal
|
||||
isOpen={this.state.isDetailsModalOpen}
|
||||
albumId={albumId}
|
||||
artistId={artistId}
|
||||
episodeTitle={episodeTitle}
|
||||
albumTitle={albumTitle}
|
||||
selectedTab="search"
|
||||
startInteractiveSearch={true}
|
||||
onModalClose={this.onDetailsModalClose}
|
||||
|
@ -72,12 +72,12 @@ class EpisodeSearchCell extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
EpisodeSearchCell.propTypes = {
|
||||
AlbumSearchCell.propTypes = {
|
||||
albumId: PropTypes.number.isRequired,
|
||||
artistId: PropTypes.number.isRequired,
|
||||
episodeTitle: PropTypes.string.isRequired,
|
||||
albumTitle: PropTypes.string.isRequired,
|
||||
isSearching: PropTypes.bool.isRequired,
|
||||
onSearchPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default EpisodeSearchCell;
|
||||
export default AlbumSearchCell;
|
|
@ -5,7 +5,7 @@ import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
|||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import EpisodeSearchCell from './EpisodeSearchCell';
|
||||
import AlbumSearchCell from './AlbumSearchCell';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
|
@ -15,9 +15,9 @@ function createMapStateToProps() {
|
|||
createCommandsSelector(),
|
||||
(albumId, sceneSeasonNumber, artist, commands) => {
|
||||
const isSearching = _.some(commands, (command) => {
|
||||
const episodeSearch = command.name === commandNames.ALBUM_SEARCH;
|
||||
const albumSearch = command.name === commandNames.ALBUM_SEARCH;
|
||||
|
||||
if (!episodeSearch) {
|
||||
if (!albumSearch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -44,4 +44,4 @@ function createMapDispatchToProps(dispatch, props) {
|
|||
};
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(EpisodeSearchCell);
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(AlbumSearchCell);
|
|
@ -1,10 +1,10 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Link from 'Components/Link/Link';
|
||||
import EpisodeDetailsModal from 'Album/EpisodeDetailsModal';
|
||||
import styles from './EpisodeTitleLink.css';
|
||||
import AlbumDetailsModal from 'Album/AlbumDetailsModal';
|
||||
import styles from './AlbumTitleLink.css';
|
||||
|
||||
class EpisodeTitleLink extends Component {
|
||||
class AlbumTitleLink extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -33,7 +33,7 @@ class EpisodeTitleLink extends Component {
|
|||
|
||||
render() {
|
||||
const {
|
||||
episodeTitle,
|
||||
albumTitle,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
|
@ -43,12 +43,12 @@ class EpisodeTitleLink extends Component {
|
|||
className={styles.link}
|
||||
onPress={this.onLinkPress}
|
||||
>
|
||||
{episodeTitle}
|
||||
{albumTitle}
|
||||
</Link>
|
||||
|
||||
<EpisodeDetailsModal
|
||||
<AlbumDetailsModal
|
||||
isOpen={this.state.isDetailsModalOpen}
|
||||
episodeTitle={episodeTitle}
|
||||
albumTitle={albumTitle}
|
||||
{...otherProps}
|
||||
onModalClose={this.onModalClose}
|
||||
/>
|
||||
|
@ -57,12 +57,12 @@ class EpisodeTitleLink extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
EpisodeTitleLink.propTypes = {
|
||||
episodeTitle: PropTypes.string.isRequired
|
||||
AlbumTitleLink.propTypes = {
|
||||
albumTitle: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
EpisodeTitleLink.defaultProps = {
|
||||
AlbumTitleLink.defaultProps = {
|
||||
showArtistButton: false
|
||||
};
|
||||
|
||||
export default EpisodeTitleLink;
|
||||
export default AlbumTitleLink;
|
|
@ -3,18 +3,18 @@ import PropTypes from 'prop-types';
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
|
||||
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
|
||||
import createQueueItemSelector from 'Store/Selectors/createQueueItemSelector';
|
||||
import createTrackFileSelector from 'Store/Selectors/createTrackFileSelector';
|
||||
import EpisodeStatus from './EpisodeStatus';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createEpisodeSelector(),
|
||||
createAlbumSelector(),
|
||||
createQueueItemSelector(),
|
||||
createTrackFileSelector(),
|
||||
(episode, queueItem, trackFile) => {
|
||||
const result = _.pick(episode, [
|
||||
(album, queueItem, trackFile) => {
|
||||
const result = _.pick(album, [
|
||||
'airDateUtc',
|
||||
'monitored',
|
||||
'grabbed'
|
||||
|
|
|
@ -3,9 +3,9 @@ import React from 'react';
|
|||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import Button from 'Components/Link/Button';
|
||||
import Icon from 'Components/Icon';
|
||||
import styles from './EpisodeSearch.css';
|
||||
import styles from './AlbumSearch.css';
|
||||
|
||||
function EpisodeSearch(props) {
|
||||
function AlbumSearch(props) {
|
||||
const {
|
||||
onQuickSearchPress,
|
||||
onInteractiveSearchPress
|
||||
|
@ -47,9 +47,9 @@ function EpisodeSearch(props) {
|
|||
);
|
||||
}
|
||||
|
||||
EpisodeSearch.propTypes = {
|
||||
AlbumSearch.propTypes = {
|
||||
onQuickSearchPress: PropTypes.func.isRequired,
|
||||
onInteractiveSearchPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default EpisodeSearch;
|
||||
export default AlbumSearch;
|
|
@ -4,8 +4,8 @@ import { connect } from 'react-redux';
|
|||
import { createSelector } from 'reselect';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import EpisodeSearch from './EpisodeSearch';
|
||||
import InteractiveEpisodeSearchConnector from './InteractiveEpisodeSearchConnector';
|
||||
import AlbumSearch from './AlbumSearch';
|
||||
import InteractiveAlbumSearchConnector from './InteractiveAlbumSearchConnector';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
|
@ -22,7 +22,7 @@ const mapDispatchToProps = {
|
|||
executeCommand
|
||||
};
|
||||
|
||||
class EpisodeSearchConnector extends Component {
|
||||
class AlbumSearchConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -63,14 +63,14 @@ class EpisodeSearchConnector extends Component {
|
|||
render() {
|
||||
if (this.state.isInteractiveSearchOpen) {
|
||||
return (
|
||||
<InteractiveEpisodeSearchConnector
|
||||
<InteractiveAlbumSearchConnector
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<EpisodeSearch
|
||||
<AlbumSearch
|
||||
{...this.props}
|
||||
onQuickSearchPress={this.onQuickSearchPress}
|
||||
onInteractiveSearchPress={this.onInteractiveSearchPress}
|
||||
|
@ -79,7 +79,7 @@ class EpisodeSearchConnector extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
EpisodeSearchConnector.propTypes = {
|
||||
AlbumSearchConnector.propTypes = {
|
||||
albumId: PropTypes.number.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
startInteractiveSearch: PropTypes.bool.isRequired,
|
||||
|
@ -87,4 +87,4 @@ EpisodeSearchConnector.propTypes = {
|
|||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(EpisodeSearchConnector);
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(AlbumSearchConnector);
|
|
@ -5,7 +5,7 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
|||
import Icon from 'Components/Icon';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import InteractiveEpisodeSearchRow from './InteractiveEpisodeSearchRow';
|
||||
import InteractiveAlbumSearchRow from './InteractiveAlbumSearchRow';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ const columns = [
|
|||
}
|
||||
];
|
||||
|
||||
function InteractiveEpisodeSearch(props) {
|
||||
function InteractiveAlbumSearch(props) {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
|
@ -99,7 +99,7 @@ function InteractiveEpisodeSearch(props) {
|
|||
{
|
||||
items.map((item) => {
|
||||
return (
|
||||
<InteractiveEpisodeSearchRow
|
||||
<InteractiveAlbumSearchRow
|
||||
key={item.guid}
|
||||
{...item}
|
||||
longDateFormat={longDateFormat}
|
||||
|
@ -114,7 +114,7 @@ function InteractiveEpisodeSearch(props) {
|
|||
);
|
||||
}
|
||||
|
||||
InteractiveEpisodeSearch.propTypes = {
|
||||
InteractiveAlbumSearch.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
|
@ -127,4 +127,4 @@ InteractiveEpisodeSearch.propTypes = {
|
|||
onGrabPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default InteractiveEpisodeSearch;
|
||||
export default InteractiveAlbumSearch;
|
|
@ -5,7 +5,7 @@ import connectSection from 'Store/connectSection';
|
|||
import { fetchReleases, setReleasesSort, grabRelease } from 'Store/Actions/releaseActions';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import InteractiveEpisodeSearch from './InteractiveEpisodeSearch';
|
||||
import InteractiveAlbumSearch from './InteractiveAlbumSearch';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
|
@ -27,7 +27,7 @@ const mapDispatchToProps = {
|
|||
grabRelease
|
||||
};
|
||||
|
||||
class InteractiveEpisodeSearchConnector extends Component {
|
||||
class InteractiveAlbumSearchConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -64,7 +64,7 @@ class InteractiveEpisodeSearchConnector extends Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<InteractiveEpisodeSearch
|
||||
<InteractiveAlbumSearch
|
||||
{...this.props}
|
||||
onSortPress={this.onSortPress}
|
||||
onGrabPress={this.onGrabPress}
|
||||
|
@ -73,7 +73,7 @@ class InteractiveEpisodeSearchConnector extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
InteractiveEpisodeSearchConnector.propTypes = {
|
||||
InteractiveAlbumSearchConnector.propTypes = {
|
||||
albumId: PropTypes.number.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
fetchReleases: PropTypes.func.isRequired,
|
||||
|
@ -87,4 +87,4 @@ export default connectSection(
|
|||
undefined,
|
||||
undefined,
|
||||
{ section: 'releases' }
|
||||
)(InteractiveEpisodeSearchConnector);
|
||||
)(InteractiveAlbumSearchConnector);
|
|
@ -13,7 +13,7 @@ import Popover from 'Components/Tooltip/Popover';
|
|||
import EpisodeQuality from 'Album/EpisodeQuality';
|
||||
import ProtocolLabel from 'Activity/Queue/ProtocolLabel';
|
||||
import Peers from './Peers';
|
||||
import styles from './InteractiveEpisodeSearchRow.css';
|
||||
import styles from './InteractiveAlbumSearchRow.css';
|
||||
|
||||
function getDownloadIcon(isGrabbing, isGrabbed, grabError) {
|
||||
if (isGrabbing) {
|
||||
|
@ -39,7 +39,7 @@ function getDownloadTooltip(isGrabbing, isGrabbed, grabError) {
|
|||
return 'Add to downloaded queue';
|
||||
}
|
||||
|
||||
class InteractiveEpisodeSearchRow extends Component {
|
||||
class InteractiveAlbumSearchRow extends Component {
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
@ -171,7 +171,7 @@ class InteractiveEpisodeSearchRow extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
InteractiveEpisodeSearchRow.propTypes = {
|
||||
InteractiveAlbumSearchRow.propTypes = {
|
||||
guid: PropTypes.string.isRequired,
|
||||
protocol: PropTypes.string.isRequired,
|
||||
age: PropTypes.number.isRequired,
|
||||
|
@ -196,9 +196,9 @@ InteractiveEpisodeSearchRow.propTypes = {
|
|||
onGrabPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
InteractiveEpisodeSearchRow.defaultProps = {
|
||||
InteractiveAlbumSearchRow.defaultProps = {
|
||||
isGrabbing: false,
|
||||
isGrabbed: false
|
||||
};
|
||||
|
||||
export default InteractiveEpisodeSearchRow;
|
||||
export default InteractiveAlbumSearchRow;
|
|
@ -7,7 +7,7 @@ import isTomorrow from 'Utilities/Date/isTomorrow';
|
|||
import { kinds, sizes } from 'Helpers/Props';
|
||||
import Label from 'Components/Label';
|
||||
|
||||
function EpisodeAiring(props) {
|
||||
function AlbumReleasing(props) {
|
||||
const {
|
||||
releaseDate,
|
||||
albumLabel,
|
||||
|
@ -71,11 +71,11 @@ function EpisodeAiring(props) {
|
|||
);
|
||||
}
|
||||
|
||||
EpisodeAiring.propTypes = {
|
||||
AlbumReleasing.propTypes = {
|
||||
releaseDate: PropTypes.string.isRequired,
|
||||
albumLabel: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
shortDateFormat: PropTypes.string.isRequired,
|
||||
showRelativeDates: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
export default EpisodeAiring;
|
||||
export default AlbumReleasing;
|
|
@ -2,7 +2,7 @@ import _ from 'lodash';
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import EpisodeAiring from './EpisodeAiring';
|
||||
import AlbumReleasing from './AlbumReleasing';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
|
@ -16,4 +16,4 @@ function createMapStateToProps() {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps)(EpisodeAiring);
|
||||
export default connect(createMapStateToProps)(AlbumReleasing);
|
|
@ -6,11 +6,11 @@ import Label from 'Components/Label';
|
|||
import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import EpisodeAiringConnector from './EpisodeAiringConnector';
|
||||
import AlbumReleasingConnector from './AlbumReleasingConnector';
|
||||
import TrackDetailRow from './TrackDetailRow';
|
||||
import styles from './EpisodeSummary.css';
|
||||
import styles from './AlbumSummary.css';
|
||||
|
||||
class EpisodeSummary extends Component {
|
||||
class AlbumSummary extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
@ -63,7 +63,7 @@ class EpisodeSummary extends Component {
|
|||
<div>
|
||||
<span className={styles.infoTitle}>Releases</span>
|
||||
|
||||
<EpisodeAiringConnector
|
||||
<AlbumReleasingConnector
|
||||
releaseDate={releaseDate}
|
||||
albumLabel={albumLabel}
|
||||
/>
|
||||
|
@ -92,7 +92,7 @@ class EpisodeSummary extends Component {
|
|||
|
||||
<div>
|
||||
{
|
||||
<div className={styles.episodes}>
|
||||
<div className={styles.albums}>
|
||||
{
|
||||
items.length ?
|
||||
<Table
|
||||
|
@ -113,7 +113,7 @@ class EpisodeSummary extends Component {
|
|||
</TableBody>
|
||||
</Table> :
|
||||
|
||||
<div className={styles.noEpisodes}>
|
||||
<div className={styles.noAlbums}>
|
||||
No tracks in this group
|
||||
</div>
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ class EpisodeSummary extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={this.state.isRemoveTrackFileModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Delete Episode File"
|
||||
title="Delete Track File"
|
||||
message={`Are you sure you want to delete '${path}'?`}
|
||||
confirmLabel="Delete"
|
||||
onConfirm={this.onConfirmRemoveTrackFile}
|
||||
|
@ -135,7 +135,7 @@ class EpisodeSummary extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
EpisodeSummary.propTypes = {
|
||||
AlbumSummary.propTypes = {
|
||||
qualityProfileId: PropTypes.number.isRequired,
|
||||
overview: PropTypes.string,
|
||||
albumLabel: PropTypes.arrayOf(PropTypes.string),
|
||||
|
@ -149,4 +149,4 @@ EpisodeSummary.propTypes = {
|
|||
onDeleteTrackFile: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default EpisodeSummary;
|
||||
export default AlbumSummary;
|
|
@ -2,29 +2,29 @@ import _ from 'lodash';
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { deleteTrackFile } from 'Store/Actions/trackFileActions';
|
||||
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
|
||||
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
|
||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import EpisodeSummary from './EpisodeSummary';
|
||||
import AlbumSummary from './AlbumSummary';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.tracks,
|
||||
createEpisodeSelector(),
|
||||
createAlbumSelector(),
|
||||
createCommandsSelector(),
|
||||
createDimensionsSelector(),
|
||||
createArtistSelector(),
|
||||
(tracks, episode, commands, dimensions, artist) => {
|
||||
const filteredItems = _.filter(tracks.items, { albumId: episode.id });
|
||||
(tracks, album, commands, dimensions, artist) => {
|
||||
const filteredItems = _.filter(tracks.items, { albumId: album.id });
|
||||
const mediumSortedItems = _.orderBy(filteredItems, 'absoluteTrackNumber');
|
||||
const items = _.orderBy(mediumSortedItems, 'mediumNumber');
|
||||
|
||||
return {
|
||||
network: episode.label,
|
||||
network: album.label,
|
||||
qualityProfileId: artist.qualityProfileId,
|
||||
releaseDate: episode.releaseDate,
|
||||
overview: episode.overview,
|
||||
releaseDate: album.releaseDate,
|
||||
overview: album.overview,
|
||||
items,
|
||||
columns: tracks.columns
|
||||
};
|
||||
|
@ -37,10 +37,10 @@ function createMapDispatchToProps(dispatch, props) {
|
|||
onDeleteTrackFile() {
|
||||
dispatch(deleteTrackFile({
|
||||
id: props.trackFileId,
|
||||
episodeEntity: props.episodeEntity
|
||||
albumEntity: props.albumEntity
|
||||
}));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(EpisodeSummary);
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(AlbumSummary);
|
|
@ -1,12 +1,12 @@
|
|||
export const CALENDAR = 'calendar';
|
||||
export const EPISODES = 'episodes';
|
||||
export const INTERACTIVE_IMPORT = 'interactiveImport.episodes';
|
||||
export const ALBUMS = 'albums';
|
||||
export const INTERACTIVE_IMPORT = 'interactiveImport.albums';
|
||||
export const WANTED_CUTOFF_UNMET = 'wanted.cutoffUnmet';
|
||||
export const WANTED_MISSING = 'wanted.missing';
|
||||
|
||||
export default {
|
||||
CALENDAR,
|
||||
EPISODES,
|
||||
ALBUMS,
|
||||
INTERACTIVE_IMPORT,
|
||||
WANTED_CUTOFF_UNMET,
|
||||
WANTED_MISSING
|
|
@ -13,12 +13,12 @@
|
|||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.episodes {
|
||||
.tracks {
|
||||
padding: 0 4px;
|
||||
background-color: $white;
|
||||
color: $defaultColor;
|
||||
}
|
||||
|
||||
.allEpisodes {
|
||||
.allTracks {
|
||||
background-color: #e0ffe0;
|
||||
}
|
||||
|
|
|
@ -54,8 +54,8 @@ class AlbumStudioAlbum extends Component {
|
|||
|
||||
<div
|
||||
className={classNames(
|
||||
styles.episodes,
|
||||
percentOfTracks === 100 && styles.allEpisodes
|
||||
styles.tracks,
|
||||
percentOfTracks === 100 && styles.allTracks
|
||||
)}
|
||||
title={`${trackFileCount}/${totalTrackCount} tracks downloaded`}
|
||||
>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { createSelector } from 'reselect';
|
|||
import connectSection from 'Store/connectSection';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import { setAlbumStudioSort, setAlbumStudioFilter, saveAlbumStudio } from 'Store/Actions/albumStudioActions';
|
||||
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
|
||||
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
|
||||
import AlbumStudio from './AlbumStudio';
|
||||
|
||||
function createMapStateToProps() {
|
||||
|
@ -19,8 +19,8 @@ function createMapStateToProps() {
|
|||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchEpisodes,
|
||||
clearEpisodes,
|
||||
fetchAlbums,
|
||||
clearAlbums,
|
||||
setAlbumStudioSort,
|
||||
setAlbumStudioFilter,
|
||||
saveAlbumStudio
|
||||
|
@ -43,11 +43,11 @@ class AlbumStudioConnector extends Component {
|
|||
// Control
|
||||
|
||||
populate = () => {
|
||||
this.props.fetchEpisodes();
|
||||
this.props.fetchAlbums();
|
||||
}
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.clearEpisodes();
|
||||
this.props.clearAlbums();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -83,8 +83,8 @@ class AlbumStudioConnector extends Component {
|
|||
AlbumStudioConnector.propTypes = {
|
||||
setAlbumStudioSort: PropTypes.func.isRequired,
|
||||
setAlbumStudioFilter: PropTypes.func.isRequired,
|
||||
fetchEpisodes: PropTypes.func.isRequired,
|
||||
clearEpisodes: PropTypes.func.isRequired,
|
||||
fetchAlbums: PropTypes.func.isRequired,
|
||||
clearAlbums: PropTypes.func.isRequired,
|
||||
saveAlbumStudio: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -5,15 +5,15 @@ import { connect } from 'react-redux';
|
|||
import { createSelector } from 'reselect';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import { toggleArtistMonitored } from 'Store/Actions/artistActions';
|
||||
import { toggleEpisodeMonitored } from 'Store/Actions/episodeActions';
|
||||
import { toggleAlbumMonitored } from 'Store/Actions/albumActions';
|
||||
import AlbumStudioRow from './AlbumStudioRow';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.episodes,
|
||||
(state) => state.albums,
|
||||
createArtistSelector(),
|
||||
(episodes, artist) => {
|
||||
const albumsInArtist = _.filter(episodes.items, { artistId: artist.id });
|
||||
(albums, artist) => {
|
||||
const albumsInArtist = _.filter(albums.items, { artistId: artist.id });
|
||||
const sortedAlbums = _.orderBy(albumsInArtist, 'releaseDate', 'desc');
|
||||
|
||||
return {
|
||||
|
@ -32,7 +32,7 @@ function createMapStateToProps() {
|
|||
|
||||
const mapDispatchToProps = {
|
||||
toggleArtistMonitored,
|
||||
toggleEpisodeMonitored
|
||||
toggleAlbumMonitored
|
||||
};
|
||||
|
||||
class AlbumStudioRowConnector extends Component {
|
||||
|
@ -53,7 +53,7 @@ class AlbumStudioRowConnector extends Component {
|
|||
}
|
||||
|
||||
onAlbumMonitoredPress = (albumId, monitored) => {
|
||||
this.props.toggleEpisodeMonitored({
|
||||
this.props.toggleAlbumMonitored({
|
||||
albumId,
|
||||
monitored
|
||||
});
|
||||
|
@ -77,7 +77,7 @@ AlbumStudioRowConnector.propTypes = {
|
|||
artistId: PropTypes.number.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
toggleArtistMonitored: PropTypes.func.isRequired,
|
||||
toggleEpisodeMonitored: PropTypes.func.isRequired
|
||||
toggleAlbumMonitored: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(AlbumStudioRowConnector);
|
||||
|
|
|
@ -7,13 +7,13 @@ 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 'Album/EpisodeSearchCellConnector';
|
||||
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
|
||||
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
|
||||
import AlbumTitleLink from 'Album/AlbumTitleLink';
|
||||
|
||||
import styles from './AlbumRow.css';
|
||||
|
||||
function getEpisodeCountKind(monitored, trackFileCount, episodeCount) {
|
||||
if (trackFileCount === episodeCount && episodeCount > 0) {
|
||||
function getTrackCountKind(monitored, trackFileCount, trackCount) {
|
||||
if (trackFileCount === trackCount && trackCount > 0) {
|
||||
return kinds.SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -111,10 +111,10 @@ class AlbumRow extends Component {
|
|||
key={name}
|
||||
className={styles.title}
|
||||
>
|
||||
<EpisodeTitleLink
|
||||
<AlbumTitleLink
|
||||
albumId={id}
|
||||
artistId={artistId}
|
||||
episodeTitle={title}
|
||||
albumTitle={title}
|
||||
showOpenArtistButton={false}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
@ -168,7 +168,7 @@ class AlbumRow extends Component {
|
|||
>
|
||||
<Label
|
||||
title={`${totalTrackCount} tracks total. ${trackFileCount} tracks with files.`}
|
||||
kind={getEpisodeCountKind(monitored, trackFileCount, trackCount)}
|
||||
kind={getTrackCountKind(monitored, trackFileCount, trackCount)}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
{
|
||||
|
@ -181,11 +181,11 @@ class AlbumRow extends Component {
|
|||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<EpisodeSearchCellConnector
|
||||
<AlbumSearchCellConnector
|
||||
key={name}
|
||||
albumId={id}
|
||||
artistId={artistId}
|
||||
episodeTitle={title}
|
||||
albumTitle={title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ class ArtistDetails extends Component {
|
|||
|
||||
this.state = {
|
||||
isOrganizeModalOpen: false,
|
||||
isManageEpisodesOpen: false,
|
||||
isManageTracksOpen: false,
|
||||
isEditArtistModalOpen: false,
|
||||
isDeleteArtistModalOpen: false,
|
||||
isArtistHistoryModalOpen: false,
|
||||
|
@ -113,12 +113,12 @@ class ArtistDetails extends Component {
|
|||
this.setState({ isOrganizeModalOpen: false });
|
||||
}
|
||||
|
||||
onManageEpisodesPress = () => {
|
||||
this.setState({ isManageEpisodesOpen: true });
|
||||
onManageTracksPress = () => {
|
||||
this.setState({ isManageTracksOpen: true });
|
||||
}
|
||||
|
||||
onManageEpisodesModalClose = () => {
|
||||
this.setState({ isManageEpisodesOpen: false });
|
||||
onManageTracksModalClose = () => {
|
||||
this.setState({ isManageTracksOpen: false });
|
||||
}
|
||||
|
||||
onInteractiveImportPress = () => {
|
||||
|
@ -203,7 +203,7 @@ class ArtistDetails extends Component {
|
|||
isSearching,
|
||||
isFetching,
|
||||
isPopulated,
|
||||
episodesError,
|
||||
albumsError,
|
||||
trackFilesError,
|
||||
previousArtist,
|
||||
nextArtist,
|
||||
|
@ -213,7 +213,7 @@ class ArtistDetails extends Component {
|
|||
|
||||
const {
|
||||
isOrganizeModalOpen,
|
||||
isManageEpisodesOpen,
|
||||
isManageTracksOpen,
|
||||
isEditArtistModalOpen,
|
||||
isDeleteArtistModalOpen,
|
||||
isArtistHistoryModalOpen,
|
||||
|
@ -271,8 +271,8 @@ class ArtistDetails extends Component {
|
|||
|
||||
<PageToolbarButton
|
||||
label="Manage Tracks"
|
||||
iconName={icons.EPISODE_FILE}
|
||||
onPress={this.onManageEpisodesPress}
|
||||
iconName={icons.TRACK_FILE}
|
||||
onPress={this.onManageTracksPress}
|
||||
/>
|
||||
|
||||
<PageToolbarButton
|
||||
|
@ -524,12 +524,12 @@ class ArtistDetails extends Component {
|
|||
|
||||
<div className={styles.contentContainer}>
|
||||
{
|
||||
!isPopulated && !episodesError && !trackFilesError &&
|
||||
!isPopulated && !albumsError && !trackFilesError &&
|
||||
<LoadingIndicator />
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && episodesError &&
|
||||
!isFetching && albumsError &&
|
||||
<div>Loading albums failed</div>
|
||||
}
|
||||
|
||||
|
@ -568,9 +568,9 @@ class ArtistDetails extends Component {
|
|||
/>
|
||||
|
||||
<TrackFileEditorModal
|
||||
isOpen={isManageEpisodesOpen}
|
||||
isOpen={isManageTracksOpen}
|
||||
artistId={id}
|
||||
onModalClose={this.onManageEpisodesModalClose}
|
||||
onModalClose={this.onManageTracksModalClose}
|
||||
/>
|
||||
|
||||
<ArtistHistoryModal
|
||||
|
@ -624,7 +624,7 @@ ArtistDetails.propTypes = {
|
|||
isSearching: PropTypes.bool.isRequired,
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
episodesError: PropTypes.object,
|
||||
albumsError: PropTypes.object,
|
||||
trackFilesError: PropTypes.object,
|
||||
previousArtist: PropTypes.object.isRequired,
|
||||
nextArtist: PropTypes.object.isRequired,
|
||||
|
|
|
@ -8,7 +8,7 @@ import { findCommand } from 'Utilities/Command';
|
|||
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
|
||||
import createAllArtistSelector from 'Store/Selectors/createAllArtistSelector';
|
||||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import { fetchEpisodes, clearEpisodes } from 'Store/Actions/episodeActions';
|
||||
import { fetchAlbums, clearAlbums } from 'Store/Actions/albumActions';
|
||||
import { fetchTrackFiles, clearTrackFiles } from 'Store/Actions/trackFileActions';
|
||||
import { fetchQueueDetails, clearQueueDetails } from 'Store/Actions/queueActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
|
@ -18,11 +18,11 @@ import ArtistDetails from './ArtistDetails';
|
|||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { nameSlug }) => nameSlug,
|
||||
(state) => state.episodes,
|
||||
(state) => state.albums,
|
||||
(state) => state.trackFiles,
|
||||
createAllArtistSelector(),
|
||||
createCommandsSelector(),
|
||||
(nameSlug, episodes, trackFiles, allArtists, commands) => {
|
||||
(nameSlug, albums, trackFiles, allArtists, commands) => {
|
||||
const sortedArtist = _.orderBy(allArtists, 'sortName');
|
||||
const artistIndex = _.findIndex(sortedArtist, { nameSlug });
|
||||
const artist = sortedArtist[artistIndex];
|
||||
|
@ -41,9 +41,9 @@ function createMapStateToProps() {
|
|||
const isRenamingArtistCommand = findCommand(commands, { name: commandNames.RENAME_ARTIST });
|
||||
const isRenamingArtist = !!(isRenamingArtistCommand && isRenamingArtistCommand.body.artistId.indexOf(artist.id) > -1);
|
||||
|
||||
const isFetching = episodes.isFetching || trackFiles.isFetching;
|
||||
const isPopulated = episodes.isPopulated && trackFiles.isPopulated;
|
||||
const episodesError = episodes.error;
|
||||
const isFetching = albums.isFetching || trackFiles.isFetching;
|
||||
const isPopulated = albums.isPopulated && trackFiles.isPopulated;
|
||||
const albumsError = albums.error;
|
||||
const trackFilesError = trackFiles.error;
|
||||
const alternateTitles = _.reduce(artist.alternateTitles, (acc, alternateTitle) => {
|
||||
if ((alternateTitle.seasonNumber === -1 || alternateTitle.seasonNumber === undefined) &&
|
||||
|
@ -65,7 +65,7 @@ function createMapStateToProps() {
|
|||
isRenamingArtist,
|
||||
isFetching,
|
||||
isPopulated,
|
||||
episodesError,
|
||||
albumsError,
|
||||
trackFilesError,
|
||||
previousArtist,
|
||||
nextArtist
|
||||
|
@ -75,8 +75,8 @@ function createMapStateToProps() {
|
|||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchEpisodes,
|
||||
clearEpisodes,
|
||||
fetchAlbums,
|
||||
clearAlbums,
|
||||
fetchTrackFiles,
|
||||
clearTrackFiles,
|
||||
fetchQueueDetails,
|
||||
|
@ -112,7 +112,7 @@ class ArtistDetailsConnector extends Component {
|
|||
this.populate();
|
||||
}
|
||||
|
||||
// If the id has changed we need to clear the episodes/episode
|
||||
// If the id has changed we need to clear the albums
|
||||
// files and fetch from the server.
|
||||
|
||||
if (prevProps.id !== id) {
|
||||
|
@ -132,13 +132,13 @@ class ArtistDetailsConnector extends Component {
|
|||
populate = () => {
|
||||
const artistId = this.props.id;
|
||||
|
||||
this.props.fetchEpisodes({ artistId });
|
||||
this.props.fetchAlbums({ artistId });
|
||||
this.props.fetchTrackFiles({ artistId });
|
||||
this.props.fetchQueueDetails({ artistId });
|
||||
}
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.clearEpisodes();
|
||||
this.props.clearAlbums();
|
||||
this.props.clearTrackFiles();
|
||||
this.props.clearQueueDetails();
|
||||
}
|
||||
|
@ -182,8 +182,8 @@ ArtistDetailsConnector.propTypes = {
|
|||
isRefreshing: PropTypes.bool.isRequired,
|
||||
isRenamingFiles: PropTypes.bool.isRequired,
|
||||
isRenamingArtist: PropTypes.bool.isRequired,
|
||||
fetchEpisodes: PropTypes.func.isRequired,
|
||||
clearEpisodes: PropTypes.func.isRequired,
|
||||
fetchAlbums: PropTypes.func.isRequired,
|
||||
clearAlbums: PropTypes.func.isRequired,
|
||||
fetchTrackFiles: PropTypes.func.isRequired,
|
||||
clearTrackFiles: PropTypes.func.isRequired,
|
||||
fetchQueueDetails: PropTypes.func.isRequired,
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
width: 30px;
|
||||
}
|
||||
|
||||
.episodes {
|
||||
.albums {
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid $borderColor;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
|||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.noEpisodes {
|
||||
.noAlbums {
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ class ArtistDetailsSeason extends Component {
|
|||
|
||||
this.state = {
|
||||
isOrganizeModalOpen: false,
|
||||
isManageEpisodesOpen: false,
|
||||
lastToggledEpisode: null
|
||||
isManageTracksOpen: false,
|
||||
lastToggledAlbum: null
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -68,12 +68,12 @@ class ArtistDetailsSeason extends Component {
|
|||
this.setState({ isOrganizeModalOpen: false });
|
||||
}
|
||||
|
||||
onManageEpisodesPress = () => {
|
||||
this.setState({ isManageEpisodesOpen: true });
|
||||
onManageTracksPress = () => {
|
||||
this.setState({ isManageTracksOpen: true });
|
||||
}
|
||||
|
||||
onManageEpisodesModalClose = () => {
|
||||
this.setState({ isManageEpisodesOpen: false });
|
||||
onManageTracksModalClose = () => {
|
||||
this.setState({ isManageTracksOpen: false });
|
||||
}
|
||||
|
||||
onExpandPress = () => {
|
||||
|
@ -86,7 +86,7 @@ class ArtistDetailsSeason extends Component {
|
|||
}
|
||||
|
||||
onMonitorAlbumPress = (albumId, monitored, { shiftKey }) => {
|
||||
const lastToggled = this.state.lastToggledEpisode;
|
||||
const lastToggled = this.state.lastToggledAlbum;
|
||||
const albumIds = [albumId];
|
||||
|
||||
if (shiftKey && lastToggled) {
|
||||
|
@ -98,7 +98,7 @@ class ArtistDetailsSeason extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
this.setState({ lastToggledEpisode: albumId });
|
||||
this.setState({ lastToggledAlbum: albumId });
|
||||
|
||||
this.props.onMonitorAlbumPress(_.uniq(albumIds), monitored);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ class ArtistDetailsSeason extends Component {
|
|||
|
||||
const {
|
||||
isOrganizeModalOpen,
|
||||
isManageEpisodesOpen
|
||||
isManageTracksOpen
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
|
@ -166,7 +166,7 @@ class ArtistDetailsSeason extends Component {
|
|||
<div>
|
||||
{
|
||||
isExpanded &&
|
||||
<div className={styles.episodes}>
|
||||
<div className={styles.albums}>
|
||||
{
|
||||
items.length ?
|
||||
<Table
|
||||
|
@ -189,7 +189,7 @@ class ArtistDetailsSeason extends Component {
|
|||
</TableBody>
|
||||
</Table> :
|
||||
|
||||
<div className={styles.noEpisodes}>
|
||||
<div className={styles.noAlbums}>
|
||||
No albums in this group
|
||||
</div>
|
||||
}
|
||||
|
@ -212,9 +212,9 @@ class ArtistDetailsSeason extends Component {
|
|||
/>
|
||||
|
||||
<TrackFileEditorModal
|
||||
isOpen={isManageEpisodesOpen}
|
||||
isOpen={isManageTracksOpen}
|
||||
artistId={artistId}
|
||||
onModalClose={this.onManageEpisodesModalClose}
|
||||
onModalClose={this.onManageTracksModalClose}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@ import { findCommand } from 'Utilities/Command';
|
|||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import { toggleEpisodesMonitored, setEpisodesTableOption } from 'Store/Actions/episodeActions';
|
||||
import { toggleAlbumsMonitored, setAlbumsTableOption } from 'Store/Actions/albumActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import ArtistDetailsSeason from './ArtistDetailsSeason';
|
||||
|
@ -16,18 +16,18 @@ import ArtistDetailsSeason from './ArtistDetailsSeason';
|
|||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { label }) => label,
|
||||
(state) => state.episodes,
|
||||
(state) => state.albums,
|
||||
createArtistSelector(),
|
||||
createCommandsSelector(),
|
||||
createDimensionsSelector(),
|
||||
(label, episodes, artist, commands, dimensions) => {
|
||||
(label, albums, artist, commands, dimensions) => {
|
||||
|
||||
const episodesInSeason = _.filter(episodes.items, { albumType: label });
|
||||
const sortedEpisodes = _.orderBy(episodesInSeason, 'releaseDate', 'desc');
|
||||
const albumsInGroup = _.filter(albums.items, { albumType: label });
|
||||
const sortedAlbums = _.orderBy(albumsInGroup, 'releaseDate', 'desc');
|
||||
|
||||
return {
|
||||
items: sortedEpisodes,
|
||||
columns: episodes.columns,
|
||||
items: sortedAlbums,
|
||||
columns: albums.columns,
|
||||
artistMonitored: artist.monitored,
|
||||
isSmallScreen: dimensions.isSmallScreen
|
||||
};
|
||||
|
@ -36,8 +36,8 @@ function createMapStateToProps() {
|
|||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
toggleEpisodesMonitored,
|
||||
setEpisodesTableOption,
|
||||
toggleAlbumsMonitored,
|
||||
setAlbumsTableOption,
|
||||
executeCommand
|
||||
};
|
||||
|
||||
|
@ -47,11 +47,11 @@ class ArtistDetailsSeasonConnector extends Component {
|
|||
// Listeners
|
||||
|
||||
onTableOptionChange = (payload) => {
|
||||
this.props.setEpisodesTableOption(payload);
|
||||
this.props.setAlbumsTableOption(payload);
|
||||
}
|
||||
|
||||
onMonitorAlbumPress = (albumIds, monitored) => {
|
||||
this.props.toggleEpisodesMonitored({
|
||||
this.props.toggleAlbumsMonitored({
|
||||
albumIds,
|
||||
monitored
|
||||
});
|
||||
|
@ -73,8 +73,8 @@ class ArtistDetailsSeasonConnector extends Component {
|
|||
|
||||
ArtistDetailsSeasonConnector.propTypes = {
|
||||
artistId: PropTypes.number.isRequired,
|
||||
toggleEpisodesMonitored: PropTypes.func.isRequired,
|
||||
setEpisodesTableOption: PropTypes.func.isRequired,
|
||||
toggleAlbumsMonitored: PropTypes.func.isRequired,
|
||||
setAlbumsTableOption: PropTypes.func.isRequired,
|
||||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -2,13 +2,13 @@ import { connect } from 'react-redux';
|
|||
import { createSelector } from 'reselect';
|
||||
import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions';
|
||||
import createArtistSelector from 'Store/Selectors/createArtistSelector';
|
||||
import createEpisodeSelector from 'Store/Selectors/createEpisodeSelector';
|
||||
import createAlbumSelector from 'Store/Selectors/createAlbumSelector';
|
||||
import ArtistHistoryRow from './ArtistHistoryRow';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createArtistSelector(),
|
||||
createEpisodeSelector(),
|
||||
createAlbumSelector(),
|
||||
(artist, album) => {
|
||||
return {
|
||||
artist,
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
flex: 0 0 100px;
|
||||
}
|
||||
|
||||
.episodeSeparator {
|
||||
.albumSeparator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@
|
|||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.episodeSeparator {
|
||||
.albumSeparator {
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import { icons } from 'Helpers/Props';
|
|||
import getStatusStyle from 'Calendar/getStatusStyle';
|
||||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import EpisodeDetailsModal from 'Album/EpisodeDetailsModal';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import AlbumDetailsModal from 'Album/AlbumDetailsModal';
|
||||
import CalendarEventQueueDetails from 'Calendar/Events/CalendarEventQueueDetails';
|
||||
import styles from './AgendaEvent.css';
|
||||
|
||||
|
@ -88,7 +88,7 @@ class AgendaEvent extends Component {
|
|||
{artist.artistName}
|
||||
</div>
|
||||
|
||||
<div className={styles.episodeSeparator}> - </div>
|
||||
<div className={styles.albumSeparator}> - </div>
|
||||
|
||||
<div className={styles.albumTitle}>
|
||||
{title}
|
||||
|
@ -110,12 +110,12 @@ class AgendaEvent extends Component {
|
|||
}
|
||||
</Link>
|
||||
|
||||
<EpisodeDetailsModal
|
||||
<AlbumDetailsModal
|
||||
isOpen={this.state.isDetailsModalOpen}
|
||||
albumId={id}
|
||||
episodeEntity={episodeEntities.CALENDAR}
|
||||
albumEntity={albumEntities.CALENDAR}
|
||||
artistId={artist.id}
|
||||
episodeTitle={title}
|
||||
albumTitle={title}
|
||||
showOpenArtistButton={true}
|
||||
onModalClose={this.onDetailsModalClose}
|
||||
/>
|
||||
|
|
|
@ -4,10 +4,10 @@ import React, { Component } from 'react';
|
|||
import classNames from 'classnames';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import getStatusStyle from 'Calendar/getStatusStyle';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import Icon from 'Components/Icon';
|
||||
import Link from 'Components/Link/Link';
|
||||
import EpisodeDetailsModal from 'Album/EpisodeDetailsModal';
|
||||
import AlbumDetailsModal from 'Album/AlbumDetailsModal';
|
||||
import CalendarEventQueueDetails from './CalendarEventQueueDetails';
|
||||
import styles from './CalendarEvent.css';
|
||||
|
||||
|
@ -108,12 +108,12 @@ class CalendarEvent extends Component {
|
|||
</div>
|
||||
</Link>
|
||||
|
||||
<EpisodeDetailsModal
|
||||
<AlbumDetailsModal
|
||||
isOpen={this.state.isDetailsModalOpen}
|
||||
albumId={id}
|
||||
episodeEntity={episodeEntities.CALENDAR}
|
||||
albumEntity={albumEntities.CALENDAR}
|
||||
artistId={artist.id}
|
||||
episodeTitle={title}
|
||||
albumTitle={title}
|
||||
showOpenArtistButton={true}
|
||||
onModalClose={this.onDetailsModalClose}
|
||||
/>
|
||||
|
|
|
@ -25,7 +25,7 @@ function CalendarEventQueueDetails(props) {
|
|||
status={status}
|
||||
errorMessage={errorMessage}
|
||||
progressBar={
|
||||
<div title={`Episode is downloading - ${progress.toFixed(1)}% ${title}`}>
|
||||
<div title={`Album is downloading - ${progress.toFixed(1)}% ${title}`}>
|
||||
<CircularProgressBar
|
||||
progress={progress}
|
||||
size={20}
|
||||
|
|
|
@ -13,7 +13,7 @@ function getIconName(name) {
|
|||
return icons.BACKUP;
|
||||
case 'CheckHealth':
|
||||
return icons.HEALTH;
|
||||
case 'EpisodeSearch':
|
||||
case 'AlbumSearch':
|
||||
return icons.SEARCH;
|
||||
case 'Housekeeping':
|
||||
return icons.HOUSEKEEPING;
|
||||
|
|
|
@ -127,8 +127,8 @@ class SignalRConnector extends Component {
|
|||
return;
|
||||
}
|
||||
|
||||
if (name === 'episode') {
|
||||
this.handleEpisode(body);
|
||||
if (name === 'album') {
|
||||
this.handleAlbum(body);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ class SignalRConnector extends Component {
|
|||
return;
|
||||
}
|
||||
|
||||
if (name === 'episodefile') {
|
||||
if (name === 'trackfile') {
|
||||
this.handleTrackFile(body);
|
||||
return;
|
||||
}
|
||||
|
@ -207,10 +207,10 @@ class SignalRConnector extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleEpisode = (body) => {
|
||||
handleAlbum = (body) => {
|
||||
if (body.action === 'updated') {
|
||||
this.props.updateItem({
|
||||
section: 'episodes',
|
||||
section: 'albums',
|
||||
updateOnly: true,
|
||||
...body.resource
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ export const DOWNLOADED = 'fa fa-download';
|
|||
export const DOWNLOADING = 'fa fa-cloud-download';
|
||||
export const DRIVE = 'fa fa-hdd-o';
|
||||
export const EDIT = 'fa fa-wrench';
|
||||
export const EPISODE_FILE = 'fa fa-file-video-o';
|
||||
export const TRACK_FILE = 'fa fa-file-audio-o';
|
||||
export const EXPAND = 'fa fa-chevron-circle-down';
|
||||
export const EXPAND_INDETERMINATE = 'fa fa-chevron-circle-right';
|
||||
export const EXTERNAL_LINK = 'fa fa-external-link';
|
||||
|
|
|
@ -15,8 +15,8 @@ import SelectAlbumModalContent from './SelectAlbumModalContent';
|
|||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createClientSideCollectionSelector(),
|
||||
(episodes) => {
|
||||
return episodes;
|
||||
(albums) => {
|
||||
return albums;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ function EditNotificationModalContent(props) {
|
|||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onGrab"
|
||||
helpText="Be notified when episodes are available for download and has been sent to a download client"
|
||||
helpText="Be notified when albums are available for download and has been sent to a download client"
|
||||
isDisabled={!supportsOnGrab.value}
|
||||
{...onGrab}
|
||||
onChange={onInputChange}
|
||||
|
@ -127,7 +127,7 @@ function EditNotificationModalContent(props) {
|
|||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onUpgrade"
|
||||
helpText="Be notified when episodes are upgraded to a better quality"
|
||||
helpText="Be notified when tracks are upgraded to a better quality"
|
||||
isDisabled={!supportsOnUpgrade.value}
|
||||
{...onUpgrade}
|
||||
onChange={onInputChange}
|
||||
|
@ -141,7 +141,7 @@ function EditNotificationModalContent(props) {
|
|||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onRename"
|
||||
helpText="Be notified when episodes are renamed"
|
||||
helpText="Be notified when tracks are renamed"
|
||||
isDisabled={!supportsOnRename.value}
|
||||
{...onRename}
|
||||
onChange={onInputChange}
|
||||
|
|
|
@ -81,7 +81,7 @@ function EditLanguageProfileModalContent(props) {
|
|||
{...cutoff}
|
||||
value={cutoff ? cutoff.value.id : 0}
|
||||
values={languages}
|
||||
helpText="Once this language is reached Lidarr will no longer download episodes"
|
||||
helpText="Once this language is reached Lidarr will no longer download albums"
|
||||
onChange={onCutoffChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
|
|
@ -87,7 +87,7 @@ function Settings() {
|
|||
</Link>
|
||||
|
||||
<div className={styles.summary}>
|
||||
Create metadata files when episodes are imported or artist are refreshed
|
||||
Create metadata files when tracks are imported or artist are refreshed
|
||||
</div>
|
||||
|
||||
<Link
|
||||
|
|
|
@ -6,7 +6,7 @@ import { sortDirections } from 'Helpers/Props';
|
|||
import { createThunk, handleThunks } from 'Store/thunks';
|
||||
import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
|
||||
import createSetTableOptionReducer from './Creators/Reducers/createSetTableOptionReducer';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import createFetchHandler from './Creators/createFetchHandler';
|
||||
import createHandleActions from './Creators/createHandleActions';
|
||||
import { updateItem } from './baseActions';
|
||||
|
@ -14,7 +14,7 @@ import { updateItem } from './baseActions';
|
|||
//
|
||||
// Variables
|
||||
|
||||
export const section = 'episodes';
|
||||
export const section = 'albums';
|
||||
|
||||
//
|
||||
// State
|
||||
|
@ -74,47 +74,47 @@ export const defaultState = {
|
|||
};
|
||||
|
||||
export const persistState = [
|
||||
'episodes.columns'
|
||||
'albums.columns'
|
||||
];
|
||||
|
||||
//
|
||||
// Actions Types
|
||||
|
||||
export const FETCH_EPISODES = 'episodes/fetchEpisodes';
|
||||
export const SET_EPISODES_SORT = 'episodes/setEpisodesSort';
|
||||
export const SET_EPISODES_TABLE_OPTION = 'episodes/setEpisodesTableOption';
|
||||
export const CLEAR_EPISODES = 'episodes/clearEpisodes';
|
||||
export const TOGGLE_EPISODE_MONITORED = 'episodes/toggleEpisodeMonitored';
|
||||
export const TOGGLE_EPISODES_MONITORED = 'episodes/toggleEpisodesMonitored';
|
||||
export const FETCH_ALBUMS = 'albums/fetchAlbums';
|
||||
export const SET_ALBUMS_SORT = 'albums/setAlbumsSort';
|
||||
export const SET_ALBUMS_TABLE_OPTION = 'albums/setAlbumsTableOption';
|
||||
export const CLEAR_ALBUMS = 'albums/clearAlbums';
|
||||
export const TOGGLE_ALBUM_MONITORED = 'albums/toggleAlbumMonitored';
|
||||
export const TOGGLE_ALBUMS_MONITORED = 'albums/toggleAlbumsMonitored';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
||||
export const fetchEpisodes = createThunk(FETCH_EPISODES);
|
||||
export const setEpisodesSort = createAction(SET_EPISODES_SORT);
|
||||
export const setEpisodesTableOption = createAction(SET_EPISODES_TABLE_OPTION);
|
||||
export const clearEpisodes = createAction(CLEAR_EPISODES);
|
||||
export const toggleEpisodeMonitored = createThunk(TOGGLE_EPISODE_MONITORED);
|
||||
export const toggleEpisodesMonitored = createThunk(TOGGLE_EPISODES_MONITORED);
|
||||
export const fetchAlbums = createThunk(FETCH_ALBUMS);
|
||||
export const setAlbumsSort = createAction(SET_ALBUMS_SORT);
|
||||
export const setAlbumsTableOption = createAction(SET_ALBUMS_TABLE_OPTION);
|
||||
export const clearAlbums = createAction(CLEAR_ALBUMS);
|
||||
export const toggleAlbumMonitored = createThunk(TOGGLE_ALBUM_MONITORED);
|
||||
export const toggleAlbumsMonitored = createThunk(TOGGLE_ALBUMS_MONITORED);
|
||||
|
||||
//
|
||||
// Action Handlers
|
||||
|
||||
export const actionHandlers = handleThunks({
|
||||
[FETCH_EPISODES]: createFetchHandler(section, '/album'),
|
||||
[FETCH_ALBUMS]: createFetchHandler(section, '/album'),
|
||||
|
||||
[TOGGLE_EPISODE_MONITORED]: function(getState, payload, dispatch) {
|
||||
[TOGGLE_ALBUM_MONITORED]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
albumId,
|
||||
episodeEntity = episodeEntities.EPISODES,
|
||||
albumEntity = albumEntities.ALBUMS,
|
||||
monitored
|
||||
} = payload;
|
||||
|
||||
const episodeSection = _.last(episodeEntity.split('.'));
|
||||
const albumSection = _.last(albumEntity.split('.'));
|
||||
|
||||
dispatch(updateItem({
|
||||
id: albumId,
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
isSaving: true
|
||||
}));
|
||||
|
||||
|
@ -128,7 +128,7 @@ export const actionHandlers = handleThunks({
|
|||
promise.done((data) => {
|
||||
dispatch(updateItem({
|
||||
id: albumId,
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
isSaving: false,
|
||||
monitored
|
||||
}));
|
||||
|
@ -137,26 +137,26 @@ export const actionHandlers = handleThunks({
|
|||
promise.fail((xhr) => {
|
||||
dispatch(updateItem({
|
||||
id: albumId,
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
isSaving: false
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
[TOGGLE_EPISODES_MONITORED]: function(getState, payload, dispatch) {
|
||||
[TOGGLE_ALBUMS_MONITORED]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
albumIds,
|
||||
episodeEntity = episodeEntities.EPISODES,
|
||||
albumEntity = albumEntities.ALBUMS,
|
||||
monitored
|
||||
} = payload;
|
||||
|
||||
const episodeSection = _.last(episodeEntity.split('.'));
|
||||
const albumSection = _.last(albumEntity.split('.'));
|
||||
|
||||
dispatch(batchActions(
|
||||
albumIds.map((albumId) => {
|
||||
return updateItem({
|
||||
id: albumId,
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
isSaving: true
|
||||
});
|
||||
})
|
||||
|
@ -174,7 +174,7 @@ export const actionHandlers = handleThunks({
|
|||
albumIds.map((albumId) => {
|
||||
return updateItem({
|
||||
id: albumId,
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
isSaving: false,
|
||||
monitored
|
||||
});
|
||||
|
@ -187,7 +187,7 @@ export const actionHandlers = handleThunks({
|
|||
albumIds.map((albumId) => {
|
||||
return updateItem({
|
||||
id: albumId,
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
isSaving: false
|
||||
});
|
||||
})
|
||||
|
@ -201,9 +201,9 @@ export const actionHandlers = handleThunks({
|
|||
|
||||
export const reducers = createHandleActions({
|
||||
|
||||
[SET_EPISODES_TABLE_OPTION]: createSetTableOptionReducer(section),
|
||||
[SET_ALBUMS_TABLE_OPTION]: createSetTableOptionReducer(section),
|
||||
|
||||
[CLEAR_EPISODES]: (state) => {
|
||||
[CLEAR_ALBUMS]: (state) => {
|
||||
return Object.assign({}, state, {
|
||||
isFetching: false,
|
||||
isPopulated: false,
|
||||
|
@ -212,6 +212,6 @@ export const reducers = createHandleActions({
|
|||
});
|
||||
},
|
||||
|
||||
[SET_EPISODES_SORT]: createSetClientSideCollectionSortReducer(section)
|
||||
[SET_ALBUMS_SORT]: createSetClientSideCollectionSortReducer(section)
|
||||
|
||||
}, defaultState, section);
|
|
@ -175,7 +175,7 @@ export const actionHandlers = handleThunks({
|
|||
});
|
||||
|
||||
promise.done((data) => {
|
||||
const episodes = _.filter(getState().episodes.items, { artistId: id, seasonNumber });
|
||||
const albums = _.filter(getState().albums.items, { artistId: id, seasonNumber });
|
||||
|
||||
dispatch(batchActions([
|
||||
updateItem({
|
||||
|
@ -184,10 +184,10 @@ export const actionHandlers = handleThunks({
|
|||
...data
|
||||
}),
|
||||
|
||||
...episodes.map((episode) => {
|
||||
...albums.map((album) => {
|
||||
return updateItem({
|
||||
id: episode.id,
|
||||
section: 'episodes',
|
||||
id: album.id,
|
||||
section: 'albums',
|
||||
monitored
|
||||
});
|
||||
})
|
||||
|
|
|
@ -42,7 +42,7 @@ export const defaultState = {
|
|||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'episodeTitle',
|
||||
name: 'albumTitle',
|
||||
label: 'Album Title',
|
||||
isVisible: true
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as blacklist from './blacklistActions';
|
|||
import * as captcha from './captchaActions';
|
||||
import * as calendar from './calendarActions';
|
||||
import * as commands from './commandActions';
|
||||
import * as episodes from './episodeActions';
|
||||
import * as albums from './albumActions';
|
||||
import * as trackFiles from './trackFileActions';
|
||||
import * as albumHistory from './albumHistoryActions';
|
||||
import * as history from './historyActions';
|
||||
|
@ -34,7 +34,7 @@ export default [
|
|||
captcha,
|
||||
calendar,
|
||||
commands,
|
||||
episodes,
|
||||
albums,
|
||||
trackFiles,
|
||||
albumHistory,
|
||||
history,
|
||||
|
|
|
@ -64,7 +64,7 @@ export const defaultState = {
|
|||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'episodeTitle',
|
||||
name: 'albumTitle',
|
||||
label: 'Album Title',
|
||||
isVisible: true
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@ import $ from 'jquery';
|
|||
import { createAction } from 'redux-actions';
|
||||
import { batchActions } from 'redux-batched-actions';
|
||||
import { createThunk, handleThunks } from 'Store/thunks';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import createFetchHandler from './Creators/createFetchHandler';
|
||||
import createHandleActions from './Creators/createHandleActions';
|
||||
import createRemoveItemHandler from './Creators/createRemoveItemHandler';
|
||||
|
@ -60,20 +60,20 @@ export const actionHandlers = handleThunks({
|
|||
[DELETE_TRACK_FILE]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
id: trackFileId,
|
||||
episodeEntity = episodeEntities.EPISODES
|
||||
albumEntity = albumEntities.ALBUMS
|
||||
} = payload;
|
||||
|
||||
const episodeSection = _.last(episodeEntity.split('.'));
|
||||
const albumSection = _.last(albumEntity.split('.'));
|
||||
const deletePromise = deleteTrackFileHelper(getState, payload, dispatch);
|
||||
|
||||
deletePromise.done(() => {
|
||||
const episodes = getState().episodes.items;
|
||||
const tracksWithRemovedFiles = _.filter(episodes, { trackFileId });
|
||||
const albums = getState().albums.items;
|
||||
const tracksWithRemovedFiles = _.filter(albums, { trackFileId });
|
||||
|
||||
dispatch(batchActions([
|
||||
...tracksWithRemovedFiles.map((track) => {
|
||||
return updateItem({
|
||||
section: episodeSection,
|
||||
section: albumSection,
|
||||
...track,
|
||||
trackFileId: 0,
|
||||
hasFile: false
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
|
||||
function createAlbumSelector() {
|
||||
return createSelector(
|
||||
(state, { albumId }) => albumId,
|
||||
(state, { albumEntity = albumEntities.ALBUMS }) => _.get(state, albumEntity, { items: [] }),
|
||||
(albumId, albums) => {
|
||||
return _.find(albums.items, { id: albumId });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createAlbumSelector;
|
|
@ -1,15 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import { createSelector } from 'reselect';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
|
||||
function createEpisodeSelector() {
|
||||
return createSelector(
|
||||
(state, { albumId }) => albumId,
|
||||
(state, { episodeEntity = episodeEntities.EPISODES }) => _.get(state, episodeEntity, { items: [] }),
|
||||
(albumId, episodes) => {
|
||||
return _.find(episodes.items, { id: albumId });
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default createEpisodeSelector;
|
|
@ -2,8 +2,8 @@
|
|||
import _ from 'lodash';
|
||||
import { update } from 'Store/Actions/baseActions';
|
||||
|
||||
function updateAlbums(dispatch, section, episodes, albumIds, options) {
|
||||
const data = _.reduce(episodes, (result, item) => {
|
||||
function updateAlbums(dispatch, section, albums, albumIds, options) {
|
||||
const data = _.reduce(albums, (result, item) => {
|
||||
if (albumIds.indexOf(item.id) > -1) {
|
||||
result.push({
|
||||
...item,
|
||||
|
|
|
@ -242,11 +242,11 @@ class CutoffUnmet extends Component {
|
|||
<ConfirmModal
|
||||
isOpen={isConfirmSearchAllCutoffUnmetModalOpen}
|
||||
kind={kinds.DANGER}
|
||||
title="Search for all Cutoff Unmet episodes"
|
||||
title="Search for all Cutoff Unmet albums"
|
||||
message={
|
||||
<div>
|
||||
<div>
|
||||
Are you sure you want to search for all {totalRecords} Cutoff Unmet episodes?
|
||||
Are you sure you want to search for all {totalRecords} Cutoff Unmet albums?
|
||||
</div>
|
||||
<div>
|
||||
This cannot be cancelled once started without restarting Lidarr.
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import AlbumTitleLink from 'Album/AlbumTitleLink';
|
||||
import EpisodeStatusConnector from 'Album/EpisodeStatusConnector';
|
||||
import EpisodeSearchCellConnector from 'Album/EpisodeSearchCellConnector';
|
||||
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
|
||||
import TrackFileLanguageConnector from 'TrackFile/TrackFileLanguageConnector';
|
||||
import ArtistNameLink from 'Artist/ArtistNameLink';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
|
@ -58,11 +58,11 @@ function CutoffUnmetRow(props) {
|
|||
if (name === 'albumTitle') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
<EpisodeTitleLink
|
||||
<AlbumTitleLink
|
||||
albumId={id}
|
||||
artistId={artist.id}
|
||||
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
|
||||
episodeTitle={title}
|
||||
albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
|
||||
albumTitle={title}
|
||||
showOpenArtistButton={true}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
@ -108,7 +108,7 @@ function CutoffUnmetRow(props) {
|
|||
<EpisodeStatusConnector
|
||||
albumId={id}
|
||||
trackFileId={trackFileId}
|
||||
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
|
||||
albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
|
||||
/>
|
||||
</TableRowCell>
|
||||
);
|
||||
|
@ -116,12 +116,12 @@ function CutoffUnmetRow(props) {
|
|||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<EpisodeSearchCellConnector
|
||||
<AlbumSearchCellConnector
|
||||
key={name}
|
||||
albumId={id}
|
||||
artistId={artist.id}
|
||||
episodeTitle={title}
|
||||
episodeEntity={episodeEntities.WANTED_CUTOFF_UNMET}
|
||||
albumTitle={title}
|
||||
albumEntity={albumEntities.WANTED_CUTOFF_UNMET}
|
||||
showOpenArtistButton={true}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import episodeEntities from 'Album/episodeEntities';
|
||||
import EpisodeTitleLink from 'Album/EpisodeTitleLink';
|
||||
import albumEntities from 'Album/albumEntities';
|
||||
import AlbumTitleLink from 'Album/AlbumTitleLink';
|
||||
import EpisodeStatusConnector from 'Album/EpisodeStatusConnector';
|
||||
import EpisodeSearchCellConnector from 'Album/EpisodeSearchCellConnector';
|
||||
import AlbumSearchCellConnector from 'Album/AlbumSearchCellConnector';
|
||||
import ArtistNameLink from 'Artist/ArtistNameLink';
|
||||
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
|
@ -75,11 +75,11 @@ function MissingRow(props) {
|
|||
if (name === 'albumTitle') {
|
||||
return (
|
||||
<TableRowCell key={name}>
|
||||
<EpisodeTitleLink
|
||||
<AlbumTitleLink
|
||||
albumId={id}
|
||||
artistId={artist.id}
|
||||
episodeEntity={episodeEntities.WANTED_MISSING}
|
||||
episodeTitle={title}
|
||||
albumEntity={albumEntities.WANTED_MISSING}
|
||||
albumTitle={title}
|
||||
showOpenArtistButton={true}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
@ -112,7 +112,7 @@ function MissingRow(props) {
|
|||
// <EpisodeStatusConnector
|
||||
// albumId={id}
|
||||
// trackFileId={trackFileId}
|
||||
// episodeEntity={episodeEntities.WANTED_MISSING}
|
||||
// albumEntity={albumEntities.WANTED_MISSING}
|
||||
// />
|
||||
// </TableRowCell>
|
||||
// );
|
||||
|
@ -120,12 +120,12 @@ function MissingRow(props) {
|
|||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<EpisodeSearchCellConnector
|
||||
<AlbumSearchCellConnector
|
||||
key={name}
|
||||
albumId={id}
|
||||
artistId={artist.id}
|
||||
episodeTitle={title}
|
||||
episodeEntity={episodeEntities.WANTED_MISSING}
|
||||
albumTitle={title}
|
||||
albumEntity={albumEntities.WANTED_MISSING}
|
||||
showOpenArtistButton={true}
|
||||
/>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue