import React, { RefObject, useCallback, useEffect, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { FixedSizeList, ListChildComponentProps } from 'react-window'; import { useAddSeriesOptions } from 'AddSeries/addSeriesOptionsStore'; import { useSelect } from 'App/SelectContext'; import AppState from 'App/State/AppState'; import { ImportSeries } from 'App/State/ImportSeriesAppState'; import VirtualTable from 'Components/Table/VirtualTable'; import usePrevious from 'Helpers/Hooks/usePrevious'; import { queueLookupSeries, setImportSeriesValue, } from 'Store/Actions/importSeriesActions'; import createAllSeriesSelector from 'Store/Selectors/createAllSeriesSelector'; import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; import { CheckInputChanged } from 'typings/inputs'; import { SelectStateInputProps } from 'typings/props'; import { UnmappedFolder } from 'typings/RootFolder'; import ImportSeriesHeader from './ImportSeriesHeader'; import ImportSeriesRow from './ImportSeriesRow'; import styles from './ImportSeriesTable.css'; const ROW_HEIGHT = 52; interface RowItemData { items: ImportSeries[]; } interface ImportSeriesTableProps { unmappedFolders: UnmappedFolder[]; scrollerRef: RefObject; } function Row({ index, style, data }: ListChildComponentProps) { const { items } = data; if (index >= items.length) { return null; } const item = items[index]; return (
); } function ImportSeriesTable({ unmappedFolders, scrollerRef, }: ImportSeriesTableProps) { const dispatch = useDispatch(); const { monitor, qualityProfileId, seriesType, seasonFolder } = useAddSeriesOptions(); const items = useSelector((state: AppState) => state.importSeries.items); const { isSmallScreen } = useSelector(createDimensionsSelector()); const allSeries = useSelector(createAllSeriesSelector()); const [selectState, selectDispatch] = useSelect(); const defaultValues = useRef({ monitor, qualityProfileId, seriesType, seasonFolder, }); const listRef = useRef>(null); const initialUnmappedFolders = useRef(unmappedFolders); const previousItems = usePrevious(items); const { allSelected, allUnselected, selectedState } = selectState; const handleSelectAllChange = useCallback( ({ value }: CheckInputChanged) => { selectDispatch({ type: value ? 'selectAll' : 'unselectAll', }); }, [selectDispatch] ); const handleSelectedChange = useCallback( ({ id, value, shiftKey }: SelectStateInputProps) => { selectDispatch({ type: 'toggleSelected', id, isSelected: value, shiftKey, }); }, [selectDispatch] ); const handleRemoveSelectedStateItem = useCallback( (id: string) => { selectDispatch({ type: 'removeItem', id, }); }, [selectDispatch] ); useEffect(() => { initialUnmappedFolders.current.forEach(({ name, path, relativePath }) => { dispatch( queueLookupSeries({ name, path, relativePath, term: name, }) ); dispatch( // @ts-expect-error - actions are not typed setImportSeriesValue({ id: name, ...defaultValues.current, }) ); }); }, [dispatch]); useEffect(() => { previousItems?.forEach((prevItem) => { const { id } = prevItem; const item = items.find((i) => i.id === id); if (!item) { handleRemoveSelectedStateItem(id); return; } const selectedSeries = item.selectedSeries; const isSelected = selectedState[id]; const isExistingSeries = !!selectedSeries && allSeries.some((s) => s.tvdbId === selectedSeries.tvdbId); if ( (!selectedSeries && prevItem.selectedSeries) || (isExistingSeries && !prevItem.selectedSeries) ) { handleSelectedChange({ id, value: false, shiftKey: false }); return; } if (isSelected && (!selectedSeries || isExistingSeries)) { handleSelectedChange({ id, value: false, shiftKey: false }); return; } if (selectedSeries && selectedSeries !== prevItem.selectedSeries) { handleSelectedChange({ id, value: true, shiftKey: false }); return; } }); }, [ allSeries, items, previousItems, selectedState, handleRemoveSelectedStateItem, handleSelectedChange, ]); if (!items.length) { return null; } return ( } itemCount={items.length} itemData={{ items, }} isSmallScreen={isSmallScreen} listRef={listRef} rowHeight={ROW_HEIGHT} Row={Row} scrollerRef={scrollerRef} /> ); } export default ImportSeriesTable;