mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): port all toasts to use new util
This commit is contained in:
parent
683ec8e5f2
commit
a66b3497e0
@ -1073,8 +1073,9 @@
|
||||
},
|
||||
"toast": {
|
||||
"addedToBoard": "Added to board",
|
||||
"baseModelChangedCleared_one": "Base model changed, cleared or disabled {{count}} incompatible submodel",
|
||||
"baseModelChangedCleared_other": "Base model changed, cleared or disabled {{count}} incompatible submodels",
|
||||
"baseModelChanged": "Base Model Changed",
|
||||
"baseModelChangedCleared_one": "Cleared or disabled {{count}} incompatible submodel",
|
||||
"baseModelChangedCleared_other": "Cleared or disabled {{count}} incompatible submodels",
|
||||
"canceled": "Processing Canceled",
|
||||
"canvasCopiedClipboard": "Canvas Copied to Clipboard",
|
||||
"canvasDownloaded": "Canvas Downloaded",
|
||||
@ -1095,10 +1096,17 @@
|
||||
"metadataLoadFailed": "Failed to load metadata",
|
||||
"modelAddedSimple": "Model Added to Queue",
|
||||
"modelImportCanceled": "Model Import Canceled",
|
||||
"outOfMemoryError": "Out of Memory Error",
|
||||
"outOfMemoryErrorDesc": "Your current generation settings exceed system capacity. Please adjust your settings and try again.",
|
||||
"parameters": "Parameters",
|
||||
"parameterNotSet": "{{parameter}} not set",
|
||||
"parameterSet": "{{parameter}} set",
|
||||
"parametersNotSet": "Parameters Not Set",
|
||||
"parameterSet": "Parameter Recalled",
|
||||
"parameterSetDesc": "Recalled {{parameter}}",
|
||||
"parameterNotSet": "Parameter Recalled",
|
||||
"parameterNotSetDesc": "Unable to recall {{parameter}}",
|
||||
"parameterNotSetDescWithMessage": "Unable to recall {{parameter}}: {{message}}",
|
||||
"parametersSet": "Parameters Recalled",
|
||||
"parametersNotSet": "Parameters Not Recalled",
|
||||
"errorCopied": "Error Copied",
|
||||
"problemCopyingCanvas": "Problem Copying Canvas",
|
||||
"problemCopyingCanvasDesc": "Unable to export base layer",
|
||||
"problemCopyingImage": "Unable to Copy Image",
|
||||
@ -1118,11 +1126,13 @@
|
||||
"sentToImageToImage": "Sent To Image To Image",
|
||||
"sentToUnifiedCanvas": "Sent to Unified Canvas",
|
||||
"serverError": "Server Error",
|
||||
"sessionRef": "Session: {{sessionId}}",
|
||||
"setAsCanvasInitialImage": "Set as canvas initial image",
|
||||
"setCanvasInitialImage": "Set canvas initial image",
|
||||
"setControlImage": "Set as control image",
|
||||
"setInitialImage": "Set as initial image",
|
||||
"setNodeField": "Set as node field",
|
||||
"somethingWentWrong": "Something Went Wrong",
|
||||
"uploadFailed": "Upload failed",
|
||||
"uploadFailedInvalidUploadDesc": "Must be single PNG or JPEG image",
|
||||
"uploadInitialImage": "Upload Initial Image",
|
||||
|
@ -25,7 +25,6 @@ import { useGetOpenAPISchemaQuery } from 'services/api/endpoints/appInfo';
|
||||
|
||||
import AppErrorBoundaryFallback from './AppErrorBoundaryFallback';
|
||||
import PreselectedImage from './PreselectedImage';
|
||||
import Toaster from './Toaster';
|
||||
|
||||
const DEFAULT_CONFIG = {};
|
||||
|
||||
@ -96,7 +95,6 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => {
|
||||
<DeleteImageModal />
|
||||
<ChangeBoardModal />
|
||||
<DynamicPromptsModal />
|
||||
<Toaster />
|
||||
<PreselectedImage selectedImage={selectedImage} />
|
||||
</ErrorBoundary>
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Button, Flex, Heading, Link, Text, useToast } from '@invoke-ai/ui-library';
|
||||
import { Button, Flex, Heading, Link, Text } from '@invoke-ai/ui-library';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import newGithubIssueUrl from 'new-github-issue-url';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -11,16 +12,16 @@ type Props = {
|
||||
};
|
||||
|
||||
const AppErrorBoundaryFallback = ({ error, resetErrorBoundary }: Props) => {
|
||||
const toast = useToast();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
const text = JSON.stringify(serializeError(error), null, 2);
|
||||
navigator.clipboard.writeText(`\`\`\`\n${text}\n\`\`\``);
|
||||
toast({
|
||||
title: 'Error Copied',
|
||||
id: 'ERROR_COPIED',
|
||||
title: t('toast.errorCopied'),
|
||||
});
|
||||
}, [error, toast]);
|
||||
}, [error, t]);
|
||||
|
||||
const url = useMemo(
|
||||
() =>
|
||||
|
@ -1,44 +0,0 @@
|
||||
import { useToast } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast, clearToastQueue } from 'features/system/store/systemSlice';
|
||||
import type { MakeToastArg } from 'features/system/util/makeToast';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { memo, useCallback, useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Logical component. Watches the toast queue and makes toasts when the queue is not empty.
|
||||
* @returns null
|
||||
*/
|
||||
const Toaster = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const toastQueue = useAppSelector((s) => s.system.toastQueue);
|
||||
const toast = useToast();
|
||||
useEffect(() => {
|
||||
toastQueue.forEach((t) => {
|
||||
toast(t);
|
||||
});
|
||||
toastQueue.length > 0 && dispatch(clearToastQueue());
|
||||
}, [dispatch, toast, toastQueue]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function that can be used to make a toast.
|
||||
* @example
|
||||
* const toaster = useAppToaster();
|
||||
* toaster('Hello world!');
|
||||
* toaster({ title: 'Hello world!', status: 'success' });
|
||||
* @returns A function that can be used to make a toast.
|
||||
* @see makeToast
|
||||
* @see MakeToastArg
|
||||
* @see UseToastOptions
|
||||
*/
|
||||
export const useAppToaster = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const toaster = useCallback((arg: MakeToastArg) => dispatch(addToast(makeToast(arg))), [dispatch]);
|
||||
|
||||
return toaster;
|
||||
};
|
||||
|
||||
export default memo(Toaster);
|
@ -41,12 +41,10 @@ import { addGeneratorProgressEventListener } from 'app/store/middleware/listener
|
||||
import { addGraphExecutionStateCompleteEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketGraphExecutionStateComplete';
|
||||
import { addInvocationCompleteEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationComplete';
|
||||
import { addInvocationErrorEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationError';
|
||||
import { addInvocationRetrievalErrorEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationRetrievalError';
|
||||
import { addInvocationStartedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketInvocationStarted';
|
||||
import { addModelInstallEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketModelInstall';
|
||||
import { addModelLoadEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketModelLoad';
|
||||
import { addSocketQueueItemStatusChangedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketQueueItemStatusChanged';
|
||||
import { addSessionRetrievalErrorEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketSessionRetrievalError';
|
||||
import { addSocketSubscribedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketSubscribed';
|
||||
import { addSocketUnsubscribedEventListener } from 'app/store/middleware/listenerMiddleware/listeners/socketio/socketUnsubscribed';
|
||||
import { addStagingAreaImageSavedListener } from 'app/store/middleware/listenerMiddleware/listeners/stagingAreaImageSaved';
|
||||
@ -114,8 +112,6 @@ addSocketSubscribedEventListener(startAppListening);
|
||||
addSocketUnsubscribedEventListener(startAppListening);
|
||||
addModelLoadEventListener(startAppListening);
|
||||
addModelInstallEventListener(startAppListening);
|
||||
addSessionRetrievalErrorEventListener(startAppListening);
|
||||
addInvocationRetrievalErrorEventListener(startAppListening);
|
||||
addSocketQueueItemStatusChangedEventListener(startAppListening);
|
||||
addBulkDownloadListeners(startAppListening);
|
||||
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
resetCanvas,
|
||||
setInitialCanvasImage,
|
||||
} from 'features/canvas/store/canvasSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { queueApi } from 'services/api/endpoints/queue';
|
||||
|
||||
@ -30,22 +30,20 @@ export const addCommitStagingAreaImageListener = (startAppListening: AppStartLis
|
||||
req.reset();
|
||||
if (canceled > 0) {
|
||||
log.debug(`Canceled ${canceled} canvas batches`);
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelBatchSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANCEL_BATCH_SUCCEEDED',
|
||||
title: t('queue.cancelBatchSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
}
|
||||
dispatch(canvasBatchIdsReset());
|
||||
} catch {
|
||||
log.error('Failed to cancel canvas batches');
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelBatchFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANCEL_BATCH_FAILED',
|
||||
title: t('queue.cancelBatchFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { parseify } from 'common/util/serialize';
|
||||
import { toast } from 'common/util/toast';
|
||||
import { zPydanticValidationError } from 'features/system/store/zodSchemas';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { truncate, upperFirst } from 'lodash-es';
|
||||
import { queueApi } from 'services/api/endpoints/queue';
|
||||
@ -16,18 +16,15 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
const arg = action.meta.arg.originalArgs;
|
||||
logger('queue').debug({ enqueueResult: parseify(response) }, 'Batch enqueued');
|
||||
|
||||
if (!toast.isActive('batch-queued')) {
|
||||
toast({
|
||||
id: 'batch-queued',
|
||||
title: t('queue.batchQueued'),
|
||||
description: t('queue.batchQueuedDesc', {
|
||||
count: response.enqueued,
|
||||
direction: arg.prepend ? t('queue.front') : t('queue.back'),
|
||||
}),
|
||||
duration: 1000,
|
||||
status: 'success',
|
||||
});
|
||||
}
|
||||
toast({
|
||||
id: 'QUEUE_BATCH_SUCCEEDED',
|
||||
title: t('queue.batchQueued'),
|
||||
status: 'success',
|
||||
description: t('queue.batchQueuedDesc', {
|
||||
count: response.enqueued,
|
||||
direction: arg.prepend ? t('queue.front') : t('queue.back'),
|
||||
}),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@ -40,9 +37,10 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
|
||||
if (!response) {
|
||||
toast({
|
||||
id: 'QUEUE_BATCH_FAILED',
|
||||
title: t('queue.batchFailedToQueue'),
|
||||
status: 'error',
|
||||
description: 'Unknown Error',
|
||||
description: t('common.unknownError'),
|
||||
});
|
||||
logger('queue').error({ batchConfig: parseify(arg), error: parseify(response) }, t('queue.batchFailedToQueue'));
|
||||
return;
|
||||
@ -52,7 +50,7 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
if (result.success) {
|
||||
result.data.data.detail.map((e) => {
|
||||
toast({
|
||||
id: 'batch-failed-to-queue',
|
||||
id: 'QUEUE_BATCH_FAILED',
|
||||
title: truncate(upperFirst(e.msg), { length: 128 }),
|
||||
status: 'error',
|
||||
description: truncate(
|
||||
@ -64,9 +62,10 @@ export const addBatchEnqueuedListener = (startAppListening: AppStartListening) =
|
||||
});
|
||||
} else if (response.status !== 403) {
|
||||
toast({
|
||||
id: 'QUEUE_BATCH_FAILED',
|
||||
title: t('queue.batchFailedToQueue'),
|
||||
description: t('common.unknownError'),
|
||||
status: 'error',
|
||||
description: t('common.unknownError'),
|
||||
});
|
||||
}
|
||||
logger('queue').error({ batchConfig: parseify(arg), error: parseify(response) }, t('queue.batchFailedToQueue'));
|
||||
|
@ -1,8 +1,7 @@
|
||||
import type { UseToastOptions } from '@invoke-ai/ui-library';
|
||||
import { ExternalLink } from '@invoke-ai/ui-library';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { toast } from 'common/util/toast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
import {
|
||||
@ -28,7 +27,6 @@ export const addBulkDownloadListeners = (startAppListening: AppStartListening) =
|
||||
// Show the response message if it exists, otherwise show the default message
|
||||
description: action.payload.response || t('gallery.bulkDownloadRequestedDesc'),
|
||||
duration: null,
|
||||
isClosable: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
@ -40,9 +38,9 @@ export const addBulkDownloadListeners = (startAppListening: AppStartListening) =
|
||||
|
||||
// There isn't any toast to update if we get this event.
|
||||
toast({
|
||||
id: 'BULK_DOWNLOAD_REQUEST_FAILED',
|
||||
title: t('gallery.bulkDownloadRequestFailed'),
|
||||
status: 'success',
|
||||
isClosable: true,
|
||||
status: 'error',
|
||||
});
|
||||
},
|
||||
});
|
||||
@ -65,7 +63,7 @@ export const addBulkDownloadListeners = (startAppListening: AppStartListening) =
|
||||
// TODO(psyche): This URL may break in in some environments (e.g. Nvidia workbench) but we need to test it first
|
||||
const url = `/api/v1/images/download/${bulk_download_item_name}`;
|
||||
|
||||
const toastOptions: UseToastOptions = {
|
||||
toast({
|
||||
id: bulk_download_item_name,
|
||||
title: t('gallery.bulkDownloadReady', 'Download ready'),
|
||||
status: 'success',
|
||||
@ -77,14 +75,7 @@ export const addBulkDownloadListeners = (startAppListening: AppStartListening) =
|
||||
/>
|
||||
),
|
||||
duration: null,
|
||||
isClosable: true,
|
||||
};
|
||||
|
||||
if (toast.isActive(bulk_download_item_name)) {
|
||||
toast.update(bulk_download_item_name, toastOptions);
|
||||
} else {
|
||||
toast(toastOptions);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@ -95,20 +86,13 @@ export const addBulkDownloadListeners = (startAppListening: AppStartListening) =
|
||||
|
||||
const { bulk_download_item_name } = action.payload.data;
|
||||
|
||||
const toastOptions: UseToastOptions = {
|
||||
toast({
|
||||
id: bulk_download_item_name,
|
||||
title: t('gallery.bulkDownloadFailed'),
|
||||
status: 'error',
|
||||
description: action.payload.data.error,
|
||||
duration: null,
|
||||
isClosable: true,
|
||||
};
|
||||
|
||||
if (toast.isActive(bulk_download_item_name)) {
|
||||
toast.update(bulk_download_item_name, toastOptions);
|
||||
} else {
|
||||
toast(toastOptions);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -2,14 +2,14 @@ import { $logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { canvasCopiedToClipboard } from 'features/canvas/store/actions';
|
||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
|
||||
export const addCanvasCopiedToClipboardListener = (startAppListening: AppStartListening) => {
|
||||
startAppListening({
|
||||
actionCreator: canvasCopiedToClipboard,
|
||||
effect: async (action, { dispatch, getState }) => {
|
||||
effect: async (action, { getState }) => {
|
||||
const moduleLog = $logger.get().child({ namespace: 'canvasCopiedToClipboardListener' });
|
||||
const state = getState();
|
||||
|
||||
@ -19,22 +19,20 @@ export const addCanvasCopiedToClipboardListener = (startAppListening: AppStartLi
|
||||
copyBlobToClipboard(blob);
|
||||
} catch (err) {
|
||||
moduleLog.error(String(err));
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemCopyingCanvas'),
|
||||
description: t('toast.problemCopyingCanvasDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANVAS_COPY_FAILED',
|
||||
title: t('toast.problemCopyingCanvas'),
|
||||
description: t('toast.problemCopyingCanvasDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.canvasCopiedClipboard'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANVAS_COPY_SUCCEEDED',
|
||||
title: t('toast.canvasCopiedClipboard'),
|
||||
status: 'success',
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -3,13 +3,13 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import { canvasDownloadedAsImage } from 'features/canvas/store/actions';
|
||||
import { downloadBlob } from 'features/canvas/util/downloadBlob';
|
||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
|
||||
export const addCanvasDownloadedAsImageListener = (startAppListening: AppStartListening) => {
|
||||
startAppListening({
|
||||
actionCreator: canvasDownloadedAsImage,
|
||||
effect: async (action, { dispatch, getState }) => {
|
||||
effect: async (action, { getState }) => {
|
||||
const moduleLog = $logger.get().child({ namespace: 'canvasSavedToGalleryListener' });
|
||||
const state = getState();
|
||||
|
||||
@ -18,18 +18,17 @@ export const addCanvasDownloadedAsImageListener = (startAppListening: AppStartLi
|
||||
blob = await getBaseLayerBlob(state);
|
||||
} catch (err) {
|
||||
moduleLog.error(String(err));
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemDownloadingCanvas'),
|
||||
description: t('toast.problemDownloadingCanvasDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANVAS_DOWNLOAD_FAILED',
|
||||
title: t('toast.problemDownloadingCanvas'),
|
||||
description: t('toast.problemDownloadingCanvasDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
downloadBlob(blob, 'canvas.png');
|
||||
dispatch(addToast({ title: t('toast.canvasDownloaded'), status: 'success' }));
|
||||
toast({ id: 'CANVAS_DOWNLOAD_SUCCEEDED', title: t('toast.canvasDownloaded'), status: 'success' });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -3,7 +3,7 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import { canvasImageToControlAdapter } from 'features/canvas/store/actions';
|
||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
@ -20,13 +20,12 @@ export const addCanvasImageToControlNetListener = (startAppListening: AppStartLi
|
||||
blob = await getBaseLayerBlob(state, true);
|
||||
} catch (err) {
|
||||
log.error(String(err));
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemSavingCanvas'),
|
||||
description: t('toast.problemSavingCanvasDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROBLEM_SAVING_CANVAS',
|
||||
title: t('toast.problemSavingCanvas'),
|
||||
description: t('toast.problemSavingCanvasDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -43,7 +42,7 @@ export const addCanvasImageToControlNetListener = (startAppListening: AppStartLi
|
||||
crop_visible: false,
|
||||
postUploadAction: {
|
||||
type: 'TOAST',
|
||||
toastOptions: { title: t('toast.canvasSentControlnetAssets') },
|
||||
title: t('toast.canvasSentControlnetAssets'),
|
||||
},
|
||||
})
|
||||
).unwrap();
|
||||
|
@ -2,7 +2,7 @@ import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { canvasMaskSavedToGallery } from 'features/canvas/store/actions';
|
||||
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
@ -29,13 +29,12 @@ export const addCanvasMaskSavedToGalleryListener = (startAppListening: AppStartL
|
||||
|
||||
if (!maskBlob) {
|
||||
log.error('Problem getting mask layer blob');
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemSavingMask'),
|
||||
description: t('toast.problemSavingMaskDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROBLEM_SAVING_MASK',
|
||||
title: t('toast.problemSavingMask'),
|
||||
description: t('toast.problemSavingMaskDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -52,7 +51,7 @@ export const addCanvasMaskSavedToGalleryListener = (startAppListening: AppStartL
|
||||
crop_visible: true,
|
||||
postUploadAction: {
|
||||
type: 'TOAST',
|
||||
toastOptions: { title: t('toast.maskSavedAssets') },
|
||||
title: t('toast.maskSavedAssets'),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
@ -3,7 +3,7 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import { canvasMaskToControlAdapter } from 'features/canvas/store/actions';
|
||||
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
||||
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
@ -30,13 +30,12 @@ export const addCanvasMaskToControlNetListener = (startAppListening: AppStartLis
|
||||
|
||||
if (!maskBlob) {
|
||||
log.error('Problem getting mask layer blob');
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemImportingMask'),
|
||||
description: t('toast.problemImportingMaskDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROBLEM_IMPORTING_MASK',
|
||||
title: t('toast.problemImportingMask'),
|
||||
description: t('toast.problemImportingMaskDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -53,7 +52,7 @@ export const addCanvasMaskToControlNetListener = (startAppListening: AppStartLis
|
||||
crop_visible: false,
|
||||
postUploadAction: {
|
||||
type: 'TOAST',
|
||||
toastOptions: { title: t('toast.maskSentControlnetAssets') },
|
||||
title: t('toast.maskSentControlnetAssets'),
|
||||
},
|
||||
})
|
||||
).unwrap();
|
||||
|
@ -4,7 +4,7 @@ import { canvasMerged } from 'features/canvas/store/actions';
|
||||
import { $canvasBaseLayer } from 'features/canvas/store/canvasNanostore';
|
||||
import { setMergedCanvas } from 'features/canvas/store/canvasSlice';
|
||||
import { getFullBaseLayerBlob } from 'features/canvas/util/getFullBaseLayerBlob';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
@ -17,13 +17,12 @@ export const addCanvasMergedListener = (startAppListening: AppStartListening) =>
|
||||
|
||||
if (!blob) {
|
||||
moduleLog.error('Problem getting base layer blob');
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemMergingCanvas'),
|
||||
description: t('toast.problemMergingCanvasDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROBLEM_MERGING_CANVAS',
|
||||
title: t('toast.problemMergingCanvas'),
|
||||
description: t('toast.problemMergingCanvasDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -31,13 +30,12 @@ export const addCanvasMergedListener = (startAppListening: AppStartListening) =>
|
||||
|
||||
if (!canvasBaseLayer) {
|
||||
moduleLog.error('Problem getting canvas base layer');
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemMergingCanvas'),
|
||||
description: t('toast.problemMergingCanvasDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROBLEM_MERGING_CANVAS',
|
||||
title: t('toast.problemMergingCanvas'),
|
||||
description: t('toast.problemMergingCanvasDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,7 +52,7 @@ export const addCanvasMergedListener = (startAppListening: AppStartListening) =>
|
||||
is_intermediate: true,
|
||||
postUploadAction: {
|
||||
type: 'TOAST',
|
||||
toastOptions: { title: t('toast.canvasMerged') },
|
||||
title: t('toast.canvasMerged'),
|
||||
},
|
||||
})
|
||||
).unwrap();
|
||||
|
@ -3,7 +3,7 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import { parseify } from 'common/util/serialize';
|
||||
import { canvasSavedToGallery } from 'features/canvas/store/actions';
|
||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
@ -19,13 +19,12 @@ export const addCanvasSavedToGalleryListener = (startAppListening: AppStartListe
|
||||
blob = await getBaseLayerBlob(state);
|
||||
} catch (err) {
|
||||
log.error(String(err));
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.problemSavingCanvas'),
|
||||
description: t('toast.problemSavingCanvasDesc'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANVAS_SAVE_FAILED',
|
||||
title: t('toast.problemSavingCanvas'),
|
||||
description: t('toast.problemSavingCanvasDesc'),
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -42,7 +41,7 @@ export const addCanvasSavedToGalleryListener = (startAppListening: AppStartListe
|
||||
crop_visible: true,
|
||||
postUploadAction: {
|
||||
type: 'TOAST',
|
||||
toastOptions: { title: t('toast.canvasSavedGallery') },
|
||||
title: t('toast.canvasSavedGallery'),
|
||||
},
|
||||
metadata: {
|
||||
_canvas_objects: parseify(state.canvas.layerState.objects),
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from 'features/controlLayers/store/controlLayersSlice';
|
||||
import { CA_PROCESSOR_DATA } from 'features/controlLayers/util/controlAdapters';
|
||||
import { isImageOutput } from 'features/nodes/types/common';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { getImageDTO } from 'services/api/endpoints/images';
|
||||
@ -174,12 +174,11 @@ export const addControlAdapterPreprocessor = (startAppListening: AppStartListeni
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: ToastID.GRAPH_QUEUE_FAILED,
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
req.reset();
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||
import { isImageOutput } from 'features/nodes/types/common';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
import { queueApi } from 'services/api/endpoints/queue';
|
||||
@ -108,12 +108,11 @@ export const addControlNetImageProcessedListener = (startAppListening: AppStartL
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: ToastID.GRAPH_QUEUE_FAILED,
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,3 @@
|
||||
import type { UseToastOptions } from '@invoke-ai/ui-library';
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||
@ -14,7 +13,7 @@ import {
|
||||
} from 'features/controlLayers/store/controlLayersSlice';
|
||||
import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
|
||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { omit } from 'lodash-es';
|
||||
import { boardsApi } from 'services/api/endpoints/boards';
|
||||
@ -42,16 +41,17 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
return;
|
||||
}
|
||||
|
||||
const DEFAULT_UPLOADED_TOAST: UseToastOptions = {
|
||||
const DEFAULT_UPLOADED_TOAST = {
|
||||
id: 'IMAGE_UPLOADED',
|
||||
title: t('toast.imageUploaded'),
|
||||
status: 'success',
|
||||
};
|
||||
} as const;
|
||||
|
||||
// default action - just upload and alert user
|
||||
if (postUploadAction?.type === 'TOAST') {
|
||||
const { toastOptions } = postUploadAction;
|
||||
if (!autoAddBoardId || autoAddBoardId === 'none') {
|
||||
dispatch(addToast({ ...DEFAULT_UPLOADED_TOAST, ...toastOptions }));
|
||||
const title = postUploadAction.title || DEFAULT_UPLOADED_TOAST.title;
|
||||
toast({ ...DEFAULT_UPLOADED_TOAST, title });
|
||||
} else {
|
||||
// Add this image to the board
|
||||
dispatch(
|
||||
@ -70,24 +70,20 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
? `${t('toast.addedToBoard')} ${board.board_name}`
|
||||
: `${t('toast.addedToBoard')} ${autoAddBoardId}`;
|
||||
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description,
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description,
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (postUploadAction?.type === 'SET_CANVAS_INITIAL_IMAGE') {
|
||||
dispatch(setInitialCanvasImage(imageDTO, selectOptimalDimension(state)));
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setAsCanvasInitialImage'),
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setAsCanvasInitialImage'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -105,68 +101,56 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
controlImage: imageDTO.image_name,
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (postUploadAction?.type === 'SET_CA_LAYER_IMAGE') {
|
||||
const { layerId } = postUploadAction;
|
||||
dispatch(caLayerImageChanged({ layerId, imageDTO }));
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
});
|
||||
}
|
||||
|
||||
if (postUploadAction?.type === 'SET_IPA_LAYER_IMAGE') {
|
||||
const { layerId } = postUploadAction;
|
||||
dispatch(ipaLayerImageChanged({ layerId, imageDTO }));
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
});
|
||||
}
|
||||
|
||||
if (postUploadAction?.type === 'SET_RG_LAYER_IP_ADAPTER_IMAGE') {
|
||||
const { layerId, ipAdapterId } = postUploadAction;
|
||||
dispatch(rgLayerIPAdapterImageChanged({ layerId, ipAdapterId, imageDTO }));
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
});
|
||||
}
|
||||
|
||||
if (postUploadAction?.type === 'SET_II_LAYER_IMAGE') {
|
||||
const { layerId } = postUploadAction;
|
||||
dispatch(iiLayerImageChanged({ layerId, imageDTO }));
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: t('toast.setControlImage'),
|
||||
});
|
||||
}
|
||||
|
||||
if (postUploadAction?.type === 'SET_NODES_IMAGE') {
|
||||
const { nodeId, fieldName } = postUploadAction;
|
||||
dispatch(fieldImageValueChanged({ nodeId, fieldName, value: imageDTO }));
|
||||
dispatch(
|
||||
addToast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: `${t('toast.setNodeField')} ${fieldName}`,
|
||||
})
|
||||
);
|
||||
toast({
|
||||
...DEFAULT_UPLOADED_TOAST,
|
||||
description: `${t('toast.setNodeField')} ${fieldName}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
},
|
||||
@ -174,7 +158,7 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
|
||||
startAppListening({
|
||||
matcher: imagesApi.endpoints.uploadImage.matchRejected,
|
||||
effect: (action, { dispatch }) => {
|
||||
effect: (action) => {
|
||||
const log = logger('images');
|
||||
const sanitizedData = {
|
||||
arg: {
|
||||
@ -183,13 +167,11 @@ export const addImageUploadedFulfilledListener = (startAppListening: AppStartLis
|
||||
},
|
||||
};
|
||||
log.error({ ...sanitizedData }, 'Image upload failed');
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.imageUploadFailed'),
|
||||
description: action.error.message,
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
title: t('toast.imageUploadFailed'),
|
||||
description: action.error.message,
|
||||
status: 'error',
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -8,8 +8,7 @@ import { loraRemoved } from 'features/lora/store/loraSlice';
|
||||
import { modelSelected } from 'features/parameters/store/actions';
|
||||
import { modelChanged, vaeSelected } from 'features/parameters/store/generationSlice';
|
||||
import { zParameterModel } from 'features/parameters/types/parameterSchemas';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { forEach } from 'lodash-es';
|
||||
|
||||
@ -60,16 +59,14 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
||||
});
|
||||
|
||||
if (modelsCleared > 0) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.baseModelChangedCleared', {
|
||||
count: modelsCleared,
|
||||
}),
|
||||
status: 'warning',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'BASE_MODEL_CHANGED',
|
||||
title: t('toast.baseModelChanged'),
|
||||
description: t('toast.baseModelChangedCleared', {
|
||||
count: modelsCleared,
|
||||
}),
|
||||
status: 'warning',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,7 @@ import {
|
||||
isParameterWidth,
|
||||
zParameterVAEModel,
|
||||
} from 'features/parameters/types/parameterSchemas';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { modelConfigsAdapterSelectors, modelsApi } from 'services/api/endpoints/models';
|
||||
import { isNonRefinerMainModelConfig } from 'services/api/types';
|
||||
@ -109,7 +108,7 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(addToast(makeToast({ title: t('toast.parameterSet', { parameter: 'Default settings' }) })));
|
||||
toast({ id: ToastID.PARAMETER_SET, title: t('toast.parameterSet', { parameter: 'Default settings' }) });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -3,6 +3,10 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import { deepClone } from 'common/util/deepClone';
|
||||
import { $nodeExecutionStates, upsertExecutionState } from 'features/nodes/hooks/useExecutionState';
|
||||
import { zNodeStatus } from 'features/nodes/types/invocation';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import ToastWithSessionRefDescription from 'features/toast/ToastWithSessionRefDescription';
|
||||
import { t } from 'i18next';
|
||||
import { startCase } from 'lodash-es';
|
||||
import { socketInvocationError } from 'services/events/actions';
|
||||
|
||||
const log = logger('socketio');
|
||||
@ -12,7 +16,7 @@ export const addInvocationErrorEventListener = (startAppListening: AppStartListe
|
||||
actionCreator: socketInvocationError,
|
||||
effect: (action) => {
|
||||
log.error(action.payload, `Invocation error (${action.payload.data.node.type})`);
|
||||
const { source_node_id } = action.payload.data;
|
||||
const { source_node_id, error_type } = action.payload.data;
|
||||
const nes = deepClone($nodeExecutionStates.get()[source_node_id]);
|
||||
if (nes) {
|
||||
nes.status = zNodeStatus.enum.FAILED;
|
||||
@ -21,6 +25,30 @@ export const addInvocationErrorEventListener = (startAppListening: AppStartListe
|
||||
nes.progressImage = null;
|
||||
upsertExecutionState(nes.nodeId, nes);
|
||||
}
|
||||
const errorType = startCase(action.payload.data.error_type);
|
||||
const sessionId = action.payload.data.graph_execution_state_id;
|
||||
|
||||
if (error_type === 'OutOfMemoryError') {
|
||||
toast({
|
||||
id: 'INVOCATION_ERROR',
|
||||
title: t('toast.outOfMemoryError'),
|
||||
status: 'error',
|
||||
description: ToastWithSessionRefDescription({
|
||||
message: t('toast.outOfMemoryDescription'),
|
||||
sessionId,
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
id: `INVOCATION_ERROR_${errorType}`,
|
||||
title: t('toast.serverError'),
|
||||
status: 'error',
|
||||
description: ToastWithSessionRefDescription({
|
||||
message: errorType,
|
||||
sessionId,
|
||||
}),
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { socketInvocationRetrievalError } from 'services/events/actions';
|
||||
|
||||
const log = logger('socketio');
|
||||
|
||||
export const addInvocationRetrievalErrorEventListener = (startAppListening: AppStartListening) => {
|
||||
startAppListening({
|
||||
actionCreator: socketInvocationRetrievalError,
|
||||
effect: (action) => {
|
||||
log.error(action.payload, `Invocation retrieval error (${action.payload.data.graph_execution_state_id})`);
|
||||
},
|
||||
});
|
||||
};
|
@ -1,14 +0,0 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { socketSessionRetrievalError } from 'services/events/actions';
|
||||
|
||||
const log = logger('socketio');
|
||||
|
||||
export const addSessionRetrievalErrorEventListener = (startAppListening: AppStartListening) => {
|
||||
startAppListening({
|
||||
actionCreator: socketSessionRetrievalError,
|
||||
effect: (action) => {
|
||||
log.error(action.payload, `Session retrieval error (${action.payload.data.graph_execution_state_id})`);
|
||||
},
|
||||
});
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { stagingAreaImageSaved } from 'features/canvas/store/actions';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { imagesApi } from 'services/api/endpoints/images';
|
||||
|
||||
@ -29,15 +29,14 @@ export const addStagingAreaImageSavedListener = (startAppListening: AppStartList
|
||||
})
|
||||
);
|
||||
}
|
||||
dispatch(addToast({ title: t('toast.imageSaved'), status: 'success' }));
|
||||
toast({ id: 'IMAGE_SAVED', title: t('toast.imageSaved'), status: 'success' });
|
||||
} catch (error) {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('toast.imageSavingFailed'),
|
||||
description: (error as Error)?.message,
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'IMAGE_SAVE_FAILED',
|
||||
title: t('toast.imageSavingFailed'),
|
||||
description: (error as Error)?.message,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -5,8 +5,7 @@ import { $templates, nodesChanged } from 'features/nodes/store/nodesSlice';
|
||||
import { NodeUpdateError } from 'features/nodes/types/error';
|
||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||
import { getNeedsUpdate, updateNode } from 'features/nodes/util/node/nodeUpdate';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
|
||||
export const addUpdateAllNodesRequestedListener = (startAppListening: AppStartListening) => {
|
||||
@ -50,24 +49,18 @@ export const addUpdateAllNodesRequestedListener = (startAppListening: AppStartLi
|
||||
count: unableToUpdateCount,
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.unableToUpdateNodes', {
|
||||
count: unableToUpdateCount,
|
||||
}),
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'UNABLE_TO_UPDATE_NODES',
|
||||
title: t('nodes.unableToUpdateNodes', {
|
||||
count: unableToUpdateCount,
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.allNodesUpdated'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'ALL_NODES_UPDATED',
|
||||
title: t('nodes.allNodesUpdated'),
|
||||
status: 'success',
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
||||
import { parseify } from 'common/util/serialize';
|
||||
import { buildAdHocUpscaleGraph } from 'features/nodes/util/graph/buildAdHocUpscaleGraph';
|
||||
import { createIsAllowedToUpscaleSelector } from 'features/parameters/hooks/useIsAllowedToUpscale';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { queueApi } from 'services/api/endpoints/queue';
|
||||
import type { BatchConfig, ImageDTO } from 'services/api/types';
|
||||
@ -29,12 +29,11 @@ export const addUpscaleRequestedListener = (startAppListening: AppStartListening
|
||||
{ imageDTO },
|
||||
t(detailTKey ?? 'parameters.isAllowedToUpscale.tooLarge') // should never coalesce
|
||||
);
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t(detailTKey ?? 'parameters.isAllowedToUpscale.tooLarge'), // should never coalesce
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'NOT_ALLOWED_TO_UPSCALE',
|
||||
title: t(detailTKey ?? 'parameters.isAllowedToUpscale.tooLarge'), // should never coalesce
|
||||
status: 'error',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -65,12 +64,11 @@ export const addUpscaleRequestedListener = (startAppListening: AppStartListening
|
||||
if (error instanceof Object && 'status' in error && error.status === 403) {
|
||||
return;
|
||||
} else {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: ToastID.GRAPH_QUEUE_FAILED,
|
||||
title: t('queue.graphFailedToQueue'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8,8 +8,7 @@ import type { Templates } from 'features/nodes/store/types';
|
||||
import { WorkflowMigrationError, WorkflowVersionError } from 'features/nodes/types/error';
|
||||
import { graphToWorkflow } from 'features/nodes/util/workflow/graphToWorkflow';
|
||||
import { validateWorkflow } from 'features/nodes/util/workflow/validateWorkflow';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { checkBoardAccess, checkImageAccess, checkModelAccess } from 'services/api/hooks/accessChecks';
|
||||
import type { GraphAndWorkflowResponse, NonNullableGraph } from 'services/api/types';
|
||||
@ -49,23 +48,18 @@ export const addWorkflowLoadRequestedListener = (startAppListening: AppStartList
|
||||
|
||||
dispatch(workflowLoaded(workflow));
|
||||
if (!warnings.length) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.workflowLoaded'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'WORKFLOW_LOADED',
|
||||
title: t('toast.workflowLoaded'),
|
||||
status: 'success',
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.loadedWithWarnings'),
|
||||
status: 'warning',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'WORKFLOW_LOADED',
|
||||
title: t('toast.loadedWithWarnings'),
|
||||
status: 'warning',
|
||||
});
|
||||
|
||||
warnings.forEach(({ message, ...rest }) => {
|
||||
log.warn(rest, message);
|
||||
});
|
||||
@ -78,54 +72,42 @@ export const addWorkflowLoadRequestedListener = (startAppListening: AppStartList
|
||||
if (e instanceof WorkflowVersionError) {
|
||||
// The workflow version was not recognized in the valid list of versions
|
||||
log.error({ error: parseify(e) }, e.message);
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: e.message,
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'UNABLE_TO_VALIDATE_WORKFLOW',
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: e.message,
|
||||
});
|
||||
} else if (e instanceof WorkflowMigrationError) {
|
||||
// There was a problem migrating the workflow to the latest version
|
||||
log.error({ error: parseify(e) }, e.message);
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: e.message,
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'UNABLE_TO_VALIDATE_WORKFLOW',
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: e.message,
|
||||
});
|
||||
} else if (e instanceof z.ZodError) {
|
||||
// There was a problem validating the workflow itself
|
||||
const { message } = fromZodError(e, {
|
||||
prefix: t('nodes.workflowValidation'),
|
||||
});
|
||||
log.error({ error: parseify(e) }, message);
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: message,
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'UNABLE_TO_VALIDATE_WORKFLOW',
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: message,
|
||||
});
|
||||
} else {
|
||||
// Some other error occurred
|
||||
log.error({ error: parseify(e) }, t('nodes.unknownErrorValidatingWorkflow'));
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: t('nodes.unknownErrorValidatingWorkflow'),
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'UNABLE_TO_VALIDATE_WORKFLOW',
|
||||
title: t('nodes.unableToValidateWorkflow'),
|
||||
status: 'error',
|
||||
description: t('nodes.unknownErrorValidatingWorkflow'),
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useImageUrlToBlob } from 'common/hooks/useImageUrlToBlob';
|
||||
import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const useCopyImageToClipboard = () => {
|
||||
const toaster = useAppToaster();
|
||||
const { t } = useTranslation();
|
||||
const imageUrlToBlob = useImageUrlToBlob();
|
||||
|
||||
@ -16,12 +15,11 @@ export const useCopyImageToClipboard = () => {
|
||||
const copyImageToClipboard = useCallback(
|
||||
async (image_url: string) => {
|
||||
if (!isClipboardAPIAvailable) {
|
||||
toaster({
|
||||
toast({
|
||||
id: 'PROBLEM_COPYING_IMAGE',
|
||||
title: t('toast.problemCopyingImage'),
|
||||
description: "Your browser doesn't support the Clipboard API.",
|
||||
status: 'error',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
try {
|
||||
@ -33,23 +31,21 @@ export const useCopyImageToClipboard = () => {
|
||||
|
||||
copyBlobToClipboard(blob);
|
||||
|
||||
toaster({
|
||||
toast({
|
||||
id: 'IMAGE_COPIED',
|
||||
title: t('toast.imageCopied'),
|
||||
status: 'success',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
} catch (err) {
|
||||
toaster({
|
||||
toast({
|
||||
id: 'PROBLEM_COPYING_IMAGE',
|
||||
title: t('toast.problemCopyingImage'),
|
||||
description: String(err),
|
||||
status: 'error',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[imageUrlToBlob, isClipboardAPIAvailable, t, toaster]
|
||||
[imageUrlToBlob, isClipboardAPIAvailable, t]
|
||||
);
|
||||
|
||||
return { isClipboardAPIAvailable, copyImageToClipboard };
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { $authToken } from 'app/store/nanostores/authToken';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { imageDownloaded } from 'features/gallery/store/actions';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const useDownloadImage = () => {
|
||||
const toaster = useAppToaster();
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const authToken = useStore($authToken);
|
||||
@ -37,16 +36,15 @@ export const useDownloadImage = () => {
|
||||
window.URL.revokeObjectURL(url);
|
||||
dispatch(imageDownloaded());
|
||||
} catch (err) {
|
||||
toaster({
|
||||
toast({
|
||||
id: 'PROBLEM_DOWNLOADING_IMAGE',
|
||||
title: t('toast.problemDownloadingImage'),
|
||||
description: String(err),
|
||||
status: 'error',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[t, toaster, dispatch, authToken]
|
||||
[t, dispatch, authToken]
|
||||
);
|
||||
|
||||
return { downloadImage };
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import type { Accept, FileRejection } from 'react-dropzone';
|
||||
@ -26,7 +26,6 @@ const selectPostUploadAction = createMemoizedSelector(activeTabNameSelector, (ac
|
||||
|
||||
export const useFullscreenDropzone = () => {
|
||||
const { t } = useTranslation();
|
||||
const toaster = useAppToaster();
|
||||
const postUploadAction = useAppSelector(selectPostUploadAction);
|
||||
const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId);
|
||||
const [isHandlingUpload, setIsHandlingUpload] = useState<boolean>(false);
|
||||
@ -37,13 +36,14 @@ export const useFullscreenDropzone = () => {
|
||||
(rejection: FileRejection) => {
|
||||
setIsHandlingUpload(true);
|
||||
|
||||
toaster({
|
||||
toast({
|
||||
id: 'UPLOAD_FAILED',
|
||||
title: t('toast.uploadFailed'),
|
||||
description: rejection.errors.map((error) => error.message).join('\n'),
|
||||
status: 'error',
|
||||
});
|
||||
},
|
||||
[t, toaster]
|
||||
[t]
|
||||
);
|
||||
|
||||
const fileAcceptedCallback = useCallback(
|
||||
@ -62,7 +62,8 @@ export const useFullscreenDropzone = () => {
|
||||
const onDrop = useCallback(
|
||||
(acceptedFiles: Array<File>, fileRejections: Array<FileRejection>) => {
|
||||
if (fileRejections.length > 1) {
|
||||
toaster({
|
||||
toast({
|
||||
id: 'UPLOAD_FAILED',
|
||||
title: t('toast.uploadFailed'),
|
||||
description: t('toast.uploadFailedInvalidUploadDesc'),
|
||||
status: 'error',
|
||||
@ -78,7 +79,7 @@ export const useFullscreenDropzone = () => {
|
||||
fileAcceptedCallback(file);
|
||||
});
|
||||
},
|
||||
[t, toaster, fileAcceptedCallback, fileRejectionCallback]
|
||||
[t, fileAcceptedCallback, fileRejectionCallback]
|
||||
);
|
||||
|
||||
const onDragOver = useCallback(() => {
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { createStandaloneToast, theme, TOAST_OPTIONS } from '@invoke-ai/ui-library';
|
||||
|
||||
export const { toast } = createStandaloneToast({
|
||||
theme: theme,
|
||||
defaultOptions: TOAST_OPTIONS.defaultOptions,
|
||||
});
|
@ -1,6 +1,5 @@
|
||||
import { Flex, MenuDivider, MenuItem, Spinner } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { $customStarUI } from 'app/store/nanostores/customStarUI';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useCopyImageToClipboard } from 'common/hooks/useCopyImageToClipboard';
|
||||
@ -14,6 +13,7 @@ import { sentImageToCanvas, sentImageToImg2Img } from 'features/gallery/store/ac
|
||||
import { $templates } from 'features/nodes/store/nodesSlice';
|
||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import { useGetAndLoadEmbeddedWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadEmbeddedWorkflow';
|
||||
import { size } from 'lodash-es';
|
||||
@ -46,7 +46,6 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const toaster = useAppToaster();
|
||||
const isCanvasEnabled = useFeatureStatus('canvas');
|
||||
const customStarUi = useStore($customStarUI);
|
||||
const { downloadImage } = useDownloadImage();
|
||||
@ -86,13 +85,12 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
||||
});
|
||||
dispatch(setInitialCanvasImage(imageDTO, optimalDimension));
|
||||
|
||||
toaster({
|
||||
toast({
|
||||
id: 'SENT_TO_CANVAS',
|
||||
title: t('toast.sentToUnifiedCanvas'),
|
||||
status: 'success',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
}, [dispatch, imageDTO, t, toaster, optimalDimension]);
|
||||
}, [dispatch, imageDTO, t, optimalDimension]);
|
||||
|
||||
const handleChangeBoard = useCallback(() => {
|
||||
dispatch(imagesToChangeSelected([imageDTO]));
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { IconButton } from '@invoke-ai/ui-library';
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
||||
import { setShouldShowImageDetails } from 'features/ui/store/uiSlice';
|
||||
@ -14,7 +13,6 @@ export const ToggleMetadataViewerButton = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const shouldShowImageDetails = useAppSelector((s) => s.ui.shouldShowImageDetails);
|
||||
const lastSelectedImage = useAppSelector(selectLastSelectedImage);
|
||||
const toaster = useAppToaster();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { currentData: imageDTO } = useGetImageDTOQuery(lastSelectedImage?.image_name ?? skipToken);
|
||||
@ -24,7 +22,7 @@ export const ToggleMetadataViewerButton = memo(() => {
|
||||
[dispatch, shouldShowImageDetails]
|
||||
);
|
||||
|
||||
useHotkeys('i', toggleMetadataViewer, { enabled: Boolean(imageDTO) }, [imageDTO, shouldShowImageDetails, toaster]);
|
||||
useHotkeys('i', toggleMetadataViewer, { enabled: Boolean(imageDTO) }, [imageDTO, shouldShowImageDetails]);
|
||||
|
||||
return (
|
||||
<IconButton
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { objectKeys } from 'common/util/objectKeys';
|
||||
import { toast } from 'common/util/toast';
|
||||
import type { Layer } from 'features/controlLayers/store/types';
|
||||
import type { LoRA } from 'features/lora/store/loraSlice';
|
||||
import type {
|
||||
@ -15,6 +14,7 @@ import type {
|
||||
import { fetchModelConfig } from 'features/metadata/util/modelFetchingHelpers';
|
||||
import { validators } from 'features/metadata/util/validators';
|
||||
import type { ModelIdentifierField } from 'features/nodes/types/common';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
@ -89,23 +89,23 @@ const renderLayersValue: MetadataRenderValueFunc<Layer[]> = async (layers) => {
|
||||
return `${layers.length} ${t('controlLayers.layers', { count: layers.length })}`;
|
||||
};
|
||||
|
||||
const parameterSetToast = (parameter: string, description?: string) => {
|
||||
const parameterSetToast = (parameter: string) => {
|
||||
toast({
|
||||
title: t('toast.parameterSet', { parameter }),
|
||||
description,
|
||||
id: ToastID.PARAMETER_SET,
|
||||
title: t('toast.parameterSet'),
|
||||
description: t('toast.parameterSetDesc', { parameter }),
|
||||
status: 'info',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
};
|
||||
|
||||
const parameterNotSetToast = (parameter: string, description?: string) => {
|
||||
const parameterNotSetToast = (parameter: string, message?: string) => {
|
||||
toast({
|
||||
title: t('toast.parameterNotSet', { parameter }),
|
||||
description,
|
||||
id: 'PARAMETER_NOT_SET',
|
||||
title: t('toast.parameterNotSet'),
|
||||
description: message
|
||||
? t('toast.parameterNotSetDescWithMessage', { parameter, message })
|
||||
: t('toast.parameterNotSetDesc', { parameter }),
|
||||
status: 'warning',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
};
|
||||
|
||||
@ -458,7 +458,18 @@ export const parseAndRecallAllMetadata = async (
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
if (results.some((result) => result.status === 'fulfilled')) {
|
||||
parameterSetToast(t('toast.parameters'));
|
||||
toast({
|
||||
id: ToastID.PARAMETER_SET,
|
||||
title: t('toast.parametersSet'),
|
||||
status: 'info',
|
||||
});
|
||||
} else {
|
||||
toast({
|
||||
id: ToastID.PARAMETER_SET,
|
||||
title: t('toast.parametersNotSet'),
|
||||
status: 'warning',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Button, Flex, FormControl, FormErrorMessage, FormHelperText, FormLabel, Input } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import type { ChangeEventHandler } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -14,7 +12,6 @@ export const HuggingFaceForm = () => {
|
||||
const [displayResults, setDisplayResults] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState('');
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [_getHuggingFaceModels, { isLoading, data }] = useLazyGetHuggingFaceModelsQuery();
|
||||
const [installModel] = useInstallModelMutation();
|
||||
@ -24,29 +21,23 @@ export const HuggingFaceForm = () => {
|
||||
installModel({ source })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
[installModel, dispatch, t]
|
||||
[installModel, t]
|
||||
);
|
||||
|
||||
const getModels = useCallback(async () => {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Flex, IconButton, Text } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiPlusBold } from 'react-icons/pi';
|
||||
@ -12,7 +10,6 @@ type Props = {
|
||||
};
|
||||
export const HuggingFaceResultItem = ({ result }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [installModel] = useInstallModelMutation();
|
||||
|
||||
@ -20,28 +17,22 @@ export const HuggingFaceResultItem = ({ result }: Props) => {
|
||||
installModel({ source: result })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [installModel, result, dispatch, t]);
|
||||
}, [installModel, result, t]);
|
||||
|
||||
return (
|
||||
<Flex alignItems="center" justifyContent="space-between" w="100%" gap={3}>
|
||||
|
@ -8,10 +8,8 @@ import {
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import type { ChangeEventHandler } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -27,7 +25,6 @@ type HuggingFaceResultsProps = {
|
||||
export const HuggingFaceResults = ({ results }: HuggingFaceResultsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [installModel] = useInstallModelMutation();
|
||||
|
||||
@ -51,29 +48,23 @@ export const HuggingFaceResults = ({ results }: HuggingFaceResultsProps) => {
|
||||
installModel({ source: result })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [filteredResults, installModel, dispatch, t]);
|
||||
}, [filteredResults, installModel, t]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Button, Checkbox, Flex, FormControl, FormHelperText, FormLabel, Input } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { useCallback } from 'react';
|
||||
import type { SubmitHandler } from 'react-hook-form';
|
||||
@ -14,8 +12,6 @@ type SimpleImportModelConfig = {
|
||||
};
|
||||
|
||||
export const InstallModelForm = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [installModel, { isLoading }] = useInstallModelMutation();
|
||||
|
||||
const { register, handleSubmit, formState, reset } = useForm<SimpleImportModelConfig>({
|
||||
@ -35,31 +31,25 @@ export const InstallModelForm = () => {
|
||||
installModel({ source: values.location, inplace: values.inplace })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
reset(undefined, { keepValues: true });
|
||||
})
|
||||
.catch((error) => {
|
||||
reset(undefined, { keepValues: true });
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
[dispatch, reset, installModel]
|
||||
[reset, installModel]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { Box, Button, Flex, Heading } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useListModelInstallsQuery, usePruneCompletedModelInstallsMutation } from 'services/api/endpoints/models';
|
||||
@ -10,8 +8,6 @@ import { useListModelInstallsQuery, usePruneCompletedModelInstallsMutation } fro
|
||||
import { ModelInstallQueueItem } from './ModelInstallQueueItem';
|
||||
|
||||
export const ModelInstallQueue = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { data } = useListModelInstallsQuery();
|
||||
|
||||
const [_pruneCompletedModelInstalls] = usePruneCompletedModelInstallsMutation();
|
||||
@ -20,28 +16,22 @@ export const ModelInstallQueue = () => {
|
||||
_pruneCompletedModelInstalls()
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.prunedQueue'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_INSTALL_QUEUE_PRUNED',
|
||||
title: t('toast.prunedQueue'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_INSTALL_QUEUE_PRUNE_FAILED',
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [_pruneCompletedModelInstalls, dispatch]);
|
||||
}, [_pruneCompletedModelInstalls]);
|
||||
|
||||
const pruneAvailable = useMemo(() => {
|
||||
return data?.some(
|
||||
|
@ -1,7 +1,5 @@
|
||||
import { Flex, IconButton, Progress, Text, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
@ -29,7 +27,6 @@ const formatBytes = (bytes: number) => {
|
||||
|
||||
export const ModelInstallQueueItem = (props: ModelListItemProps) => {
|
||||
const { installJob } = props;
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [deleteImportModel] = useCancelModelInstallMutation();
|
||||
|
||||
@ -37,28 +34,22 @@ export const ModelInstallQueueItem = (props: ModelListItemProps) => {
|
||||
deleteImportModel(installJob.id)
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelImportCanceled'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_INSTALL_CANCELED',
|
||||
title: t('toast.modelImportCanceled'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_INSTALL_CANCEL_FAILED',
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [deleteImportModel, installJob, dispatch]);
|
||||
}, [deleteImportModel, installJob]);
|
||||
|
||||
const sourceLocation = useMemo(() => {
|
||||
switch (installJob.source.type) {
|
||||
|
@ -11,10 +11,8 @@ import {
|
||||
InputGroup,
|
||||
InputRightElement,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import type { ChangeEvent, ChangeEventHandler } from 'react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -30,7 +28,6 @@ type ScanModelResultsProps = {
|
||||
export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const dispatch = useAppDispatch();
|
||||
const [inplace, setInplace] = useState(true);
|
||||
const [installModel] = useInstallModelMutation();
|
||||
|
||||
@ -61,58 +58,46 @@ export const ScanModelsResults = ({ results }: ScanModelResultsProps) => {
|
||||
installModel({ source: result.path, inplace })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [filteredResults, installModel, inplace, dispatch, t]);
|
||||
}, [filteredResults, installModel, inplace, t]);
|
||||
|
||||
const handleInstallOne = useCallback(
|
||||
(source: string) => {
|
||||
installModel({ source, inplace })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
[installModel, inplace, dispatch, t]
|
||||
[installModel, inplace, t]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { Badge, Box, Flex, IconButton, Text } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import ModelBaseBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelBaseBadge';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast, ToastID } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiPlusBold } from 'react-icons/pi';
|
||||
@ -14,7 +12,6 @@ type Props = {
|
||||
};
|
||||
export const StarterModelsResultItem = ({ result }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const allSources = useMemo(() => {
|
||||
const _allSources = [result.source];
|
||||
if (result.dependencies) {
|
||||
@ -29,29 +26,23 @@ export const StarterModelsResultItem = ({ result }: Props) => {
|
||||
installModel({ source })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUED,
|
||||
title: t('toast.modelAddedSimple'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: ToastID.MODEL_INSTALL_QUEUE_FAILED,
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [allSources, installModel, dispatch, t]);
|
||||
}, [allSources, installModel, t]);
|
||||
|
||||
return (
|
||||
<Flex alignItems="center" justifyContent="space-between" w="100%" gap={3}>
|
||||
|
@ -4,8 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { setSelectedModelKey } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||
import ModelBaseBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelBaseBadge';
|
||||
import ModelFormatBadge from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelFormatBadge';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import type { MouseEvent } from 'react';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -53,25 +52,19 @@ const ModelListItem = (props: ModelListItemProps) => {
|
||||
deleteModel({ key: model.key })
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${t('modelManager.modelDeleted')}: ${model.name}`,
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_DELETED',
|
||||
title: `${t('modelManager.modelDeleted')}: ${model.name}`,
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${t('modelManager.modelDeleteFailed')}: ${model.name}`,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_DELETE_FAILED',
|
||||
title: `${t('modelManager.modelDeleteFailed')}: ${model.name}`,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
dispatch(setSelectedModelKey(null));
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Button, Flex, Heading, SimpleGrid, Text } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useControlNetOrT2IAdapterDefaultSettings } from 'features/modelManagerV2/hooks/useControlNetOrT2IAdapterDefaultSettings';
|
||||
import { DefaultPreprocessor } from 'features/modelManagerV2/subpanels/ModelPanel/ControlNetOrT2IAdapterDefaultSettings/DefaultPreprocessor';
|
||||
import type { FormField } from 'features/modelManagerV2/subpanels/ModelPanel/MainModelDefaultSettings/MainModelDefaultSettings';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import type { SubmitHandler } from 'react-hook-form';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@ -19,7 +18,6 @@ export type ControlNetOrT2IAdapterDefaultSettingsFormData = {
|
||||
export const ControlNetOrT2IAdapterDefaultSettings = () => {
|
||||
const selectedModelKey = useAppSelector((s) => s.modelmanagerV2.selectedModelKey);
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { defaultSettingsDefaults, isLoading: isLoadingDefaultSettings } =
|
||||
useControlNetOrT2IAdapterDefaultSettings(selectedModelKey);
|
||||
@ -46,30 +44,24 @@ export const ControlNetOrT2IAdapterDefaultSettings = () => {
|
||||
})
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.defaultSettingsSaved'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'DEFAULT_SETTINGS_SAVED',
|
||||
title: t('modelManager.defaultSettingsSaved'),
|
||||
status: 'success',
|
||||
});
|
||||
reset(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'DEFAULT_SETTINGS_SAVE_FAILED',
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
[selectedModelKey, dispatch, reset, updateModel, t]
|
||||
[selectedModelKey, reset, updateModel, t]
|
||||
);
|
||||
|
||||
if (isLoadingDefaultSettings) {
|
||||
|
@ -1,8 +1,6 @@
|
||||
import { Box, Button, Flex, Icon, IconButton, Image, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { typedMemo } from 'common/util/typedMemo';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -15,7 +13,6 @@ type Props = {
|
||||
};
|
||||
|
||||
const ModelImageUpload = ({ model_key, model_image }: Props) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const [image, setImage] = useState<string | null>(model_image || null);
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -34,27 +31,21 @@ const ModelImageUpload = ({ model_key, model_image }: Props) => {
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
setImage(URL.createObjectURL(file));
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageUpdated'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_IMAGE_UPDATED',
|
||||
title: t('modelManager.modelImageUpdated'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageUpdateFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
.catch(() => {
|
||||
toast({
|
||||
id: 'MODEL_IMAGE_UPDATE_FAILED',
|
||||
title: t('modelManager.modelImageUpdateFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
});
|
||||
},
|
||||
[dispatch, model_key, t, updateModelImage]
|
||||
[model_key, t, updateModelImage]
|
||||
);
|
||||
|
||||
const handleResetImage = useCallback(() => {
|
||||
@ -65,26 +56,20 @@ const ModelImageUpload = ({ model_key, model_image }: Props) => {
|
||||
deleteModelImage(model_key)
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageDeleted'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_IMAGE_DELETED',
|
||||
title: t('modelManager.modelImageDeleted'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelImageDeleteFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
.catch(() => {
|
||||
toast({
|
||||
id: 'MODEL_IMAGE_DELETE_FAILED',
|
||||
title: t('modelManager.modelImageDeleteFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
});
|
||||
}, [dispatch, model_key, t, deleteModelImage]);
|
||||
}, [model_key, t, deleteModelImage]);
|
||||
|
||||
const { getInputProps, getRootProps } = useDropzone({
|
||||
accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg', '.png'] },
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { Button, Flex, Heading, SimpleGrid, Text } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useMainModelDefaultSettings } from 'features/modelManagerV2/hooks/useMainModelDefaultSettings';
|
||||
import { DefaultHeight } from 'features/modelManagerV2/subpanels/ModelPanel/MainModelDefaultSettings/DefaultHeight';
|
||||
import { DefaultWidth } from 'features/modelManagerV2/subpanels/ModelPanel/MainModelDefaultSettings/DefaultWidth';
|
||||
import type { ParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import type { SubmitHandler } from 'react-hook-form';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@ -39,7 +38,6 @@ export type MainModelDefaultSettingsFormData = {
|
||||
export const MainModelDefaultSettings = () => {
|
||||
const selectedModelKey = useAppSelector((s) => s.modelmanagerV2.selectedModelKey);
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const {
|
||||
defaultSettingsDefaults,
|
||||
@ -76,30 +74,24 @@ export const MainModelDefaultSettings = () => {
|
||||
})
|
||||
.unwrap()
|
||||
.then((_) => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.defaultSettingsSaved'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'DEFAULT_SETTINGS_SAVED',
|
||||
title: t('modelManager.defaultSettingsSaved'),
|
||||
status: 'success',
|
||||
});
|
||||
reset(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'DEFAULT_SETTINGS_SAVE_FAILED',
|
||||
title: `${error.data.detail} `,
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
[selectedModelKey, dispatch, reset, updateModel, t]
|
||||
[selectedModelKey, reset, updateModel, t]
|
||||
);
|
||||
|
||||
if (isLoadingDefaultSettings) {
|
||||
|
@ -4,8 +4,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { setSelectedModelMode } from 'features/modelManagerV2/store/modelManagerV2Slice';
|
||||
import { ModelConvertButton } from 'features/modelManagerV2/subpanels/ModelPanel/ModelConvertButton';
|
||||
import { ModelEditButton } from 'features/modelManagerV2/subpanels/ModelPanel/ModelEditButton';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import type { SubmitHandler } from 'react-hook-form';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@ -47,25 +46,19 @@ export const Model = () => {
|
||||
.then((payload) => {
|
||||
form.reset(payload, { keepDefaultValues: true });
|
||||
dispatch(setSelectedModelMode('view'));
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelUpdated'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_UPDATED',
|
||||
title: t('modelManager.modelUpdated'),
|
||||
status: 'success',
|
||||
});
|
||||
})
|
||||
.catch((_) => {
|
||||
form.reset();
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('modelManager.modelUpdateFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'MODEL_UPDATE_FAILED',
|
||||
title: t('modelManager.modelUpdateFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
});
|
||||
},
|
||||
[dispatch, data?.key, form, t, updateModel]
|
||||
|
@ -9,9 +9,7 @@ import {
|
||||
useDisclosure,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useConvertModelMutation, useGetModelConfigQuery } from 'services/api/endpoints/models';
|
||||
@ -22,7 +20,6 @@ interface ModelConvertProps {
|
||||
|
||||
export const ModelConvertButton = (props: ModelConvertProps) => {
|
||||
const { modelKey } = props;
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const { data } = useGetModelConfigQuery(modelKey ?? skipToken);
|
||||
const [convertModel, { isLoading }] = useConvertModelMutation();
|
||||
@ -33,38 +30,26 @@ export const ModelConvertButton = (props: ModelConvertProps) => {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${t('modelManager.convertingModelBegin')}: ${data?.name}`,
|
||||
status: 'info',
|
||||
})
|
||||
)
|
||||
);
|
||||
const toastId = `CONVERTING_MODEL_${data.key}`;
|
||||
toast({
|
||||
id: toastId,
|
||||
title: `${t('modelManager.convertingModelBegin')}: ${data?.name}`,
|
||||
status: 'info',
|
||||
});
|
||||
|
||||
convertModel(data?.key)
|
||||
.unwrap()
|
||||
.then(() => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${t('modelManager.modelConverted')}: ${data?.name}`,
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({ id: toastId, title: `${t('modelManager.modelConverted')}: ${data?.name}`, status: 'success' });
|
||||
})
|
||||
.catch(() => {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: `${t('modelManager.modelConversionFailed')}: ${data?.name}`,
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: toastId,
|
||||
title: `${t('modelManager.modelConversionFailed')}: ${data?.name}`,
|
||||
status: 'error',
|
||||
});
|
||||
});
|
||||
}, [data, isLoading, dispatch, t, convertModel]);
|
||||
}, [data, isLoading, t, convertModel]);
|
||||
|
||||
if (data?.format !== 'checkpoint') {
|
||||
return;
|
||||
|
@ -3,7 +3,6 @@ import 'reactflow/dist/style.css';
|
||||
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||
import { Combobox, Flex, Popover, PopoverAnchor, PopoverBody, PopoverContent } from '@invoke-ai/ui-library';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useAppDispatch, useAppStore } from 'app/store/storeHooks';
|
||||
import type { SelectInstance } from 'chakra-react-select';
|
||||
import { useBuildNode } from 'features/nodes/hooks/useBuildNode';
|
||||
@ -24,6 +23,7 @@ import { connectionToEdge } from 'features/nodes/store/util/reactFlowUtil';
|
||||
import { validateConnectionTypes } from 'features/nodes/store/util/validateConnectionTypes';
|
||||
import type { AnyNode } from 'features/nodes/types/invocation';
|
||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { filter, map, memoize, some } from 'lodash-es';
|
||||
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
@ -60,7 +60,6 @@ const filterOption = memoize((option: FilterOptionOption<ComboboxOption>, inputV
|
||||
const AddNodePopover = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const buildInvocation = useBuildNode();
|
||||
const toaster = useAppToaster();
|
||||
const { t } = useTranslation();
|
||||
const selectRef = useRef<SelectInstance<ComboboxOption> | null>(null);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
@ -127,7 +126,7 @@ const AddNodePopover = () => {
|
||||
const errorMessage = t('nodes.unknownNode', {
|
||||
nodeType: nodeType,
|
||||
});
|
||||
toaster({
|
||||
toast({
|
||||
status: 'error',
|
||||
title: errorMessage,
|
||||
});
|
||||
@ -163,7 +162,7 @@ const AddNodePopover = () => {
|
||||
}
|
||||
return node;
|
||||
},
|
||||
[buildInvocation, store, dispatch, t, toaster]
|
||||
[buildInvocation, store, dispatch, t]
|
||||
);
|
||||
|
||||
const onChange = useCallback<ComboboxOnChange>(
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiTrashSimpleFill } from 'react-icons/pi';
|
||||
@ -16,14 +15,11 @@ const ClearFlowButton = () => {
|
||||
const handleNewWorkflow = useCallback(() => {
|
||||
dispatch(nodeEditorReset());
|
||||
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('workflows.workflowCleared'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'WORKFLOW_CLEARED',
|
||||
title: t('workflows.workflowCleared'),
|
||||
status: 'success',
|
||||
});
|
||||
|
||||
onClose();
|
||||
}, [dispatch, onClose, t]);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||
import { iiLayerAdded } from 'features/controlLayers/store/controlLayersSlice';
|
||||
import { parseAndRecallAllMetadata } from 'features/metadata/util/handlers';
|
||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import { t } from 'i18next';
|
||||
import { useCallback, useEffect } from 'react';
|
||||
@ -16,7 +16,6 @@ export const usePreselectedImage = (selectedImage?: {
|
||||
}) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||
const toaster = useAppToaster();
|
||||
|
||||
const { currentData: selectedImageDto } = useGetImageDTOQuery(selectedImage?.imageName ?? skipToken);
|
||||
|
||||
@ -26,14 +25,13 @@ export const usePreselectedImage = (selectedImage?: {
|
||||
if (selectedImageDto) {
|
||||
dispatch(setInitialCanvasImage(selectedImageDto, optimalDimension));
|
||||
dispatch(setActiveTab('canvas'));
|
||||
toaster({
|
||||
toast({
|
||||
id: 'SENT_TO_CANVAS',
|
||||
title: t('toast.sentToUnifiedCanvas'),
|
||||
status: 'info',
|
||||
duration: 2500,
|
||||
isClosable: true,
|
||||
});
|
||||
}
|
||||
}, [selectedImageDto, dispatch, optimalDimension, toaster]);
|
||||
}, [selectedImageDto, dispatch, optimalDimension]);
|
||||
|
||||
const handleSendToImg2Img = useCallback(() => {
|
||||
if (selectedImageDto) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCancelByBatchIdsMutation, useGetBatchStatusQuery } from 'services/api/endpoints/queue';
|
||||
@ -23,7 +23,6 @@ export const useCancelBatch = (batch_id: string) => {
|
||||
const [trigger, { isLoading }] = useCancelByBatchIdsMutation({
|
||||
fixedCacheKey: 'cancelByBatchIds',
|
||||
});
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const cancelBatch = useCallback(async () => {
|
||||
if (isCanceled) {
|
||||
@ -31,21 +30,19 @@ export const useCancelBatch = (batch_id: string) => {
|
||||
}
|
||||
try {
|
||||
await trigger({ batch_ids: [batch_id] }).unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelBatchSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANCEL_BATCH_SUCCEEDED',
|
||||
title: t('queue.cancelBatchSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelBatchFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'CANCEL_BATCH_FAILED',
|
||||
title: t('queue.cancelBatchFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [batch_id, dispatch, isCanceled, t, trigger]);
|
||||
}, [batch_id, isCanceled, t, trigger]);
|
||||
|
||||
return { cancelBatch, isLoading, isCanceled, isDisabled: !isConnected };
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -9,7 +9,6 @@ export const useCancelCurrentQueueItem = () => {
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||
const [trigger, { isLoading }] = useCancelQueueItemMutation();
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const currentQueueItemId = useMemo(() => queueStatus?.queue.item_id, [queueStatus?.queue.item_id]);
|
||||
const cancelQueueItem = useCallback(async () => {
|
||||
@ -18,21 +17,19 @@ export const useCancelCurrentQueueItem = () => {
|
||||
}
|
||||
try {
|
||||
await trigger(currentQueueItemId).unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'QUEUE_CANCEL_SUCCEEDED',
|
||||
title: t('queue.cancelSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'QUEUE_CANCEL_FAILED',
|
||||
title: t('queue.cancelFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [currentQueueItemId, dispatch, t, trigger]);
|
||||
}, [currentQueueItemId, t, trigger]);
|
||||
|
||||
const isDisabled = useMemo(() => !isConnected || isNil(currentQueueItemId), [isConnected, currentQueueItemId]);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useCancelQueueItemMutation } from 'services/api/endpoints/queue';
|
||||
@ -7,26 +7,23 @@ import { useCancelQueueItemMutation } from 'services/api/endpoints/queue';
|
||||
export const useCancelQueueItem = (item_id: number) => {
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const [trigger, { isLoading }] = useCancelQueueItemMutation();
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const cancelQueueItem = useCallback(async () => {
|
||||
try {
|
||||
await trigger(item_id).unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'QUEUE_CANCEL_SUCCEEDED',
|
||||
title: t('queue.cancelSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.cancelFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'QUEUE_CANCEL_FAILED',
|
||||
title: t('queue.cancelFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [dispatch, item_id, t, trigger]);
|
||||
}, [item_id, t, trigger]);
|
||||
|
||||
return { cancelQueueItem, isLoading, isDisabled: !isConnected };
|
||||
};
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useClearInvocationCacheMutation, useGetInvocationCacheStatusQuery } from 'services/api/endpoints/appInfo';
|
||||
|
||||
export const useClearInvocationCache = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const { data: cacheStatus } = useGetInvocationCacheStatusQuery();
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const [trigger, { isLoading }] = useClearInvocationCacheMutation({
|
||||
@ -22,21 +21,19 @@ export const useClearInvocationCache = () => {
|
||||
|
||||
try {
|
||||
await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('invocationCache.clearSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INVOCATION_CACHE_CLEAR_SUCCEEDED',
|
||||
title: t('invocationCache.clearSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('invocationCache.clearFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INVOCATION_CACHE_CLEAR_FAILED',
|
||||
title: t('invocationCache.clearFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [isDisabled, trigger, dispatch, t]);
|
||||
}, [isDisabled, trigger, t]);
|
||||
|
||||
return { clearInvocationCache, isLoading, cacheStatus, isDisabled };
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { listCursorChanged, listPriorityChanged } from 'features/queue/store/queueSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useClearQueueMutation, useGetQueueStatusQuery } from 'services/api/endpoints/queue';
|
||||
@ -21,21 +21,19 @@ export const useClearQueue = () => {
|
||||
|
||||
try {
|
||||
await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.clearSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'QUEUE_CLEAR_SUCCEEDED',
|
||||
title: t('queue.clearSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
dispatch(listCursorChanged(undefined));
|
||||
dispatch(listPriorityChanged(undefined));
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.clearFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'QUEUE_CLEAR_FAILED',
|
||||
title: t('queue.clearFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [queueStatus?.queue.total, trigger, dispatch, t]);
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDisableInvocationCacheMutation, useGetInvocationCacheStatusQuery } from 'services/api/endpoints/appInfo';
|
||||
|
||||
export const useDisableInvocationCache = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const { data: cacheStatus } = useGetInvocationCacheStatusQuery();
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const [trigger, { isLoading }] = useDisableInvocationCacheMutation({
|
||||
@ -25,21 +24,19 @@ export const useDisableInvocationCache = () => {
|
||||
|
||||
try {
|
||||
await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('invocationCache.disableSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INVOCATION_CACHE_DISABLE_SUCCEEDED',
|
||||
title: t('invocationCache.disableSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('invocationCache.disableFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INVOCATION_CACHE_DISABLE_FAILED',
|
||||
title: t('invocationCache.disableFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [isDisabled, trigger, dispatch, t]);
|
||||
}, [isDisabled, trigger, t]);
|
||||
|
||||
return { disableInvocationCache, isLoading, cacheStatus, isDisabled };
|
||||
};
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useEnableInvocationCacheMutation, useGetInvocationCacheStatusQuery } from 'services/api/endpoints/appInfo';
|
||||
|
||||
export const useEnableInvocationCache = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const { data: cacheStatus } = useGetInvocationCacheStatusQuery();
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const [trigger, { isLoading }] = useEnableInvocationCacheMutation({
|
||||
@ -25,21 +24,19 @@ export const useEnableInvocationCache = () => {
|
||||
|
||||
try {
|
||||
await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('invocationCache.enableSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INVOCATION_CACHE_ENABLE_SUCCEEDED',
|
||||
title: t('invocationCache.enableSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('invocationCache.enableFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INVOCATION_CACHE_ENABLE_FAILED',
|
||||
title: t('invocationCache.enableFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [isDisabled, trigger, dispatch, t]);
|
||||
}, [isDisabled, trigger, t]);
|
||||
|
||||
return { enableInvocationCache, isLoading, cacheStatus, isDisabled };
|
||||
};
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetQueueStatusQuery, usePauseProcessorMutation } from 'services/api/endpoints/queue';
|
||||
|
||||
export const usePauseProcessor = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||
@ -21,21 +20,19 @@ export const usePauseProcessor = () => {
|
||||
}
|
||||
try {
|
||||
await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.pauseSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PAUSE_SUCCEEDED',
|
||||
title: t('queue.pauseSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.pauseFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PAUSE_FAILED',
|
||||
title: t('queue.pauseFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [isStarted, trigger, dispatch, t]);
|
||||
}, [isStarted, trigger, t]);
|
||||
|
||||
const isDisabled = useMemo(() => !isConnected || !isStarted, [isConnected, isStarted]);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { listCursorChanged, listPriorityChanged } from 'features/queue/store/queueSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetQueueStatusQuery, usePruneQueueMutation } from 'services/api/endpoints/queue';
|
||||
@ -30,21 +30,19 @@ export const usePruneQueue = () => {
|
||||
}
|
||||
try {
|
||||
const data = await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.pruneSucceeded', { item_count: data.deleted }),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PRUNE_SUCCEEDED',
|
||||
title: t('queue.pruneSucceeded', { item_count: data.deleted }),
|
||||
status: 'success',
|
||||
});
|
||||
dispatch(listCursorChanged(undefined));
|
||||
dispatch(listPriorityChanged(undefined));
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.pruneFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PRUNE_FAILED',
|
||||
title: t('queue.pruneFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [finishedCount, trigger, dispatch, t]);
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetQueueStatusQuery, useResumeProcessorMutation } from 'services/api/endpoints/queue';
|
||||
|
||||
export const useResumeProcessor = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||
const { t } = useTranslation();
|
||||
@ -21,21 +20,19 @@ export const useResumeProcessor = () => {
|
||||
}
|
||||
try {
|
||||
await trigger().unwrap();
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.resumeSucceeded'),
|
||||
status: 'success',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROCESSOR_RESUMED',
|
||||
title: t('queue.resumeSucceeded'),
|
||||
status: 'success',
|
||||
});
|
||||
} catch {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('queue.resumeFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'PROCESSOR_RESUME_FAILED',
|
||||
title: t('queue.resumeFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
}, [isStarted, trigger, dispatch, t]);
|
||||
}, [isStarted, trigger, t]);
|
||||
|
||||
const isDisabled = useMemo(() => !isConnected || isStarted, [isConnected, isStarted]);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { resetCanvas } from 'features/canvas/store/canvasSlice';
|
||||
import { controlAdaptersReset } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useClearIntermediatesMutation, useGetIntermediatesCountQuery } from 'services/api/endpoints/images';
|
||||
@ -42,20 +42,18 @@ export const useClearIntermediates = (shouldShowClearIntermediates: boolean): Us
|
||||
.then((clearedCount) => {
|
||||
dispatch(controlAdaptersReset());
|
||||
dispatch(resetCanvas());
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('settings.intermediatesCleared', { count: clearedCount }),
|
||||
status: 'info',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INTERMEDIATES_CLEARED',
|
||||
title: t('settings.intermediatesCleared', { count: clearedCount }),
|
||||
status: 'info',
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('settings.intermediatesClearedFailed'),
|
||||
status: 'error',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'INTERMEDIATES_CLEAR_FAILED',
|
||||
title: t('settings.intermediatesClearedFailed'),
|
||||
status: 'error',
|
||||
});
|
||||
});
|
||||
}, [t, _clearIntermediates, dispatch, hasPendingItems]);
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
import type { UseToastOptions } from '@invoke-ai/ui-library';
|
||||
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 { calculateStepPercentage } from 'features/system/util/calculateStepPercentage';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { t } from 'i18next';
|
||||
import { startCase } from 'lodash-es';
|
||||
import type { LogLevelName } from 'roarr';
|
||||
import {
|
||||
socketConnected,
|
||||
@ -13,13 +9,10 @@ import {
|
||||
socketGeneratorProgress,
|
||||
socketGraphExecutionStateComplete,
|
||||
socketInvocationComplete,
|
||||
socketInvocationError,
|
||||
socketInvocationRetrievalError,
|
||||
socketInvocationStarted,
|
||||
socketModelLoadCompleted,
|
||||
socketModelLoadStarted,
|
||||
socketQueueItemStatusChanged,
|
||||
socketSessionRetrievalError,
|
||||
} from 'services/events/actions';
|
||||
|
||||
import type { Language, SystemState } from './types';
|
||||
@ -29,7 +22,6 @@ const initialSystemState: SystemState = {
|
||||
isConnected: false,
|
||||
shouldConfirmOnDelete: true,
|
||||
enableImageDebugging: false,
|
||||
toastQueue: [],
|
||||
denoiseProgress: null,
|
||||
shouldAntialiasProgressImage: false,
|
||||
consoleLogLevel: 'debug',
|
||||
@ -51,12 +43,6 @@ export const systemSlice = createSlice({
|
||||
setEnableImageDebugging: (state, action: PayloadAction<boolean>) => {
|
||||
state.enableImageDebugging = action.payload;
|
||||
},
|
||||
addToast: (state, action: PayloadAction<UseToastOptions>) => {
|
||||
state.toastQueue.push(action.payload);
|
||||
},
|
||||
clearToastQueue: (state) => {
|
||||
state.toastQueue = [];
|
||||
},
|
||||
consoleLogLevelChanged: (state, action: PayloadAction<LogLevelName>) => {
|
||||
state.consoleLogLevel = action.payload;
|
||||
},
|
||||
@ -162,29 +148,12 @@ export const systemSlice = createSlice({
|
||||
state.denoiseProgress = null;
|
||||
}
|
||||
});
|
||||
|
||||
// *** Matchers - must be after all cases ***
|
||||
|
||||
/**
|
||||
* Any server error
|
||||
*/
|
||||
builder.addMatcher(isAnyServerError, (state, action) => {
|
||||
state.toastQueue.push(
|
||||
makeToast({
|
||||
title: t('toast.serverError'),
|
||||
status: 'error',
|
||||
description: startCase(action.payload.data.error_type),
|
||||
})
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setShouldConfirmOnDelete,
|
||||
setEnableImageDebugging,
|
||||
addToast,
|
||||
clearToastQueue,
|
||||
consoleLogLevelChanged,
|
||||
shouldLogToConsoleChanged,
|
||||
shouldAntialiasProgressImageChanged,
|
||||
@ -194,8 +163,6 @@ export const {
|
||||
setShouldEnableInformationalPopovers,
|
||||
} = systemSlice.actions;
|
||||
|
||||
const isAnyServerError = isAnyOf(socketInvocationError, socketSessionRetrievalError, socketInvocationRetrievalError);
|
||||
|
||||
export const selectSystemSlice = (state: RootState) => state.system;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
|
@ -1,4 +1,3 @@
|
||||
import type { UseToastOptions } from '@invoke-ai/ui-library';
|
||||
import type { LogLevel } from 'app/logging/logger';
|
||||
import type { ProgressImage } from 'services/events/types';
|
||||
import { z } from 'zod';
|
||||
@ -47,7 +46,6 @@ export interface SystemState {
|
||||
isConnected: boolean;
|
||||
shouldConfirmOnDelete: boolean;
|
||||
enableImageDebugging: boolean;
|
||||
toastQueue: UseToastOptions[];
|
||||
denoiseProgress: DenoiseProgress | null;
|
||||
consoleLogLevel: LogLevel;
|
||||
shouldLogToConsole: boolean;
|
||||
|
@ -1,20 +0,0 @@
|
||||
import type { UseToastOptions } from '@invoke-ai/ui-library';
|
||||
|
||||
export type MakeToastArg = string | UseToastOptions;
|
||||
|
||||
/**
|
||||
* Makes a toast from a string or a UseToastOptions object.
|
||||
* If a string is passed, the toast will have the status 'info' and will be closable with a duration of 2500ms.
|
||||
*/
|
||||
export const makeToast = (arg: MakeToastArg): UseToastOptions => {
|
||||
if (typeof arg === 'string') {
|
||||
return {
|
||||
title: arg,
|
||||
status: 'info',
|
||||
isClosable: true,
|
||||
duration: 2500,
|
||||
};
|
||||
}
|
||||
|
||||
return { status: 'info', isClosable: true, duration: 2500, ...arg };
|
||||
};
|
@ -2,8 +2,7 @@ import { ConfirmationAlertDialog, Flex, Text, useDisclosure } from '@invoke-ai/u
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
||||
import { workflowModeChanged } from 'features/nodes/store/workflowSlice';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -21,14 +20,11 @@ export const NewWorkflowConfirmationAlertDialog = memo((props: Props) => {
|
||||
dispatch(nodeEditorReset());
|
||||
dispatch(workflowModeChanged('edit'));
|
||||
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('workflows.newWorkflowCreated'),
|
||||
status: 'success',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'NEW_WORKFLOW_CREATED',
|
||||
title: t('workflows.newWorkflowCreated'),
|
||||
status: 'success',
|
||||
});
|
||||
|
||||
onClose();
|
||||
}, [dispatch, onClose, t]);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useToast } from '@invoke-ai/ui-library';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDeleteWorkflowMutation, workflowsApi } from 'services/api/endpoints/workflows';
|
||||
@ -17,8 +16,6 @@ type UseDeleteLibraryWorkflowReturn = {
|
||||
type UseDeleteLibraryWorkflow = (arg: UseDeleteLibraryWorkflowOptions) => UseDeleteLibraryWorkflowReturn;
|
||||
|
||||
export const useDeleteLibraryWorkflow: UseDeleteLibraryWorkflow = ({ onSuccess, onError }) => {
|
||||
const toaster = useAppToaster();
|
||||
const toast = useToast();
|
||||
const { t } = useTranslation();
|
||||
const [_deleteWorkflow, deleteWorkflowResult] = useDeleteWorkflowMutation();
|
||||
|
||||
@ -26,21 +23,21 @@ export const useDeleteLibraryWorkflow: UseDeleteLibraryWorkflow = ({ onSuccess,
|
||||
async (workflow_id: string) => {
|
||||
try {
|
||||
await _deleteWorkflow(workflow_id).unwrap();
|
||||
toaster({
|
||||
toast({
|
||||
id: 'WORKFLOW_DELETED',
|
||||
title: t('toast.workflowDeleted'),
|
||||
});
|
||||
onSuccess && onSuccess();
|
||||
} catch {
|
||||
if (!toast.isActive(`auth-error-toast-${workflowsApi.endpoints.deleteWorkflow.name}`)) {
|
||||
toaster({
|
||||
title: t('toast.problemDeletingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
toast({
|
||||
id: `AUTH_ERROR_TOAST_${workflowsApi.endpoints.deleteWorkflow.name}`,
|
||||
title: t('toast.problemDeletingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
onError && onError();
|
||||
}
|
||||
},
|
||||
[_deleteWorkflow, toaster, t, onSuccess, onError, toast]
|
||||
[_deleteWorkflow, t, onSuccess, onError]
|
||||
);
|
||||
|
||||
return { deleteWorkflow, deleteWorkflowResult };
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLazyGetImageWorkflowQuery } from 'services/api/endpoints/images';
|
||||
@ -21,7 +21,6 @@ type UseGetAndLoadEmbeddedWorkflow = (
|
||||
|
||||
export const useGetAndLoadEmbeddedWorkflow: UseGetAndLoadEmbeddedWorkflow = ({ onSuccess, onError }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const toaster = useAppToaster();
|
||||
const { t } = useTranslation();
|
||||
const [_getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult] = useLazyGetImageWorkflowQuery();
|
||||
const getAndLoadEmbeddedWorkflow = useCallback(
|
||||
@ -33,20 +32,22 @@ export const useGetAndLoadEmbeddedWorkflow: UseGetAndLoadEmbeddedWorkflow = ({ o
|
||||
// No toast - the listener for this action does that after the workflow is loaded
|
||||
onSuccess && onSuccess();
|
||||
} else {
|
||||
toaster({
|
||||
toast({
|
||||
id: 'PROBLEM_RETRIEVING_WORKFLOW',
|
||||
title: t('toast.problemRetrievingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
toaster({
|
||||
toast({
|
||||
id: 'PROBLEM_RETRIEVING_WORKFLOW',
|
||||
title: t('toast.problemRetrievingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
onError && onError();
|
||||
}
|
||||
},
|
||||
[_getAndLoadEmbeddedWorkflow, dispatch, onSuccess, toaster, t, onError]
|
||||
[_getAndLoadEmbeddedWorkflow, dispatch, onSuccess, t, onError]
|
||||
);
|
||||
|
||||
return { getAndLoadEmbeddedWorkflow, getAndLoadEmbeddedWorkflowResult };
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useToast } from '@invoke-ai/ui-library';
|
||||
import { useAppToaster } from 'app/components/Toaster';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
||||
import { useCallback } from 'react';
|
||||
@ -20,7 +19,6 @@ type UseGetAndLoadLibraryWorkflow = (arg: UseGetAndLoadLibraryWorkflowOptions) =
|
||||
|
||||
export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({ onSuccess, onError }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const toaster = useAppToaster();
|
||||
const toast = useToast();
|
||||
const { t } = useTranslation();
|
||||
const [_getAndLoadWorkflow, getAndLoadWorkflowResult] = useLazyGetWorkflowQuery();
|
||||
@ -33,16 +31,15 @@ export const useGetAndLoadLibraryWorkflow: UseGetAndLoadLibraryWorkflow = ({ onS
|
||||
// No toast - the listener for this action does that after the workflow is loaded
|
||||
onSuccess && onSuccess();
|
||||
} catch {
|
||||
if (!toast.isActive(`auth-error-toast-${workflowsApi.endpoints.getWorkflow.name}`)) {
|
||||
toaster({
|
||||
title: t('toast.problemRetrievingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
}
|
||||
toast({
|
||||
id: `AUTH_ERROR_TOAST_${workflowsApi.endpoints.getWorkflow.name}`,
|
||||
title: t('toast.problemRetrievingWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
onError && onError();
|
||||
}
|
||||
},
|
||||
[_getAndLoadWorkflow, dispatch, onSuccess, toaster, t, onError, toast]
|
||||
[_getAndLoadWorkflow, dispatch, onSuccess, t, onError, toast]
|
||||
);
|
||||
|
||||
return { getAndLoadWorkflow, getAndLoadWorkflowResult };
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { useLogger } from 'app/logging/useLogger';
|
||||
import { useAppDispatch } from 'app/store/storeHooks';
|
||||
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { workflowLoadedFromFile } from 'features/workflowLibrary/store/actions';
|
||||
import type { RefObject } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
@ -35,14 +34,11 @@ export const useLoadWorkflowFromFile: UseLoadWorkflowFromFile = ({ resetRef, onS
|
||||
} catch (e) {
|
||||
// There was a problem reading the file
|
||||
logger.error(t('nodes.unableToLoadWorkflow'));
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: t('nodes.unableToLoadWorkflow'),
|
||||
status: 'error',
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: 'UNABLE_TO_LOAD_WORKFLOW',
|
||||
title: t('nodes.unableToLoadWorkflow'),
|
||||
status: 'error',
|
||||
});
|
||||
reader.abort();
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { Middleware, MiddlewareAPI } from '@reduxjs/toolkit';
|
||||
import type { Middleware } from '@reduxjs/toolkit';
|
||||
import { isRejectedWithValue } from '@reduxjs/toolkit';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { z } from 'zod';
|
||||
|
||||
@ -22,7 +22,7 @@ const zRejectedForbiddenAction = z.object({
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export const authToastMiddleware: Middleware = (api: MiddlewareAPI) => (next) => (action) => {
|
||||
export const authToastMiddleware: Middleware = () => (next) => (action) => {
|
||||
if (isRejectedWithValue(action)) {
|
||||
try {
|
||||
const parsed = zRejectedForbiddenAction.parse(action);
|
||||
@ -32,16 +32,13 @@ export const authToastMiddleware: Middleware = (api: MiddlewareAPI) => (next) =>
|
||||
return;
|
||||
}
|
||||
|
||||
const { dispatch } = api;
|
||||
const customMessage = parsed.payload.data.detail !== 'Forbidden' ? parsed.payload.data.detail : undefined;
|
||||
dispatch(
|
||||
addToast({
|
||||
id: `auth-error-toast-${endpointName}`,
|
||||
title: t('common.somethingWentWrong'),
|
||||
status: 'error',
|
||||
description: customMessage,
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: `auth-error-toast-${endpointName}`,
|
||||
title: t('toast.somethingWentWrong'),
|
||||
status: 'error',
|
||||
description: customMessage,
|
||||
});
|
||||
} catch (error) {
|
||||
// no-op
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { getStore } from 'app/store/nanostores/store';
|
||||
import type { JSONObject } from 'common/types';
|
||||
import type { BoardId } from 'features/gallery/store/types';
|
||||
import { ASSETS_CATEGORIES, IMAGE_CATEGORIES, IMAGE_LIMIT } from 'features/gallery/store/types';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import { t } from 'i18next';
|
||||
import { keyBy } from 'lodash-es';
|
||||
import type { components, paths } from 'services/api/schema';
|
||||
@ -206,13 +206,12 @@ export const imagesApi = api.injectEndpoints({
|
||||
const { data } = await queryFulfilled;
|
||||
|
||||
if (data.deleted_images.length < imageDTOs.length) {
|
||||
dispatch(
|
||||
addToast({
|
||||
title: t('gallery.problemDeletingImages'),
|
||||
description: t('gallery.problemDeletingImagesDesc'),
|
||||
status: 'warning',
|
||||
})
|
||||
);
|
||||
toast({
|
||||
id: 'problem-deleting-images',
|
||||
title: t('gallery.problemDeletingImages'),
|
||||
description: t('gallery.problemDeletingImagesDesc'),
|
||||
status: 'warning',
|
||||
});
|
||||
}
|
||||
|
||||
// convert to an object so we can access the successfully delete image DTOs by name
|
||||
|
@ -1,4 +1,3 @@
|
||||
import type { UseToastOptions } from '@invoke-ai/ui-library';
|
||||
import type { EntityState } from '@reduxjs/toolkit';
|
||||
import type { components, paths } from 'services/api/schema';
|
||||
import type { O } from 'ts-toolbelt';
|
||||
@ -200,7 +199,7 @@ type CanvasInitialImageAction = {
|
||||
|
||||
type ToastAction = {
|
||||
type: 'TOAST';
|
||||
toastOptions?: UseToastOptions;
|
||||
title?: string;
|
||||
};
|
||||
|
||||
type AddToBatchAction = {
|
||||
|
@ -2,8 +2,7 @@ import { $baseUrl } from 'app/store/nanostores/baseUrl';
|
||||
import { $bulkDownloadId } from 'app/store/nanostores/bulkDownloadId';
|
||||
import { $queueId } from 'app/store/nanostores/queueId';
|
||||
import type { AppDispatch } from 'app/store/store';
|
||||
import { addToast } from 'features/system/store/systemSlice';
|
||||
import { makeToast } from 'features/system/util/makeToast';
|
||||
import { toast } from 'features/toast/toast';
|
||||
import {
|
||||
socketBulkDownloadCompleted,
|
||||
socketBulkDownloadFailed,
|
||||
@ -52,15 +51,12 @@ export const setEventListeners = (arg: SetEventListenersArg) => {
|
||||
if (error && error.message) {
|
||||
const data: string | undefined = (error as unknown as { data: string | undefined }).data;
|
||||
if (data === 'ERR_UNAUTHENTICATED') {
|
||||
dispatch(
|
||||
addToast(
|
||||
makeToast({
|
||||
title: error.message,
|
||||
status: 'error',
|
||||
duration: 10000,
|
||||
})
|
||||
)
|
||||
);
|
||||
toast({
|
||||
id: `connect-error-${error.message}`,
|
||||
title: error.message,
|
||||
status: 'error',
|
||||
duration: 10000,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user