fix(ui): image uploading handling

Rework uploadImage and uploadImages helpers and the RTK listener, ensuring gallery view isn't changed unexpectedly and preventing extraneous toasts.

Fix staging area save to gallery button to essentially make a copy of the image, instead of changing its intermediate status.
This commit is contained in:
psychedelicious
2024-11-14 11:26:16 -08:00
committed by Kent Keirsey
parent d5ff7ef250
commit 878093f64e
12 changed files with 136 additions and 130 deletions

View File

@@ -6,10 +6,10 @@ import type { components, paths } from 'services/api/schema';
import type {
DeleteBoardResult,
GraphAndWorkflowResponse,
ImageCategory,
ImageDTO,
ListImagesArgs,
ListImagesResponse,
UploadImageArg,
} from 'services/api/types';
import { getCategories, getListImagesUrl } from 'services/api/util';
import type { JsonObject } from 'type-fest';
@@ -260,20 +260,7 @@ export const imagesApi = api.injectEndpoints({
return [];
},
}),
uploadImage: build.mutation<
ImageDTO,
{
file: File;
image_category: ImageCategory;
is_intermediate: boolean;
session_id?: string;
board_id?: string;
crop_visible?: boolean;
metadata?: JsonObject;
isFirstUploadOfBatch?: boolean;
withToast?: boolean;
}
>({
uploadImage: build.mutation<ImageDTO, UploadImageArg>({
query: ({ file, image_category, is_intermediate, session_id, board_id, crop_visible, metadata }) => {
const formData = new FormData();
formData.append('file', file);
@@ -622,79 +609,17 @@ export const getImageMetadata = (
return req.unwrap();
};
export type UploadImageArg = {
file: File;
image_category: ImageCategory;
is_intermediate: boolean;
session_id?: string;
board_id?: string;
crop_visible?: boolean;
metadata?: JsonObject;
withToast?: boolean;
};
export const uploadImage = (arg: UploadImageArg): Promise<ImageDTO> => {
const {
file,
image_category,
is_intermediate,
crop_visible = false,
board_id,
metadata,
session_id,
withToast = true,
} = arg;
const { dispatch } = getStore();
const req = dispatch(
imagesApi.endpoints.uploadImage.initiate(
{
file,
image_category,
is_intermediate,
crop_visible,
board_id,
metadata,
session_id,
withToast,
},
{ track: false }
)
);
const req = dispatch(imagesApi.endpoints.uploadImage.initiate(arg, { track: false }));
return req.unwrap();
};
export const uploadImages = async (args: UploadImageArg[]): Promise<ImageDTO[]> => {
const { dispatch } = getStore();
const results = await Promise.allSettled(
args.map((arg, i) => {
const {
file,
image_category,
is_intermediate,
crop_visible = false,
board_id,
metadata,
session_id,
withToast = true,
} = arg;
const req = dispatch(
imagesApi.endpoints.uploadImage.initiate(
{
file,
image_category,
is_intermediate,
crop_visible,
board_id,
metadata,
session_id,
isFirstUploadOfBatch: i === 0,
withToast,
},
{ track: false }
)
);
args.map((arg) => {
const req = dispatch(imagesApi.endpoints.uploadImage.initiate(arg, { track: false }));
return req.unwrap();
})
);

View File

@@ -1,5 +1,5 @@
import type { components, paths } from 'services/api/schema';
import type { SetRequired } from 'type-fest';
import type { JsonObject, SetRequired } from 'type-fest';
export type S = components['schemas'];
@@ -287,3 +287,42 @@ export type SetHFTokenResponse = NonNullable<
export type SetHFTokenArg = NonNullable<
paths['/api/v2/models/hf_login']['post']['requestBody']['content']['application/json']
>;
export type UploadImageArg = {
/**
* The file object to upload
*/
file: File;
/**
* THe category of image to upload
*/
image_category: ImageCategory;
/**
* Whether the uploaded image is an intermediate image (intermediate images are not shown int he gallery)
*/
is_intermediate: boolean;
/**
* The session with which to associate the uploaded image
*/
session_id?: string;
/**
* The board id to add the image to
*/
board_id?: string;
/**
* Whether or not to crop the image to its bounding box before saving
*/
crop_visible?: boolean;
/**
* Metadata to embed in the image when saving it
*/
metadata?: JsonObject;
/**
* Whether this upload should be "silent" (no toast on upload, no changing of gallery view)
*/
silent?: boolean;
/**
* Whether this is the first upload of a batch (used when displaying user feedback with toasts - ignored if the upload is silent)
*/
isFirstUploadOfBatch?: boolean;
};