import _ from 'lodash'; import moment from 'moment'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import TextTruncate from 'react-text-truncate'; 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 fonts from 'Styles/Variables/fonts'; import HeartRating from 'Components/HeartRating'; import Icon from 'Components/Icon'; import IconButton from 'Components/Link/IconButton'; import Label from 'Components/Label'; import Tooltip from 'Components/Tooltip/Tooltip'; import AlbumCover from 'Album/AlbumCover'; import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector'; import EditAlbumModalConnector from 'Album/Edit/EditAlbumModalConnector'; 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 AlbumDetailsMediumConnector from './AlbumDetailsMediumConnector'; import ArtistHistoryModal from 'Artist/History/ArtistHistoryModal'; import InteractiveSearchModal from 'InteractiveSearch/InteractiveSearchModal'; import TrackFileEditorModal from 'TrackFile/Editor/TrackFileEditorModal'; import AlbumDetailsLinks from './AlbumDetailsLinks'; import styles from './AlbumDetails.css'; const defaultFontSize = parseInt(fonts.defaultFontSize); const lineHeight = parseFloat(fonts.lineHeight); 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 AlbumDetails extends Component { // // Lifecycle constructor(props, context) { super(props, context); this.state = { isOrganizeModalOpen: false, isArtistHistoryModalOpen: false, isInteractiveSearchModalOpen: false, isManageTracksOpen: false, isEditAlbumModalOpen: false, allExpanded: false, allCollapsed: false, expandedState: {} }; } // // Listeners onOrganizePress = () => { this.setState({ isOrganizeModalOpen: true }); } onOrganizeModalClose = () => { this.setState({ isOrganizeModalOpen: false }); } onEditAlbumPress = () => { this.setState({ isEditAlbumModalOpen: true }); } onEditAlbumModalClose = () => { this.setState({ isEditAlbumModalOpen: false }); } onManageTracksPress = () => { this.setState({ isManageTracksOpen: true }); } onManageTracksModalClose = () => { this.setState({ isManageTracksOpen: false }); } onInteractiveSearchPress = () => { this.setState({ isInteractiveSearchModalOpen: true }); } onInteractiveSearchModalClose = () => { this.setState({ isInteractiveSearchModalOpen: false }); } onArtistHistoryPress = () => { this.setState({ isArtistHistoryModalOpen: true }); } onArtistHistoryModalClose = () => { this.setState({ isArtistHistoryModalOpen: 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, foreignAlbumId, title, disambiguation, overview, albumType, statistics = {}, monitored, releaseDate, ratings, images, links, media, isFetching, isPopulated, albumsError, trackFilesError, shortDateFormat, artist, previousAlbum, nextAlbum, isSearching, onSearchPress } = this.props; const { isOrganizeModalOpen, isArtistHistoryModalOpen, isInteractiveSearchModalOpen, isEditAlbumModalOpen, isManageTracksOpen, allExpanded, allCollapsed, expandedState } = this.state; let expandIcon = icons.EXPAND_INDETERMINATE; if (allExpanded) { expandIcon = icons.COLLAPSE; } else if (allCollapsed) { expandIcon = icons.EXPAND; } return (
{title}{disambiguation ? ` (${disambiguation})` : ''}
{ !!albumType && } Links } tooltip={ } kind={kinds.INVERSE} position={tooltipPositions.BOTTOM} />
{ !isPopulated && !albumsError && !trackFilesError && } { !isFetching && albumsError &&
Loading albums failed
} { !isFetching && trackFilesError &&
Loading track files failed
} { isPopulated && !!media.length &&
{ media.slice(0).map((medium) => { return ( ); }) }
}
); } } AlbumDetails.propTypes = { id: PropTypes.number.isRequired, foreignAlbumId: PropTypes.string.isRequired, title: PropTypes.string.isRequired, disambiguation: PropTypes.string, overview: PropTypes.string, albumType: PropTypes.string.isRequired, statistics: PropTypes.object.isRequired, releaseDate: PropTypes.string.isRequired, ratings: PropTypes.object.isRequired, images: PropTypes.arrayOf(PropTypes.object).isRequired, links: PropTypes.arrayOf(PropTypes.object).isRequired, media: PropTypes.arrayOf(PropTypes.object).isRequired, monitored: PropTypes.bool.isRequired, shortDateFormat: PropTypes.string.isRequired, isSearching: PropTypes.bool, isFetching: PropTypes.bool, isPopulated: PropTypes.bool, albumsError: PropTypes.object, tracksError: PropTypes.object, trackFilesError: PropTypes.object, artist: PropTypes.object, previousAlbum: PropTypes.object, nextAlbum: PropTypes.object, onRefreshPress: PropTypes.func, onSearchPress: PropTypes.func.isRequired }; AlbumDetails.defaultProps = { isSaving: false }; export default AlbumDetails;