Fixed: Override and Grab release with unknown series

Closes #5533
This commit is contained in:
Mark McDowall 2023-04-04 10:39:27 -07:00
parent 3dce7e729c
commit 221bb10261
5 changed files with 51 additions and 21 deletions

View File

@ -5,7 +5,7 @@ import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent'; import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter'; import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import createSeriesSelector from 'Store/Selectors/createSeriesSelector'; import { createSeriesSelectorForHook } from 'Store/Selectors/createSeriesSelector';
import SelectSeasonRow from './SelectSeasonRow'; import SelectSeasonRow from './SelectSeasonRow';
interface SelectSeasonModalContentProps { interface SelectSeasonModalContentProps {
@ -17,7 +17,7 @@ interface SelectSeasonModalContentProps {
function SelectSeasonModalContent(props: SelectSeasonModalContentProps) { function SelectSeasonModalContent(props: SelectSeasonModalContentProps) {
const { seriesId, modalTitle, onSeasonSelect, onModalClose } = props; const { seriesId, modalTitle, onSeasonSelect, onModalClose } = props;
const series = useSelector(createSeriesSelector(seriesId)); const series = useSelector(createSeriesSelectorForHook(seriesId));
const seasons = useMemo(() => { const seasons = useMemo(() => {
return series.seasons.slice(0).reverse(); return series.seasons.slice(0).reverse();
}, [series]); }, [series]);

View File

@ -23,7 +23,7 @@ import Series from 'Series/Series';
import { grabRelease } from 'Store/Actions/releaseActions'; import { grabRelease } from 'Store/Actions/releaseActions';
import { fetchDownloadClients } from 'Store/Actions/settingsActions'; import { fetchDownloadClients } from 'Store/Actions/settingsActions';
import createEnabledDownloadClientsSelector from 'Store/Selectors/createEnabledDownloadClientsSelector'; import createEnabledDownloadClientsSelector from 'Store/Selectors/createEnabledDownloadClientsSelector';
import createSeriesSelector from 'Store/Selectors/createSeriesSelector'; import { createSeriesSelectorForHook } from 'Store/Selectors/createSeriesSelector';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import SelectDownloadClientModal from './DownloadClient/SelectDownloadClientModal'; import SelectDownloadClientModal from './DownloadClient/SelectDownloadClientModal';
import OverrideMatchData from './OverrideMatchData'; import OverrideMatchData from './OverrideMatchData';
@ -77,7 +77,9 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
); );
const dispatch = useDispatch(); const dispatch = useDispatch();
const series: Series = useSelector(createSeriesSelector(seriesId)); const series: Series | undefined = useSelector(
createSeriesSelectorForHook(seriesId)
);
const { items: downloadClients } = useSelector( const { items: downloadClients } = useSelector(
createEnabledDownloadClientsSelector(protocol) createEnabledDownloadClientsSelector(protocol)
); );
@ -88,7 +90,7 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
<div key={episode.id}> <div key={episode.id}>
{episode.episodeNumber} {episode.episodeNumber}
{series.seriesType === 'anime' && {series?.seriesType === 'anime' &&
episode.absoluteEpisodeNumber != null episode.absoluteEpisodeNumber != null
? ` (${episode.absoluteEpisodeNumber})` ? ` (${episode.absoluteEpisodeNumber})`
: ''} : ''}
@ -351,7 +353,7 @@ function OverrideMatchModalContent(props: OverrideMatchModalContentProps) {
isOpen={selectModalOpen === 'episode'} isOpen={selectModalOpen === 'episode'}
selectedIds={[guid]} selectedIds={[guid]}
seriesId={seriesId} seriesId={seriesId}
isAnime={series.seriesType === 'anime'} isAnime={series?.seriesType === 'anime'}
seasonNumber={seasonNumber} seasonNumber={seasonNumber}
selectedDetails={title} selectedDetails={title}
modalTitle={modalTitle} modalTitle={modalTitle}

View File

@ -3,11 +3,11 @@ import { createSelector } from 'reselect';
import { REFRESH_SERIES, SERIES_SEARCH } from 'Commands/commandNames'; import { REFRESH_SERIES, SERIES_SEARCH } from 'Commands/commandNames';
import createExecutingCommandsSelector from 'Store/Selectors/createExecutingCommandsSelector'; import createExecutingCommandsSelector from 'Store/Selectors/createExecutingCommandsSelector';
import createSeriesQualityProfileSelector from 'Store/Selectors/createSeriesQualityProfileSelector'; import createSeriesQualityProfileSelector from 'Store/Selectors/createSeriesQualityProfileSelector';
import createSeriesSelector from 'Store/Selectors/createSeriesSelector'; import { createSeriesSelectorForHook } from 'Store/Selectors/createSeriesSelector';
function createSeriesIndexItemSelector(seriesId: number) { function createSeriesIndexItemSelector(seriesId: number) {
return createSelector( return createSelector(
createSeriesSelector(seriesId), createSeriesSelectorForHook(seriesId),
createSeriesQualityProfileSelector(seriesId), createSeriesQualityProfileSelector(seriesId),
createExecutingCommandsSelector(), createExecutingCommandsSelector(),
(series, qualityProfile, executingCommands) => { (series, qualityProfile, executingCommands) => {

View File

@ -1,7 +1,16 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
function createSeriesSelector(id) { export function createSeriesSelectorForHook(seriesId) {
if (id == null) { return createSelector(
(state) => state.series.itemMap,
(state) => state.series.items,
(itemMap, allSeries) => {
return seriesId ? allSeries[itemMap[seriesId]]: undefined;
}
);
}
function createSeriesSelector() {
return createSelector( return createSelector(
(state, { seriesId }) => seriesId, (state, { seriesId }) => seriesId,
(state) => state.series.itemMap, (state) => state.series.itemMap,
@ -12,13 +21,4 @@ function createSeriesSelector(id) {
); );
} }
return createSelector(
(state) => state.series.itemMap,
(state) => state.series.items,
(itemMap, allSeries) => {
return allSeries[itemMap[id]];
}
);
}
export default createSeriesSelector; export default createSeriesSelector;

View File

@ -0,0 +1,28 @@
import ModelBase from 'App/ModelBase';
export interface Field {
order: number;
name: string;
label: string;
value: boolean | number | string;
type: string;
advanced: boolean;
privacy: string;
}
interface DownloadClient extends ModelBase {
enable: boolean;
protocol: string;
priority: number;
removeCompletedDownloads: boolean;
removeFailedDownloads: boolean;
name: string;
fields: Field[];
implementationName: string;
implementation: string;
configContract: string;
infoLink: string;
tags: number[];
}
export default DownloadClient;