diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts
index 23244d9a80..8c5873903c 100644
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts
@@ -8,6 +8,7 @@ import {
import type { AppDispatch, RootState } from '../../store';
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
+import { addAppConfigReceivedListener } from './listeners/appConfigReceived';
import { addAppStartedListener } from './listeners/appStarted';
import { addBoardIdSelectedListener } from './listeners/boardIdSelected';
import { addRequestedBoardImageDeletionListener } from './listeners/boardImagesDeleted';
@@ -226,3 +227,4 @@ addModelSelectedListener();
// app startup
addAppStartedListener();
addModelsLoadedListener();
+addAppConfigReceivedListener();
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts
new file mode 100644
index 0000000000..68148a192f
--- /dev/null
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/appConfigReceived.ts
@@ -0,0 +1,17 @@
+import { setInfillMethod } from 'features/parameters/store/generationSlice';
+import { appInfoApi } from 'services/api/endpoints/appInfo';
+import { startAppListening } from '..';
+
+export const addAppConfigReceivedListener = () => {
+ startAppListening({
+ matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled,
+ effect: async (action, { getState, dispatch }) => {
+ const { infill_methods } = action.payload;
+ const infillMethod = getState().generation.infillMethod;
+
+ if (!infill_methods.includes(infillMethod)) {
+ dispatch(setInfillMethod(infill_methods[0]));
+ }
+ },
+ });
+};
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx
index 2034f11f61..9ac0e3588f 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamInfillMethod.tsx
@@ -1,25 +1,21 @@
import { createSelector } from '@reduxjs/toolkit';
+import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
-import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setInfillMethod } from 'features/parameters/store/generationSlice';
-import { systemSelector } from 'features/system/store/systemSelectors';
-import { memo, useCallback, useEffect, useMemo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
-import { useGetAppConfigQuery } from '../../../../../../services/api/endpoints/appInfo';
-import { setAvailableInfillMethods } from '../../../../../system/store/systemSlice';
+import { useGetAppConfigQuery } from 'services/api/endpoints/appInfo';
const selector = createSelector(
- [generationSelector, systemSelector],
- (parameters, system) => {
- const { infillMethod } = parameters;
- const { infillMethods } = system;
+ [stateSelector],
+ ({ generation }) => {
+ const { infillMethod } = generation;
return {
infillMethod,
- infillMethods,
};
},
defaultSelectorOptions
@@ -27,9 +23,11 @@ const selector = createSelector(
const ParamInfillMethod = () => {
const dispatch = useAppDispatch();
- const { infillMethod, infillMethods } = useAppSelector(selector);
+ const { infillMethod } = useAppSelector(selector);
- const { data: appConfigData } = useGetAppConfigQuery();
+ const { data: appConfigData, isLoading } = useGetAppConfigQuery();
+
+ const infill_methods = appConfigData?.infill_methods;
const { t } = useTranslation();
@@ -40,24 +38,13 @@ const ParamInfillMethod = () => {
[dispatch]
);
- useEffect(() => {
- if (!appConfigData) return;
- if (!appConfigData.patchmatch_enabled) {
- const filteredMethods = infillMethods.filter(
- (method) => method !== 'patchmatch'
- );
- dispatch(setAvailableInfillMethods(filteredMethods));
- dispatch(setInfillMethod(filteredMethods[0]));
- } else {
- dispatch(setInfillMethod('patchmatch'));
- }
- }, [appConfigData, infillMethods, dispatch]);
-
return (
);
diff --git a/invokeai/frontend/web/src/features/system/store/systemSlice.ts b/invokeai/frontend/web/src/features/system/store/systemSlice.ts
index 041cb34a34..01c1344263 100644
--- a/invokeai/frontend/web/src/features/system/store/systemSlice.ts
+++ b/invokeai/frontend/web/src/features/system/store/systemSlice.ts
@@ -4,8 +4,14 @@ import * as InvokeAI from 'app/types/invokeai';
import { InvokeLogLevel } from 'app/logging/useLogger';
import { userInvoked } from 'app/store/actions';
+import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
import { TFuncKey, t } from 'i18next';
import { LogLevelName } from 'roarr';
+import { imageUploaded } from 'services/api/thunks/image';
+import {
+ isAnySessionRejected,
+ sessionCanceled,
+} from 'services/api/thunks/session';
import {
appSocketConnected,
appSocketDisconnected,
@@ -18,19 +24,11 @@ import {
appSocketUnsubscribed,
} from 'services/events/actions';
import { ProgressImage } from 'services/events/types';
-import { imageUploaded } from 'services/api/thunks/image';
-import {
- isAnySessionRejected,
- sessionCanceled,
-} from 'services/api/thunks/session';
import { makeToast } from '../../../app/components/Toaster';
import { LANGUAGES } from '../components/LanguagePicker';
-import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
export type CancelStrategy = 'immediate' | 'scheduled';
-export type InfillMethod = 'tile' | 'patchmatch';
-
export interface SystemState {
isGFPGANAvailable: boolean;
isESRGANAvailable: boolean;
@@ -87,10 +85,6 @@ export interface SystemState {
* When a session is canceled, its ID is stored here until a new session is created.
*/
canceledSession: string;
- /**
- * TODO: get this from backend
- */
- infillMethods: InfillMethod[];
isPersisted: boolean;
shouldAntialiasProgressImage: boolean;
language: keyof typeof LANGUAGES;
@@ -128,7 +122,6 @@ export const initialSystemState: SystemState = {
shouldLogToConsole: true,
statusTranslationKey: 'common.statusDisconnected',
canceledSession: '',
- infillMethods: ['tile', 'patchmatch'],
isPersisted: false,
language: 'en',
isUploading: false,
@@ -219,9 +212,6 @@ export const systemSlice = createSlice({
progressImageSet(state, action: PayloadAction) {
state.progressImage = action.payload;
},
- setAvailableInfillMethods(state, action: PayloadAction) {
- state.infillMethods = action.payload;
- },
},
extraReducers(builder) {
/**
@@ -454,7 +444,6 @@ export const {
shouldAntialiasProgressImageChanged,
languageChanged,
progressImageSet,
- setAvailableInfillMethods,
} = systemSlice.actions;
export default systemSlice.reducer;
diff --git a/invokeai/frontend/web/src/services/api/endpoints/appInfo.ts b/invokeai/frontend/web/src/services/api/endpoints/appInfo.ts
index 29f94c8bb2..f76b56761c 100644
--- a/invokeai/frontend/web/src/services/api/endpoints/appInfo.ts
+++ b/invokeai/frontend/web/src/services/api/endpoints/appInfo.ts
@@ -1,5 +1,5 @@
import { api } from '..';
-import { AppVersion, AppConfig } from '../types';
+import { AppConfig, AppVersion } from '../types';
export const appInfoApi = api.injectEndpoints({
endpoints: (build) => ({
@@ -8,12 +8,14 @@ export const appInfoApi = api.injectEndpoints({
url: `app/version`,
method: 'GET',
}),
+ keepUnusedDataFor: 86400000, // 1 day
}),
getAppConfig: build.query({
query: () => ({
url: `app/config`,
method: 'GET',
}),
+ keepUnusedDataFor: 86400000, // 1 day
}),
}),
});