mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
(ui) hook up toggle pin mutation with context menu for single image
This commit is contained in:
parent
04a9894e77
commit
37be827e17
@ -29,10 +29,14 @@ import {
|
||||
FaShare,
|
||||
FaTrash,
|
||||
} from 'react-icons/fa';
|
||||
import { useGetImageMetadataQuery } from 'services/api/endpoints/images';
|
||||
import {
|
||||
useChangeImagePinnedMutation,
|
||||
useGetImageMetadataQuery,
|
||||
} from 'services/api/endpoints/images';
|
||||
import { ImageDTO } from 'services/api/types';
|
||||
import { useDebounce } from 'use-debounce';
|
||||
import { sentImageToCanvas, sentImageToImg2Img } from '../../store/actions';
|
||||
import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
|
||||
|
||||
type SingleSelectionMenuItemsProps = {
|
||||
imageDTO: ImageDTO;
|
||||
@ -59,6 +63,8 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
||||
: debouncedMetadataQueryArg ?? skipToken
|
||||
);
|
||||
|
||||
const [togglePin] = useChangeImagePinnedMutation();
|
||||
|
||||
const { isClipboardAPIAvailable, copyImageToClipboard } =
|
||||
useCopyImageToClipboard();
|
||||
|
||||
@ -127,6 +133,14 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
||||
copyImageToClipboard(imageDTO.image_url);
|
||||
}, [copyImageToClipboard, imageDTO.image_url]);
|
||||
|
||||
const handlePinImage = useCallback(() => {
|
||||
togglePin({ imageName: imageDTO.image_name, pinned: true });
|
||||
}, [togglePin, imageDTO.image_name]);
|
||||
|
||||
const handleUnpinImage = useCallback(() => {
|
||||
togglePin({ imageName: imageDTO.image_name, pinned: false });
|
||||
}, [togglePin, imageDTO.image_name]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuItem
|
||||
@ -196,6 +210,15 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
||||
<MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}>
|
||||
Change Board
|
||||
</MenuItem>
|
||||
{imageDTO.pinned ? (
|
||||
<MenuItem icon={<BsPinAngle />} onClickCapture={handleUnpinImage}>
|
||||
Unpin Image
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem icon={<BsPinAngleFill />} onClickCapture={handlePinImage}>
|
||||
Pin Image
|
||||
</MenuItem>
|
||||
)}
|
||||
<MenuItem
|
||||
sx={{ color: 'error.600', _dark: { color: 'error.300' } }}
|
||||
icon={<FaTrash />}
|
||||
|
@ -296,11 +296,11 @@ export const imagesApi = api.injectEndpoints({
|
||||
imageDTO.image_category
|
||||
)
|
||||
? boardsApi.endpoints.getBoardImagesTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
: boardsApi.endpoints.getBoardAssetsTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
|
||||
// IF it eligible for insertion into existing $cache
|
||||
// "eligible" means either:
|
||||
@ -387,6 +387,54 @@ export const imagesApi = api.injectEndpoints({
|
||||
}
|
||||
},
|
||||
}),
|
||||
/**
|
||||
* Change an image's `pinned` state.
|
||||
*/
|
||||
changeImagePinned: build.mutation<
|
||||
ImageDTO,
|
||||
{ imageName: string; pinned: boolean }
|
||||
>({
|
||||
query: ({ imageName, pinned }) => ({
|
||||
url: `images/i/${imageName}`,
|
||||
method: 'PATCH',
|
||||
body: { pinned },
|
||||
}),
|
||||
// invalidatesTags: (result, error, { imageDTO }) => [
|
||||
// { type: 'BoardImagesTotal', id: imageDTO.board_id ?? 'none' },
|
||||
// { type: 'BoardAssetsTotal', id: imageDTO.board_id ?? 'none' },
|
||||
// ],
|
||||
async onQueryStarted(
|
||||
{ imageName, pinned },
|
||||
{ dispatch, queryFulfilled, getState }
|
||||
) {
|
||||
/**
|
||||
* Cache changes for `changeImageSessionId`:
|
||||
* - *update* getImageDTO
|
||||
*/
|
||||
|
||||
// Store patches so we can undo if the query fails
|
||||
const patches: PatchCollection[] = [];
|
||||
|
||||
// *update* getImageDTO
|
||||
patches.push(
|
||||
dispatch(
|
||||
imagesApi.util.updateQueryData(
|
||||
'getImageDTO',
|
||||
imageName,
|
||||
(draft) => {
|
||||
Object.assign(draft, { pinned });
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
try {
|
||||
await queryFulfilled;
|
||||
} catch {
|
||||
patches.forEach((patchResult) => patchResult.undo());
|
||||
}
|
||||
},
|
||||
}),
|
||||
uploadImage: build.mutation<
|
||||
ImageDTO,
|
||||
{
|
||||
@ -726,11 +774,11 @@ export const imagesApi = api.injectEndpoints({
|
||||
imageDTO.image_category
|
||||
)
|
||||
? boardsApi.endpoints.getBoardImagesTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
: boardsApi.endpoints.getBoardAssetsTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data && currentCache.data.ids.length >= (total ?? 0);
|
||||
@ -846,11 +894,11 @@ export const imagesApi = api.injectEndpoints({
|
||||
imageDTO.image_category
|
||||
)
|
||||
? boardsApi.endpoints.getBoardImagesTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
: boardsApi.endpoints.getBoardAssetsTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data && currentCache.data.ids.length >= (total ?? 0);
|
||||
@ -973,11 +1021,11 @@ export const imagesApi = api.injectEndpoints({
|
||||
imageDTO.image_category
|
||||
)
|
||||
? boardsApi.endpoints.getBoardImagesTotal.select(
|
||||
new_board_id ?? 'none'
|
||||
)(getState())
|
||||
new_board_id ?? 'none'
|
||||
)(getState())
|
||||
: boardsApi.endpoints.getBoardAssetsTotal.select(
|
||||
new_board_id ?? 'none'
|
||||
)(getState());
|
||||
new_board_id ?? 'none'
|
||||
)(getState());
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data &&
|
||||
@ -1104,11 +1152,11 @@ export const imagesApi = api.injectEndpoints({
|
||||
imageDTO.image_category
|
||||
)
|
||||
? boardsApi.endpoints.getBoardImagesTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState())
|
||||
: boardsApi.endpoints.getBoardAssetsTotal.select(
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
imageDTO.board_id ?? 'none'
|
||||
)(getState());
|
||||
|
||||
const isCacheFullyPopulated =
|
||||
currentCache.data && currentCache.data.ids.length >= (total ?? 0);
|
||||
@ -1158,6 +1206,7 @@ export const {
|
||||
useRemoveImageFromBoardMutation,
|
||||
useChangeImageIsIntermediateMutation,
|
||||
useChangeImageSessionIdMutation,
|
||||
useChangeImagePinnedMutation,
|
||||
useDeleteBoardAndImagesMutation,
|
||||
useDeleteBoardMutation,
|
||||
} = imagesApi;
|
||||
|
4857
invokeai/frontend/web/src/services/api/schema.d.ts
vendored
4857
invokeai/frontend/web/src/services/api/schema.d.ts
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user