import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import formatBytes from 'Utilities/Number/formatBytes'; import selectAll from 'Utilities/Table/selectAll'; import toggleSelected from 'Utilities/Table/toggleSelected'; import { align, icons, kinds, sizes, tooltipPositions } from 'Helpers/Props'; import HeartRating from 'Components/HeartRating'; import Icon from 'Components/Icon'; import IconButton from 'Components/Link/IconButton'; import Label from 'Components/Label'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector'; import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; import Popover from 'Components/Tooltip/Popover'; import Tooltip from 'Components/Tooltip/Tooltip'; import TrackFileEditorModal from 'TrackFile/Editor/TrackFileEditorModal'; import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector'; import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector'; import ArtistPoster from 'Artist/ArtistPoster'; import EditArtistModalConnector from 'Artist/Edit/EditArtistModalConnector'; import DeleteArtistModal from 'Artist/Delete/DeleteArtistModal'; 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 }, { name: 'broadcast', label: 'Broadcast', isVisible: true }, { name: 'other', label: 'Other', isVisible: true } ]; function getFanartUrl(images) { const fanartImage = _.find(images, { coverType: 'fanart' }); if (fanartImage) { // Remove protocol return fanartImage.url.replace(/^https?:/, ''); } } function getExpandedState(newState) { return { allExpanded: newState.allSelected, allCollapsed: newState.allUnselected, expandedState: newState.selectedState }; } class ArtistDetails extends Component { // // Lifecycle constructor(props, context) { super(props, context); this.state = { isOrganizeModalOpen: false, isManageEpisodesOpen: false, isEditArtistModalOpen: false, isDeleteArtistModalOpen: false, allExpanded: false, allCollapsed: false, expandedState: {} }; } // // Listeners onOrganizePress = () => { this.setState({ isOrganizeModalOpen: true }); } onOrganizeModalClose = () => { this.setState({ isOrganizeModalOpen: false }); } onManageEpisodesPress = () => { this.setState({ isManageEpisodesOpen: true }); } onManageEpisodesModalClose = () => { this.setState({ isManageEpisodesOpen: false }); } onEditArtistPress = () => { this.setState({ isEditArtistModalOpen: true }); } onEditArtistModalClose = () => { this.setState({ isEditArtistModalOpen: false }); } onDeleteArtistPress = () => { this.setState({ isEditArtistModalOpen: false, isDeleteArtistModalOpen: true }); } onDeleteArtistModalClose = () => { this.setState({ isDeleteArtistModalOpen: false }); } onExpandAllPress = () => { const { allExpanded, expandedState } = this.state; this.setState(getExpandedState(selectAll(expandedState, !allExpanded))); } onExpandPress = (albumId, isExpanded) => { this.setState((state) => { const convertedState = { allSelected: state.allExpanded, allUnselected: state.allCollapsed, selectedState: state.expandedState }; const newState = toggleSelected(convertedState, [], albumId, isExpanded, false); return getExpandedState(newState); }); } // // Render render() { const { id, foreignArtistId, artistName, ratings, sizeOnDisk, trackFileCount, qualityProfileId, monitored, status, overview, links, images, albums, alternateTitles, tags, isRefreshing, isSearching, isFetching, isPopulated, episodesError, trackFilesError, previousArtist, nextArtist, onRefreshPress, onSearchPress } = this.props; const { isOrganizeModalOpen, isManageEpisodesOpen, isEditArtistModalOpen, isDeleteArtistModalOpen, allExpanded, allCollapsed, expandedState } = this.state; const continuing = status === 'continuing'; let trackFilesCountMessage = 'No track files'; if (trackFileCount === 1) { trackFilesCountMessage = '1 track file'; } else if (trackFileCount > 1) { trackFilesCountMessage = `${trackFileCount} track files`; } let expandIcon = icons.EXPAND_INDETERMINATE; if (allExpanded) { expandIcon = icons.COLLAPSE; } else if (allCollapsed) { expandIcon = icons.EXPAND; } return (
{artistName} { !!alternateTitles.length && } title="Alternate Titles" body={} position={tooltipPositions.BOTTOM} /> }
Links } tooltip={ } kind={kinds.INVERSE} position={tooltipPositions.BOTTOM} /> { !!tags.length && Tags } tooltip={} kind={kinds.INVERSE} position={tooltipPositions.BOTTOM} /> }
{overview}
{ !isPopulated && !episodesError && !trackFilesError && } { !isFetching && episodesError &&
Loading episodes failed
} { !isFetching && trackFilesError &&
Loading episode files failed
} { isPopulated && !!albumTypes.length &&
{ albumTypes.slice(0).map((season) => { return ( ); }) }
} { isPopulated && !albums.length &&
No episode information is available.
}
); } } ArtistDetails.propTypes = { id: PropTypes.number.isRequired, foreignArtistId: PropTypes.string.isRequired, artistName: PropTypes.string.isRequired, ratings: PropTypes.object.isRequired, sizeOnDisk: PropTypes.number.isRequired, trackFileCount: PropTypes.number, qualityProfileId: PropTypes.number.isRequired, monitored: PropTypes.bool.isRequired, status: PropTypes.string.isRequired, overview: PropTypes.string.isRequired, links: PropTypes.arrayOf(PropTypes.object).isRequired, images: PropTypes.arrayOf(PropTypes.object).isRequired, albums: PropTypes.arrayOf(PropTypes.object).isRequired, alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired, tags: PropTypes.arrayOf(PropTypes.number).isRequired, isRefreshing: PropTypes.bool.isRequired, isSearching: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired, isPopulated: PropTypes.bool.isRequired, episodesError: PropTypes.object, trackFilesError: PropTypes.object, previousArtist: PropTypes.object.isRequired, nextArtist: PropTypes.object.isRequired, onRefreshPress: PropTypes.func.isRequired, onSearchPress: PropTypes.func.isRequired }; ArtistDetails.defaultProps = { isSaving: false }; export default ArtistDetails;