mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
tidy(ui): remove unused stuff 4
This commit is contained in:
parent
1a14860b3b
commit
2568441e6a
@ -18,7 +18,7 @@ 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 { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "features/ui/store/uiTypes";
|
||||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||||
import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow';
|
import { useGetAndLoadLibraryWorkflow } from 'features/workflowLibrary/hooks/useGetAndLoadLibraryWorkflow';
|
||||||
import { AnimatePresence } from 'framer-motion';
|
import { AnimatePresence } from 'framer-motion';
|
||||||
@ -40,7 +40,7 @@ interface Props {
|
|||||||
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
||||||
};
|
};
|
||||||
selectedWorkflowId?: string;
|
selectedWorkflowId?: string;
|
||||||
destination?: InvokeTabName | undefined;
|
destination?: TabName | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflowId, destination }: Props) => {
|
const App = ({ config = DEFAULT_CONFIG, selectedImage, selectedWorkflowId, destination }: Props) => {
|
||||||
|
@ -19,7 +19,7 @@ import type { PartialAppConfig } from 'app/types/invokeai';
|
|||||||
import Loading from 'common/components/Loading/Loading';
|
import Loading from 'common/components/Loading/Loading';
|
||||||
import AppDndContext from 'features/dnd/components/AppDndContext';
|
import AppDndContext from 'features/dnd/components/AppDndContext';
|
||||||
import type { WorkflowCategory } from 'features/nodes/types/workflow';
|
import type { WorkflowCategory } from 'features/nodes/types/workflow';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "features/ui/store/uiTypes";
|
||||||
import type { PropsWithChildren, ReactNode } from 'react';
|
import type { PropsWithChildren, ReactNode } from 'react';
|
||||||
import React, { lazy, memo, useEffect, useMemo } from 'react';
|
import React, { lazy, memo, useEffect, useMemo } from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
@ -45,7 +45,7 @@ interface Props extends PropsWithChildren {
|
|||||||
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
action: 'sendToImg2Img' | 'sendToCanvas' | 'useAllParameters';
|
||||||
};
|
};
|
||||||
selectedWorkflowId?: string;
|
selectedWorkflowId?: string;
|
||||||
destination?: InvokeTabName;
|
destination?: TabName;
|
||||||
customStarUi?: CustomStarUi;
|
customStarUi?: CustomStarUi;
|
||||||
socketOptions?: Partial<ManagerOptions & SocketOptions>;
|
socketOptions?: Partial<ManagerOptions & SocketOptions>;
|
||||||
isDebugging?: boolean;
|
isDebugging?: boolean;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createAction } from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "features/ui/store/uiTypes";
|
||||||
|
|
||||||
export const enqueueRequested = createAction<{
|
export const enqueueRequested = createAction<{
|
||||||
tabName: InvokeTabName;
|
tabName: TabName;
|
||||||
prepend: boolean;
|
prepend: boolean;
|
||||||
}>('app/enqueueRequested');
|
}>('app/enqueueRequested');
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||||
import { ipaAllDeleted, rasterLayerAllDeleted } from 'features/controlLayers/store/canvasV2Slice';
|
|
||||||
import { getImageUsage } from 'features/deleteImageModal/store/selectors';
|
import { getImageUsage } from 'features/deleteImageModal/store/selectors';
|
||||||
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
@ -7,39 +6,22 @@ import { imagesApi } from 'services/api/endpoints/images';
|
|||||||
export const addDeleteBoardAndImagesFulfilledListener = (startAppListening: AppStartListening) => {
|
export const addDeleteBoardAndImagesFulfilledListener = (startAppListening: AppStartListening) => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
matcher: imagesApi.endpoints.deleteBoardAndImages.matchFulfilled,
|
matcher: imagesApi.endpoints.deleteBoardAndImages.matchFulfilled,
|
||||||
effect: async (action, { dispatch, getState }) => {
|
effect: (action, { dispatch, getState }) => {
|
||||||
const { deleted_images } = action.payload;
|
const { deleted_images } = action.payload;
|
||||||
|
|
||||||
// Remove all deleted images from the UI
|
// Remove all deleted images from the UI
|
||||||
|
|
||||||
let wereLayersReset = false;
|
|
||||||
let wasNodeEditorReset = false;
|
let wasNodeEditorReset = false;
|
||||||
const wereControlAdaptersReset = false;
|
|
||||||
let wereIPAdaptersReset = false;
|
|
||||||
|
|
||||||
const { nodes, canvasV2 } = getState();
|
const { nodes, canvasV2 } = getState();
|
||||||
|
|
||||||
deleted_images.forEach((image_name) => {
|
deleted_images.forEach((image_name) => {
|
||||||
const imageUsage = getImageUsage(nodes.present, canvasV2, image_name);
|
const imageUsage = getImageUsage(nodes.present, canvasV2, image_name);
|
||||||
|
|
||||||
if (imageUsage.isLayerImage && !wereLayersReset) {
|
|
||||||
dispatch(rasterLayerAllDeleted());
|
|
||||||
wereLayersReset = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imageUsage.isNodesImage && !wasNodeEditorReset) {
|
if (imageUsage.isNodesImage && !wasNodeEditorReset) {
|
||||||
dispatch(nodeEditorReset());
|
dispatch(nodeEditorReset());
|
||||||
wasNodeEditorReset = true;
|
wasNodeEditorReset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (imageUsage.isControlAdapterImage && !wereControlAdaptersReset) {
|
|
||||||
// dispatch(caAllDeleted());
|
|
||||||
// wereControlAdaptersReset = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (imageUsage.isIPAdapterImage && !wereIPAdaptersReset) {
|
|
||||||
dispatch(ipaAllDeleted());
|
|
||||||
wereIPAdaptersReset = true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { FilterType } from 'features/controlLayers/store/types';
|
import type { FilterType } from 'features/controlLayers/store/types';
|
||||||
import type { ParameterPrecision, ParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
import type { ParameterPrecision, ParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "features/ui/store/uiTypes";
|
||||||
import type { O } from 'ts-toolbelt';
|
import type { O } from 'ts-toolbelt';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +72,7 @@ export type AppConfig = {
|
|||||||
maxUpscaleDimension?: number;
|
maxUpscaleDimension?: number;
|
||||||
allowPrivateBoards: boolean;
|
allowPrivateBoards: boolean;
|
||||||
allowPrivateStylePresets: boolean;
|
allowPrivateStylePresets: boolean;
|
||||||
disabledTabs: InvokeTabName[];
|
disabledTabs: TabName[];
|
||||||
disabledFeatures: AppFeature[];
|
disabledFeatures: AppFeature[];
|
||||||
disabledSDFeatures: SDFeature[];
|
disabledSDFeatures: SDFeature[];
|
||||||
nodesAllowlist: string[] | undefined;
|
nodesAllowlist: string[] | undefined;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import type { Accept, FileRejection } from 'react-dropzone';
|
import type { Accept, FileRejection } from 'react-dropzone';
|
||||||
import { useDropzone } from 'react-dropzone';
|
import { useDropzone } from 'react-dropzone';
|
||||||
@ -14,7 +14,7 @@ const accept: Accept = {
|
|||||||
'image/jpeg': ['.jpg', '.jpeg', '.png'],
|
'image/jpeg': ['.jpg', '.jpeg', '.png'],
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectPostUploadAction = createMemoizedSelector(activeTabNameSelector, (activeTabName) => {
|
const selectPostUploadAction = createMemoizedSelector(selectActiveTab, (activeTabName) => {
|
||||||
let postUploadAction: PostUploadAction = { type: 'TOAST' };
|
let postUploadAction: PostUploadAction = { type: 'TOAST' };
|
||||||
|
|
||||||
if (activeTabName === 'upscaling') {
|
if (activeTabName === 'upscaling') {
|
||||||
|
@ -12,7 +12,7 @@ import { isInvocationNode } from 'features/nodes/types/invocation';
|
|||||||
import { selectUpscalelice } from 'features/parameters/store/upscaleSlice';
|
import { selectUpscalelice } from 'features/parameters/store/upscaleSlice';
|
||||||
import { selectConfigSlice } from 'features/system/store/configSlice';
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import { forEach, upperFirst } from 'lodash-es';
|
import { forEach, upperFirst } from 'lodash-es';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
@ -36,7 +36,7 @@ const createSelector = (templates: Templates, isConnected: boolean) =>
|
|||||||
selectCanvasV2Slice,
|
selectCanvasV2Slice,
|
||||||
selectUpscalelice,
|
selectUpscalelice,
|
||||||
selectConfigSlice,
|
selectConfigSlice,
|
||||||
activeTabNameSelector,
|
selectActiveTab,
|
||||||
],
|
],
|
||||||
(system, nodes, workflowSettings, dynamicPrompts, canvasV2, upscale, config, activeTabName) => {
|
(system, nodes, workflowSettings, dynamicPrompts, canvasV2, upscale, config, activeTabName) => {
|
||||||
const { bbox } = canvasV2;
|
const { bbox } = canvasV2;
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
import { PubSub } from 'common/util/PubSub/PubSub';
|
|
||||||
import { describe, expect, it, vi } from 'vitest';
|
|
||||||
|
|
||||||
describe('PubSub', () => {
|
|
||||||
it('should call listener when value is published and value changes', () => {
|
|
||||||
const pubsub = new PubSub<number>(1);
|
|
||||||
const listener = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener);
|
|
||||||
pubsub.publish(42);
|
|
||||||
|
|
||||||
expect(listener).toHaveBeenCalledWith(42, 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not call listener if value does not change', () => {
|
|
||||||
const pubsub = new PubSub<number>(42);
|
|
||||||
const listener = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener);
|
|
||||||
pubsub.publish(42);
|
|
||||||
|
|
||||||
expect(listener).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle non-primitive values', () => {
|
|
||||||
const pubsub = new PubSub<{ foo: string }>({ foo: 'bar' });
|
|
||||||
const listener = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener);
|
|
||||||
pubsub.publish({ foo: 'bar' });
|
|
||||||
|
|
||||||
expect(listener).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call listener with old and new value', () => {
|
|
||||||
const pubsub = new PubSub<number>(1);
|
|
||||||
const listener = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener);
|
|
||||||
pubsub.publish(2);
|
|
||||||
|
|
||||||
expect(listener).toHaveBeenCalledWith(2, 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow unsubscribing', () => {
|
|
||||||
const pubsub = new PubSub<number>(1);
|
|
||||||
const listener1 = vi.fn();
|
|
||||||
const listener2 = vi.fn();
|
|
||||||
|
|
||||||
const unsubscribe = pubsub.subscribe(listener1);
|
|
||||||
pubsub.subscribe(listener2);
|
|
||||||
unsubscribe();
|
|
||||||
pubsub.publish(42);
|
|
||||||
|
|
||||||
expect(listener1).not.toHaveBeenCalled();
|
|
||||||
expect(listener2).toHaveBeenCalled();
|
|
||||||
expect(pubsub.getListeners().size).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should clear all listeners', () => {
|
|
||||||
const pubsub = new PubSub<number>(1);
|
|
||||||
const listener1 = vi.fn();
|
|
||||||
const listener2 = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener1);
|
|
||||||
pubsub.subscribe(listener2);
|
|
||||||
pubsub.off();
|
|
||||||
pubsub.publish(42);
|
|
||||||
|
|
||||||
expect(listener1).not.toHaveBeenCalled();
|
|
||||||
expect(listener2).not.toHaveBeenCalled();
|
|
||||||
expect(pubsub.getListeners().size).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use custom compareFn', () => {
|
|
||||||
const compareFn = (a: number, b: number) => Math.abs(a) === Math.abs(b);
|
|
||||||
const pubsub = new PubSub<number>(1, compareFn);
|
|
||||||
const listener = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener);
|
|
||||||
pubsub.publish(-1);
|
|
||||||
|
|
||||||
expect(listener).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle multiple listeners', () => {
|
|
||||||
const pubsub = new PubSub<number>(1);
|
|
||||||
const listener1 = vi.fn();
|
|
||||||
const listener2 = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener1);
|
|
||||||
pubsub.subscribe(listener2);
|
|
||||||
pubsub.publish(42);
|
|
||||||
|
|
||||||
expect(listener1).toHaveBeenCalledWith(42, 1);
|
|
||||||
expect(listener2).toHaveBeenCalledWith(42, 1);
|
|
||||||
expect(pubsub.getListeners().size).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get the current value', () => {
|
|
||||||
const pubsub = new PubSub<number>(42);
|
|
||||||
expect(pubsub.getValue()).toBe(42);
|
|
||||||
pubsub.publish(43);
|
|
||||||
expect(pubsub.getValue()).toBe(43);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get the listeners', () => {
|
|
||||||
const pubsub = new PubSub<number>(1);
|
|
||||||
const listener1 = vi.fn();
|
|
||||||
const listener2 = vi.fn();
|
|
||||||
|
|
||||||
pubsub.subscribe(listener1);
|
|
||||||
pubsub.subscribe(listener2);
|
|
||||||
|
|
||||||
expect(pubsub.getListeners()).toEqual(new Set([listener1, listener2]));
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,76 +0,0 @@
|
|||||||
export type Listener<T> = (newValue: T, oldValue: T) => void;
|
|
||||||
export type CompareFn<T> = (a: T, b: T) => boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple PubSub implementation.
|
|
||||||
*
|
|
||||||
* @template T The type of the value to be published.
|
|
||||||
* @param initialValue The initial value to publish.
|
|
||||||
*/
|
|
||||||
export class PubSub<T> {
|
|
||||||
private _listeners: Set<Listener<T>> = new Set();
|
|
||||||
private _oldValue: T;
|
|
||||||
private _compareFn: CompareFn<T>;
|
|
||||||
|
|
||||||
public constructor(initialValue: T, compareFn?: CompareFn<T>) {
|
|
||||||
this._oldValue = initialValue;
|
|
||||||
this._compareFn = compareFn || ((a, b) => a === b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribes to the PubSub.
|
|
||||||
* @param listener The listener to be called when the value is published.
|
|
||||||
* @returns A function that can be called to unsubscribe the listener.
|
|
||||||
*/
|
|
||||||
public subscribe = (listener: Listener<T>): (() => void) => {
|
|
||||||
this._listeners.add(listener);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
this.unsubscribe(listener);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribes a listener from the PubSub.
|
|
||||||
* @param listener The listener to unsubscribe.
|
|
||||||
*/
|
|
||||||
public unsubscribe = (listener: Listener<T>): void => {
|
|
||||||
this._listeners.delete(listener);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Publishes a new value to the PubSub.
|
|
||||||
* @param newValue The new value to publish.
|
|
||||||
*/
|
|
||||||
public publish = (newValue: T): void => {
|
|
||||||
if (!this._compareFn(this._oldValue, newValue)) {
|
|
||||||
for (const listener of this._listeners) {
|
|
||||||
listener(newValue, this._oldValue);
|
|
||||||
}
|
|
||||||
this._oldValue = newValue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears all listeners from the PubSub.
|
|
||||||
*/
|
|
||||||
public off = (): void => {
|
|
||||||
this._listeners.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current value of the PubSub.
|
|
||||||
* @returns The current value of the PubSub.
|
|
||||||
*/
|
|
||||||
public getValue = (): T | undefined => {
|
|
||||||
return this._oldValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the listeners of the PubSub.
|
|
||||||
* @returns The listeners of the PubSub.
|
|
||||||
*/
|
|
||||||
public getListeners = (): Set<Listener<T>> => {
|
|
||||||
return this._listeners;
|
|
||||||
};
|
|
||||||
}
|
|
@ -156,7 +156,7 @@ export function selectEntity(state: CanvasV2State, { id, type }: CanvasEntityIde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function selectAllEntitiesOfType(state: CanvasV2State, type: CanvasEntityState['type']): CanvasEntityState[] {
|
function selectAllEntitiesOfType(state: CanvasV2State, type: CanvasEntityState['type']): CanvasEntityState[] {
|
||||||
if (type === 'raster_layer') {
|
if (type === 'raster_layer') {
|
||||||
return state.rasterLayers.entities;
|
return state.rasterLayers.entities;
|
||||||
} else if (type === 'control_layer') {
|
} else if (type === 'control_layer') {
|
||||||
@ -474,12 +474,10 @@ export const {
|
|||||||
// Raster layers
|
// Raster layers
|
||||||
rasterLayerAdded,
|
rasterLayerAdded,
|
||||||
rasterLayerRecalled,
|
rasterLayerRecalled,
|
||||||
rasterLayerAllDeleted,
|
|
||||||
rasterLayerConvertedToControlLayer,
|
rasterLayerConvertedToControlLayer,
|
||||||
// Control layers
|
// Control layers
|
||||||
controlLayerAdded,
|
controlLayerAdded,
|
||||||
controlLayerRecalled,
|
controlLayerRecalled,
|
||||||
controlLayerAllDeleted,
|
|
||||||
controlLayerConvertedToRasterLayer,
|
controlLayerConvertedToRasterLayer,
|
||||||
controlLayerModelChanged,
|
controlLayerModelChanged,
|
||||||
controlLayerControlModeChanged,
|
controlLayerControlModeChanged,
|
||||||
@ -489,9 +487,6 @@ export const {
|
|||||||
// IP Adapters
|
// IP Adapters
|
||||||
ipaAdded,
|
ipaAdded,
|
||||||
ipaRecalled,
|
ipaRecalled,
|
||||||
ipaIsEnabledToggled,
|
|
||||||
ipaDeleted,
|
|
||||||
ipaAllDeleted,
|
|
||||||
ipaImageChanged,
|
ipaImageChanged,
|
||||||
ipaMethodChanged,
|
ipaMethodChanged,
|
||||||
ipaModelChanged,
|
ipaModelChanged,
|
||||||
@ -501,7 +496,6 @@ export const {
|
|||||||
// Regions
|
// Regions
|
||||||
rgAdded,
|
rgAdded,
|
||||||
rgRecalled,
|
rgRecalled,
|
||||||
rgAllDeleted,
|
|
||||||
rgPositivePromptChanged,
|
rgPositivePromptChanged,
|
||||||
rgNegativePromptChanged,
|
rgNegativePromptChanged,
|
||||||
rgFillColorChanged,
|
rgFillColorChanged,
|
||||||
@ -607,10 +601,6 @@ export const canvasV2PersistConfig: PersistConfig<CanvasV2State> = {
|
|||||||
persistDenylist: [],
|
persistDenylist: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sessionRequested = createAction(`${canvasV2Slice.name}/sessionRequested`);
|
|
||||||
export const sessionStagingAreaImageAccepted = createAction<{ index: number }>(
|
export const sessionStagingAreaImageAccepted = createAction<{ index: number }>(
|
||||||
`${canvasV2Slice.name}/sessionStagingAreaImageAccepted`
|
`${canvasV2Slice.name}/sessionStagingAreaImageAccepted`
|
||||||
);
|
);
|
||||||
export const transformationApplied = createAction<CanvasEntityIdentifier>(
|
|
||||||
`${canvasV2Slice.name}/transformationApplied`
|
|
||||||
);
|
|
||||||
|
@ -57,9 +57,6 @@ export const controlLayersReducers = {
|
|||||||
state.controlLayers.entities.push(data);
|
state.controlLayers.entities.push(data);
|
||||||
state.selectedEntityIdentifier = { type: 'control_layer', id: data.id };
|
state.selectedEntityIdentifier = { type: 'control_layer', id: data.id };
|
||||||
},
|
},
|
||||||
controlLayerAllDeleted: (state) => {
|
|
||||||
state.controlLayers.entities = [];
|
|
||||||
},
|
|
||||||
controlLayerConvertedToRasterLayer: {
|
controlLayerConvertedToRasterLayer: {
|
||||||
reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => {
|
reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => {
|
||||||
const { id, newId } = action.payload;
|
const { id, newId } = action.payload;
|
||||||
|
@ -10,7 +10,7 @@ import type {
|
|||||||
import { merge } from 'lodash-es';
|
import { merge } from 'lodash-es';
|
||||||
import { assert } from 'tsafe';
|
import { assert } from 'tsafe';
|
||||||
|
|
||||||
export const selectInpaintMaskEntity = (state: CanvasV2State, id: string) =>
|
const selectInpaintMaskEntity = (state: CanvasV2State, id: string) =>
|
||||||
state.inpaintMasks.entities.find((layer) => layer.id === id);
|
state.inpaintMasks.entities.find((layer) => layer.id === id);
|
||||||
export const selectInpaintMaskEntityOrThrow = (state: CanvasV2State, id: string) => {
|
export const selectInpaintMaskEntityOrThrow = (state: CanvasV2State, id: string) => {
|
||||||
const entity = selectInpaintMaskEntity(state, id);
|
const entity = selectInpaintMaskEntity(state, id);
|
||||||
|
@ -7,7 +7,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
import type { CanvasIPAdapterState, CanvasV2State, CLIPVisionModelV2, IPAdapterConfig, IPMethodV2 } from './types';
|
import type { CanvasIPAdapterState, CanvasV2State, CLIPVisionModelV2, IPAdapterConfig, IPMethodV2 } from './types';
|
||||||
import { imageDTOToImageWithDims } from './types';
|
import { imageDTOToImageWithDims } from './types';
|
||||||
|
|
||||||
export const selectIPAdapterEntity = (state: CanvasV2State, id: string) =>
|
const selectIPAdapterEntity = (state: CanvasV2State, id: string) =>
|
||||||
state.ipAdapters.entities.find((ipa) => ipa.id === id);
|
state.ipAdapters.entities.find((ipa) => ipa.id === id);
|
||||||
export const selectIPAdapterEntityOrThrow = (state: CanvasV2State, id: string) => {
|
export const selectIPAdapterEntityOrThrow = (state: CanvasV2State, id: string) => {
|
||||||
const entity = selectIPAdapterEntity(state, id);
|
const entity = selectIPAdapterEntity(state, id);
|
||||||
@ -36,20 +36,6 @@ export const ipAdaptersReducers = {
|
|||||||
state.ipAdapters.entities.push(data);
|
state.ipAdapters.entities.push(data);
|
||||||
state.selectedEntityIdentifier = { type: 'ip_adapter', id: data.id };
|
state.selectedEntityIdentifier = { type: 'ip_adapter', id: data.id };
|
||||||
},
|
},
|
||||||
ipaIsEnabledToggled: (state, action: PayloadAction<{ id: string }>) => {
|
|
||||||
const { id } = action.payload;
|
|
||||||
const ipa = selectIPAdapterEntity(state, id);
|
|
||||||
if (ipa) {
|
|
||||||
ipa.isEnabled = !ipa.isEnabled;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ipaDeleted: (state, action: PayloadAction<{ id: string }>) => {
|
|
||||||
const { id } = action.payload;
|
|
||||||
state.ipAdapters.entities = state.ipAdapters.entities.filter((ipa) => ipa.id !== id);
|
|
||||||
},
|
|
||||||
ipaAllDeleted: (state) => {
|
|
||||||
state.ipAdapters.entities = [];
|
|
||||||
},
|
|
||||||
ipaImageChanged: {
|
ipaImageChanged: {
|
||||||
reducer: (state, action: PayloadAction<{ id: string; imageDTO: ImageDTO | null }>) => {
|
reducer: (state, action: PayloadAction<{ id: string; imageDTO: ImageDTO | null }>) => {
|
||||||
const { id, imageDTO } = action.payload;
|
const { id, imageDTO } = action.payload;
|
||||||
|
@ -2,7 +2,6 @@ import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
|||||||
import type { CanvasV2State, LoRA } from 'features/controlLayers/store/types';
|
import type { CanvasV2State, LoRA } from 'features/controlLayers/store/types';
|
||||||
import { zModelIdentifierField } from 'features/nodes/types/common';
|
import { zModelIdentifierField } from 'features/nodes/types/common';
|
||||||
import type { LoRAModelConfig } from 'services/api/types';
|
import type { LoRAModelConfig } from 'services/api/types';
|
||||||
import { assert } from 'tsafe';
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
export const defaultLoRAConfig: Pick<LoRA, 'weight' | 'isEnabled'> = {
|
export const defaultLoRAConfig: Pick<LoRA, 'weight' | 'isEnabled'> = {
|
||||||
@ -10,12 +9,7 @@ export const defaultLoRAConfig: Pick<LoRA, 'weight' | 'isEnabled'> = {
|
|||||||
isEnabled: true,
|
isEnabled: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const selectLoRA = (state: CanvasV2State, id: string) => state.loras.find((lora) => lora.id === id);
|
const selectLoRA = (state: CanvasV2State, id: string) => state.loras.find((lora) => lora.id === id);
|
||||||
export const selectLoRAOrThrow = (state: CanvasV2State, id: string) => {
|
|
||||||
const lora = selectLoRA(state, id);
|
|
||||||
assert(lora, `LoRA with id ${id} not found`);
|
|
||||||
return lora;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const lorasReducers = {
|
export const lorasReducers = {
|
||||||
loraAdded: {
|
loraAdded: {
|
||||||
|
@ -2,18 +2,12 @@ import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
|||||||
import { deepClone } from 'common/util/deepClone';
|
import { deepClone } from 'common/util/deepClone';
|
||||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||||
import { merge } from 'lodash-es';
|
import { merge } from 'lodash-es';
|
||||||
import { assert } from 'tsafe';
|
|
||||||
|
|
||||||
import type { CanvasControlLayerState, CanvasRasterLayerState, CanvasV2State } from './types';
|
import type { CanvasControlLayerState, CanvasRasterLayerState, CanvasV2State } from './types';
|
||||||
import { initialControlNet } from './types';
|
import { initialControlNet } from './types';
|
||||||
|
|
||||||
export const selectRasterLayer = (state: CanvasV2State, id: string) =>
|
const selectRasterLayerEntity = (state: CanvasV2State, id: string) =>
|
||||||
state.rasterLayers.entities.find((layer) => layer.id === id);
|
state.rasterLayers.entities.find((layer) => layer.id === id);
|
||||||
export const selectLayerOrThrow = (state: CanvasV2State, id: string) => {
|
|
||||||
const layer = selectRasterLayer(state, id);
|
|
||||||
assert(layer, `Layer with id ${id} not found`);
|
|
||||||
return layer;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const rasterLayersReducers = {
|
export const rasterLayersReducers = {
|
||||||
rasterLayerAdded: {
|
rasterLayerAdded: {
|
||||||
@ -46,13 +40,10 @@ export const rasterLayersReducers = {
|
|||||||
state.rasterLayers.entities.push(data);
|
state.rasterLayers.entities.push(data);
|
||||||
state.selectedEntityIdentifier = { type: 'raster_layer', id: data.id };
|
state.selectedEntityIdentifier = { type: 'raster_layer', id: data.id };
|
||||||
},
|
},
|
||||||
rasterLayerAllDeleted: (state) => {
|
|
||||||
state.rasterLayers.entities = [];
|
|
||||||
},
|
|
||||||
rasterLayerConvertedToControlLayer: {
|
rasterLayerConvertedToControlLayer: {
|
||||||
reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => {
|
reducer: (state, action: PayloadAction<{ id: string; newId: string }>) => {
|
||||||
const { id, newId } = action.payload;
|
const { id, newId } = action.payload;
|
||||||
const layer = selectRasterLayer(state, id);
|
const layer = selectRasterLayerEntity(state, id);
|
||||||
if (!layer) {
|
if (!layer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,10 @@ import { assert } from 'tsafe';
|
|||||||
|
|
||||||
import type { CanvasRegionalGuidanceState } from './types';
|
import type { CanvasRegionalGuidanceState } from './types';
|
||||||
|
|
||||||
export const selectRegionalGuidanceEntity = (state: CanvasV2State, id: string) => {
|
const selectRegionalGuidanceEntity = (state: CanvasV2State, id: string) => {
|
||||||
return state.regions.entities.find((rg) => rg.id === id);
|
return state.regions.entities.find((rg) => rg.id === id);
|
||||||
};
|
};
|
||||||
export const selectRegionalGuidanceIPAdapter = (state: CanvasV2State, id: string, ipAdapterId: string) => {
|
const selectRegionalGuidanceIPAdapter = (state: CanvasV2State, id: string, ipAdapterId: string) => {
|
||||||
const entity = state.regions.entities.find((rg) => rg.id === id);
|
const entity = state.regions.entities.find((rg) => rg.id === id);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
return;
|
return;
|
||||||
@ -85,9 +85,6 @@ export const regionsReducers = {
|
|||||||
state.regions.entities.push(data);
|
state.regions.entities.push(data);
|
||||||
state.selectedEntityIdentifier = { type: 'regional_guidance', id: data.id };
|
state.selectedEntityIdentifier = { type: 'regional_guidance', id: data.id };
|
||||||
},
|
},
|
||||||
rgAllDeleted: (state) => {
|
|
||||||
state.regions.entities = [];
|
|
||||||
},
|
|
||||||
rgPositivePromptChanged: (state, action: PayloadAction<{ id: string; prompt: string | null }>) => {
|
rgPositivePromptChanged: (state, action: PayloadAction<{ id: string; prompt: string | null }>) => {
|
||||||
const { id, prompt } = action.payload;
|
const { id, prompt } = action.payload;
|
||||||
const entity = selectRegionalGuidanceEntity(state, id);
|
const entity = selectRegionalGuidanceEntity(state, id);
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
||||||
import type { CanvasV2State, SessionMode, StagingAreaImage } from 'features/controlLayers/store/types';
|
import type {
|
||||||
|
CanvasV2State,
|
||||||
|
SessionMode,
|
||||||
|
StagingAreaImage,
|
||||||
|
} from 'features/controlLayers/store/types';
|
||||||
|
|
||||||
export const sessionReducers = {
|
export const sessionReducers = {
|
||||||
sessionStartedStaging: (state) => {
|
sessionStartedStaging: (state) => {
|
||||||
|
@ -524,9 +524,6 @@ const zCanvasRectState = z.object({
|
|||||||
});
|
});
|
||||||
export type CanvasRectState = z.infer<typeof zCanvasRectState>;
|
export type CanvasRectState = z.infer<typeof zCanvasRectState>;
|
||||||
|
|
||||||
const zLayerEffect = z.enum(['LightnessToAlphaFilter']);
|
|
||||||
export type LayerEffect = z.infer<typeof zLayerEffect>;
|
|
||||||
|
|
||||||
const zCanvasImageState = z.object({
|
const zCanvasImageState = z.object({
|
||||||
id: zId,
|
id: zId,
|
||||||
type: z.literal('image'),
|
type: z.literal('image'),
|
||||||
@ -540,7 +537,6 @@ const zCanvasObjectState = z.discriminatedUnion('type', [
|
|||||||
zCanvasEraserLineState,
|
zCanvasEraserLineState,
|
||||||
zCanvasRectState,
|
zCanvasRectState,
|
||||||
]);
|
]);
|
||||||
export type CanvasObjectState = z.infer<typeof zCanvasObjectState>;
|
|
||||||
|
|
||||||
const zIPAdapterConfig = z.object({
|
const zIPAdapterConfig = z.object({
|
||||||
image: zImageWithDims.nullable(),
|
image: zImageWithDims.nullable(),
|
||||||
@ -822,9 +818,6 @@ export type StageAttrs = {
|
|||||||
height: Dimensions['height'];
|
height: Dimensions['height'];
|
||||||
scale: number;
|
scale: number;
|
||||||
};
|
};
|
||||||
export type PositionChangedArg = { id: string; position: Coordinate };
|
|
||||||
export type ScaleChangedArg = { id: string; scale: Coordinate; position: Coordinate };
|
|
||||||
export type BboxChangedArg = { id: string; bbox: Rect | null };
|
|
||||||
|
|
||||||
export type EntityIdentifierPayload<T = object> = { entityIdentifier: CanvasEntityIdentifier } & T;
|
export type EntityIdentifierPayload<T = object> = { entityIdentifier: CanvasEntityIdentifier } & T;
|
||||||
export type EntityMovedPayload = EntityIdentifierPayload<{ position: Coordinate }>;
|
export type EntityMovedPayload = EntityIdentifierPayload<{ position: Coordinate }>;
|
||||||
@ -836,7 +829,6 @@ export type EntityRasterizedPayload = EntityIdentifierPayload<{
|
|||||||
rect: Rect;
|
rect: Rect;
|
||||||
replaceObjects: boolean;
|
replaceObjects: boolean;
|
||||||
}>;
|
}>;
|
||||||
export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: Coordinate };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper type to remove `[index: string]: any;` from a type.
|
* A helper type to remove `[index: string]: any;` from a type.
|
||||||
@ -845,9 +837,9 @@ export type ImageObjectAddedArg = { id: string; imageDTO: ImageDTO; position?: C
|
|||||||
* `RectConfig`, `ImageConfig`, etc all include `[index: string]: any;` in their type signature.
|
* `RectConfig`, `ImageConfig`, etc all include `[index: string]: any;` in their type signature.
|
||||||
* TODO(psyche): Fix this upstream.
|
* TODO(psyche): Fix this upstream.
|
||||||
*/
|
*/
|
||||||
export type RemoveIndexString<T> = {
|
// export type RemoveIndexString<T> = {
|
||||||
[K in keyof T as string extends K ? never : K]: T[K];
|
// [K in keyof T as string extends K ? never : K]: T[K];
|
||||||
};
|
// };
|
||||||
|
|
||||||
export type GenerationMode = 'txt2img' | 'img2img' | 'inpaint' | 'outpaint';
|
export type GenerationMode = 'txt2img' | 'img2img' | 'inpaint' | 'outpaint';
|
||||||
|
|
||||||
|
@ -3,14 +3,14 @@ import { getEventCoordinates } from '@dnd-kit/utilities';
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { $viewport } from 'features/nodes/store/nodesSlice';
|
import { $viewport } from 'features/nodes/store/nodesSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies scaling to the drag transform (if on node editor tab) and centers it on cursor.
|
* Applies scaling to the drag transform (if on node editor tab) and centers it on cursor.
|
||||||
*/
|
*/
|
||||||
export const useScaledModifer = () => {
|
export const useScaledModifer = () => {
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
const workflowsViewport = useStore($viewport);
|
const workflowsViewport = useStore($viewport);
|
||||||
const modifier: Modifier = useCallback(
|
const modifier: Modifier = useCallback(
|
||||||
({ activatorEvent, draggingNodeRect, transform }) => {
|
({ activatorEvent, draggingNodeRect, transform }) => {
|
||||||
|
@ -18,17 +18,6 @@ type BaseDropData = {
|
|||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CurrentImageDropData = BaseDropData & {
|
|
||||||
actionType: 'SET_CURRENT_IMAGE';
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CAImageDropData = BaseDropData & {
|
|
||||||
actionType: 'SET_CA_IMAGE';
|
|
||||||
context: {
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IPAImageDropData = BaseDropData & {
|
export type IPAImageDropData = BaseDropData & {
|
||||||
actionType: 'SET_IPA_IMAGE';
|
actionType: 'SET_IPA_IMAGE';
|
||||||
context: {
|
context: {
|
||||||
@ -56,10 +45,6 @@ type UpscaleInitialImageDropData = BaseDropData & {
|
|||||||
actionType: 'SET_UPSCALE_INITIAL_IMAGE';
|
actionType: 'SET_UPSCALE_INITIAL_IMAGE';
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InitialImageDropData = BaseDropData & {
|
|
||||||
actionType: 'SET_INITIAL_IMAGE';
|
|
||||||
};
|
|
||||||
|
|
||||||
type NodesImageDropData = BaseDropData & {
|
type NodesImageDropData = BaseDropData & {
|
||||||
actionType: 'SET_NODES_IMAGE';
|
actionType: 'SET_NODES_IMAGE';
|
||||||
context: {
|
context: {
|
||||||
@ -86,11 +71,9 @@ export type SelectForCompareDropData = BaseDropData & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TypesafeDroppableData =
|
export type TypesafeDroppableData =
|
||||||
| CurrentImageDropData
|
|
||||||
| NodesImageDropData
|
| NodesImageDropData
|
||||||
| AddToBoardDropData
|
| AddToBoardDropData
|
||||||
| RemoveFromBoardDropData
|
| RemoveFromBoardDropData
|
||||||
| CAImageDropData
|
|
||||||
| IPAImageDropData
|
| IPAImageDropData
|
||||||
| RGIPAdapterImageDropData
|
| RGIPAdapterImageDropData
|
||||||
| SelectForCompareDropData
|
| SelectForCompareDropData
|
||||||
|
@ -6,7 +6,7 @@ import { MetadataLayers } from 'features/metadata/components/MetadataLayers';
|
|||||||
import { MetadataLoRAs } from 'features/metadata/components/MetadataLoRAs';
|
import { MetadataLoRAs } from 'features/metadata/components/MetadataLoRAs';
|
||||||
import { MetadataT2IAdapters } from 'features/metadata/components/MetadataT2IAdapters';
|
import { MetadataT2IAdapters } from 'features/metadata/components/MetadataT2IAdapters';
|
||||||
import { handlers } from 'features/metadata/util/handlers';
|
import { handlers } from 'features/metadata/util/handlers';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -14,7 +14,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ImageMetadataActions = (props: Props) => {
|
const ImageMetadataActions = (props: Props) => {
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
const { metadata } = props;
|
const { metadata } = props;
|
||||||
|
|
||||||
if (!metadata || Object.keys(metadata).length === 0) {
|
if (!metadata || Object.keys(metadata).length === 0) {
|
||||||
|
@ -2,7 +2,7 @@ import { Flex } from '@invoke-ai/ui-library';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { ToggleMetadataViewerButton } from 'features/gallery/components/ImageViewer/ToggleMetadataViewerButton';
|
import { ToggleMetadataViewerButton } from 'features/gallery/components/ImageViewer/ToggleMetadataViewerButton';
|
||||||
import { ToggleProgressButton } from 'features/gallery/components/ImageViewer/ToggleProgressButton';
|
import { ToggleProgressButton } from 'features/gallery/components/ImageViewer/ToggleProgressButton';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
import CurrentImageButtons from './CurrentImageButtons';
|
import CurrentImageButtons from './CurrentImageButtons';
|
||||||
@ -10,7 +10,7 @@ import { ViewerToggleMenu } from './ViewerToggleMenu';
|
|||||||
|
|
||||||
export const ViewerToolbar = memo(() => {
|
export const ViewerToolbar = memo(() => {
|
||||||
const showToggle = useAppSelector((s) => {
|
const showToggle = useAppSelector((s) => {
|
||||||
const tab = activeTabNameSelector(s);
|
const tab = selectActiveTab(s);
|
||||||
if (tab === 'upscaling' || tab === 'workflows') {
|
if (tab === 'upscaling' || tab === 'workflows') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { handlers, parseAndRecallAllMetadata, parseAndRecallPrompts } from 'feat
|
|||||||
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
import { $stylePresetModalState } from 'features/stylePresets/store/stylePresetModal';
|
||||||
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||||
@ -13,8 +13,8 @@ import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
|
|||||||
export const useImageActions = (image_name?: string) => {
|
export const useImageActions = (image_name?: string) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
|
||||||
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);
|
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);
|
||||||
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata(image_name);
|
const { metadata, isLoading: isLoadingMetadata } = useDebouncedMetadata(image_name);
|
||||||
const [hasMetadata, setHasMetadata] = useState(false);
|
const [hasMetadata, setHasMetadata] = useState(false);
|
||||||
const [hasSeed, setHasSeed] = useState(false);
|
const [hasSeed, setHasSeed] = useState(false);
|
||||||
|
@ -21,7 +21,6 @@ import {
|
|||||||
negativePromptChanged,
|
negativePromptChanged,
|
||||||
positivePrompt2Changed,
|
positivePrompt2Changed,
|
||||||
positivePromptChanged,
|
positivePromptChanged,
|
||||||
rasterLayerAllDeleted,
|
|
||||||
rasterLayerRecalled,
|
rasterLayerRecalled,
|
||||||
refinerModelChanged,
|
refinerModelChanged,
|
||||||
rgRecalled,
|
rgRecalled,
|
||||||
@ -40,7 +39,6 @@ import {
|
|||||||
vaeSelected,
|
vaeSelected,
|
||||||
} from 'features/controlLayers/store/canvasV2Slice';
|
} from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import type {
|
import type {
|
||||||
CanvasControlAdapterState,
|
|
||||||
CanvasIPAdapterState,
|
CanvasIPAdapterState,
|
||||||
CanvasRasterLayerState,
|
CanvasRasterLayerState,
|
||||||
CanvasRegionalGuidanceState,
|
CanvasRegionalGuidanceState,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Box, Flex } from '@invoke-ai/ui-library';
|
import { Box, Flex } from '@invoke-ai/ui-library';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
import InvocationCacheStatus from './InvocationCacheStatus';
|
import InvocationCacheStatus from './InvocationCacheStatus';
|
||||||
@ -11,7 +11,7 @@ import QueueTabQueueControls from './QueueTabQueueControls';
|
|||||||
|
|
||||||
const QueueTabContent = () => {
|
const QueueTabContent = () => {
|
||||||
const isInvocationCacheEnabled = useFeatureStatus('invocationCache');
|
const isInvocationCacheEnabled = useFeatureStatus('invocationCache');
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { enqueueRequested } from 'app/store/actions';
|
import { enqueueRequested } from 'app/store/actions';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue';
|
import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useEnqueueBatchMutation } from 'services/api/endpoints/queue';
|
import { useEnqueueBatchMutation } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
export const useQueueBack = () => {
|
export const useQueueBack = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const tabName = useAppSelector(activeTabNameSelector);
|
const tabName = useAppSelector(selectActiveTab);
|
||||||
const { isReady } = useIsReadyToEnqueue();
|
const { isReady } = useIsReadyToEnqueue();
|
||||||
const [_, { isLoading }] = useEnqueueBatchMutation({
|
const [_, { isLoading }] = useEnqueueBatchMutation({
|
||||||
fixedCacheKey: 'enqueueBatch',
|
fixedCacheKey: 'enqueueBatch',
|
||||||
|
@ -2,13 +2,13 @@ import { enqueueRequested } from 'app/store/actions';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue';
|
import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useEnqueueBatchMutation } from 'services/api/endpoints/queue';
|
import { useEnqueueBatchMutation } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
export const useQueueFront = () => {
|
export const useQueueFront = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const tabName = useAppSelector(activeTabNameSelector);
|
const tabName = useAppSelector(selectActiveTab);
|
||||||
const { isReady } = useIsReadyToEnqueue();
|
const { isReady } = useIsReadyToEnqueue();
|
||||||
const [_, { isLoading }] = useEnqueueBatchMutation({
|
const [_, { isLoading }] = useEnqueueBatchMutation({
|
||||||
fixedCacheKey: 'enqueueBatch',
|
fixedCacheKey: 'enqueueBatch',
|
||||||
|
@ -14,7 +14,7 @@ import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedS
|
|||||||
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
|
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
|
||||||
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
|
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
|
||||||
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
||||||
@ -30,7 +30,7 @@ const formLabelProps2: FormLabelProps = {
|
|||||||
export const AdvancedSettingsAccordion = memo(() => {
|
export const AdvancedSettingsAccordion = memo(() => {
|
||||||
const vaeKey = useAppSelector((state) => state.canvasV2.params.vae?.key);
|
const vaeKey = useAppSelector((state) => state.canvasV2.params.vae?.key);
|
||||||
const { currentData: vaeConfig } = useGetModelConfigQuery(vaeKey ?? skipToken);
|
const { currentData: vaeConfig } = useGetModelConfigQuery(vaeKey ?? skipToken);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
|
|
||||||
const selectBadges = useMemo(
|
const selectBadges = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
@ -14,7 +14,7 @@ import ParamMainModelSelect from 'features/parameters/components/MainModel/Param
|
|||||||
import { UseDefaultSettingsButton } from 'features/parameters/components/MainModel/UseDefaultSettingsButton';
|
import { UseDefaultSettingsButton } from 'features/parameters/components/MainModel/UseDefaultSettingsButton';
|
||||||
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
|
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
|
||||||
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useSelectedModelConfig } from 'services/api/hooks/useSelectedModelConfig';
|
import { useSelectedModelConfig } from 'services/api/hooks/useSelectedModelConfig';
|
||||||
@ -26,7 +26,7 @@ const formLabelProps: FormLabelProps = {
|
|||||||
export const GenerationSettingsAccordion = memo(() => {
|
export const GenerationSettingsAccordion = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const modelConfig = useSelectedModelConfig();
|
const modelConfig = useSelectedModelConfig();
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
const selectBadges = useMemo(
|
const selectBadges = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(selectCanvasV2Slice, (canvasV2) => {
|
createMemoizedSelector(selectCanvasV2Slice, (canvasV2) => {
|
||||||
|
@ -2,17 +2,17 @@ import { createSelector } from '@reduxjs/toolkit';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import type { AppFeature, SDFeature } from 'app/types/invokeai';
|
import type { AppFeature, SDFeature } from 'app/types/invokeai';
|
||||||
import { selectConfigSlice } from 'features/system/store/configSlice';
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "features/ui/store/uiTypes";
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useFeatureStatus = (feature: AppFeature | SDFeature | InvokeTabName) => {
|
export const useFeatureStatus = (feature: AppFeature | SDFeature | TabName) => {
|
||||||
const selectIsFeatureEnabled = useMemo(
|
const selectIsFeatureEnabled = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createSelector(selectConfigSlice, (config) => {
|
createSelector(selectConfigSlice, (config) => {
|
||||||
return !(
|
return !(
|
||||||
config.disabledFeatures.includes(feature as AppFeature) ||
|
config.disabledFeatures.includes(feature as AppFeature) ||
|
||||||
config.disabledSDFeatures.includes(feature as SDFeature) ||
|
config.disabledSDFeatures.includes(feature as SDFeature) ||
|
||||||
config.disabledTabs.includes(feature as InvokeTabName)
|
config.disabledTabs.includes(feature as TabName)
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
[feature]
|
[feature]
|
||||||
|
@ -18,8 +18,8 @@ import { VerticalNavBar } from 'features/ui/components/VerticalNavBar';
|
|||||||
import type { UsePanelOptions } from 'features/ui/hooks/usePanel';
|
import type { UsePanelOptions } from 'features/ui/hooks/usePanel';
|
||||||
import { usePanel } from 'features/ui/hooks/usePanel';
|
import { usePanel } from 'features/ui/hooks/usePanel';
|
||||||
import { usePanelStorage } from 'features/ui/hooks/usePanelStorage';
|
import { usePanelStorage } from 'features/ui/hooks/usePanelStorage';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
|
||||||
import { $isGalleryPanelOpen, $isParametersPanelOpen } from 'features/ui/store/uiSlice';
|
import { $isGalleryPanelOpen, $isParametersPanelOpen } from 'features/ui/store/uiSlice';
|
||||||
|
import type { TabName } from "features/ui/store/uiTypes";
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { memo, useMemo, useRef } from 'react';
|
import { memo, useMemo, useRef } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
@ -29,8 +29,8 @@ import { Panel, PanelGroup } from 'react-resizable-panels';
|
|||||||
import ParametersPanelUpscale from './ParametersPanels/ParametersPanelUpscale';
|
import ParametersPanelUpscale from './ParametersPanels/ParametersPanelUpscale';
|
||||||
import ResizeHandle from './tabs/ResizeHandle';
|
import ResizeHandle from './tabs/ResizeHandle';
|
||||||
|
|
||||||
const TABS_WITH_GALLERY_PANEL: InvokeTabName[] = ['generation', 'upscaling', 'workflows'] as const;
|
const TABS_WITH_GALLERY_PANEL: TabName[] = ['generation', 'upscaling', 'workflows'] as const;
|
||||||
const TABS_WITH_OPTIONS_PANEL: InvokeTabName[] = ['generation', 'upscaling', 'workflows'] as const;
|
const TABS_WITH_OPTIONS_PANEL: TabName[] = ['generation', 'upscaling', 'workflows'] as const;
|
||||||
|
|
||||||
const panelStyles: CSSProperties = { position: 'relative', height: '100%', width: '100%' };
|
const panelStyles: CSSProperties = { position: 'relative', height: '100%', width: '100%' };
|
||||||
const GALLERY_MIN_SIZE_PX = 310;
|
const GALLERY_MIN_SIZE_PX = 310;
|
||||||
@ -38,8 +38,8 @@ const GALLERY_MIN_SIZE_PCT = 20;
|
|||||||
const OPTIONS_PANEL_MIN_SIZE_PX = 430;
|
const OPTIONS_PANEL_MIN_SIZE_PX = 430;
|
||||||
const OPTIONS_PANEL_MIN_SIZE_PCT = 20;
|
const OPTIONS_PANEL_MIN_SIZE_PCT = 20;
|
||||||
|
|
||||||
export const onGalleryPanelCollapse = (isCollapsed: boolean) => $isGalleryPanelOpen.set(!isCollapsed);
|
const onGalleryPanelCollapse = (isCollapsed: boolean) => $isGalleryPanelOpen.set(!isCollapsed);
|
||||||
export const onParametersPanelCollapse = (isCollapsed: boolean) => $isParametersPanelOpen.set(!isCollapsed);
|
const onParametersPanelCollapse = (isCollapsed: boolean) => $isParametersPanelOpen.set(!isCollapsed);
|
||||||
|
|
||||||
export const AppContent = memo(() => {
|
export const AppContent = memo(() => {
|
||||||
const panelGroupRef = useRef<ImperativePanelGroupHandle>(null);
|
const panelGroupRef = useRef<ImperativePanelGroupHandle>(null);
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
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 { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "../store/uiTypes";
|
||||||
import { activeTabNameSelector } 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 { memo, type ReactElement, useCallback } from 'react';
|
import { memo, type ReactElement, useCallback } from 'react';
|
||||||
|
|
||||||
export const TabButton = memo(({ tab, icon, label }: { tab: InvokeTabName; icon: ReactElement; label: string }) => {
|
export const TabButton = memo(({ tab, icon, label }: { tab: TabName; icon: ReactElement; label: string }) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(setActiveTab(tab));
|
dispatch(setActiveTab(tab));
|
||||||
}, [dispatch, tab]);
|
}, [dispatch, tab]);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
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 { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "../store/uiTypes";
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
|
|
||||||
export const TabMountGate = memo(({ tab, children }: PropsWithChildren<{ tab: InvokeTabName }>) => {
|
export const TabMountGate = memo(({ tab, children }: PropsWithChildren<{ tab: TabName }>) => {
|
||||||
const selectIsTabEnabled = useMemo(
|
const selectIsTabEnabled = useMemo(
|
||||||
() => createSelector(selectConfigSlice, (config) => !config.disabledTabs.includes(tab)),
|
() => createSelector(selectConfigSlice, (config) => !config.disabledTabs.includes(tab)),
|
||||||
[tab]
|
[tab]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
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 { InvokeTabName } from 'features/ui/store/tabMap';
|
import type { TabName } from "../store/uiTypes";
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
export const TabVisibilityGate = memo(({ tab, children }: PropsWithChildren<{ tab: InvokeTabName }>) => {
|
export const TabVisibilityGate = memo(({ tab, children }: PropsWithChildren<{ tab: TabName }>) => {
|
||||||
const activeTabName = useAppSelector((s) => s.ui.activeTab);
|
const activeTabName = useAppSelector((s) => s.ui.activeTab);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,13 +2,13 @@ import { Box } from '@invoke-ai/ui-library';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useScopeOnFocus } from 'common/hooks/interactionScopes';
|
import { useScopeOnFocus } from 'common/hooks/interactionScopes';
|
||||||
import NodeEditor from 'features/nodes/components/NodeEditor';
|
import NodeEditor from 'features/nodes/components/NodeEditor';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { selectActiveTab } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useRef } from 'react';
|
import { memo, useRef } from 'react';
|
||||||
import { ReactFlowProvider } from 'reactflow';
|
import { ReactFlowProvider } from 'reactflow';
|
||||||
|
|
||||||
const NodesTab = () => {
|
const NodesTab = () => {
|
||||||
const mode = useAppSelector((s) => s.workflow.mode);
|
const mode = useAppSelector((s) => s.workflow.mode);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(selectActiveTab);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
useScopeOnFocus('workflows', ref);
|
useScopeOnFocus('workflows', ref);
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
export const TAB_NUMBER_MAP = ['generation', 'upscaling', 'workflows', 'models', 'queue'] as const;
|
|
||||||
|
|
||||||
export type InvokeTabName = (typeof TAB_NUMBER_MAP)[number];
|
|
@ -1,21 +1,4 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { selectConfigSlice } from 'features/system/store/configSlice';
|
|
||||||
import { selectUiSlice } from 'features/ui/store/uiSlice';
|
import { selectUiSlice } from 'features/ui/store/uiSlice';
|
||||||
import { isString } from 'lodash-es';
|
|
||||||
|
|
||||||
import { TAB_NUMBER_MAP } from './tabMap';
|
export const selectActiveTab = createSelector(selectUiSlice, (ui) => ui.activeTab);
|
||||||
|
|
||||||
export const activeTabNameSelector = createSelector(
|
|
||||||
selectUiSlice,
|
|
||||||
/**
|
|
||||||
* Previously `activeTab` was an integer, but now it's a string.
|
|
||||||
* Default to first tab in case user has integer.
|
|
||||||
*/
|
|
||||||
(ui) => (isString(ui.activeTab) ? ui.activeTab : 'generation')
|
|
||||||
);
|
|
||||||
|
|
||||||
export const activeTabIndexSelector = createSelector(selectUiSlice, selectConfigSlice, (ui, config) => {
|
|
||||||
const tabs = TAB_NUMBER_MAP.filter((t) => !config.disabledTabs.includes(t));
|
|
||||||
const idx = tabs.indexOf(ui.activeTab);
|
|
||||||
return idx === -1 ? 0 : idx;
|
|
||||||
});
|
|
||||||
|
@ -4,7 +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 { InvokeTabName } from './tabMap';
|
import type { TabName } from "./uiTypes";
|
||||||
import type { UIState } from './uiTypes';
|
import type { UIState } from './uiTypes';
|
||||||
|
|
||||||
const initialUIState: UIState = {
|
const initialUIState: UIState = {
|
||||||
@ -21,7 +21,7 @@ export const uiSlice = createSlice({
|
|||||||
name: 'ui',
|
name: 'ui',
|
||||||
initialState: initialUIState,
|
initialState: initialUIState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setActiveTab: (state, action: PayloadAction<InvokeTabName>) => {
|
setActiveTab: (state, action: PayloadAction<TabName>) => {
|
||||||
state.activeTab = action.payload;
|
state.activeTab = action.payload;
|
||||||
},
|
},
|
||||||
setShouldShowImageDetails: (state, action: PayloadAction<boolean>) => {
|
setShouldShowImageDetails: (state, action: PayloadAction<boolean>) => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { InvokeTabName } from './tabMap';
|
|
||||||
|
export type TabName = 'generation' | 'upscaling' | 'workflows' | 'models' | 'queue';
|
||||||
|
|
||||||
export interface UIState {
|
export interface UIState {
|
||||||
/**
|
/**
|
||||||
@ -8,7 +9,7 @@ export interface UIState {
|
|||||||
/**
|
/**
|
||||||
* The currently active tab.
|
* The currently active tab.
|
||||||
*/
|
*/
|
||||||
activeTab: InvokeTabName;
|
activeTab: TabName;
|
||||||
/**
|
/**
|
||||||
* Whether or not to show image details, e.g. metadata, workflow, etc.
|
* Whether or not to show image details, e.g. metadata, workflow, etc.
|
||||||
*/
|
*/
|
||||||
|
@ -110,12 +110,6 @@ export const isSpandrelImageToImageModelConfig = (
|
|||||||
return config.type === 'spandrel_image_to_image';
|
return config.type === 'spandrel_image_to_image';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isControlAdapterModelConfig = (
|
|
||||||
config: AnyModelConfig
|
|
||||||
): config is ControlNetModelConfig | T2IAdapterModelConfig | IPAdapterModelConfig => {
|
|
||||||
return isControlNetModelConfig(config) || isT2IAdapterModelConfig(config) || isIPAdapterModelConfig(config);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isControlNetOrT2IAdapterModelConfig = (
|
export const isControlNetOrT2IAdapterModelConfig = (
|
||||||
config: AnyModelConfig
|
config: AnyModelConfig
|
||||||
): config is ControlNetModelConfig | T2IAdapterModelConfig => {
|
): config is ControlNetModelConfig | T2IAdapterModelConfig => {
|
||||||
@ -191,11 +185,6 @@ export type OutputFields<T extends AnyInvocation> = Extract<
|
|||||||
// Node Outputs
|
// Node Outputs
|
||||||
export type ImageOutput = S['ImageOutput'];
|
export type ImageOutput = S['ImageOutput'];
|
||||||
|
|
||||||
export type CAImagePostUploadAction = {
|
|
||||||
type: 'SET_CA_IMAGE';
|
|
||||||
id: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IPALayerImagePostUploadAction = {
|
export type IPALayerImagePostUploadAction = {
|
||||||
type: 'SET_IPA_IMAGE';
|
type: 'SET_IPA_IMAGE';
|
||||||
id: string;
|
id: string;
|
||||||
@ -230,7 +219,6 @@ export type PostUploadAction =
|
|||||||
| NodesAction
|
| NodesAction
|
||||||
| ToastAction
|
| ToastAction
|
||||||
| AddToBatchAction
|
| AddToBatchAction
|
||||||
| CAImagePostUploadAction
|
|
||||||
| IPALayerImagePostUploadAction
|
| IPALayerImagePostUploadAction
|
||||||
| RGIPAdapterImagePostUploadAction
|
| RGIPAdapterImagePostUploadAction
|
||||||
| UpscaleInitialImageAction;
|
| UpscaleInitialImageAction;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user