chore(ui): eslint

This commit is contained in:
psychedelicious 2024-08-23 16:51:44 +10:00
parent c1fb9cdb93
commit ee57302fc3
41 changed files with 178 additions and 176 deletions

View File

@ -38,7 +38,7 @@ async function generateTypes(schema) {
process.stdout.write(`\nOK!\r\n`); process.stdout.write(`\nOK!\r\n`);
} }
async function main() { function main() {
const encoding = 'utf-8'; const encoding = 'utf-8';
if (process.stdin.isTTY) { if (process.stdin.isTTY) {

View File

@ -18,8 +18,8 @@ import { StylePresetModal } from 'features/stylePresets/components/StylePresetFo
import { configChanged } from 'features/system/store/configSlice'; import { configChanged } from 'features/system/store/configSlice';
import { languageSelector } from 'features/system/store/systemSelectors'; import { languageSelector } from 'features/system/store/systemSelectors';
import { AppContent } from 'features/ui/components/AppContent'; import { AppContent } from 'features/ui/components/AppContent';
import type { TabName } from "features/ui/store/uiTypes";
import { setActiveTab } from 'features/ui/store/uiSlice'; import { setActiveTab } from 'features/ui/store/uiSlice';
import type { TabName } from "features/ui/store/uiTypes";
import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow'; import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow';
import { AnimatePresence } from 'framer-motion'; import { AnimatePresence } from 'framer-motion';
import i18n from 'i18n'; import i18n from 'i18n';

View File

@ -23,7 +23,7 @@ export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartLis
*/ */
startAppListening({ startAppListening({
matcher: matchAnyBoardDeleted, matcher: matchAnyBoardDeleted,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const state = getState(); const state = getState();
const deletedBoardId = action.meta.arg.originalArgs; const deletedBoardId = action.meta.arg.originalArgs;
const { autoAddBoardId, selectedBoardId } = state.gallery; const { autoAddBoardId, selectedBoardId } = state.gallery;
@ -44,7 +44,7 @@ export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartLis
// If we archived a board, it may end up hidden. If it's selected or the auto-add board, we should reset those. // If we archived a board, it may end up hidden. If it's selected or the auto-add board, we should reset those.
startAppListening({ startAppListening({
matcher: boardsApi.endpoints.updateBoard.matchFulfilled, matcher: boardsApi.endpoints.updateBoard.matchFulfilled,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const state = getState(); const state = getState();
const { shouldShowArchivedBoards } = state.gallery; const { shouldShowArchivedBoards } = state.gallery;
@ -61,7 +61,7 @@ export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartLis
// When we hide archived boards, if the selected or the auto-add board is archived, we should reset those. // When we hide archived boards, if the selected or the auto-add board is archived, we should reset those.
startAppListening({ startAppListening({
actionCreator: shouldShowArchivedBoardsChanged, actionCreator: shouldShowArchivedBoardsChanged,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const shouldShowArchivedBoards = action.payload; const shouldShowArchivedBoards = action.payload;
// We only need to take action if we have just hidden archived boards. // We only need to take action if we have just hidden archived boards.
@ -100,7 +100,7 @@ export const addArchivedOrDeletedBoardListener = (startAppListening: AppStartLis
*/ */
startAppListening({ startAppListening({
matcher: boardsApi.endpoints.listAllBoards.matchFulfilled, matcher: boardsApi.endpoints.listAllBoards.matchFulfilled,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const boards = action.payload; const boards = action.payload;
const state = getState(); const state = getState();
const { selectedBoardId, autoAddBoardId } = state.gallery; const { selectedBoardId, autoAddBoardId } = state.gallery;

View File

@ -4,7 +4,7 @@ import { queueApi, selectQueueStatus } from 'services/api/endpoints/queue';
export const addAnyEnqueuedListener = (startAppListening: AppStartListening) => { export const addAnyEnqueuedListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
matcher: queueApi.endpoints.enqueueBatch.matchFulfilled, matcher: queueApi.endpoints.enqueueBatch.matchFulfilled,
effect: async (_, { dispatch, getState }) => { effect: (_, { dispatch, getState }) => {
const { data } = selectQueueStatus(getState()); const { data } = selectQueueStatus(getState());
if (!data || data.processor.is_started) { if (!data || data.processor.is_started) {

View File

@ -6,7 +6,7 @@ import { appInfoApi } from 'services/api/endpoints/appInfo';
export const addAppConfigReceivedListener = (startAppListening: AppStartListening) => { export const addAppConfigReceivedListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled, matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled,
effect: async (action, { getState, dispatch }) => { effect: (action, { getState, dispatch }) => {
const { infill_methods = [], nsfw_methods = [], watermarking_methods = [] } = action.payload; const { infill_methods = [], nsfw_methods = [], watermarking_methods = [] } = action.payload;
const infillMethod = getState().canvasV2.compositing.infillMethod; const infillMethod = getState().canvasV2.compositing.infillMethod;

View File

@ -6,7 +6,7 @@ export const appStarted = createAction('app/appStarted');
export const addAppStartedListener = (startAppListening: AppStartListening) => { export const addAppStartedListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
actionCreator: appStarted, actionCreator: appStarted,
effect: async (action, { unsubscribe, cancelActiveListeners }) => { effect: (action, { unsubscribe, cancelActiveListeners }) => {
// this should only run once // this should only run once
cancelActiveListeners(); cancelActiveListeners();
unsubscribe(); unsubscribe();

View File

@ -27,7 +27,7 @@ export const galleryImageClicked = createAction<{
export const addGalleryImageClickedListener = (startAppListening: AppStartListening) => { export const addGalleryImageClickedListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
actionCreator: galleryImageClicked, actionCreator: galleryImageClicked,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const { imageDTO, shiftKey, ctrlKey, metaKey, altKey } = action.payload; const { imageDTO, shiftKey, ctrlKey, metaKey, altKey } = action.payload;
const state = getState(); const state = getState();
const queryArgs = selectListImagesQueryArgs(state); const queryArgs = selectListImagesQueryArgs(state);

View File

@ -6,7 +6,7 @@ import { imagesToDeleteSelected, isModalOpenChanged } from 'features/deleteImage
export const addImageToDeleteSelectedListener = (startAppListening: AppStartListening) => { export const addImageToDeleteSelectedListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
actionCreator: imagesToDeleteSelected, actionCreator: imagesToDeleteSelected,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const imageDTOs = action.payload; const imageDTOs = action.payload;
const state = getState(); const state = getState();
const { shouldConfirmOnDelete } = state.system; const { shouldConfirmOnDelete } = state.system;

View File

@ -6,7 +6,7 @@ import type { ImageDTO } from 'services/api/types';
export const addImagesStarredListener = (startAppListening: AppStartListening) => { export const addImagesStarredListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.starImages.matchFulfilled, matcher: imagesApi.endpoints.starImages.matchFulfilled,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const { updated_image_names: starredImages } = action.payload; const { updated_image_names: starredImages } = action.payload;
const state = getState(); const state = getState();

View File

@ -6,7 +6,7 @@ import type { ImageDTO } from 'services/api/types';
export const addImagesUnstarredListener = (startAppListening: AppStartListening) => { export const addImagesUnstarredListener = (startAppListening: AppStartListening) => {
startAppListening({ startAppListening({
matcher: imagesApi.endpoints.unstarImages.matchFulfilled, matcher: imagesApi.endpoints.unstarImages.matchFulfilled,
effect: async (action, { dispatch, getState }) => { effect: (action, { dispatch, getState }) => {
const { updated_image_names: unstarredImages } = action.payload; const { updated_image_names: unstarredImages } = action.payload;
const state = getState(); const state = getState();

View File

@ -46,7 +46,7 @@ export const useFullscreenDropzone = () => {
); );
const fileAcceptedCallback = useCallback( const fileAcceptedCallback = useCallback(
async (file: File) => { (file: File) => {
uploadImage({ uploadImage({
file, file,
image_category: 'user', image_category: 'user',
@ -96,7 +96,7 @@ export const useFullscreenDropzone = () => {
useEffect(() => { useEffect(() => {
// This is a hack to allow pasting images into the uploader // This is a hack to allow pasting images into the uploader
const handlePaste = async (e: ClipboardEvent) => { const handlePaste = (e: ClipboardEvent) => {
if (!dropzone.inputRef.current) { if (!dropzone.inputRef.current) {
return; return;
} }

View File

@ -7,7 +7,7 @@ import { $authToken } from 'app/store/nanostores/authToken';
* @returns A function that takes a URL and returns a Promise that resolves with a Blob * @returns A function that takes a URL and returns a Promise that resolves with a Blob
*/ */
export const convertImageUrlToBlob = async (url: string) => export const convertImageUrlToBlob = (url: string) =>
new Promise<Blob | null>((resolve, reject) => { new Promise<Blob | null>((resolve, reject) => {
const img = new Image(); const img = new Image();
img.onload = () => { img.onload = () => {

View File

@ -1,5 +1,4 @@
import { Flex, Grid, GridItem, IconButton } from '@invoke-ai/ui-library'; import { Flex, Grid, GridItem, IconButton } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { memo, useCallback, useState } from 'react'; import { memo, useCallback, useState } from 'react';
import { import {
PiArrowDownBold, PiArrowDownBold,
@ -25,7 +24,6 @@ type ResizeDirection =
| 'down-right'; | 'down-right';
export const CanvasResizer = memo(() => { export const CanvasResizer = memo(() => {
const bbox = useAppSelector((s) => s.canvasV2.bbox);
const [resizeDirection, setResizeDirection] = useState<ResizeDirection>('center-out'); const [resizeDirection, setResizeDirection] = useState<ResizeDirection>('center-out');
const setDirUpLeft = useCallback(() => { const setDirUpLeft = useCallback(() => {

View File

@ -10,17 +10,16 @@ import { ToolChooser } from 'features/controlLayers/components/Tool/ToolChooser'
import { ToolEraserWidth } from 'features/controlLayers/components/Tool/ToolEraserWidth'; import { ToolEraserWidth } from 'features/controlLayers/components/Tool/ToolEraserWidth';
import { ToolFillColorPicker } from 'features/controlLayers/components/Tool/ToolFillColorPicker'; import { ToolFillColorPicker } from 'features/controlLayers/components/Tool/ToolFillColorPicker';
import { UndoRedoButtonGroup } from 'features/controlLayers/components/UndoRedoButtonGroup'; import { UndoRedoButtonGroup } from 'features/controlLayers/components/UndoRedoButtonGroup';
import { CanvasManagerProviderGate, useCanvasManager } from 'features/controlLayers/contexts/CanvasManagerProviderGate'; import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
import { ToggleProgressButton } from 'features/gallery/components/ImageViewer/ToggleProgressButton'; import { ToggleProgressButton } from 'features/gallery/components/ImageViewer/ToggleProgressButton';
import { ViewerToggleMenu } from 'features/gallery/components/ImageViewer/ViewerToggleMenu'; import { ViewerToggleMenu } from 'features/gallery/components/ImageViewer/ViewerToggleMenu';
import { memo, useSyncExternalStore } from 'react'; import { memo } from 'react';
export const ControlLayersToolbar = memo(() => { export const ControlLayersToolbar = memo(() => {
const tool = useAppSelector((s) => s.canvasV2.tool.selected); const tool = useAppSelector((s) => s.canvasV2.tool.selected);
return ( return (
<CanvasManagerProviderGate> <CanvasManagerProviderGate>
<Flex w="full" gap={2} alignItems="center"> <Flex w="full" gap={2} alignItems="center">
<ReactiveTest />
<ToggleProgressButton /> <ToggleProgressButton />
<ToolChooser /> <ToolChooser />
<Spacer /> <Spacer />
@ -41,15 +40,3 @@ export const ControlLayersToolbar = memo(() => {
}); });
ControlLayersToolbar.displayName = 'ControlLayersToolbar'; ControlLayersToolbar.displayName = 'ControlLayersToolbar';
const ReactiveTest = () => {
const canvasManager = useCanvasManager();
const adapters = useSyncExternalStore(
canvasManager.adapters.rasterLayers.subscribe,
canvasManager.adapters.rasterLayers.getSnapshot
);
console.log(adapters);
return null;
};

View File

@ -38,7 +38,6 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
} }
const manager = new CanvasManager(stage, container, store, socket); const manager = new CanvasManager(stage, container, store, socket);
console.log(manager);
const cleanup = manager.initialize(); const cleanup = manager.initialize();
return cleanup; return cleanup;
}, [asPreview, container, socket, stage, store]); }, [asPreview, container, socket, stage, store]);

View File

@ -2,6 +2,7 @@ import type { AppSocket } from 'app/hooks/useSocketIO';
import { logger } from 'app/logging/logger'; import { logger } from 'app/logging/logger';
import type { AppStore } from 'app/store/store'; import type { AppStore } from 'app/store/store';
import type { SerializableObject } from 'common/types'; import type { SerializableObject } from 'common/types';
import { SyncableMap } from 'common/util/SyncableMap/SyncableMap';
import { CanvasCacheModule } from 'features/controlLayers/konva/CanvasCacheModule'; import { CanvasCacheModule } from 'features/controlLayers/konva/CanvasCacheModule';
import { CanvasCompositorModule } from 'features/controlLayers/konva/CanvasCompositorModule'; import { CanvasCompositorModule } from 'features/controlLayers/konva/CanvasCompositorModule';
import { CanvasFilterModule } from 'features/controlLayers/konva/CanvasFilterModule'; import { CanvasFilterModule } from 'features/controlLayers/konva/CanvasFilterModule';
@ -9,7 +10,6 @@ import { CanvasRenderingModule } from 'features/controlLayers/konva/CanvasRender
import { CanvasStageModule } from 'features/controlLayers/konva/CanvasStageModule'; import { CanvasStageModule } from 'features/controlLayers/konva/CanvasStageModule';
import { CanvasWorkerModule } from 'features/controlLayers/konva/CanvasWorkerModule.js'; import { CanvasWorkerModule } from 'features/controlLayers/konva/CanvasWorkerModule.js';
import { getPrefixedId } from 'features/controlLayers/konva/util'; import { getPrefixedId } from 'features/controlLayers/konva/util';
import { SyncableMap } from 'common/util/SyncableMap/SyncableMap';
import type Konva from 'konva'; import type Konva from 'konva';
import { atom } from 'nanostores'; import { atom } from 'nanostores';
import type { Logger } from 'roarr'; import type { Logger } from 'roarr';

View File

@ -12,6 +12,8 @@ import type {
DepthAnythingModelSize, DepthAnythingModelSize,
DepthAnythingProcessorConfig, DepthAnythingProcessorConfig,
DWOpenposeProcessorConfig, DWOpenposeProcessorConfig,
FilterConfig,
FilterType,
HedProcessorConfig, HedProcessorConfig,
IPMethodV2, IPMethodV2,
LineartAnimeProcessorConfig, LineartAnimeProcessorConfig,
@ -21,8 +23,6 @@ import type {
MlsdProcessorConfig, MlsdProcessorConfig,
NormalbaeProcessorConfig, NormalbaeProcessorConfig,
PidiProcessorConfig, PidiProcessorConfig,
FilterConfig,
FilterType,
ZoeDepthProcessorConfig, ZoeDepthProcessorConfig,
} from './types'; } from './types';

View File

@ -1,7 +1,7 @@
import { useStore } from '@nanostores/react'; import { useStore } from '@nanostores/react';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
import { $activeScopes } from 'common/hooks/interactionScopes'; import { $activeScopes } from 'common/hooks/interactionScopes';
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
import { useGalleryNavigation } from 'features/gallery/hooks/useGalleryNavigation'; import { useGalleryNavigation } from 'features/gallery/hooks/useGalleryNavigation';
import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination'; import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination';
import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors'; import { selectListImagesQueryArgs } from 'features/gallery/store/gallerySelectors';

View File

@ -48,7 +48,7 @@ const renderControlAdapterValue: MetadataRenderValueFunc<AnyControlAdapterConfig
return `${value.model.key} (${value.model.base.toUpperCase()}) - ${value.weight}`; return `${value.model.key} (${value.model.base.toUpperCase()}) - ${value.weight}`;
} }
}; };
const renderLayerValue: MetadataRenderValueFunc<CanvasRasterLayerState> = async (layer) => { const renderLayerValue: MetadataRenderValueFunc<CanvasRasterLayerState> = (layer) => {
if (layer.type === 'initial_image_layer') { if (layer.type === 'initial_image_layer') {
let rendered = t('controlLayers.globalInitialImageLayer'); let rendered = t('controlLayers.globalInitialImageLayer');
if (layer.image) { if (layer.image) {
@ -88,7 +88,7 @@ const renderLayerValue: MetadataRenderValueFunc<CanvasRasterLayerState> = async
} }
assert(false, 'Unknown layer type'); assert(false, 'Unknown layer type');
}; };
const renderLayersValue: MetadataRenderValueFunc<CanvasRasterLayerState[]> = async (layers) => { const renderLayersValue: MetadataRenderValueFunc<CanvasRasterLayerState[]> = (layers) => {
return `${layers.length} ${t('controlLayers.layers', { count: layers.length })}`; return `${layers.length} ${t('controlLayers.layers', { count: layers.length })}`;
}; };
@ -178,7 +178,10 @@ const buildRecallItem =
} }
}; };
const resolveToString = (value: unknown) => new Promise<string>((resolve) => resolve(String(value))); const resolveToString = (value: unknown) =>
new Promise<string>((resolve) => {
resolve(String(value));
});
const buildHandlers: BuildMetadataHandlers = ({ const buildHandlers: BuildMetadataHandlers = ({
getLabel, getLabel,
@ -395,7 +398,7 @@ export const parseAndRecallPrompts = async (metadata: unknown) => {
} }
}; };
export const parseAndRecallImageDimensions = async (metadata: unknown) => { export const parseAndRecallImageDimensions = (metadata: unknown) => {
const recalled = recallKeys(['width', 'height'], metadata); const recalled = recallKeys(['width', 'height'], metadata);
if (size(recalled) > 0) { if (size(recalled) > 0) {
parameterSetToast(t('metadata.imageDimensions')); parameterSetToast(t('metadata.imageDimensions'));

View File

@ -1,6 +1,11 @@
import { getCAId, getImageObjectId, getIPAId, getLayerId } from 'features/controlLayers/konva/naming'; import { getCAId, getImageObjectId, getIPAId, getLayerId } from 'features/controlLayers/konva/naming';
import { defaultLoRAConfig } from 'features/controlLayers/store/lorasReducers'; import { defaultLoRAConfig } from 'features/controlLayers/store/lorasReducers';
import type { CanvasControlAdapterState, CanvasIPAdapterState, CanvasRasterLayerState, LoRA } from 'features/controlLayers/store/types'; import type {
CanvasControlAdapterState,
CanvasIPAdapterState,
CanvasRasterLayerState,
LoRA,
} from 'features/controlLayers/store/types';
import { import {
IMAGE_FILTERS, IMAGE_FILTERS,
imageDTOToImageWithDims, imageDTOToImageWithDims,
@ -424,7 +429,8 @@ const parseAllIPAdapters: MetadataParseFunc<IPAdapterConfigMetadata[]> = async (
}; };
//#region Control Layers //#region Control Layers
const parseLayer: MetadataParseFunc<CanvasRasterLayerState> = async (metadataItem) => zCanvasRasterLayerState.parseAsync(metadataItem); const parseLayer: MetadataParseFunc<CanvasRasterLayerState> = (metadataItem) =>
zCanvasRasterLayerState.parseAsync(metadataItem);
const parseLayers: MetadataParseFunc<CanvasRasterLayerState[]> = async (metadata) => { const parseLayers: MetadataParseFunc<CanvasRasterLayerState[]> = async (metadata) => {
// We need to support recalling pre-Control Layers metadata into Control Layers. A separate set of parsers handles // We need to support recalling pre-Control Layers metadata into Control Layers. A separate set of parsers handles
@ -559,9 +565,7 @@ const parseControlNetToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapt
.parse(await getProperty(metadataItem, 'control_mode')); .parse(await getProperty(metadataItem, 'control_mode'));
const defaultPreprocessor = controlNetModel.default_settings?.preprocessor; const defaultPreprocessor = controlNetModel.default_settings?.preprocessor;
const processorConfig = isFilterType(defaultPreprocessor) const processorConfig = isFilterType(defaultPreprocessor) ? IMAGE_FILTERS[defaultPreprocessor].buildDefaults() : null;
? IMAGE_FILTERS[defaultPreprocessor].buildDefaults()
: null;
const beginEndStepPct: [number, number] = [ const beginEndStepPct: [number, number] = [
begin_step_percent ?? initialControlNet.beginEndStepPct[0], begin_step_percent ?? initialControlNet.beginEndStepPct[0],
end_step_percent ?? initialControlNet.beginEndStepPct[1], end_step_percent ?? initialControlNet.beginEndStepPct[1],
@ -620,9 +624,7 @@ const parseT2IAdapterToControlAdapterLayer: MetadataParseFunc<CanvasControlAdapt
.parse(await getProperty(metadataItem, 'end_step_percent')); .parse(await getProperty(metadataItem, 'end_step_percent'));
const defaultPreprocessor = t2iAdapterModel.default_settings?.preprocessor; const defaultPreprocessor = t2iAdapterModel.default_settings?.preprocessor;
const processorConfig = isFilterType(defaultPreprocessor) const processorConfig = isFilterType(defaultPreprocessor) ? IMAGE_FILTERS[defaultPreprocessor].buildDefaults() : null;
? IMAGE_FILTERS[defaultPreprocessor].buildDefaults()
: null;
const beginEndStepPct: [number, number] = [ const beginEndStepPct: [number, number] = [
begin_step_percent ?? initialT2IAdapter.beginEndStepPct[0], begin_step_percent ?? initialT2IAdapter.beginEndStepPct[0],
end_step_percent ?? initialT2IAdapter.beginEndStepPct[1], end_step_percent ?? initialT2IAdapter.beginEndStepPct[1],

View File

@ -3,18 +3,14 @@ import { getStore } from 'app/store/nanostores/store';
import { deepClone } from 'common/util/deepClone'; import { deepClone } from 'common/util/deepClone';
import { import {
getBrushLineId, getBrushLineId,
getCAId,
getEraserLineId, getEraserLineId,
getImageObjectId, getImageObjectId,
getIPAId,
getRectShapeId, getRectShapeId,
getRGId, getRGId,
} from 'features/controlLayers/konva/naming'; } from 'features/controlLayers/konva/naming';
import { import {
bboxHeightChanged, bboxHeightChanged,
bboxWidthChanged, bboxWidthChanged,
// caRecalled,
ipaRecalled,
loraAllDeleted, loraAllDeleted,
loraRecalled, loraRecalled,
negativePrompt2Changed, negativePrompt2Changed,
@ -23,7 +19,6 @@ import {
positivePromptChanged, positivePromptChanged,
rasterLayerRecalled, rasterLayerRecalled,
refinerModelChanged, refinerModelChanged,
rgRecalled,
setCfgRescaleMultiplier, setCfgRescaleMultiplier,
setCfgScale, setCfgScale,
setImg2imgStrength, setImg2imgStrength,
@ -39,9 +34,7 @@ import {
vaeSelected, vaeSelected,
} from 'features/controlLayers/store/canvasV2Slice'; } from 'features/controlLayers/store/canvasV2Slice';
import type { import type {
CanvasIPAdapterState,
CanvasRasterLayerState, CanvasRasterLayerState,
CanvasRegionalGuidanceState,
LoRA, LoRA,
} from 'features/controlLayers/store/types'; } from 'features/controlLayers/store/types';
import { setHrfEnabled, setHrfMethod, setHrfStrength } from 'features/hrf/store/hrfSlice'; import { setHrfEnabled, setHrfMethod, setHrfStrength } from 'features/hrf/store/hrfSlice';
@ -51,7 +44,6 @@ import type {
MetadataRecallFunc, MetadataRecallFunc,
T2IAdapterConfigMetadata, T2IAdapterConfigMetadata,
} from 'features/metadata/types'; } from 'features/metadata/types';
import { fetchModelConfigByIdentifier } from 'features/metadata/util/modelFetchingHelpers';
import { modelSelected } from 'features/parameters/store/actions'; import { modelSelected } from 'features/parameters/store/actions';
import type { import type {
ParameterCFGRescaleMultiplier, ParameterCFGRescaleMultiplier,
@ -246,86 +238,86 @@ const recallIPAdapters: MetadataRecallFunc<IPAdapterConfigMetadata[]> = (ipAdapt
}); });
}; };
const recallCA: MetadataRecallFunc<CanvasControlAdapterState> = async (ca) => { // const recallCA: MetadataRecallFunc<CanvasControlAdapterState> = async (ca) => {
const { dispatch } = getStore(); // const { dispatch } = getStore();
const clone = deepClone(ca); // const clone = deepClone(ca);
if (clone.image) { // if (clone.image) {
const imageDTO = await getImageDTO(clone.image.name); // const imageDTO = await getImageDTO(clone.image.name);
if (!imageDTO) { // if (!imageDTO) {
clone.image = null; // clone.image = null;
} // }
} // }
if (clone.processedImage) { // if (clone.processedImage) {
const imageDTO = await getImageDTO(clone.processedImage.name); // const imageDTO = await getImageDTO(clone.processedImage.name);
if (!imageDTO) { // if (!imageDTO) {
clone.processedImage = null; // clone.processedImage = null;
} // }
} // }
if (clone.model) { // if (clone.model) {
try { // try {
await fetchModelConfigByIdentifier(clone.model); // await fetchModelConfigByIdentifier(clone.model);
} catch { // } catch {
// MODEL SMITED! // // MODEL SMITED!
clone.model = null; // clone.model = null;
} // }
} // }
// No clobber // // No clobber
clone.id = getCAId(uuidv4()); // clone.id = getCAId(uuidv4());
// dispatch(caRecalled({ data: clone })); // // dispatch(caRecalled({ data: clone }));
return; // return;
}; // };
const recallIPA: MetadataRecallFunc<CanvasIPAdapterState> = async (ipa) => { // const recallIPA: MetadataRecallFunc<CanvasIPAdapterState> = async (ipa) => {
const { dispatch } = getStore(); // const { dispatch } = getStore();
const clone = deepClone(ipa); // const clone = deepClone(ipa);
if (clone.imageObject) { // if (clone.imageObject) {
const imageDTO = await getImageDTO(clone.imageObject.name); // const imageDTO = await getImageDTO(clone.imageObject.name);
if (!imageDTO) { // if (!imageDTO) {
clone.imageObject = null; // clone.imageObject = null;
} // }
} // }
if (clone.model) { // if (clone.model) {
try { // try {
await fetchModelConfigByIdentifier(clone.model); // await fetchModelConfigByIdentifier(clone.model);
} catch { // } catch {
// MODEL SMITED! // // MODEL SMITED!
clone.model = null; // clone.model = null;
} // }
} // }
// No clobber // // No clobber
clone.id = getIPAId(uuidv4()); // clone.id = getIPAId(uuidv4());
dispatch(ipaRecalled({ data: clone })); // dispatch(ipaRecalled({ data: clone }));
return; // return;
}; // };
const recallRG: MetadataRecallFunc<CanvasRegionalGuidanceState> = async (rg) => { // const recallRG: MetadataRecallFunc<CanvasRegionalGuidanceState> = async (rg) => {
const { dispatch } = getStore(); // const { dispatch } = getStore();
const clone = deepClone(rg); // const clone = deepClone(rg);
// Strip out the uploaded mask image property - this is an intermediate image // // Strip out the uploaded mask image property - this is an intermediate image
clone.imageCache = null; // clone.imageCache = null;
for (const ipAdapter of clone.ipAdapters) { // for (const ipAdapter of clone.ipAdapters) {
if (ipAdapter.imageObject) { // if (ipAdapter.imageObject) {
const imageDTO = await getImageDTO(ipAdapter.imageObject.name); // const imageDTO = await getImageDTO(ipAdapter.imageObject.name);
if (!imageDTO) { // if (!imageDTO) {
ipAdapter.imageObject = null; // ipAdapter.imageObject = null;
} // }
} // }
if (ipAdapter.model) { // if (ipAdapter.model) {
try { // try {
await fetchModelConfigByIdentifier(ipAdapter.model); // await fetchModelConfigByIdentifier(ipAdapter.model);
} catch { // } catch {
// MODEL SMITED! // // MODEL SMITED!
ipAdapter.model = null; // ipAdapter.model = null;
} // }
} // }
// No clobber // // No clobber
ipAdapter.id = uuidv4(); // ipAdapter.id = uuidv4();
} // }
clone.id = getRGId(uuidv4()); // clone.id = getRGId(uuidv4());
dispatch(rgRecalled({ data: clone })); // dispatch(rgRecalled({ data: clone }));
return; // return;
}; // };
//#region Control Layers //#region Control Layers
const recallLayer: MetadataRecallFunc<CanvasRasterLayerState> = async (layer) => { const recallLayer: MetadataRecallFunc<CanvasRasterLayerState> = async (layer) => {

View File

@ -29,17 +29,23 @@ const validateBaseCompatibility = (base?: BaseModelType, message?: string) => {
const validateRefinerModel: MetadataValidateFunc<ParameterSDXLRefinerModel> = (refinerModel) => { const validateRefinerModel: MetadataValidateFunc<ParameterSDXLRefinerModel> = (refinerModel) => {
validateBaseCompatibility('sdxl', 'Refiner incompatible with currently-selected model'); validateBaseCompatibility('sdxl', 'Refiner incompatible with currently-selected model');
return new Promise((resolve) => resolve(refinerModel)); return new Promise((resolve) => {
resolve(refinerModel);
});
}; };
const validateVAEModel: MetadataValidateFunc<ParameterVAEModel> = (vaeModel) => { const validateVAEModel: MetadataValidateFunc<ParameterVAEModel> = (vaeModel) => {
validateBaseCompatibility(vaeModel.base, 'VAE incompatible with currently-selected model'); validateBaseCompatibility(vaeModel.base, 'VAE incompatible with currently-selected model');
return new Promise((resolve) => resolve(vaeModel)); return new Promise((resolve) => {
resolve(vaeModel);
});
}; };
const validateLoRA: MetadataValidateFunc<LoRA> = (lora) => { const validateLoRA: MetadataValidateFunc<LoRA> = (lora) => {
validateBaseCompatibility(lora.model.base, 'LoRA incompatible with currently-selected model'); validateBaseCompatibility(lora.model.base, 'LoRA incompatible with currently-selected model');
return new Promise((resolve) => resolve(lora)); return new Promise((resolve) => {
resolve(lora);
});
}; };
const validateLoRAs: MetadataValidateFunc<LoRA[]> = (loras) => { const validateLoRAs: MetadataValidateFunc<LoRA[]> = (loras) => {
@ -52,12 +58,16 @@ const validateLoRAs: MetadataValidateFunc<LoRA[]> = (loras) => {
// This is a no-op - we want to continue validating the rest of the LoRAs, and an empty list is valid. // This is a no-op - we want to continue validating the rest of the LoRAs, and an empty list is valid.
} }
}); });
return new Promise((resolve) => resolve(validatedLoRAs)); return new Promise((resolve) => {
resolve(validatedLoRAs);
});
}; };
const validateControlNet: MetadataValidateFunc<ControlNetConfigMetadata> = (controlNet) => { const validateControlNet: MetadataValidateFunc<ControlNetConfigMetadata> = (controlNet) => {
validateBaseCompatibility(controlNet.model?.base, 'ControlNet incompatible with currently-selected model'); validateBaseCompatibility(controlNet.model?.base, 'ControlNet incompatible with currently-selected model');
return new Promise((resolve) => resolve(controlNet)); return new Promise((resolve) => {
resolve(controlNet);
});
}; };
const validateControlNets: MetadataValidateFunc<ControlNetConfigMetadata[]> = (controlNets) => { const validateControlNets: MetadataValidateFunc<ControlNetConfigMetadata[]> = (controlNets) => {
@ -70,12 +80,16 @@ const validateControlNets: MetadataValidateFunc<ControlNetConfigMetadata[]> = (c
// This is a no-op - we want to continue validating the rest of the ControlNets, and an empty list is valid. // This is a no-op - we want to continue validating the rest of the ControlNets, and an empty list is valid.
} }
}); });
return new Promise((resolve) => resolve(validatedControlNets)); return new Promise((resolve) => {
resolve(validatedControlNets);
});
}; };
const validateT2IAdapter: MetadataValidateFunc<T2IAdapterConfigMetadata> = (t2iAdapter) => { const validateT2IAdapter: MetadataValidateFunc<T2IAdapterConfigMetadata> = (t2iAdapter) => {
validateBaseCompatibility(t2iAdapter.model?.base, 'T2I Adapter incompatible with currently-selected model'); validateBaseCompatibility(t2iAdapter.model?.base, 'T2I Adapter incompatible with currently-selected model');
return new Promise((resolve) => resolve(t2iAdapter)); return new Promise((resolve) => {
resolve(t2iAdapter);
});
}; };
const validateT2IAdapters: MetadataValidateFunc<T2IAdapterConfigMetadata[]> = (t2iAdapters) => { const validateT2IAdapters: MetadataValidateFunc<T2IAdapterConfigMetadata[]> = (t2iAdapters) => {
@ -88,12 +102,16 @@ const validateT2IAdapters: MetadataValidateFunc<T2IAdapterConfigMetadata[]> = (t
// This is a no-op - we want to continue validating the rest of the T2I Adapters, and an empty list is valid. // This is a no-op - we want to continue validating the rest of the T2I Adapters, and an empty list is valid.
} }
}); });
return new Promise((resolve) => resolve(validatedT2IAdapters)); return new Promise((resolve) => {
resolve(validatedT2IAdapters);
});
}; };
const validateIPAdapter: MetadataValidateFunc<IPAdapterConfigMetadata> = (ipAdapter) => { const validateIPAdapter: MetadataValidateFunc<IPAdapterConfigMetadata> = (ipAdapter) => {
validateBaseCompatibility(ipAdapter.model?.base, 'IP Adapter incompatible with currently-selected model'); validateBaseCompatibility(ipAdapter.model?.base, 'IP Adapter incompatible with currently-selected model');
return new Promise((resolve) => resolve(ipAdapter)); return new Promise((resolve) => {
resolve(ipAdapter);
});
}; };
const validateIPAdapters: MetadataValidateFunc<IPAdapterConfigMetadata[]> = (ipAdapters) => { const validateIPAdapters: MetadataValidateFunc<IPAdapterConfigMetadata[]> = (ipAdapters) => {
@ -106,10 +124,12 @@ const validateIPAdapters: MetadataValidateFunc<IPAdapterConfigMetadata[]> = (ipA
// This is a no-op - we want to continue validating the rest of the IP Adapters, and an empty list is valid. // This is a no-op - we want to continue validating the rest of the IP Adapters, and an empty list is valid.
} }
}); });
return new Promise((resolve) => resolve(validatedIPAdapters)); return new Promise((resolve) => {
resolve(validatedIPAdapters);
});
}; };
const validateLayer: MetadataValidateFunc<CanvasRasterLayerState> = async (layer) => { const validateLayer: MetadataValidateFunc<CanvasRasterLayerState> = (layer) => {
if (layer.type === 'control_adapter_layer') { if (layer.type === 'control_adapter_layer') {
const model = layer.controlAdapter.model; const model = layer.controlAdapter.model;
assert(model, 'Control Adapter layer missing model'); assert(model, 'Control Adapter layer missing model');
@ -141,7 +161,9 @@ const validateLayers: MetadataValidateFunc<CanvasRasterLayerState[]> = async (la
// This is a no-op - we want to continue validating the rest of the layers, and an empty list is valid. // This is a no-op - we want to continue validating the rest of the layers, and an empty list is valid.
} }
} }
return new Promise((resolve) => resolve(validatedLayers)); return new Promise((resolve) => {
resolve(validatedLayers);
});
}; };
export const validators = { export const validators = {

View File

@ -16,7 +16,7 @@ export const HuggingFaceForm = memo(() => {
const [_getHuggingFaceModels, { isLoading, data }] = useLazyGetHuggingFaceModelsQuery(); const [_getHuggingFaceModels, { isLoading, data }] = useLazyGetHuggingFaceModelsQuery();
const [installModel] = useInstallModel(); const [installModel] = useInstallModel();
const getModels = useCallback(async () => { const getModels = useCallback(() => {
_getHuggingFaceModels(huggingFaceRepo) _getHuggingFaceModels(huggingFaceRepo)
.unwrap() .unwrap()
.then((response) => { .then((response) => {

View File

@ -16,7 +16,7 @@ export const ScanModelsForm = memo(() => {
const [_scanFolder, { isLoading, data }] = useLazyScanFolderQuery(); const [_scanFolder, { isLoading, data }] = useLazyScanFolderQuery();
const scanFolder = useCallback(async () => { const scanFolder = useCallback(() => {
_scanFolder({ scan_path: scanPath }) _scanFolder({ scan_path: scanPath })
.unwrap() .unwrap()
.catch((error) => { .catch((error) => {

View File

@ -38,7 +38,7 @@ const EditableFieldTitle = forwardRef((props: Props, ref) => {
const [localTitle, setLocalTitle] = useState(label || fieldTemplateTitle || t('nodes.unknownField')); const [localTitle, setLocalTitle] = useState(label || fieldTemplateTitle || t('nodes.unknownField'));
const handleSubmit = useCallback( const handleSubmit = useCallback(
async (newTitleRaw: string) => { (newTitleRaw: string) => {
const newTitle = newTitleRaw.trim(); const newTitle = newTitleRaw.trim();
const finalTitle = newTitle || fieldTemplateTitle || t('nodes.unknownField'); const finalTitle = newTitle || fieldTemplateTitle || t('nodes.unknownField');
setLocalTitle(finalTitle); setLocalTitle(finalTitle);

View File

@ -22,7 +22,7 @@ const NodeTitle = ({ nodeId, title }: Props) => {
const [localTitle, setLocalTitle] = useState(''); const [localTitle, setLocalTitle] = useState('');
const handleSubmit = useCallback( const handleSubmit = useCallback(
async (newTitle: string) => { (newTitle: string) => {
dispatch(nodeLabelChanged({ nodeId, label: newTitle })); dispatch(nodeLabelChanged({ nodeId, label: newTitle }));
setLocalTitle(label || title || templateTitle || t('nodes.problemSettingTitle')); setLocalTitle(label || title || templateTitle || t('nodes.problemSettingTitle'));
}, },

View File

@ -13,7 +13,7 @@ const SaveWorkflowButton = () => {
const { onOpen } = useSaveWorkflowAsDialog(); const { onOpen } = useSaveWorkflowAsDialog();
const { saveWorkflow } = useSaveLibraryWorkflow(); const { saveWorkflow } = useSaveLibraryWorkflow();
const handleClickSave = useCallback(async () => { const handleClickSave = useCallback(() => {
const builtWorkflow = $builtWorkflow.get(); const builtWorkflow = $builtWorkflow.get();
if (!builtWorkflow) { if (!builtWorkflow) {
return; return;

View File

@ -19,7 +19,7 @@ const EditableNodeTitle = ({ nodeId, title }: Props) => {
const [localTitle, setLocalTitle] = useState(''); const [localTitle, setLocalTitle] = useState('');
const handleSubmit = useCallback( const handleSubmit = useCallback(
async (newTitle: string) => { (newTitle: string) => {
dispatch(nodeLabelChanged({ nodeId, label: newTitle })); dispatch(nodeLabelChanged({ nodeId, label: newTitle }));
setLocalTitle(label || title || templateTitle || t('nodes.problemSettingTitle')); setLocalTitle(label || title || templateTitle || t('nodes.problemSettingTitle'));
}, },

View File

@ -267,7 +267,7 @@ const specialCases: ParseFieldTypeTestCase[] = [
}, },
]; ];
describe('refObjectToSchemaName', async () => { describe('refObjectToSchemaName', () => {
it('parses ref object 1', () => { it('parses ref object 1', () => {
expect( expect(
refObjectToSchemaName({ refObjectToSchemaName({
@ -284,7 +284,7 @@ describe('refObjectToSchemaName', async () => {
}); });
}); });
describe.concurrent('parseFieldType', async () => { describe.concurrent('parseFieldType', () => {
it.each(primitiveTypes)('parses primitive types ($name)', ({ schema, expected }: ParseFieldTypeTestCase) => { it.each(primitiveTypes)('parses primitive types ($name)', ({ schema, expected }: ParseFieldTypeTestCase) => {
expect(parseFieldType(schema)).toEqual(expected); expect(parseFieldType(schema)).toEqual(expected);
}); });

View File

@ -78,8 +78,14 @@ describe('validateWorkflow', () => {
], ],
edges: [], edges: [],
}; };
const resolveTrue = async (): Promise<boolean> => new Promise((resolve) => resolve(true)); const resolveTrue = (): Promise<boolean> =>
const resolveFalse = async (): Promise<boolean> => new Promise((resolve) => resolve(false)); new Promise((resolve) => {
resolve(true);
});
const resolveFalse = (): Promise<boolean> =>
new Promise((resolve) => {
resolve(false);
});
it('should reset images that are inaccessible', async () => { it('should reset images that are inaccessible', async () => {
const validationResult = await validateWorkflow( const validationResult = await validateWorkflow(
workflow, workflow,

View File

@ -41,7 +41,7 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
[preset] [preset]
); );
const handleClickApply = useCallback(async () => { const handleClickApply = useCallback(() => {
dispatch(activeStylePresetIdChanged(preset.id)); dispatch(activeStylePresetIdChanged(preset.id));
$isMenuOpen.set(false); $isMenuOpen.set(false);
}, [dispatch, preset.id]); }, [dispatch, preset.id]);

View File

@ -1,4 +1,3 @@
import { useAppDispatch } from 'app/store/storeHooks';
import { toast } from 'features/toast/toast'; import { toast } from 'features/toast/toast';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -15,7 +14,6 @@ type UseClearIntermediatesReturn = {
export const useClearIntermediates = (shouldShowClearIntermediates: boolean): UseClearIntermediatesReturn => { export const useClearIntermediates = (shouldShowClearIntermediates: boolean): UseClearIntermediatesReturn => {
const { t } = useTranslation(); const { t } = useTranslation();
const dispatch = useAppDispatch();
const { data: intermediatesCount, refetch: refetchIntermediatesCount } = useGetIntermediatesCountQuery(undefined, { const { data: intermediatesCount, refetch: refetchIntermediatesCount } = useGetIntermediatesCountQuery(undefined, {
refetchOnMountOrArgChange: true, refetchOnMountOrArgChange: true,
@ -54,7 +52,7 @@ export const useClearIntermediates = (shouldShowClearIntermediates: boolean): Us
status: 'error', status: 'error',
}); });
}); });
}, [t, _clearIntermediates, dispatch, hasPendingItems]); }, [t, _clearIntermediates, hasPendingItems]);
return { intermediatesCount, clearIntermediates, isLoading, hasPendingItems, refetchIntermediatesCount }; return { intermediatesCount, clearIntermediates, isLoading, hasPendingItems, refetchIntermediatesCount };
}; };

View File

@ -1,8 +1,8 @@
import { IconButton, Tooltip } from '@invoke-ai/ui-library'; import { IconButton, Tooltip } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import type { TabName } from "../store/uiTypes";
import { selectActiveTab } from 'features/ui/store/uiSelectors'; import { selectActiveTab } from 'features/ui/store/uiSelectors';
import { setActiveTab } from 'features/ui/store/uiSlice'; import { setActiveTab } from 'features/ui/store/uiSlice';
import type { TabName } from "features/ui/store/uiTypes";
import { memo, type ReactElement, useCallback } from 'react'; import { memo, type ReactElement, useCallback } from 'react';
export const TabButton = memo(({ tab, icon, label }: { tab: TabName; icon: ReactElement; label: string }) => { export const TabButton = memo(({ tab, icon, label }: { tab: TabName; icon: ReactElement; label: string }) => {

View File

@ -1,7 +1,7 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { selectConfigSlice } from 'features/system/store/configSlice'; import { selectConfigSlice } from 'features/system/store/configSlice';
import type { TabName } from "../store/uiTypes"; import type { TabName } from "features/ui/store/uiTypes";
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { memo, useMemo } from 'react'; import { memo, useMemo } from 'react';

View File

@ -1,6 +1,6 @@
import { Box } from '@invoke-ai/ui-library'; import { Box } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import type { TabName } from "../store/uiTypes"; import type { TabName } from "features/ui/store/uiTypes";
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { memo } from 'react'; import { memo } from 'react';

View File

@ -4,8 +4,7 @@ import type { PersistConfig, RootState } from 'app/store/store';
import { workflowLoadRequested } from 'features/nodes/store/actions'; import { workflowLoadRequested } from 'features/nodes/store/actions';
import { atom } from 'nanostores'; import { atom } from 'nanostores';
import type { TabName } from "./uiTypes"; import type { TabName , UIState } from "./uiTypes";
import type { UIState } from './uiTypes';
const initialUIState: UIState = { const initialUIState: UIState = {
_version: 2, _version: 2,

View File

@ -13,7 +13,7 @@ const SaveWorkflowMenuItem = () => {
const { onOpen } = useSaveWorkflowAsDialog(); const { onOpen } = useSaveWorkflowAsDialog();
const isTouched = useAppSelector((s) => s.workflow.isTouched); const isTouched = useAppSelector((s) => s.workflow.isTouched);
const handleClickSave = useCallback(async () => { const handleClickSave = useCallback(() => {
const builtWorkflow = $builtWorkflow.get(); const builtWorkflow = $builtWorkflow.get();
if (!builtWorkflow) { if (!builtWorkflow) {
return; return;

View File

@ -16,7 +16,7 @@ type UseLoadWorkflowFromFile = (options: useLoadWorkflowFromFileOptions) => (fil
export const useLoadWorkflowFromFile: UseLoadWorkflowFromFile = ({ resetRef, onSuccess }) => { export const useLoadWorkflowFromFile: UseLoadWorkflowFromFile = ({ resetRef, onSuccess }) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const logger = useLogger('nodes'); const logger = useLogger('workflows');
const { t } = useTranslation(); const { t } = useTranslation();
const loadWorkflowFromFile = useCallback( const loadWorkflowFromFile = useCallback(
(file: File | null) => { (file: File | null) => {
@ -24,7 +24,7 @@ export const useLoadWorkflowFromFile: UseLoadWorkflowFromFile = ({ resetRef, onS
return; return;
} }
const reader = new FileReader(); const reader = new FileReader();
reader.onload = async () => { reader.onload = () => {
const rawJSON = reader.result; const rawJSON = reader.result;
try { try {

View File

@ -52,7 +52,7 @@ export const imagesApi = api.injectEndpoints({
'FetchOnReconnect', 'FetchOnReconnect',
]; ];
}, },
async onQueryStarted(_, { dispatch, queryFulfilled }) { onQueryStarted(_, { dispatch, queryFulfilled }) {
// Populate the getImageDTO cache with these images. This makes image selection smoother, because it doesn't // Populate the getImageDTO cache with these images. This makes image selection smoother, because it doesn't
// need to re-fetch image data when the user selects an image. The getImageDTO cache keeps data for the default // need to re-fetch image data when the user selects an image. The getImageDTO cache keeps data for the default
// of 60s, so this data won't stick around too long. // of 60s, so this data won't stick around too long.

View File

@ -245,7 +245,7 @@ export const modelsApi = api.injectEndpoints({
transformResponse: (response: GetModelConfigsResponse) => { transformResponse: (response: GetModelConfigsResponse) => {
return modelConfigsAdapter.setAll(modelConfigsAdapter.getInitialState(), response.models); return modelConfigsAdapter.setAll(modelConfigsAdapter.getInitialState(), response.models);
}, },
onQueryStarted: async (_, { dispatch, queryFulfilled }) => { onQueryStarted: (_, { dispatch, queryFulfilled }) => {
queryFulfilled.then(({ data }) => { queryFulfilled.then(({ data }) => {
modelConfigsAdapterSelectors.selectAll(data).forEach((modelConfig) => { modelConfigsAdapterSelectors.selectAll(data).forEach((modelConfig) => {
dispatch(modelsApi.util.upsertQueryData('getModelConfig', modelConfig.key, modelConfig)); dispatch(modelsApi.util.upsertQueryData('getModelConfig', modelConfig.key, modelConfig));

View File

@ -49,11 +49,7 @@ const tagTypes = [
export type ApiTagDescription = TagDescription<(typeof tagTypes)[number]>; export type ApiTagDescription = TagDescription<(typeof tagTypes)[number]>;
export const LIST_TAG = 'LIST'; export const LIST_TAG = 'LIST';
const dynamicBaseQuery: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async ( const dynamicBaseQuery: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = (args, api, extraOptions) => {
args,
api,
extraOptions
) => {
const baseUrl = $baseUrl.get(); const baseUrl = $baseUrl.get();
const authToken = $authToken.get(); const authToken = $authToken.get();
const projectId = $projectId.get(); const projectId = $projectId.get();