diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptTriggerListChanged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptTriggerListChanged.ts index 68f0628f16..67d92d217e 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptTriggerListChanged.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/promptTriggerListChanged.ts @@ -1,3 +1,4 @@ +import type { ComboboxOption } from '@invoke-ai/ui-library'; import { isAnyOf } from '@reduxjs/toolkit'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import { loraAdded, loraIsEnabledChanged, loraRecalled, loraRemoved } from 'features/lora/store/loraSlice'; @@ -15,7 +16,7 @@ export const addPromptTriggerListChanged = (startAppListening: AppStartListening const { model: mainModel } = state.generation; const { loras } = state.lora; - let triggerPhrases: string[] = []; + let triggerPhrases: ComboboxOption[] = []; if (!mainModel) { dispatch(triggerPhrasesChanged([])); @@ -23,13 +24,19 @@ export const addPromptTriggerListChanged = (startAppListening: AppStartListening } const { data: mainModelData } = await dispatch(modelsApi.endpoints.getModelMetadata.initiate(mainModel.key)); - triggerPhrases = mainModelData?.trigger_phrases || []; + triggerPhrases = (mainModelData?.trigger_phrases || []).map((phrase) => ({ label: phrase, value: phrase })); for (let index = 0; index < Object.values(loras).length; index++) { const lora = Object.values(loras)[index]; if (lora && lora.isEnabled) { - const { data: loraData } = await dispatch(modelsApi.endpoints.getModelMetadata.initiate(lora.model.key)); - triggerPhrases = [...triggerPhrases, ...(loraData?.trigger_phrases || [])]; + const { data: loraMetadata } = await dispatch(modelsApi.endpoints.getModelMetadata.initiate(lora.model.key)); + const { data: loraConfig } = modelsApi.endpoints.getModelConfig.select(lora.model.key)(state); + const loraTriggerPhrases = (loraMetadata?.trigger_phrases || []).map((phrase) => ({ + label: phrase, + value: phrase, + description: loraConfig?.name ? `(${loraConfig?.name})` : '', + })); + triggerPhrases = [...triggerPhrases, ...loraTriggerPhrases]; } } diff --git a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/DefaultSettings.tsx b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/DefaultSettings.tsx index 1ea1221d93..70d7f99980 100644 --- a/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/DefaultSettings.tsx +++ b/invokeai/frontend/web/src/features/modelManagerV2/subpanels/ModelPanel/DefaultSettings.tsx @@ -1,11 +1,12 @@ +import { Text } from '@invoke-ai/ui-library'; import { skipToken } from '@reduxjs/toolkit/query'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { useAppSelector } from 'app/store/storeHooks'; -import Loading from 'common/components/Loading/Loading'; import { selectConfigSlice } from 'features/system/store/configSlice'; import { isNil } from 'lodash-es'; import { useMemo } from 'react'; -import { useGetModelConfigQuery } from 'services/api/endpoints/models'; +import { useTranslation } from 'react-i18next'; +import { useGetModelConfigQuery } from 'services/api/endpoints/models'; import { DefaultSettingsForm } from './DefaultSettings/DefaultSettingsForm'; @@ -23,6 +24,7 @@ const initialStatesSelector = createMemoizedSelector(selectConfigSlice, (config) export const DefaultSettings = () => { const selectedModelKey = useAppSelector((s) => s.modelmanagerV2.selectedModelKey); + const { t } = useTranslation(); const { data, isLoading } = useGetModelConfigQuery(selectedModelKey ?? skipToken); const { initialSteps, initialCfg, initialScheduler, initialCfgRescaleMultiplier, initialVaePrecision } = @@ -59,7 +61,7 @@ export const DefaultSettings = () => { ]); if (isLoading) { - return ; + return {t('common.loading')}; } return ; diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 1be5460e03..14289aae5f 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -1,3 +1,4 @@ +import type { ComboboxOption } from '@invoke-ai/ui-library'; import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import type { PersistConfig, RootState } from 'app/store/store'; @@ -208,7 +209,7 @@ export const generationSlice = createSlice({ aspectRatioChanged: (state, action: PayloadAction) => { state.aspectRatio = action.payload; }, - triggerPhrasesChanged: (state, action: PayloadAction) => { + triggerPhrasesChanged: (state, action: PayloadAction) => { state.triggerPhrases = action.payload; }, }, diff --git a/invokeai/frontend/web/src/features/parameters/store/types.ts b/invokeai/frontend/web/src/features/parameters/store/types.ts index 823f329e28..7930110a2e 100644 --- a/invokeai/frontend/web/src/features/parameters/store/types.ts +++ b/invokeai/frontend/web/src/features/parameters/store/types.ts @@ -1,3 +1,4 @@ +import type { ComboboxOption } from '@invoke-ai/ui-library'; import type { PayloadAction } from '@reduxjs/toolkit'; import type { AspectRatioState } from 'features/parameters/components/ImageSize/types'; import type { @@ -51,7 +52,7 @@ export interface GenerationState { shouldUseCpuNoise: boolean; shouldShowAdvancedOptions: boolean; aspectRatio: AspectRatioState; - triggerPhrases: string[]; + triggerPhrases: ComboboxOption[]; } export type PayloadActionWithOptimalDimension = PayloadAction; diff --git a/invokeai/frontend/web/src/features/prompt/PromptTriggerSelect.tsx b/invokeai/frontend/web/src/features/prompt/PromptTriggerSelect.tsx index e148005bf0..3c3311ac06 100644 --- a/invokeai/frontend/web/src/features/prompt/PromptTriggerSelect.tsx +++ b/invokeai/frontend/web/src/features/prompt/PromptTriggerSelect.tsx @@ -48,7 +48,7 @@ export const PromptTriggerSelect = memo(({ onSelect, onClose }: PromptTriggerSel const metadataOptions = [ { label: t('modelManager.triggerPhrases'), - options: triggerPhrases.map((phrase) => ({ label: phrase, value: phrase })), + options: triggerPhrases, }, ]; return [...metadataOptions, ...embeddingOptions];