import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { Tab, Tabs, TabList, TabPanel } from 'react-tabs'; 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 { 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 InfoLabel from 'Components/InfoLabel'; import MovieStatusLabel from './MovieStatusLabel'; import Measure from 'Components/Measure'; import MonitorToggleButton from 'Components/MonitorToggleButton'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; 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 InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable'; import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable'; import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector'; import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector'; import MoviePoster from 'Movie/MoviePoster'; import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import MovieHistoryTable from 'Movie/History/MovieHistoryTable'; import MovieTitlesTable from './Titles/MovieTitlesTable'; import MovieCastPostersConnector from './Credits/Cast/MovieCastPostersConnector'; import MovieCrewPostersConnector from './Credits/Crew/MovieCrewPostersConnector'; import MovieAlternateTitles from './MovieAlternateTitles'; import MovieDetailsLinks from './MovieDetailsLinks'; import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable'; import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector'; import MovieTagsConnector from './MovieTagsConnector'; import styles from './MovieDetails.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 MovieDetails extends Component { // // Lifecycle constructor(props, context) { super(props, context); this.state = { isOrganizeModalOpen: false, isEditMovieModalOpen: false, isDeleteMovieModalOpen: false, isInteractiveImportModalOpen: false, allExpanded: false, allCollapsed: false, expandedState: {}, selectedTabIndex: 0, overviewHeight: 0 }; } // // Listeners onOrganizePress = () => { this.setState({ isOrganizeModalOpen: true }); } onOrganizeModalClose = () => { this.setState({ isOrganizeModalOpen: false }); } onManageEpisodesPress = () => { this.setState({ isManageEpisodesOpen: true }); } onInteractiveImportPress = () => { this.setState({ isInteractiveImportModalOpen: true }); } onInteractiveImportModalClose = () => { this.setState({ isInteractiveImportModalOpen: false }); } onEditMoviePress = () => { this.setState({ isEditMovieModalOpen: true }); } onEditMovieModalClose = () => { this.setState({ isEditMovieModalOpen: false }); } onDeleteMoviePress = () => { this.setState({ isEditMovieModalOpen: false, isDeleteMovieModalOpen: true }); } onDeleteMovieModalClose = () => { this.setState({ isDeleteMovieModalOpen: false }); } onExpandAllPress = () => { const { allExpanded, expandedState } = this.state; this.setState(getExpandedState(selectAll(expandedState, !allExpanded))); } onExpandPress = (seasonNumber, isExpanded) => { this.setState((state) => { const convertedState = { allSelected: state.allExpanded, allUnselected: state.allCollapsed, selectedState: state.expandedState }; const newState = toggleSelected(convertedState, [], seasonNumber, isExpanded, false); return getExpandedState(newState); }); } onMeasure = ({ height }) => { this.setState({ overviewHeight: height }); } // // Render render() { const { id, tmdbId, imdbId, title, year, runtime, certification, ratings, path, sizeOnDisk, qualityProfileId, monitored, studio, collection, overview, youTubeTrailerId, inCinemas, images, alternateTitles, tags, isSaving, isRefreshing, isSearching, isFetching, isPopulated, isSmallScreen, movieFilesError, movieCreditsError, extraFilesError, hasMovieFiles, previousMovie, nextMovie, onMonitorTogglePress, onRefreshPress, onSearchPress } = this.props; const { isOrganizeModalOpen, isEditMovieModalOpen, isDeleteMovieModalOpen, isInteractiveImportModalOpen, overviewHeight, selectedTabIndex } = this.state; return (
{title}
{ !!certification && {certification} } { year > 0 && {year} } { !!runtime && {runtime} Minutes } { !!ratings && } { } title="Links" body={ } position={tooltipPositions.BOTTOM} /> } { !!tags.length && } title="Tags" body={ } position={tooltipPositions.BOTTOM} /> }
{path} { } { formatBytes(sizeOnDisk) } { !!collection && {collection.name} } { !!studio && {studio} }
{ !isPopulated && !movieFilesError && !movieCreditsError && !extraFilesError && } { !isFetching && movieFilesError &&
Loading movie files failed
} { !isFetching && movieCreditsError &&
Loading movie credits failed
} { !isFetching && extraFilesError &&
Loading movie extra files failed
} this.setState({ selectedTabIndex: tabIndex })}> History Search Files Titles Cast Crew { selectedTabIndex === 1 &&
}
); } } MovieDetails.propTypes = { id: PropTypes.number.isRequired, tmdbId: PropTypes.number.isRequired, imdbId: PropTypes.string, title: PropTypes.string.isRequired, year: PropTypes.number.isRequired, runtime: PropTypes.number.isRequired, certification: PropTypes.string, ratings: PropTypes.object.isRequired, path: PropTypes.string.isRequired, sizeOnDisk: PropTypes.number.isRequired, qualityProfileId: PropTypes.number.isRequired, monitored: PropTypes.bool.isRequired, status: PropTypes.string.isRequired, studio: PropTypes.string, collection: PropTypes.object, youTubeTrailerId: PropTypes.string, inCinemas: PropTypes.string, overview: PropTypes.string.isRequired, images: PropTypes.arrayOf(PropTypes.object).isRequired, alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired, tags: PropTypes.arrayOf(PropTypes.number).isRequired, isSaving: PropTypes.bool.isRequired, isRefreshing: PropTypes.bool.isRequired, isSearching: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired, isPopulated: PropTypes.bool.isRequired, isSmallScreen: PropTypes.bool.isRequired, movieFilesError: PropTypes.object, movieCreditsError: PropTypes.object, extraFilesError: PropTypes.object, hasMovieFiles: PropTypes.bool.isRequired, previousMovie: PropTypes.object.isRequired, nextMovie: PropTypes.object.isRequired, onMonitorTogglePress: PropTypes.func.isRequired, onRefreshPress: PropTypes.func.isRequired, onSearchPress: PropTypes.func.isRequired }; MovieDetails.defaultProps = { tags: [], isSaving: false, sizeOnDisk: 0 }; export default MovieDetails;