Fix/library manga selection type error (#566)

* Prevent TypeError when deselecting items from a specific key

This was noticed when changing the categories of a manga to a category without any selected mangas, in this case, when trying to deselect a manga after changing the categories, a TypeError was thrown which resulted in a white screen

* Remove duplicates from the list of all selected ids

* Update state via setter

* Clear selection after disabling the library selection mode

* Remove console log
This commit is contained in:
schroda
2024-01-21 22:31:43 +01:00
committed by GitHub
parent 69a62b6c2c
commit dcbf5a1899
3 changed files with 16 additions and 4 deletions

View File

@@ -19,6 +19,7 @@ export type SelectableCollectionReturnType<Id extends number | string, Key exten
handleSelectAll: (selectAll: boolean, itemIds: Id[], key?: Key) => void; handleSelectAll: (selectAll: boolean, itemIds: Id[], key?: Key) => void;
setSelectionForKey: (key: Key, itemIds: Id[]) => void; setSelectionForKey: (key: Key, itemIds: Id[]) => void;
getSelectionForKey: (key: Key) => Id[]; getSelectionForKey: (key: Key) => Id[];
clearSelection: () => void;
}; };
export const useSelectableCollection = <Id extends number | string, Key extends string = 'default'>( export const useSelectableCollection = <Id extends number | string, Key extends string = 'default'>(
@@ -35,7 +36,7 @@ export const useSelectableCollection = <Id extends number | string, Key extends
): SelectableCollectionReturnType<Id, Key> => { ): SelectableCollectionReturnType<Id, Key> => {
const [keyToSelectedItemIds, setKeyToSelectedItemIds] = useState<Record<string, Id[]>>(initialState); const [keyToSelectedItemIds, setKeyToSelectedItemIds] = useState<Record<string, Id[]>>(initialState);
const selectedItemIds = Object.values(keyToSelectedItemIds).flat(); const selectedItemIds = [...new Set(Object.values(keyToSelectedItemIds).flat())];
const areAllItemsSelected = selectedItemIds.length === totalCount; const areAllItemsSelected = selectedItemIds.length === totalCount;
const areNoItemsSelected = !selectedItemIds.length; const areNoItemsSelected = !selectedItemIds.length;
@@ -48,7 +49,7 @@ export const useSelectableCollection = <Id extends number | string, Key extends
if (deselect) { if (deselect) {
setKeyToSelectedItemIds((prevState) => ({ setKeyToSelectedItemIds((prevState) => ({
...prevState, ...prevState,
[key]: prevState[key].filter((selectedItemId) => selectedItemId !== id), [key]: prevState[key]?.filter((selectedItemId) => selectedItemId !== id) ?? [],
})); }));
return; return;
} }
@@ -79,11 +80,18 @@ export const useSelectableCollection = <Id extends number | string, Key extends
}; };
const setSelectionForKey = (key: Key, itemIds: Id[]) => { const setSelectionForKey = (key: Key, itemIds: Id[]) => {
keyToSelectedItemIds[key] = itemIds; setKeyToSelectedItemIds((prevState) => ({
...prevState,
[key]: [...itemIds],
}));
}; };
const getSelectionForKey = (key: Key) => keyToSelectedItemIds[key]; const getSelectionForKey = (key: Key) => keyToSelectedItemIds[key];
const clearSelection = () => {
setKeyToSelectedItemIds({});
};
return { return {
selectedItemIds, selectedItemIds,
keySelectedItemIds, keySelectedItemIds,
@@ -95,5 +103,6 @@ export const useSelectableCollection = <Id extends number | string, Key extends
areNoItemsForKeySelected, areNoItemsForKeySelected,
setSelectionForKey, setSelectionForKey,
getSelectionForKey, getSelectionForKey,
clearSelection,
}; };
}; };

View File

@@ -69,7 +69,6 @@ export const MangaActionMenuItems = ({
}; };
const performAction = (action: MangaAction, mangas: TManga[]) => { const performAction = (action: MangaAction, mangas: TManga[]) => {
console.log('MangaActionMenuItem', manga);
Mangas.performAction(action, manga ? [manga.id] : Mangas.getIds(mangas), { Mangas.performAction(action, manga ? [manga.id] : Mangas.getIds(mangas), {
wasManuallyMarkedAsRead: true, wasManuallyMarkedAsRead: true,
}).catch(defaultPromiseErrorHandler(`MangaActionMenuItems:performAction(${action})`)); }).catch(defaultPromiseErrorHandler(`MangaActionMenuItems:performAction(${action})`));

View File

@@ -75,6 +75,7 @@ export function Library() {
selectedItemIds, selectedItemIds,
handleSelectAll, handleSelectAll,
handleSelection, handleSelection,
clearSelection,
} = useSelectableCollection<TManga['id'], string>(mangas.length, { currentKey: activeTab?.id.toString() }); } = useSelectableCollection<TManga['id'], string>(mangas.length, { currentKey: activeTab?.id.toString() });
const handleSelect = (id: number, selected: boolean) => { const handleSelect = (id: number, selected: boolean) => {
@@ -108,6 +109,9 @@ export function Library() {
onClose={(selectionModeState) => { onClose={(selectionModeState) => {
handleClose(); handleClose();
setIsSelectModeActive(selectionModeState); setIsSelectModeActive(selectionModeState);
if (!selectionModeState) {
clearSelection();
}
}} }}
setHideMenu={setHideMenu} setHideMenu={setHideMenu}
/> />