mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): handle edge cases when archiving/deleting boards
If the currently selected or auto-add board is archived or deleted, we should reset them. There are some edge cases taht weren't handled in the previous implementation. All handling of this logic is moved to the (renamed) listener.
This commit is contained in:
parent
15b9ece411
commit
0d4b80780b
@ -51,7 +51,7 @@ import { addUpscaleRequestedListener } from 'app/store/middleware/listenerMiddle
|
||||
import { addWorkflowLoadRequestedListener } from 'app/store/middleware/listenerMiddleware/listeners/workflowLoadRequested';
|
||||
import type { AppDispatch, RootState } from 'app/store/store';
|
||||
|
||||
import { addCheckAutoAddBoardVisibleListener } from './listeners/checkAutoAddBoardVisible';
|
||||
import { addArchivedOrDeletedBoardListener } from './listeners/addArchivedOrDeletedBoardListener';
|
||||
|
||||
export const listenerMiddleware = createListenerMiddleware();
|
||||
|
||||
@ -118,7 +118,7 @@ addControlNetAutoProcessListener(startAppListening);
|
||||
addImageAddedToBoardFulfilledListener(startAppListening);
|
||||
addImageRemovedFromBoardFulfilledListener(startAppListening);
|
||||
addBoardIdSelectedListener(startAppListening);
|
||||
addCheckAutoAddBoardVisibleListener(startAppListening);
|
||||
addArchivedOrDeletedBoardListener(startAppListening);
|
||||
|
||||
// Node schemas
|
||||
addGetOpenAPISchemaListener(startAppListening);
|
||||
|
@ -0,0 +1,48 @@
|
||||
import { isAnyOf } from '@reduxjs/toolkit';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { selectListBoardsQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||
import {
|
||||
autoAddBoardIdChanged,
|
||||
boardIdSelected,
|
||||
galleryViewChanged,
|
||||
shouldShowArchivedBoardsChanged,
|
||||
} from 'features/gallery/store/gallerySlice';
|
||||
import { boardsApi } from 'services/api/endpoints/boards';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartListening) => {
|
||||
startAppListening({
|
||||
matcher: isAnyOf(
|
||||
// Updating a board may change its archived status
|
||||
boardsApi.endpoints.updateBoard.matchFulfilled,
|
||||
// If the selected/auto-add board was deleted from a different session, we'll only know during the list request,
|
||||
boardsApi.endpoints.listAllBoards.matchFulfilled,
|
||||
// If a board is deleted, we'll need to reset the auto-add board
|
||||
imagesApi.endpoints.deleteBoard.matchFulfilled,
|
||||
imagesApi.endpoints.deleteBoardAndImages.matchFulfilled,
|
||||
// When we change the visibility of archived boards, we may need to reset the auto-add board
|
||||
shouldShowArchivedBoardsChanged
|
||||
),
|
||||
effect: async (action, { dispatch, getState }) => {
|
||||
/**
|
||||
* The auto-add board shouldn't be set to an archived board or deleted board. When we archive a board, delete
|
||||
* a board, or change a the archived board visibility flag, we may need to reset the auto-add board.
|
||||
*/
|
||||
|
||||
const state = getState();
|
||||
const queryArgs = selectListBoardsQueryArgs(state);
|
||||
const queryResult = boardsApi.endpoints.listAllBoards.select(queryArgs)(state);
|
||||
const autoAddBoardId = state.gallery.autoAddBoardId;
|
||||
|
||||
if (!queryResult.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!queryResult.data.find((board) => board.board_id === autoAddBoardId)) {
|
||||
dispatch(autoAddBoardIdChanged('none'));
|
||||
dispatch(boardIdSelected({ boardId: 'none' }));
|
||||
dispatch(galleryViewChanged('images'));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
@ -1,25 +0,0 @@
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { checkAutoAddBoardVisible } from 'features/gallery/store/actions';
|
||||
import { selectListBoardsQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||
import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice';
|
||||
import { boardsApi } from 'services/api/endpoints/boards';
|
||||
|
||||
export const addCheckAutoAddBoardVisibleListener = (startAppListening: AppStartListening) => {
|
||||
startAppListening({
|
||||
actionCreator: checkAutoAddBoardVisible,
|
||||
effect: async (action, { dispatch, getState }) => {
|
||||
const state = getState();
|
||||
const queryArgs = selectListBoardsQueryArgs(state);
|
||||
const queryResult = boardsApi.endpoints.listAllBoards.select(queryArgs)(state);
|
||||
const autoAddBoardId = state.gallery.autoAddBoardId;
|
||||
|
||||
if (!queryResult.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!queryResult.data.find((board) => board.board_id === autoAddBoardId)) {
|
||||
dispatch(autoAddBoardIdChanged('none'));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
@ -2,7 +2,6 @@ import type { ContextMenuProps } from '@invoke-ai/ui-library';
|
||||
import { ContextMenu, MenuGroup, MenuItem, MenuList } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { checkAutoAddBoardVisible } from 'features/gallery/store/actions';
|
||||
import { autoAddBoardIdChanged, selectGallerySlice } from 'features/gallery/store/gallerySlice';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { toast } from 'features/toast/toast';
|
||||
@ -53,14 +52,13 @@ const BoardContextMenu = ({ board, setBoardToDelete, children }: Props) => {
|
||||
board_id: board.board_id,
|
||||
changes: { archived: true },
|
||||
}).unwrap();
|
||||
dispatch(checkAutoAddBoardVisible());
|
||||
} catch (error) {
|
||||
toast({
|
||||
status: 'error',
|
||||
title: 'Unable to archive board',
|
||||
});
|
||||
}
|
||||
}, [board.board_id, updateBoard, dispatch]);
|
||||
}, [board.board_id, updateBoard]);
|
||||
|
||||
const handleUnarchive = useCallback(() => {
|
||||
updateBoard({
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
Switch,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { checkAutoAddBoardVisible } from 'features/gallery/store/actions';
|
||||
import {
|
||||
alwaysShowImageSizeBadgeChanged,
|
||||
autoAssignBoardOnClickChanged,
|
||||
@ -69,7 +68,6 @@ const GallerySettingsPopover = () => {
|
||||
const handleChangeShouldShowArchivedBoardsChanged = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => {
|
||||
dispatch(shouldShowArchivedBoardsChanged(e.target.checked));
|
||||
dispatch(checkAutoAddBoardVisible());
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
@ -5,5 +5,3 @@ export const sentImageToCanvas = createAction('gallery/sentImageToCanvas');
|
||||
export const sentImageToImg2Img = createAction('gallery/sentImageToImg2Img');
|
||||
|
||||
export const imageDownloaded = createAction('gallery/imageDownloaded');
|
||||
|
||||
export const checkAutoAddBoardVisible = createAction('gallery/checkAutoAddBoardVisible');
|
||||
|
@ -1,9 +1,7 @@
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice, isAnyOf } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import type { PersistConfig, RootState } from 'app/store/store';
|
||||
import { uniqBy } from 'lodash-es';
|
||||
import { boardsApi } from 'services/api/endpoints/boards';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
import type { ImageDTO } from 'services/api/types';
|
||||
|
||||
import type { BoardId, ComparisonMode, GalleryState, GalleryView } from './types';
|
||||
@ -115,29 +113,6 @@ export const gallerySlice = createSlice({
|
||||
state.shouldShowArchivedBoards = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addMatcher(isAnyBoardDeleted, (state, action) => {
|
||||
const deletedBoardId = action.meta.arg.originalArgs;
|
||||
if (deletedBoardId === state.selectedBoardId) {
|
||||
state.selectedBoardId = 'none';
|
||||
state.galleryView = 'images';
|
||||
}
|
||||
if (deletedBoardId === state.autoAddBoardId) {
|
||||
state.autoAddBoardId = 'none';
|
||||
}
|
||||
});
|
||||
builder.addMatcher(boardsApi.endpoints.listAllBoards.matchFulfilled, (state, action) => {
|
||||
const boards = action.payload;
|
||||
|
||||
if (!state.autoAddBoardId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!boards.map((b) => b.board_id).includes(state.autoAddBoardId)) {
|
||||
state.autoAddBoardId = 'none';
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
@ -162,11 +137,6 @@ export const {
|
||||
shouldShowArchivedBoardsChanged,
|
||||
} = gallerySlice.actions;
|
||||
|
||||
const isAnyBoardDeleted = isAnyOf(
|
||||
imagesApi.endpoints.deleteBoard.matchFulfilled,
|
||||
imagesApi.endpoints.deleteBoardAndImages.matchFulfilled
|
||||
);
|
||||
|
||||
export const selectGallerySlice = (state: RootState) => state.gallery;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
|
Loading…
Reference in New Issue
Block a user