import PropTypes from 'prop-types'; import React, { Component } from 'react'; import Icon from 'Components/Icon'; import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableRowCellButton from 'Components/Table/Cells/TableRowCellButton'; import TableSelectCell from 'Components/Table/Cells/TableSelectCell'; import TableRow from 'Components/Table/TableRow'; import Popover from 'Components/Tooltip/Popover'; import EpisodeFormats from 'Episode/EpisodeFormats'; import EpisodeLanguages from 'Episode/EpisodeLanguages'; import EpisodeQuality from 'Episode/EpisodeQuality'; import { icons, kinds, tooltipPositions } from 'Helpers/Props'; import SelectEpisodeModal from 'InteractiveImport/Episode/SelectEpisodeModal'; import SelectLanguageModal from 'InteractiveImport/Language/SelectLanguageModal'; import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal'; import SelectReleaseGroupModal from 'InteractiveImport/ReleaseGroup/SelectReleaseGroupModal'; import SelectSeasonModal from 'InteractiveImport/Season/SelectSeasonModal'; import SelectSeriesModal from 'InteractiveImport/Series/SelectSeriesModal'; import formatBytes from 'Utilities/Number/formatBytes'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; import InteractiveImportRowCellPlaceholder from './InteractiveImportRowCellPlaceholder'; import styles from './InteractiveImportRow.css'; class InteractiveImportRow extends Component { // // Lifecycle constructor(props, context) { super(props, context); this.state = { isSelectSeriesModalOpen: false, isSelectSeasonModalOpen: false, isSelectEpisodeModalOpen: false, isSelectReleaseGroupModalOpen: false, isSelectQualityModalOpen: false, isSelectLanguageModalOpen: false }; } componentDidMount() { const { allowSeriesChange, id, series, seasonNumber, episodes, quality, languages, episodeFileId, columns } = this.props; if ( allowSeriesChange && series && seasonNumber != null && episodes.length && quality && languages ) { this.props.onSelectedChange({ id, hasEpisodeFileId: !!episodeFileId, value: true }); } this.setState({ isSeriesColumnVisible: columns.find((c) => c.name === 'series').isVisible }); } componentDidUpdate(prevProps) { const { id, series, seasonNumber, episodes, quality, languages, isSelected, onValidRowChange } = this.props; if ( prevProps.series === series && prevProps.seasonNumber === seasonNumber && !hasDifferentItems(prevProps.episodes, episodes) && prevProps.quality === quality && prevProps.languages === languages && prevProps.isSelected === isSelected ) { return; } const isValid = !!( series && seasonNumber != null && episodes.length && quality && languages ); if (isSelected && !isValid) { onValidRowChange(id, false); } else { onValidRowChange(id, true); } } // // Control selectRowAfterChange = (value) => { const { id, episodeFileId, isSelected } = this.props; if (!isSelected && value === true) { this.props.onSelectedChange({ id, hasEpisodeFileId: !!episodeFileId, value }); } }; // // Listeners onSelectedChange = (result) => { const { episodeFileId, onSelectedChange } = this.props; onSelectedChange({ ...result, hasEpisodeFileId: !!episodeFileId }); }; onSelectSeriesPress = () => { this.setState({ isSelectSeriesModalOpen: true }); }; onSelectSeasonPress = () => { this.setState({ isSelectSeasonModalOpen: true }); }; onSelectEpisodePress = () => { this.setState({ isSelectEpisodeModalOpen: true }); }; onSelectReleaseGroupPress = () => { this.setState({ isSelectReleaseGroupModalOpen: true }); }; onSelectQualityPress = () => { this.setState({ isSelectQualityModalOpen: true }); }; onSelectLanguagePress = () => { this.setState({ isSelectLanguageModalOpen: true }); }; onSelectSeriesModalClose = (changed) => { this.setState({ isSelectSeriesModalOpen: false }); this.selectRowAfterChange(changed); }; onSelectSeasonModalClose = (changed) => { this.setState({ isSelectSeasonModalOpen: false }); this.selectRowAfterChange(changed); }; onSelectEpisodeModalClose = (changed) => { this.setState({ isSelectEpisodeModalOpen: false }); this.selectRowAfterChange(changed); }; onSelectReleaseGroupModalClose = (changed) => { this.setState({ isSelectReleaseGroupModalOpen: false }); this.selectRowAfterChange(changed); }; onSelectQualityModalClose = (changed) => { this.setState({ isSelectQualityModalOpen: false }); this.selectRowAfterChange(changed); }; onSelectLanguageModalClose = (changed) => { this.setState({ isSelectLanguageModalOpen: false }); this.selectRowAfterChange(changed); }; // // Render render() { const { id, allowSeriesChange, relativePath, series, seasonNumber, episodes, quality, languages, releaseGroup, size, customFormats, rejections, isReprocessing, isSelected, modalTitle } = this.props; const { isSelectSeriesModalOpen, isSelectSeasonModalOpen, isSelectEpisodeModalOpen, isSelectReleaseGroupModalOpen, isSelectQualityModalOpen, isSelectLanguageModalOpen } = this.state; const seriesTitle = series ? series.title : ''; const isAnime = series ? series.seriesType === 'anime' : false; const episodeInfo = episodes.map((episode) => { return (
{episode.episodeNumber} { isAnime && episode.absoluteEpisodeNumber != null ? ` (${episode.absoluteEpisodeNumber})` : '' } {` - ${episode.title}`}
); }); const showSeriesPlaceholder = isSelected && !series; const showSeasonNumberPlaceholder = isSelected && !!series && isNaN(seasonNumber) && !isReprocessing; const showEpisodeNumbersPlaceholder = isSelected && Number.isInteger(seasonNumber) && !episodes.length; const showReleaseGroupPlaceholder = isSelected && !releaseGroup; const showQualityPlaceholder = isSelected && !quality; const showLanguagePlaceholder = isSelected && !languages; return ( {relativePath} { this.state.isSeriesColumnVisible ? { showSeriesPlaceholder ? : seriesTitle } : null } { showSeasonNumberPlaceholder ? : seasonNumber } { isReprocessing && seasonNumber == null ? : null } { showEpisodeNumbersPlaceholder ? : episodeInfo } { showReleaseGroupPlaceholder ? : releaseGroup } { showQualityPlaceholder && } { !showQualityPlaceholder && !!quality && } { showLanguagePlaceholder && } { !showLanguagePlaceholder && !!languages && } {formatBytes(size)} { customFormats?.length ? } title="Formats" body={
} position={tooltipPositions.LEFT} /> : null }
{ rejections.length ? } title="Release Rejected" body={
    { rejections.map((rejection, index) => { return (
  • {rejection.reason}
  • ); }) }
} position={tooltipPositions.LEFT} canFlip={false} /> : null }
1 : false} real={quality ? quality.revision.real > 0 : false} modalTitle={modalTitle} onModalClose={this.onSelectQualityModalClose} /> l.id) : []} modalTitle={modalTitle} onModalClose={this.onSelectLanguageModalClose} />
); } } InteractiveImportRow.propTypes = { id: PropTypes.number.isRequired, allowSeriesChange: PropTypes.bool.isRequired, relativePath: PropTypes.string.isRequired, series: PropTypes.object, seasonNumber: PropTypes.number, episodes: PropTypes.arrayOf(PropTypes.object).isRequired, releaseGroup: PropTypes.string, quality: PropTypes.object, languages: PropTypes.arrayOf(PropTypes.object), size: PropTypes.number.isRequired, customFormats: PropTypes.arrayOf(PropTypes.object), rejections: PropTypes.arrayOf(PropTypes.object).isRequired, columns: PropTypes.arrayOf(PropTypes.object).isRequired, episodeFileId: PropTypes.number, isReprocessing: PropTypes.bool, isSelected: PropTypes.bool, modalTitle: PropTypes.string.isRequired, onSelectedChange: PropTypes.func.isRequired, onValidRowChange: PropTypes.func.isRequired }; InteractiveImportRow.defaultProps = { episodes: [] }; export default InteractiveImportRow;