mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): do not use state => state
as an input selector
This is a no-no, whoops!
This commit is contained in:
parent
ce64dbefce
commit
a23502f7ff
@ -167,10 +167,5 @@
|
|||||||
"vite-plugin-dts": "^3.7.0",
|
"vite-plugin-dts": "^3.7.0",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^4.2.3"
|
"vite-tsconfig-paths": "^4.2.3"
|
||||||
},
|
|
||||||
"pnpm": {
|
|
||||||
"patchedDependencies": {
|
|
||||||
"reselect@5.0.1": "patches/reselect@5.0.1.patch"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,6 @@ settings:
|
|||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
patchedDependencies:
|
|
||||||
reselect@5.0.1:
|
|
||||||
hash: kvbgwzjyy4x4fnh7znyocvb75q
|
|
||||||
path: patches/reselect@5.0.1.patch
|
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@chakra-ui/anatomy':
|
'@chakra-ui/anatomy':
|
||||||
specifier: ^2.2.2
|
specifier: ^2.2.2
|
||||||
@ -4570,7 +4565,7 @@ packages:
|
|||||||
react-redux: 9.0.4(@types/react@18.2.46)(react@18.2.0)(redux@5.0.1)
|
react-redux: 9.0.4(@types/react@18.2.46)(react@18.2.0)(redux@5.0.1)
|
||||||
redux: 5.0.1
|
redux: 5.0.1
|
||||||
redux-thunk: 3.1.0(redux@5.0.1)
|
redux-thunk: 3.1.0(redux@5.0.1)
|
||||||
reselect: 5.0.1(patch_hash=kvbgwzjyy4x4fnh7znyocvb75q)
|
reselect: 5.0.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@roarr/browser-log-writer@1.3.0:
|
/@roarr/browser-log-writer@1.3.0:
|
||||||
@ -11937,10 +11932,9 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/reselect@5.0.1(patch_hash=kvbgwzjyy4x4fnh7znyocvb75q):
|
/reselect@5.0.1:
|
||||||
resolution: {integrity: sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==}
|
resolution: {integrity: sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==}
|
||||||
dev: false
|
dev: false
|
||||||
patched: true
|
|
||||||
|
|
||||||
/resize-observer-polyfill@1.5.1:
|
/resize-observer-polyfill@1.5.1:
|
||||||
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
|
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
|
||||||
|
@ -11,7 +11,7 @@ import { memo, useCallback, useEffect } from 'react';
|
|||||||
*/
|
*/
|
||||||
const Toaster = () => {
|
const Toaster = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const toastQueue = useAppSelector((state) => state.system.toastQueue);
|
const toastQueue = useAppSelector((s) => s.system.toastQueue);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
toastQueue.forEach((t) => {
|
toastQueue.forEach((t) => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createLogWriter } from '@roarr/browser-log-writer';
|
import { createLogWriter } from '@roarr/browser-log-writer';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
import type { RootState} from 'app/store/store';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { ROARR, Roarr } from 'roarr';
|
import { ROARR, Roarr } from 'roarr';
|
||||||
@ -8,14 +8,17 @@ import { ROARR, Roarr } from 'roarr';
|
|||||||
import type { LoggerNamespace } from './logger';
|
import type { LoggerNamespace } from './logger';
|
||||||
import { $logger, BASE_CONTEXT, LOG_LEVEL_MAP, logger } from './logger';
|
import { $logger, BASE_CONTEXT, LOG_LEVEL_MAP, logger } from './logger';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ system }) => {
|
const selector = createMemoizedSelector(
|
||||||
const { consoleLogLevel, shouldLogToConsole } = system;
|
(state: RootState) => state.system,
|
||||||
|
(system) => {
|
||||||
|
const { consoleLogLevel, shouldLogToConsole } = system;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
consoleLogLevel,
|
consoleLogLevel,
|
||||||
shouldLogToConsole,
|
shouldLogToConsole,
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export const useLogger = (namespace: LoggerNamespace) => {
|
export const useLogger = (namespace: LoggerNamespace) => {
|
||||||
const { consoleLogLevel, shouldLogToConsole } = useAppSelector(selector);
|
const { consoleLogLevel, shouldLogToConsole } = useAppSelector(selector);
|
||||||
|
@ -1,33 +1,32 @@
|
|||||||
import {
|
import {
|
||||||
createDraftSafeSelectorCreator,
|
createDraftSafeSelectorCreator,
|
||||||
createSelectorCreator,
|
createSelectorCreator,
|
||||||
lruMemoize,
|
weakMapMemoize,
|
||||||
} from '@reduxjs/toolkit';
|
} from '@reduxjs/toolkit';
|
||||||
import type { GetSelectorsOptions } from '@reduxjs/toolkit/dist/entities/state_selectors';
|
import type { GetSelectorsOptions } from '@reduxjs/toolkit/dist/entities/state_selectors';
|
||||||
import { isEqual } from 'lodash-es';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A memoized selector creator that uses LRU cache and lodash's isEqual for equality check.
|
* A memoized selector creator that uses LRU cache and lodash's isEqual for equality check.
|
||||||
*/
|
*/
|
||||||
export const createMemoizedSelector = createSelectorCreator({
|
export const createMemoizedSelector = createSelectorCreator({
|
||||||
memoize: lruMemoize,
|
memoize: weakMapMemoize,
|
||||||
memoizeOptions: {
|
// memoizeOptions: {
|
||||||
resultEqualityCheck: isEqual,
|
// resultEqualityCheck: isEqual,
|
||||||
},
|
// },
|
||||||
argsMemoize: lruMemoize,
|
argsMemoize: weakMapMemoize,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A memoized selector creator that uses LRU cache default shallow equality check.
|
* A memoized selector creator that uses LRU cache default shallow equality check.
|
||||||
*/
|
*/
|
||||||
export const createLruSelector = createSelectorCreator({
|
export const createLruSelector = createSelectorCreator({
|
||||||
memoize: lruMemoize,
|
memoize: weakMapMemoize,
|
||||||
argsMemoize: lruMemoize,
|
argsMemoize: weakMapMemoize,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createLruDraftSafeSelector = createDraftSafeSelectorCreator({
|
export const createLruDraftSafeSelector = createDraftSafeSelectorCreator({
|
||||||
memoize: lruMemoize,
|
memoize: weakMapMemoize,
|
||||||
argsMemoize: lruMemoize,
|
argsMemoize: weakMapMemoize,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getSelectorsOptions: GetSelectorsOptions = {
|
export const getSelectorsOptions: GetSelectorsOptions = {
|
||||||
|
@ -8,7 +8,6 @@ import { initialPostprocessingState } from 'features/parameters/store/postproces
|
|||||||
import { initialSDXLState } from 'features/sdxl/store/sdxlSlice';
|
import { initialSDXLState } from 'features/sdxl/store/sdxlSlice';
|
||||||
import { initialConfigState } from 'features/system/store/configSlice';
|
import { initialConfigState } from 'features/system/store/configSlice';
|
||||||
import { initialSystemState } from 'features/system/store/systemSlice';
|
import { initialSystemState } from 'features/system/store/systemSlice';
|
||||||
import { initialHotkeysState } from 'features/ui/store/hotkeysSlice';
|
|
||||||
import { initialUIState } from 'features/ui/store/uiSlice';
|
import { initialUIState } from 'features/ui/store/uiSlice';
|
||||||
import { defaultsDeep } from 'lodash-es';
|
import { defaultsDeep } from 'lodash-es';
|
||||||
import type { UnserializeFunction } from 'redux-remember';
|
import type { UnserializeFunction } from 'redux-remember';
|
||||||
@ -24,7 +23,6 @@ const initialStates: {
|
|||||||
system: initialSystemState,
|
system: initialSystemState,
|
||||||
config: initialConfigState,
|
config: initialConfigState,
|
||||||
ui: initialUIState,
|
ui: initialUIState,
|
||||||
hotkeys: initialHotkeysState,
|
|
||||||
controlAdapters: initialControlAdapterState,
|
controlAdapters: initialControlAdapterState,
|
||||||
dynamicPrompts: initialDynamicPromptsState,
|
dynamicPrompts: initialDynamicPromptsState,
|
||||||
sdxl: initialSDXLState,
|
sdxl: initialSDXLState,
|
||||||
|
@ -20,9 +20,15 @@ export const addDeleteBoardAndImagesFulfilledListener = () => {
|
|||||||
let wasNodeEditorReset = false;
|
let wasNodeEditorReset = false;
|
||||||
let wereControlAdaptersReset = false;
|
let wereControlAdaptersReset = false;
|
||||||
|
|
||||||
const state = getState();
|
const { generation, canvas, nodes, controlAdapters } = getState();
|
||||||
deleted_images.forEach((image_name) => {
|
deleted_images.forEach((image_name) => {
|
||||||
const imageUsage = getImageUsage(state, image_name);
|
const imageUsage = getImageUsage(
|
||||||
|
generation,
|
||||||
|
canvas,
|
||||||
|
nodes,
|
||||||
|
controlAdapters,
|
||||||
|
image_name
|
||||||
|
);
|
||||||
|
|
||||||
if (imageUsage.isInitialImage && !wasInitialImageReset) {
|
if (imageUsage.isInitialImage && !wasInitialImageReset) {
|
||||||
dispatch(clearInitialImage());
|
dispatch(clearInitialImage());
|
||||||
|
@ -151,6 +151,3 @@ export type RootState = ReturnType<ReturnType<typeof createStore>['getState']>;
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export type AppThunkDispatch = ThunkDispatch<RootState, any, UnknownAction>;
|
export type AppThunkDispatch = ThunkDispatch<RootState, any, UnknownAction>;
|
||||||
export type AppDispatch = ReturnType<typeof createStore>['dispatch'];
|
export type AppDispatch = ReturnType<typeof createStore>['dispatch'];
|
||||||
export function stateSelector(state: RootState) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
@ -32,7 +32,7 @@ const IAIInformationalPopover = ({
|
|||||||
...rest
|
...rest
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const shouldEnableInformationalPopovers = useAppSelector(
|
const shouldEnableInformationalPopovers = useAppSelector(
|
||||||
(state) => state.system.shouldEnableInformationalPopovers
|
(s) => s.system.shouldEnableInformationalPopovers
|
||||||
);
|
);
|
||||||
|
|
||||||
const data = useMemo(() => POPOVER_DATA[feature], [feature]);
|
const data = useMemo(() => POPOVER_DATA[feature], [feature]);
|
||||||
|
@ -13,7 +13,7 @@ export const InvLabel = memo(
|
|||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const shouldEnableInformationalPopovers = useAppSelector(
|
const shouldEnableInformationalPopovers = useAppSelector(
|
||||||
(state) => state.system.shouldEnableInformationalPopovers
|
(s) => s.system.shouldEnableInformationalPopovers
|
||||||
);
|
);
|
||||||
|
|
||||||
const ctx = useContext(InvControlGroupContext);
|
const ctx = useContext(InvControlGroupContext);
|
||||||
|
@ -30,7 +30,7 @@ export const useGroupedModelInvSelect = <T extends AnyModelConfigEntity>(
|
|||||||
): UseGroupedModelInvSelectReturn => {
|
): UseGroupedModelInvSelectReturn => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const base_model = useAppSelector(
|
const base_model = useAppSelector(
|
||||||
(state) => state.generation.model?.base_model ?? 'sdxl'
|
(s) => s.generation.model?.base_model ?? 'sdxl'
|
||||||
);
|
);
|
||||||
const { modelEntities, selectedModel, getIsDisabled, onChange, isLoading } =
|
const { modelEntities, selectedModel, getIsDisabled, onChange, isLoading } =
|
||||||
arg;
|
arg;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useAppToaster } from 'app/components/Toaster';
|
import { useAppToaster } from 'app/components/Toaster';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
@ -16,8 +16,8 @@ const accept: Accept = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector],
|
[(state: RootState) => state.gallery, activeTabNameSelector],
|
||||||
({ gallery }, activeTabName) => {
|
(gallery, activeTabName) => {
|
||||||
let postUploadAction: PostUploadAction = { type: 'TOAST' };
|
let postUploadAction: PostUploadAction = { type: 'TOAST' };
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'unifiedCanvas') {
|
||||||
|
@ -33,7 +33,7 @@ export const useImageUploadButton = ({
|
|||||||
isDisabled,
|
isDisabled,
|
||||||
}: UseImageUploadButtonArgs) => {
|
}: UseImageUploadButtonArgs) => {
|
||||||
const autoAddBoardId = useAppSelector(
|
const autoAddBoardId = useAppSelector(
|
||||||
(state) => state.gallery.autoAddBoardId
|
(s) => s.gallery.autoAddBoardId
|
||||||
);
|
);
|
||||||
const [uploadImage] = useUploadImageMutation();
|
const [uploadImage] = useUploadImageMutation();
|
||||||
const onDropAccepted = useCallback(
|
const onDropAccepted = useCallback(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterAll } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import { selectControlAdapterAll } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
@ -11,16 +11,22 @@ import { forEach } from 'lodash-es';
|
|||||||
import { getConnectedEdges } from 'reactflow';
|
import { getConnectedEdges } from 'reactflow';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector],
|
[
|
||||||
|
(state: RootState) => state.controlAdapters,
|
||||||
|
(state: RootState) => state.generation,
|
||||||
|
(state: RootState) => state.system,
|
||||||
|
(state: RootState) => state.nodes,
|
||||||
|
(state: RootState) => state.nodeTemplates,
|
||||||
|
(state: RootState) => state.dynamicPrompts,
|
||||||
|
activeTabNameSelector,
|
||||||
|
],
|
||||||
(
|
(
|
||||||
{
|
controlAdapters,
|
||||||
controlAdapters,
|
generation,
|
||||||
generation,
|
system,
|
||||||
system,
|
nodes,
|
||||||
nodes,
|
nodeTemplates,
|
||||||
nodeTemplates,
|
dynamicPrompts,
|
||||||
dynamicPrompts,
|
|
||||||
},
|
|
||||||
activeTabName
|
activeTabName
|
||||||
) => {
|
) => {
|
||||||
const { initialImage, model, positivePrompt } = generation;
|
const { initialImage, model, positivePrompt } = generation;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Box, chakra, Flex } from '@chakra-ui/react';
|
import { Box, chakra, Flex } from '@chakra-ui/react';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import useCanvasDragMove from 'features/canvas/hooks/useCanvasDragMove';
|
import useCanvasDragMove from 'features/canvas/hooks/useCanvasDragMove';
|
||||||
import useCanvasHotkeys from 'features/canvas/hooks/useCanvasHotkeys';
|
import useCanvasHotkeys from 'features/canvas/hooks/useCanvasHotkeys';
|
||||||
@ -17,7 +16,10 @@ import {
|
|||||||
$isTransformingBoundingBox,
|
$isTransformingBoundingBox,
|
||||||
} from 'features/canvas/store/canvasNanostore';
|
} from 'features/canvas/store/canvasNanostore';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { canvasResized } from 'features/canvas/store/canvasSlice';
|
import {
|
||||||
|
canvasResized,
|
||||||
|
selectCanvasSlice,
|
||||||
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import {
|
import {
|
||||||
setCanvasBaseLayer,
|
setCanvasBaseLayer,
|
||||||
setCanvasStage,
|
setCanvasStage,
|
||||||
@ -41,8 +43,8 @@ import IAICanvasBoundingBox from './IAICanvasToolbar/IAICanvasBoundingBox';
|
|||||||
import IAICanvasToolPreview from './IAICanvasToolPreview';
|
import IAICanvasToolPreview from './IAICanvasToolPreview';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, isStagingSelector],
|
[selectCanvasSlice, isStagingSelector],
|
||||||
({ canvas }, isStaging) => {
|
(canvas, isStaging) => {
|
||||||
const {
|
const {
|
||||||
isMaskEnabled,
|
isMaskEnabled,
|
||||||
stageScale,
|
stageScale,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Group, Rect } from 'react-konva';
|
import { Group, Rect } from 'react-konva';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ canvas }) => {
|
const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
|
||||||
const {
|
const {
|
||||||
boundingBoxCoordinates,
|
boundingBoxCoordinates,
|
||||||
boundingBoxDimensions,
|
boundingBoxDimensions,
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
// Grid drawing adapted from https://longviewcoder.com/2021/12/08/konva-a-better-grid/
|
// Grid drawing adapted from https://longviewcoder.com/2021/12/08/konva-a-better-grid/
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { Group, Line as KonvaLine } from 'react-konva';
|
import { Group, Line as KonvaLine } from 'react-konva';
|
||||||
import { getArbitraryBaseColor } from 'theme/colors';
|
import { getArbitraryBaseColor } from 'theme/colors';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ canvas }) => {
|
const selector = createMemoizedSelector([selectCanvasSlice], (canvas) => {
|
||||||
const { stageScale, stageCoordinates, stageDimensions } = canvas;
|
const { stageScale, stageCoordinates, stageDimensions } = canvas;
|
||||||
return { stageScale, stageCoordinates, stageDimensions };
|
return { stageScale, stageCoordinates, stageDimensions };
|
||||||
});
|
});
|
||||||
|
@ -2,14 +2,15 @@ import {
|
|||||||
createLruSelector,
|
createLruSelector,
|
||||||
createMemoizedSelector,
|
createMemoizedSelector,
|
||||||
} from 'app/store/createMemoizedSelector';
|
} from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
|
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||||
import { memo, useEffect, useState } from 'react';
|
import { memo, useEffect, useState } from 'react';
|
||||||
import { Image as KonvaImage } from 'react-konva';
|
import { Image as KonvaImage } from 'react-konva';
|
||||||
|
|
||||||
const progressImageSelector = createLruSelector(
|
const progressImageSelector = createLruSelector(
|
||||||
[stateSelector],
|
[selectSystemSlice, selectCanvasSlice],
|
||||||
({ system, canvas }) => {
|
(system, canvas) => {
|
||||||
const { denoiseProgress } = system;
|
const { denoiseProgress } = system;
|
||||||
const { batchIds } = canvas;
|
const { batchIds } = canvas;
|
||||||
|
|
||||||
@ -20,8 +21,8 @@ const progressImageSelector = createLruSelector(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const boundingBoxSelector = createMemoizedSelector(
|
const boundingBoxSelector = createMemoizedSelector(
|
||||||
[stateSelector],
|
[selectCanvasSlice],
|
||||||
({ canvas }) => canvas.layerState.stagingArea.boundingBox
|
(canvas) => canvas.layerState.stagingArea.boundingBox
|
||||||
);
|
);
|
||||||
|
|
||||||
const IAICanvasIntermediateImage = () => {
|
const IAICanvasIntermediateImage = () => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
import type { RectConfig } from 'konva/lib/shapes/Rect';
|
import type { RectConfig } from 'konva/lib/shapes/Rect';
|
||||||
@ -9,8 +9,8 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { Rect } from 'react-konva';
|
import { Rect } from 'react-konva';
|
||||||
|
|
||||||
export const canvasMaskCompositerSelector = createMemoizedSelector(
|
export const canvasMaskCompositerSelector = createMemoizedSelector(
|
||||||
stateSelector,
|
selectCanvasSlice,
|
||||||
({ canvas }) => {
|
(canvas) => {
|
||||||
const { maskColor, stageCoordinates, stageDimensions, stageScale } = canvas;
|
const { maskColor, stageCoordinates, stageDimensions, stageScale } = canvas;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,18 +1,9 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { isCanvasMaskLine } from 'features/canvas/store/canvasTypes';
|
import { isCanvasMaskLine } from 'features/canvas/store/canvasTypes';
|
||||||
import type { GroupConfig } from 'konva/lib/Group';
|
import type { GroupConfig } from 'konva/lib/Group';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Group, Line } from 'react-konva';
|
import { Group, Line } from 'react-konva';
|
||||||
|
|
||||||
export const canvasLinesSelector = createMemoizedSelector(
|
|
||||||
[stateSelector],
|
|
||||||
({ canvas }) => {
|
|
||||||
return canvas.layerState.objects.filter(isCanvasMaskLine);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
type InpaintingCanvasLinesProps = GroupConfig;
|
type InpaintingCanvasLinesProps = GroupConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +12,7 @@ type InpaintingCanvasLinesProps = GroupConfig;
|
|||||||
* Uses globalCompositeOperation to handle the brush and eraser tools.
|
* Uses globalCompositeOperation to handle the brush and eraser tools.
|
||||||
*/
|
*/
|
||||||
const IAICanvasLines = (props: InpaintingCanvasLinesProps) => {
|
const IAICanvasLines = (props: InpaintingCanvasLinesProps) => {
|
||||||
const objects = useAppSelector((state) => state.canvas.layerState.objects);
|
const objects = useAppSelector((s) => s.canvas.layerState.objects);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group listening={false} {...props}>
|
<Group listening={false} {...props}>
|
||||||
|
@ -12,7 +12,7 @@ import { Group, Line, Rect } from 'react-konva';
|
|||||||
import IAICanvasImage from './IAICanvasImage';
|
import IAICanvasImage from './IAICanvasImage';
|
||||||
|
|
||||||
const IAICanvasObjectRenderer = () => {
|
const IAICanvasObjectRenderer = () => {
|
||||||
const objects = useAppSelector((state) => state.canvas.layerState.objects);
|
const objects = useAppSelector((s) => s.canvas.layerState.objects);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group name="outpainting-objects" listening={false}>
|
<Group name="outpainting-objects" listening={false}>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import type { GroupConfig } from 'konva/lib/Group';
|
import type { GroupConfig } from 'konva/lib/Group';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { Group, Rect } from 'react-konva';
|
import { Group, Rect } from 'react-konva';
|
||||||
@ -9,7 +9,7 @@ import IAICanvasImage from './IAICanvasImage';
|
|||||||
|
|
||||||
const dash = [4, 4];
|
const dash = [4, 4];
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ canvas }) => {
|
const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
|
||||||
const {
|
const {
|
||||||
layerState,
|
layerState,
|
||||||
shouldShowStagingImage,
|
shouldShowStagingImage,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
@ -11,6 +10,7 @@ import {
|
|||||||
discardStagedImages,
|
discardStagedImages,
|
||||||
nextStagingAreaImage,
|
nextStagingAreaImage,
|
||||||
prevStagingAreaImage,
|
prevStagingAreaImage,
|
||||||
|
selectCanvasSlice,
|
||||||
setShouldShowStagingImage,
|
setShouldShowStagingImage,
|
||||||
setShouldShowStagingOutline,
|
setShouldShowStagingOutline,
|
||||||
} from 'features/canvas/store/canvasSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
@ -29,7 +29,7 @@ import {
|
|||||||
} from 'react-icons/fa';
|
} from 'react-icons/fa';
|
||||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ canvas }) => {
|
const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
|
||||||
const {
|
const {
|
||||||
layerState: {
|
layerState: {
|
||||||
stagingArea: { images, selectedImageIndex },
|
stagingArea: { images, selectedImageIndex },
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Box, Flex } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import roundToHundreth from 'features/canvas/util/roundToHundreth';
|
import roundToHundreth from 'features/canvas/util/roundToHundreth';
|
||||||
import GenerationModeStatusText from 'features/parameters/components/Canvas/GenerationModeStatusText';
|
import GenerationModeStatusText from 'features/parameters/components/Canvas/GenerationModeStatusText';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -11,7 +11,7 @@ import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusT
|
|||||||
|
|
||||||
const warningColor = 'var(--invokeai-colors-warning-500)';
|
const warningColor = 'var(--invokeai-colors-warning-500)';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ canvas }) => {
|
const selector = createMemoizedSelector(selectCanvasSlice, (canvas) => {
|
||||||
const {
|
const {
|
||||||
stageDimensions: { width: stageWidth, height: stageHeight },
|
stageDimensions: { width: stageWidth, height: stageHeight },
|
||||||
stageCoordinates: { x: stageX, y: stageY },
|
stageCoordinates: { x: stageX, y: stageY },
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
$cursorPosition,
|
$cursorPosition,
|
||||||
$isMovingBoundingBox,
|
$isMovingBoundingBox,
|
||||||
$isTransformingBoundingBox,
|
$isTransformingBoundingBox,
|
||||||
} from 'features/canvas/store/canvasNanostore';
|
} from 'features/canvas/store/canvasNanostore';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
import { rgbaColorToString } from 'features/canvas/util/colorToString';
|
||||||
import {
|
import {
|
||||||
COLOR_PICKER_SIZE,
|
COLOR_PICKER_SIZE,
|
||||||
@ -17,8 +17,8 @@ import { memo, useMemo } from 'react';
|
|||||||
import { Circle, Group } from 'react-konva';
|
import { Circle, Group } from 'react-konva';
|
||||||
|
|
||||||
const canvasBrushPreviewSelector = createMemoizedSelector(
|
const canvasBrushPreviewSelector = createMemoizedSelector(
|
||||||
stateSelector,
|
selectCanvasSlice,
|
||||||
({ canvas }) => {
|
(canvas) => {
|
||||||
const {
|
const {
|
||||||
brushSize,
|
brushSize,
|
||||||
colorPickerColor,
|
colorPickerColor,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { $shift } from 'common/hooks/useGlobalModifiers';
|
import { $shift } from 'common/hooks/useGlobalModifiers';
|
||||||
import {
|
import {
|
||||||
@ -18,6 +17,7 @@ import {
|
|||||||
} from 'features/canvas/store/canvasNanostore';
|
} from 'features/canvas/store/canvasNanostore';
|
||||||
import {
|
import {
|
||||||
aspectRatioChanged,
|
aspectRatioChanged,
|
||||||
|
selectCanvasSlice,
|
||||||
setBoundingBoxCoordinates,
|
setBoundingBoxCoordinates,
|
||||||
setBoundingBoxDimensions,
|
setBoundingBoxDimensions,
|
||||||
setShouldSnapToGrid,
|
setShouldSnapToGrid,
|
||||||
@ -39,8 +39,8 @@ import { Group, Rect, Transformer } from 'react-konva';
|
|||||||
const borderDash = [4, 4];
|
const borderDash = [4, 4];
|
||||||
|
|
||||||
const boundingBoxPreviewSelector = createMemoizedSelector(
|
const boundingBoxPreviewSelector = createMemoizedSelector(
|
||||||
[stateSelector, selectOptimalDimension],
|
[selectCanvasSlice, selectOptimalDimension],
|
||||||
({ canvas }, optimalDimension) => {
|
(canvas, optimalDimension) => {
|
||||||
const {
|
const {
|
||||||
boundingBoxCoordinates,
|
boundingBoxCoordinates,
|
||||||
boundingBoxDimensions,
|
boundingBoxDimensions,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Box, Flex } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
@ -17,6 +16,7 @@ import { canvasMaskSavedToGallery } from 'features/canvas/store/actions';
|
|||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import {
|
import {
|
||||||
clearMask,
|
clearMask,
|
||||||
|
selectCanvasSlice,
|
||||||
setIsMaskEnabled,
|
setIsMaskEnabled,
|
||||||
setLayer,
|
setLayer,
|
||||||
setMaskColor,
|
setMaskColor,
|
||||||
@ -31,8 +31,8 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { FaMask, FaSave, FaTrash } from 'react-icons/fa';
|
import { FaMask, FaSave, FaTrash } from 'react-icons/fa';
|
||||||
|
|
||||||
export const selector = createMemoizedSelector(
|
export const selector = createMemoizedSelector(
|
||||||
[stateSelector, isStagingSelector],
|
[selectCanvasSlice, isStagingSelector],
|
||||||
({ canvas }, isStaging) => {
|
(canvas, isStaging) => {
|
||||||
const { maskColor, layer, isMaskEnabled, shouldPreserveMaskedArea } =
|
const { maskColor, layer, isMaskEnabled, shouldPreserveMaskedArea } =
|
||||||
canvas;
|
canvas;
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { redo } from 'features/canvas/store/canvasSlice';
|
import { redo, selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
@ -10,8 +9,8 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { FaRedo } from 'react-icons/fa';
|
import { FaRedo } from 'react-icons/fa';
|
||||||
|
|
||||||
const canvasRedoSelector = createMemoizedSelector(
|
const canvasRedoSelector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector],
|
[selectCanvasSlice, activeTabNameSelector],
|
||||||
({ canvas }, activeTabName) => {
|
(canvas, activeTabName) => {
|
||||||
const { futureLayerStates } = canvas;
|
const { futureLayerStates } = canvas;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvCheckbox } from 'common/components/InvCheckbox/wrapper';
|
import { InvCheckbox } from 'common/components/InvCheckbox/wrapper';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
@ -11,6 +10,7 @@ import {
|
|||||||
} from 'common/components/InvPopover/wrapper';
|
} from 'common/components/InvPopover/wrapper';
|
||||||
import ClearCanvasHistoryButtonModal from 'features/canvas/components/ClearCanvasHistoryButtonModal';
|
import ClearCanvasHistoryButtonModal from 'features/canvas/components/ClearCanvasHistoryButtonModal';
|
||||||
import {
|
import {
|
||||||
|
selectCanvasSlice,
|
||||||
setShouldAntialias,
|
setShouldAntialias,
|
||||||
setShouldAutoSave,
|
setShouldAutoSave,
|
||||||
setShouldCropToBoundingBoxOnSave,
|
setShouldCropToBoundingBoxOnSave,
|
||||||
@ -29,8 +29,8 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { FaWrench } from 'react-icons/fa';
|
import { FaWrench } from 'react-icons/fa';
|
||||||
|
|
||||||
export const canvasControlsSelector = createMemoizedSelector(
|
export const canvasControlsSelector = createMemoizedSelector(
|
||||||
[stateSelector],
|
[selectCanvasSlice],
|
||||||
({ canvas }) => {
|
(canvas) => {
|
||||||
const {
|
const {
|
||||||
shouldAutoSave,
|
shouldAutoSave,
|
||||||
shouldCropToBoundingBoxOnSave,
|
shouldCropToBoundingBoxOnSave,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Box, Flex } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
@ -17,6 +16,7 @@ import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
|||||||
import {
|
import {
|
||||||
addEraseRect,
|
addEraseRect,
|
||||||
addFillRect,
|
addFillRect,
|
||||||
|
selectCanvasSlice,
|
||||||
setBrushColor,
|
setBrushColor,
|
||||||
setBrushSize,
|
setBrushSize,
|
||||||
setTool,
|
setTool,
|
||||||
@ -37,8 +37,8 @@ import {
|
|||||||
} from 'react-icons/fa';
|
} from 'react-icons/fa';
|
||||||
|
|
||||||
export const selector = createMemoizedSelector(
|
export const selector = createMemoizedSelector(
|
||||||
[stateSelector, isStagingSelector],
|
[selectCanvasSlice, isStagingSelector],
|
||||||
({ canvas }, isStaging) => {
|
(canvas, isStaging) => {
|
||||||
const { tool, brushColor, brushSize } = canvas;
|
const { tool, brushColor, brushSize } = canvas;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
@ -20,6 +19,7 @@ import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
|||||||
import {
|
import {
|
||||||
resetCanvas,
|
resetCanvas,
|
||||||
resetCanvasView,
|
resetCanvasView,
|
||||||
|
selectCanvasSlice,
|
||||||
setIsMaskEnabled,
|
setIsMaskEnabled,
|
||||||
setLayer,
|
setLayer,
|
||||||
setTool,
|
setTool,
|
||||||
@ -49,8 +49,8 @@ import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
|
|||||||
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
import IAICanvasUndoButton from './IAICanvasUndoButton';
|
||||||
|
|
||||||
export const selector = createMemoizedSelector(
|
export const selector = createMemoizedSelector(
|
||||||
[stateSelector, isStagingSelector],
|
[selectCanvasSlice, isStagingSelector],
|
||||||
({ canvas }, isStaging) => {
|
(canvas, isStaging) => {
|
||||||
const { tool, shouldCropToBoundingBoxOnSave, layer, isMaskEnabled } =
|
const { tool, shouldCropToBoundingBoxOnSave, layer, isMaskEnabled } =
|
||||||
canvas;
|
canvas;
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { undo } from 'features/canvas/store/canvasSlice';
|
import { selectCanvasSlice,undo } from 'features/canvas/store/canvasSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
@ -10,8 +9,8 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { FaUndo } from 'react-icons/fa';
|
import { FaUndo } from 'react-icons/fa';
|
||||||
|
|
||||||
const canvasUndoSelector = createMemoizedSelector(
|
const canvasUndoSelector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector],
|
[selectCanvasSlice, activeTabNameSelector],
|
||||||
({ canvas }, activeTabName) => {
|
(canvas, activeTabName) => {
|
||||||
const { pastLayerStates } = canvas;
|
const { pastLayerStates } = canvas;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -12,7 +12,7 @@ import { useCallback } from 'react';
|
|||||||
const useCanvasDrag = () => {
|
const useCanvasDrag = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isStaging = useAppSelector(isStagingSelector);
|
const isStaging = useAppSelector(isStagingSelector);
|
||||||
const tool = useAppSelector((state) => state.canvas.tool);
|
const tool = useAppSelector((s) => s.canvas.tool);
|
||||||
const isMovingBoundingBox = useStore($isMovingBoundingBox);
|
const isMovingBoundingBox = useStore($isMovingBoundingBox);
|
||||||
const handleDragStart = useCallback(() => {
|
const handleDragStart = useCallback(() => {
|
||||||
if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) {
|
if (!((tool === 'move' || isStaging) && !isMovingBoundingBox)) {
|
||||||
|
@ -6,18 +6,18 @@ import { useEffect, useState } from 'react';
|
|||||||
import { useDebounce } from 'react-use';
|
import { useDebounce } from 'react-use';
|
||||||
|
|
||||||
export const useCanvasGenerationMode = () => {
|
export const useCanvasGenerationMode = () => {
|
||||||
const layerState = useAppSelector((state) => state.canvas.layerState);
|
const layerState = useAppSelector((s) => s.canvas.layerState);
|
||||||
|
|
||||||
const boundingBoxCoordinates = useAppSelector(
|
const boundingBoxCoordinates = useAppSelector(
|
||||||
(state) => state.canvas.boundingBoxCoordinates
|
(s) => s.canvas.boundingBoxCoordinates
|
||||||
);
|
);
|
||||||
const boundingBoxDimensions = useAppSelector(
|
const boundingBoxDimensions = useAppSelector(
|
||||||
(state) => state.canvas.boundingBoxDimensions
|
(s) => s.canvas.boundingBoxDimensions
|
||||||
);
|
);
|
||||||
const isMaskEnabled = useAppSelector((state) => state.canvas.isMaskEnabled);
|
const isMaskEnabled = useAppSelector((s) => s.canvas.isMaskEnabled);
|
||||||
|
|
||||||
const shouldPreserveMaskedArea = useAppSelector(
|
const shouldPreserveMaskedArea = useAppSelector(
|
||||||
(state) => state.canvas.shouldPreserveMaskedArea
|
(s) => s.canvas.shouldPreserveMaskedArea
|
||||||
);
|
);
|
||||||
const [generationMode, setGenerationMode] = useState<
|
const [generationMode, setGenerationMode] = useState<
|
||||||
GenerationMode | undefined
|
GenerationMode | undefined
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
resetCanvasInteractionState,
|
resetCanvasInteractionState,
|
||||||
@ -8,6 +7,7 @@ import {
|
|||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import {
|
import {
|
||||||
clearMask,
|
clearMask,
|
||||||
|
selectCanvasSlice,
|
||||||
setIsMaskEnabled,
|
setIsMaskEnabled,
|
||||||
setShouldShowBoundingBox,
|
setShouldShowBoundingBox,
|
||||||
setShouldSnapToGrid,
|
setShouldSnapToGrid,
|
||||||
@ -20,8 +20,8 @@ import { useRef } from 'react';
|
|||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector, isStagingSelector],
|
[selectCanvasSlice, activeTabNameSelector, isStagingSelector],
|
||||||
({ canvas }, activeTabName, isStaging) => {
|
(canvas, activeTabName, isStaging) => {
|
||||||
const {
|
const {
|
||||||
shouldLockBoundingBox,
|
shouldLockBoundingBox,
|
||||||
shouldShowBoundingBox,
|
shouldShowBoundingBox,
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
setIsDrawing,
|
setIsDrawing,
|
||||||
setIsMovingStage,
|
setIsMovingStage,
|
||||||
} from 'features/canvas/store/canvasNanostore';
|
} from 'features/canvas/store/canvasNanostore';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { addLine } from 'features/canvas/store/canvasSlice';
|
import { addLine, selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
|
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
@ -17,11 +16,10 @@ import { useCallback } from 'react';
|
|||||||
import useColorPicker from './useColorUnderCursor';
|
import useColorPicker from './useColorUnderCursor';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[activeTabNameSelector, stateSelector, isStagingSelector],
|
[activeTabNameSelector, selectCanvasSlice, isStagingSelector],
|
||||||
(activeTabName, { canvas }, isStaging) => {
|
(activeTabName, canvas, isStaging) => {
|
||||||
const { tool } = canvas;
|
|
||||||
return {
|
return {
|
||||||
tool,
|
tool: canvas.tool,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
isStaging,
|
isStaging,
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
$isDrawing,
|
$isDrawing,
|
||||||
setCursorPosition,
|
setCursorPosition,
|
||||||
} from 'features/canvas/store/canvasNanostore';
|
} from 'features/canvas/store/canvasNanostore';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { addPointToCurrentLine } from 'features/canvas/store/canvasSlice';
|
import {
|
||||||
|
addPointToCurrentLine,
|
||||||
|
selectCanvasSlice,
|
||||||
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
|
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
@ -18,11 +20,10 @@ import { useCallback } from 'react';
|
|||||||
import useColorPicker from './useColorUnderCursor';
|
import useColorPicker from './useColorUnderCursor';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[activeTabNameSelector, stateSelector, isStagingSelector],
|
[activeTabNameSelector, selectCanvasSlice, isStagingSelector],
|
||||||
(activeTabName, { canvas }, isStaging) => {
|
(activeTabName, canvas, isStaging) => {
|
||||||
const { tool } = canvas;
|
|
||||||
return {
|
return {
|
||||||
tool,
|
tool: canvas.tool,
|
||||||
activeTabName,
|
activeTabName,
|
||||||
isStaging,
|
isStaging,
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
$isDrawing,
|
$isDrawing,
|
||||||
@ -8,32 +6,20 @@ import {
|
|||||||
setIsMovingStage,
|
setIsMovingStage,
|
||||||
} from 'features/canvas/store/canvasNanostore';
|
} from 'features/canvas/store/canvasNanostore';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import {
|
import { addPointToCurrentLine } from 'features/canvas/store/canvasSlice';
|
||||||
// addPointToCurrentEraserLine,
|
|
||||||
addPointToCurrentLine,
|
|
||||||
} from 'features/canvas/store/canvasSlice';
|
|
||||||
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
|
import getScaledCursorPosition from 'features/canvas/util/getScaledCursorPosition';
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
import type { MutableRefObject } from 'react';
|
import type { MutableRefObject } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
|
||||||
[stateSelector, isStagingSelector],
|
|
||||||
({ canvas }, isStaging) => {
|
|
||||||
return {
|
|
||||||
tool: canvas.tool,
|
|
||||||
isStaging,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const useCanvasMouseUp = (
|
const useCanvasMouseUp = (
|
||||||
stageRef: MutableRefObject<Konva.Stage | null>,
|
stageRef: MutableRefObject<Konva.Stage | null>,
|
||||||
didMouseMoveRef: MutableRefObject<boolean>
|
didMouseMoveRef: MutableRefObject<boolean>
|
||||||
) => {
|
) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const isDrawing = useStore($isDrawing);
|
const isDrawing = useStore($isDrawing);
|
||||||
const { tool, isStaging } = useAppSelector(selector);
|
const tool = useAppSelector((s) => s.canvas.tool);
|
||||||
|
const isStaging = useAppSelector(isStagingSelector);
|
||||||
|
|
||||||
return useCallback(() => {
|
return useCallback(() => {
|
||||||
if (tool === 'move' || isStaging) {
|
if (tool === 'move' || isStaging) {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { $isMoveStageKeyHeld } from 'features/canvas/store/canvasNanostore';
|
import { $isMoveStageKeyHeld } from 'features/canvas/store/canvasNanostore';
|
||||||
import {
|
import {
|
||||||
@ -18,14 +16,9 @@ import { clamp } from 'lodash-es';
|
|||||||
import type { MutableRefObject } from 'react';
|
import type { MutableRefObject } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
|
||||||
[stateSelector],
|
|
||||||
(state) => state.canvas.stageScale
|
|
||||||
);
|
|
||||||
|
|
||||||
const useCanvasWheel = (stageRef: MutableRefObject<Konva.Stage | null>) => {
|
const useCanvasWheel = (stageRef: MutableRefObject<Konva.Stage | null>) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const stageScale = useAppSelector(selector);
|
const stageScale = useAppSelector((s) => s.canvas.stageScale);
|
||||||
const isMoveStageKeyHeld = useStore($isMoveStageKeyHeld);
|
const isMoveStageKeyHeld = useStore($isMoveStageKeyHeld);
|
||||||
|
|
||||||
return useCallback(
|
return useCallback(
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
|
|
||||||
|
import { selectCanvasSlice } from './canvasSlice';
|
||||||
import type { CanvasImage } from './canvasTypes';
|
import type { CanvasImage } from './canvasTypes';
|
||||||
import { isCanvasBaseImage } from './canvasTypes';
|
import { isCanvasBaseImage } from './canvasTypes';
|
||||||
|
|
||||||
export const isStagingSelector = createMemoizedSelector(
|
export const isStagingSelector = createMemoizedSelector(
|
||||||
[stateSelector],
|
selectCanvasSlice,
|
||||||
({ canvas }) =>
|
(canvas) =>
|
||||||
canvas.batchIds.length > 0 ||
|
canvas.batchIds.length > 0 ||
|
||||||
canvas.layerState.stagingArea.images.length > 0
|
canvas.layerState.stagingArea.images.length > 0
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import {
|
import {
|
||||||
roundDownToMultiple,
|
roundDownToMultiple,
|
||||||
roundToMultiple,
|
roundToMultiple,
|
||||||
@ -781,3 +782,5 @@ export const {
|
|||||||
} = canvasSlice.actions;
|
} = canvasSlice.actions;
|
||||||
|
|
||||||
export default canvasSlice.reducer;
|
export default canvasSlice.reducer;
|
||||||
|
|
||||||
|
export const selectCanvasSlice = (state: RootState) => state.canvas;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
@ -13,6 +12,7 @@ import { InvText } from 'common/components/InvText/wrapper';
|
|||||||
import {
|
import {
|
||||||
changeBoardReset,
|
changeBoardReset,
|
||||||
isModalOpenChanged,
|
isModalOpenChanged,
|
||||||
|
selectChangeBoardModalSlice,
|
||||||
} from 'features/changeBoardModal/store/slice';
|
} from 'features/changeBoardModal/store/slice';
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -23,8 +23,8 @@ import {
|
|||||||
} from 'services/api/endpoints/images';
|
} from 'services/api/endpoints/images';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector],
|
selectChangeBoardModalSlice,
|
||||||
({ changeBoardModal }) => {
|
(changeBoardModal) => {
|
||||||
const { isModalOpen, imagesToChange } = changeBoardModal;
|
const { isModalOpen, imagesToChange } = changeBoardModal;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
import type { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
import { initialState } from './initialState';
|
import { initialState } from './initialState';
|
||||||
@ -25,3 +26,6 @@ export const { isModalOpenChanged, imagesToChangeSelected, changeBoardReset } =
|
|||||||
changeBoardModal.actions;
|
changeBoardModal.actions;
|
||||||
|
|
||||||
export default changeBoardModal.reducer;
|
export default changeBoardModal.reducer;
|
||||||
|
|
||||||
|
export const selectChangeBoardModalSlice = (state: RootState) =>
|
||||||
|
state.changeBoardModal;
|
||||||
|
@ -2,7 +2,6 @@ import type { SystemStyleObject } from '@chakra-ui/react';
|
|||||||
import { Box, Flex, Spinner } from '@chakra-ui/react';
|
import { Box, Flex, Spinner } from '@chakra-ui/react';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIDndImage from 'common/components/IAIDndImage';
|
import IAIDndImage from 'common/components/IAIDndImage';
|
||||||
import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
|
import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
|
||||||
@ -10,16 +9,21 @@ import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
|||||||
import { useControlAdapterControlImage } from 'features/controlAdapters/hooks/useControlAdapterControlImage';
|
import { useControlAdapterControlImage } from 'features/controlAdapters/hooks/useControlAdapterControlImage';
|
||||||
import { useControlAdapterProcessedControlImage } from 'features/controlAdapters/hooks/useControlAdapterProcessedControlImage';
|
import { useControlAdapterProcessedControlImage } from 'features/controlAdapters/hooks/useControlAdapterProcessedControlImage';
|
||||||
import { useControlAdapterProcessorType } from 'features/controlAdapters/hooks/useControlAdapterProcessorType';
|
import { useControlAdapterProcessorType } from 'features/controlAdapters/hooks/useControlAdapterProcessorType';
|
||||||
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
controlAdapterImageChanged,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import type {
|
import type {
|
||||||
TypesafeDraggableData,
|
TypesafeDraggableData,
|
||||||
TypesafeDroppableData,
|
TypesafeDroppableData,
|
||||||
} from 'features/dnd/types';
|
} from 'features/dnd/types';
|
||||||
|
import { selectGallerySlice } from 'features/gallery/store/gallerySlice';
|
||||||
import {
|
import {
|
||||||
heightChanged,
|
heightChanged,
|
||||||
selectOptimalDimension,
|
selectOptimalDimension,
|
||||||
widthChanged,
|
widthChanged,
|
||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -38,8 +42,14 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector, selectOptimalDimension],
|
[
|
||||||
({ controlAdapters, gallery, system }, activeTabName, optimalDimension) => {
|
selectControlAdaptersSlice,
|
||||||
|
selectGallerySlice,
|
||||||
|
selectSystemSlice,
|
||||||
|
activeTabNameSelector,
|
||||||
|
selectOptimalDimension,
|
||||||
|
],
|
||||||
|
(controlAdapters, gallery, system, activeTabName, optimalDimension) => {
|
||||||
const { pendingControlImages } = controlAdapters;
|
const { pendingControlImages } = controlAdapters;
|
||||||
const { autoAddBoardId } = gallery;
|
const { autoAddBoardId } = gallery;
|
||||||
const { isConnected } = system;
|
const { isConnected } = system;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
||||||
@ -10,6 +9,7 @@ import { useControlAdapterModel } from 'features/controlAdapters/hooks/useContro
|
|||||||
import { useControlAdapterModelEntities } from 'features/controlAdapters/hooks/useControlAdapterModelEntities';
|
import { useControlAdapterModelEntities } from 'features/controlAdapters/hooks/useControlAdapterModelEntities';
|
||||||
import { useControlAdapterType } from 'features/controlAdapters/hooks/useControlAdapterType';
|
import { useControlAdapterType } from 'features/controlAdapters/hooks/useControlAdapterType';
|
||||||
import { controlAdapterModelChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import { controlAdapterModelChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
|
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
||||||
import { pick } from 'lodash-es';
|
import { pick } from 'lodash-es';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -24,9 +24,8 @@ type ParamControlAdapterModelProps = {
|
|||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ generation }) => {
|
const selector = createMemoizedSelector(selectGenerationSlice, (generation) => {
|
||||||
const { model } = generation;
|
return { mainModel: generation.model };
|
||||||
return { mainModel: model };
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ParamControlAdapterModel = ({ id }: ParamControlAdapterModelProps) => {
|
const ParamControlAdapterModel = ({ id }: ParamControlAdapterModelProps) => {
|
||||||
@ -35,7 +34,7 @@ const ParamControlAdapterModel = ({ id }: ParamControlAdapterModelProps) => {
|
|||||||
const model = useControlAdapterModel(id);
|
const model = useControlAdapterModel(id);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const currentBaseModel = useAppSelector(
|
const currentBaseModel = useAppSelector(
|
||||||
(state) => state.generation.model?.base_model
|
(s) => s.generation.model?.base_model
|
||||||
);
|
);
|
||||||
const { mainModel } = useAppSelector(selector);
|
const { mainModel } = useAppSelector(selector);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -7,7 +7,7 @@ import { useControlAdapterModels } from './useControlAdapterModels';
|
|||||||
|
|
||||||
export const useAddControlAdapter = (type: ControlAdapterType) => {
|
export const useAddControlAdapter = (type: ControlAdapterType) => {
|
||||||
const baseModel = useAppSelector(
|
const baseModel = useAppSelector(
|
||||||
(state) => state.generation.model?.base_model
|
(s) => s.generation.model?.base_model
|
||||||
);
|
);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapter = (id: string) => {
|
export const useControlAdapter = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) =>
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) =>
|
||||||
selectControlAdapterById(controlAdapters, id)
|
selectControlAdapterById(controlAdapters, id)
|
||||||
),
|
),
|
||||||
[id]
|
[id]
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterBeginEndStepPct = (id: string) => {
|
export const useControlAdapterBeginEndStepPct = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const cn = selectControlAdapterById(controlAdapters, id);
|
const cn = selectControlAdapterById(controlAdapters, id);
|
||||||
return cn
|
return cn
|
||||||
? {
|
? {
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterControlImage = (id: string) => {
|
export const useControlAdapterControlImage = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(
|
createMemoizedSelector(
|
||||||
stateSelector,
|
selectControlAdaptersSlice,
|
||||||
({ controlAdapters }) =>
|
(controlAdapters) =>
|
||||||
selectControlAdapterById(controlAdapters, id)?.controlImage
|
selectControlAdapterById(controlAdapters, id)?.controlImage
|
||||||
),
|
),
|
||||||
[id]
|
[id]
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNet } from 'features/controlAdapters/store/types';
|
import { isControlNet } from 'features/controlAdapters/store/types';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterControlMode = (id: string) => {
|
export const useControlAdapterControlMode = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const ca = selectControlAdapterById(controlAdapters, id);
|
const ca = selectControlAdapterById(controlAdapters, id);
|
||||||
if (ca && isControlNet(ca)) {
|
if (ca && isControlNet(ca)) {
|
||||||
return ca.controlMode;
|
return ca.controlMode;
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterIsEnabled = (id: string) => {
|
export const useControlAdapterIsEnabled = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(
|
createMemoizedSelector(
|
||||||
stateSelector,
|
selectControlAdaptersSlice,
|
||||||
({ controlAdapters }) =>
|
(controlAdapters) =>
|
||||||
selectControlAdapterById(controlAdapters, id)?.isEnabled ?? false
|
selectControlAdapterById(controlAdapters, id)?.isEnabled ?? false
|
||||||
),
|
),
|
||||||
[id]
|
[id]
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterModel = (id: string) => {
|
export const useControlAdapterModel = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(
|
createMemoizedSelector(
|
||||||
stateSelector,
|
selectControlAdaptersSlice,
|
||||||
({ controlAdapters }) =>
|
(controlAdapters) =>
|
||||||
selectControlAdapterById(controlAdapters, id)?.model
|
selectControlAdapterById(controlAdapters, id)?.model
|
||||||
),
|
),
|
||||||
[id]
|
[id]
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterProcessedControlImage = (id: string) => {
|
export const useControlAdapterProcessedControlImage = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const ca = selectControlAdapterById(controlAdapters, id);
|
const ca = selectControlAdapterById(controlAdapters, id);
|
||||||
|
|
||||||
return ca && isControlNetOrT2IAdapter(ca)
|
return ca && isControlNetOrT2IAdapter(ca)
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterProcessorNode = (id: string) => {
|
export const useControlAdapterProcessorNode = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const ca = selectControlAdapterById(controlAdapters, id);
|
const ca = selectControlAdapterById(controlAdapters, id);
|
||||||
|
|
||||||
return ca && isControlNetOrT2IAdapter(ca)
|
return ca && isControlNetOrT2IAdapter(ca)
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterProcessorType = (id: string) => {
|
export const useControlAdapterProcessorType = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const ca = selectControlAdapterById(controlAdapters, id);
|
const ca = selectControlAdapterById(controlAdapters, id);
|
||||||
|
|
||||||
return ca && isControlNetOrT2IAdapter(ca)
|
return ca && isControlNetOrT2IAdapter(ca)
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterResizeMode = (id: string) => {
|
export const useControlAdapterResizeMode = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const ca = selectControlAdapterById(controlAdapters, id);
|
const ca = selectControlAdapterById(controlAdapters, id);
|
||||||
if (ca && isControlNetOrT2IAdapter(ca)) {
|
if (ca && isControlNetOrT2IAdapter(ca)) {
|
||||||
return ca.resizeMode;
|
return ca.resizeMode;
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterShouldAutoConfig = (id: string) => {
|
export const useControlAdapterShouldAutoConfig = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ controlAdapters }) => {
|
createMemoizedSelector(selectControlAdaptersSlice, (controlAdapters) => {
|
||||||
const ca = selectControlAdapterById(controlAdapters, id);
|
const ca = selectControlAdapterById(controlAdapters, id);
|
||||||
if (ca && isControlNetOrT2IAdapter(ca)) {
|
if (ca && isControlNetOrT2IAdapter(ca)) {
|
||||||
return ca.shouldAutoConfig;
|
return ca.shouldAutoConfig;
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterType = (id: string) => {
|
export const useControlAdapterType = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(
|
createMemoizedSelector(
|
||||||
stateSelector,
|
selectControlAdaptersSlice,
|
||||||
({ controlAdapters }) =>
|
(controlAdapters) => selectControlAdapterById(controlAdapters, id)?.type
|
||||||
selectControlAdapterById(controlAdapters, id)?.type
|
|
||||||
),
|
),
|
||||||
[id]
|
[id]
|
||||||
);
|
);
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectControlAdapterById } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import {
|
||||||
|
selectControlAdapterById,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
export const useControlAdapterWeight = (id: string) => {
|
export const useControlAdapterWeight = (id: string) => {
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(
|
createMemoizedSelector(
|
||||||
stateSelector,
|
selectControlAdaptersSlice,
|
||||||
({ controlAdapters }) =>
|
(controlAdapters) =>
|
||||||
selectControlAdapterById(controlAdapters, id)?.weight
|
selectControlAdapterById(controlAdapters, id)?.weight
|
||||||
),
|
),
|
||||||
[id]
|
[id]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import type { PayloadAction, Update } from '@reduxjs/toolkit';
|
import type { PayloadAction, Update } from '@reduxjs/toolkit';
|
||||||
import { createEntityAdapter, createSlice, isAnyOf } from '@reduxjs/toolkit';
|
import { createEntityAdapter, createSlice, isAnyOf } from '@reduxjs/toolkit';
|
||||||
import { getSelectorsOptions } from 'app/store/createMemoizedSelector';
|
import { getSelectorsOptions } from 'app/store/createMemoizedSelector';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import { buildControlAdapter } from 'features/controlAdapters/util/buildControlAdapter';
|
import { buildControlAdapter } from 'features/controlAdapters/util/buildControlAdapter';
|
||||||
import type {
|
import type {
|
||||||
ParameterControlNetModel,
|
ParameterControlNetModel,
|
||||||
@ -489,3 +490,6 @@ export const isAnyControlAdapterAdded = isAnyOf(
|
|||||||
controlAdapterAddedFromImage,
|
controlAdapterAddedFromImage,
|
||||||
controlAdapterRecalled
|
controlAdapterRecalled
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectControlAdaptersSlice = (state: RootState) =>
|
||||||
|
state.controlAdapters;
|
||||||
|
@ -12,7 +12,7 @@ type DeleteImageButtonProps = Omit<InvIconButtonProps, 'aria-label'> & {
|
|||||||
export const DeleteImageButton = memo((props: DeleteImageButtonProps) => {
|
export const DeleteImageButton = memo((props: DeleteImageButtonProps) => {
|
||||||
const { onClick, isDisabled } = props;
|
const { onClick, isDisabled } = props;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isConnected = useAppSelector((state) => state.system.isConnected);
|
const isConnected = useAppSelector((s) => s.system.isConnected);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InvIconButton
|
<InvIconButton
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import { Divider, Flex } from '@chakra-ui/react';
|
import { Divider, Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
|
import { selectControlAdaptersSlice } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions';
|
import { imageDeletionConfirmed } from 'features/deleteImageModal/store/actions';
|
||||||
import {
|
import {
|
||||||
getImageUsage,
|
getImageUsage,
|
||||||
@ -14,9 +15,16 @@ import {
|
|||||||
import {
|
import {
|
||||||
imageDeletionCanceled,
|
imageDeletionCanceled,
|
||||||
isModalOpenChanged,
|
isModalOpenChanged,
|
||||||
|
selectDeleteImageModalSlice,
|
||||||
} from 'features/deleteImageModal/store/slice';
|
} from 'features/deleteImageModal/store/slice';
|
||||||
import type { ImageUsage } from 'features/deleteImageModal/store/types';
|
import type { ImageUsage } from 'features/deleteImageModal/store/types';
|
||||||
import { setShouldConfirmOnDelete } from 'features/system/store/systemSlice';
|
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
||||||
|
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
||||||
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
|
import {
|
||||||
|
selectSystemSlice,
|
||||||
|
setShouldConfirmOnDelete,
|
||||||
|
} from 'features/system/store/systemSlice';
|
||||||
import { some } from 'lodash-es';
|
import { some } from 'lodash-es';
|
||||||
import type { ChangeEvent } from 'react';
|
import type { ChangeEvent } from 'react';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
@ -25,15 +33,32 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import ImageUsageMessage from './ImageUsageMessage';
|
import ImageUsageMessage from './ImageUsageMessage';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, selectImageUsage],
|
[
|
||||||
(state, imagesUsage) => {
|
selectSystemSlice,
|
||||||
const { system, config, deleteImageModal } = state;
|
selectConfigSlice,
|
||||||
|
selectDeleteImageModalSlice,
|
||||||
|
selectGenerationSlice,
|
||||||
|
selectCanvasSlice,
|
||||||
|
selectNodesSlice,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
selectImageUsage,
|
||||||
|
],
|
||||||
|
(
|
||||||
|
system,
|
||||||
|
config,
|
||||||
|
deleteImageModal,
|
||||||
|
generation,
|
||||||
|
canvas,
|
||||||
|
nodes,
|
||||||
|
controlAdapters,
|
||||||
|
imagesUsage
|
||||||
|
) => {
|
||||||
const { shouldConfirmOnDelete } = system;
|
const { shouldConfirmOnDelete } = system;
|
||||||
const { canRestoreDeletedImagesFromBin } = config;
|
const { canRestoreDeletedImagesFromBin } = config;
|
||||||
const { imagesToDelete, isModalOpen } = deleteImageModal;
|
const { imagesToDelete, isModalOpen } = deleteImageModal;
|
||||||
|
|
||||||
const allImageUsage = (imagesToDelete ?? []).map(({ image_name }) =>
|
const allImageUsage = (imagesToDelete ?? []).map(({ image_name }) =>
|
||||||
getImageUsage(state, image_name)
|
getImageUsage(generation, canvas, nodes, controlAdapters, image_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
const imageUsageSummary: ImageUsage = {
|
const imageUsageSummary: ImageUsage = {
|
||||||
|
@ -1,15 +1,30 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import type { RootState } from 'app/store/store';
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { selectControlAdapterAll } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import type { CanvasState } from 'features/canvas/store/canvasTypes';
|
||||||
|
import {
|
||||||
|
selectControlAdapterAll,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
|
import type { ControlAdaptersState } from 'features/controlAdapters/store/types';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
|
import { selectDeleteImageModalSlice } from 'features/deleteImageModal/store/slice';
|
||||||
|
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
||||||
|
import type { NodesState } from 'features/nodes/store/types';
|
||||||
import { isImageFieldInputInstance } from 'features/nodes/types/field';
|
import { isImageFieldInputInstance } from 'features/nodes/types/field';
|
||||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||||
|
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
||||||
|
import type { GenerationState } from 'features/parameters/store/types';
|
||||||
import { some } from 'lodash-es';
|
import { some } from 'lodash-es';
|
||||||
|
|
||||||
import type { ImageUsage } from './types';
|
import type { ImageUsage } from './types';
|
||||||
|
|
||||||
export const getImageUsage = (state: RootState, image_name: string) => {
|
export const getImageUsage = (
|
||||||
const { generation, canvas, nodes, controlAdapters } = state;
|
generation: GenerationState,
|
||||||
|
canvas: CanvasState,
|
||||||
|
nodes: NodesState,
|
||||||
|
controlAdapters: ControlAdaptersState,
|
||||||
|
image_name: string
|
||||||
|
) => {
|
||||||
const isInitialImage = generation.initialImage?.imageName === image_name;
|
const isInitialImage = generation.initialImage?.imageName === image_name;
|
||||||
|
|
||||||
const isCanvasImage = canvas.layerState.objects.some(
|
const isCanvasImage = canvas.layerState.objects.some(
|
||||||
@ -42,16 +57,20 @@ export const getImageUsage = (state: RootState, image_name: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const selectImageUsage = createMemoizedSelector(
|
export const selectImageUsage = createMemoizedSelector(
|
||||||
[(state: RootState) => state],
|
selectDeleteImageModalSlice,
|
||||||
(state) => {
|
selectGenerationSlice,
|
||||||
const { imagesToDelete } = state.deleteImageModal;
|
selectCanvasSlice,
|
||||||
|
selectNodesSlice,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
(deleteImageModal, generation, canvas, nodes, controlAdapters) => {
|
||||||
|
const { imagesToDelete } = deleteImageModal;
|
||||||
|
|
||||||
if (!imagesToDelete.length) {
|
if (!imagesToDelete.length) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const imagesUsage = imagesToDelete.map((i) =>
|
const imagesUsage = imagesToDelete.map((i) =>
|
||||||
getImageUsage(state, i.image_name)
|
getImageUsage(generation, canvas, nodes, controlAdapters, i.image_name)
|
||||||
);
|
);
|
||||||
|
|
||||||
return imagesUsage;
|
return imagesUsage;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
import type { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
import { initialDeleteImageState } from './initialState';
|
import { initialDeleteImageState } from './initialState';
|
||||||
@ -28,3 +29,6 @@ export const {
|
|||||||
} = deleteImageModal.actions;
|
} = deleteImageModal.actions;
|
||||||
|
|
||||||
export default deleteImageModal.reducer;
|
export default deleteImageModal.reducer;
|
||||||
|
|
||||||
|
export const selectDeleteImageModalSlice = (state: RootState) =>
|
||||||
|
state.deleteImageModal;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import type { Modifier } from '@dnd-kit/core';
|
import type { Modifier } from '@dnd-kit/core';
|
||||||
import { getEventCoordinates } from '@dnd-kit/utilities';
|
import { getEventCoordinates } from '@dnd-kit/utilities';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
const selectZoom = createMemoizedSelector(
|
const selectZoom = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector],
|
[selectNodesSlice, activeTabNameSelector],
|
||||||
({ nodes }, activeTabName) =>
|
(nodes, activeTabName) =>
|
||||||
activeTabName === 'nodes' ? nodes.viewport.zoom : 1
|
activeTabName === 'nodes' ? nodes.viewport.zoom : 1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
||||||
@ -7,14 +5,8 @@ import { combinatorialToggled } from 'features/dynamicPrompts/store/dynamicPromp
|
|||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, (state) => {
|
|
||||||
const { combinatorial } = state.dynamicPrompts;
|
|
||||||
|
|
||||||
return { combinatorial };
|
|
||||||
});
|
|
||||||
|
|
||||||
const ParamDynamicPromptsCombinatorial = () => {
|
const ParamDynamicPromptsCombinatorial = () => {
|
||||||
const { combinatorial } = useAppSelector(selector);
|
const combinatorial = useAppSelector((s) => s.dynamicPrompts.combinatorial);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -1,26 +1,33 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
||||||
import { maxPromptsChanged } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
import {
|
||||||
|
maxPromptsChanged,
|
||||||
|
selectDynamicPromptsSlice,
|
||||||
|
} from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||||
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, (state) => {
|
const selector = createMemoizedSelector(
|
||||||
const { maxPrompts, combinatorial } = state.dynamicPrompts;
|
selectDynamicPromptsSlice,
|
||||||
const { min, sliderMax, inputMax, initial } =
|
selectConfigSlice,
|
||||||
state.config.sd.dynamicPrompts.maxPrompts;
|
(dynamicPrompts, config) => {
|
||||||
|
const { maxPrompts, combinatorial } = dynamicPrompts;
|
||||||
|
const { min, sliderMax, inputMax, initial } =
|
||||||
|
config.sd.dynamicPrompts.maxPrompts;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
maxPrompts,
|
maxPrompts,
|
||||||
min,
|
min,
|
||||||
sliderMax,
|
sliderMax,
|
||||||
inputMax,
|
inputMax,
|
||||||
initial,
|
initial,
|
||||||
isDisabled: !combinatorial,
|
isDisabled: !combinatorial,
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const ParamDynamicPromptsMaxPrompts = () => {
|
const ParamDynamicPromptsMaxPrompts = () => {
|
||||||
const { maxPrompts, min, sliderMax, inputMax, initial, isDisabled } =
|
const { maxPrompts, min, sliderMax, inputMax, initial, isDisabled } =
|
||||||
|
@ -1,26 +1,29 @@
|
|||||||
import type { ChakraProps } from '@chakra-ui/react';
|
import type { ChakraProps } from '@chakra-ui/react';
|
||||||
import { Flex, ListItem, OrderedList, Spinner } from '@chakra-ui/react';
|
import { Flex, ListItem, OrderedList, Spinner } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||||
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
|
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||||
|
import { selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaCircleExclamation } from 'react-icons/fa6';
|
import { FaCircleExclamation } from 'react-icons/fa6';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, (state) => {
|
const selector = createMemoizedSelector(
|
||||||
const { isLoading, isError, prompts, parsingError } = state.dynamicPrompts;
|
selectDynamicPromptsSlice,
|
||||||
|
(dynamicPrompts) => {
|
||||||
|
const { isLoading, isError, prompts, parsingError } = dynamicPrompts;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prompts,
|
prompts,
|
||||||
parsingError,
|
parsingError,
|
||||||
isError,
|
isError,
|
||||||
isLoading,
|
isLoading,
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const listItemStyles: ChakraProps['sx'] = {
|
const listItemStyles: ChakraProps['sx'] = {
|
||||||
'&::marker': { color: 'base.500' },
|
'&::marker': { color: 'base.500' },
|
||||||
|
@ -16,7 +16,7 @@ const ParamDynamicPromptsSeedBehaviour = () => {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const seedBehaviour = useAppSelector(
|
const seedBehaviour = useAppSelector(
|
||||||
(state) => state.dynamicPrompts.seedBehaviour
|
(s) => s.dynamicPrompts.seedBehaviour
|
||||||
);
|
);
|
||||||
|
|
||||||
const options = useMemo<InvSelectOption[]>(() => {
|
const options = useMemo<InvSelectOption[]>(() => {
|
||||||
|
@ -14,7 +14,7 @@ const loadingStyles: SystemStyleObject = {
|
|||||||
|
|
||||||
export const ShowDynamicPromptsPreviewButton = memo(() => {
|
export const ShowDynamicPromptsPreviewButton = memo(() => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const isLoading = useAppSelector((state) => state.dynamicPrompts.isLoading);
|
const isLoading = useAppSelector((s) => s.dynamicPrompts.isLoading);
|
||||||
const { isOpen, onOpen } = useDynamicPromptsModal();
|
const { isOpen, onOpen } = useDynamicPromptsModal();
|
||||||
return (
|
return (
|
||||||
<InvTooltip
|
<InvTooltip
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
export const zSeedBehaviour = z.enum(['PER_ITERATION', 'PER_PROMPT']);
|
export const zSeedBehaviour = z.enum(['PER_ITERATION', 'PER_PROMPT']);
|
||||||
@ -74,3 +75,6 @@ export const {
|
|||||||
} = dynamicPromptsSlice.actions;
|
} = dynamicPromptsSlice.actions;
|
||||||
|
|
||||||
export default dynamicPromptsSlice.reducer;
|
export default dynamicPromptsSlice.reducer;
|
||||||
|
|
||||||
|
export const selectDynamicPromptsSlice = (state: RootState) =>
|
||||||
|
state.dynamicPrompts;
|
||||||
|
@ -18,7 +18,7 @@ export const EmbeddingSelect = memo(
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const currentBaseModel = useAppSelector(
|
const currentBaseModel = useAppSelector(
|
||||||
(state) => state.generation.model?.base_model
|
(s) => s.generation.model?.base_model
|
||||||
);
|
);
|
||||||
|
|
||||||
const getIsDisabled = useCallback(
|
const getIsDisabled = useCallback(
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
||||||
@ -7,24 +5,22 @@ import type {
|
|||||||
InvSelectOnChange,
|
InvSelectOnChange,
|
||||||
InvSelectOption,
|
InvSelectOption,
|
||||||
} from 'common/components/InvSelect/types';
|
} from 'common/components/InvSelect/types';
|
||||||
import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice';
|
import {
|
||||||
|
autoAddBoardIdChanged,
|
||||||
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useListAllBoardsQuery } from 'services/api/endpoints/boards';
|
import { useListAllBoardsQuery } from 'services/api/endpoints/boards';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ gallery }) => {
|
|
||||||
const { autoAddBoardId, autoAssignBoardOnClick } = gallery;
|
|
||||||
|
|
||||||
return {
|
|
||||||
autoAddBoardId,
|
|
||||||
autoAssignBoardOnClick,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const BoardAutoAddSelect = () => {
|
const BoardAutoAddSelect = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { autoAddBoardId, autoAssignBoardOnClick } = useAppSelector(selector);
|
const autoAddBoardId = useAppSelector(
|
||||||
|
(s) => s.gallery.autoAddBoardId
|
||||||
|
);
|
||||||
|
const autoAssignBoardOnClick = useAppSelector(
|
||||||
|
(s) => s.gallery.autoAssignBoardOnClick
|
||||||
|
);
|
||||||
const { options, hasBoards } = useListAllBoardsQuery(undefined, {
|
const { options, hasBoards } = useListAllBoardsQuery(undefined, {
|
||||||
selectFromResult: ({ data }) => {
|
selectFromResult: ({ data }) => {
|
||||||
const options: InvSelectOption[] = [
|
const options: InvSelectOption[] = [
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import type { InvContextMenuProps } from 'common/components/InvContextMenu/InvContextMenu';
|
import type { InvContextMenuProps } from 'common/components/InvContextMenu/InvContextMenu';
|
||||||
import { InvContextMenu } from 'common/components/InvContextMenu/InvContextMenu';
|
import { InvContextMenu } from 'common/components/InvContextMenu/InvContextMenu';
|
||||||
import { InvMenuItem } from 'common/components/InvMenu/InvMenuItem';
|
import { InvMenuItem } from 'common/components/InvMenu/InvMenuItem';
|
||||||
import { InvMenuList } from 'common/components/InvMenu/InvMenuList';
|
import { InvMenuList } from 'common/components/InvMenu/InvMenuList';
|
||||||
import { InvMenuGroup } from 'common/components/InvMenu/wrapper';
|
import { InvMenuGroup } from 'common/components/InvMenu/wrapper';
|
||||||
import { autoAddBoardIdChanged } from 'features/gallery/store/gallerySlice';
|
import {
|
||||||
|
autoAddBoardIdChanged,
|
||||||
|
selectGallerySlice,
|
||||||
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import type { BoardId } from 'features/gallery/store/types';
|
import type { BoardId } from 'features/gallery/store/types';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
@ -38,7 +40,7 @@ const BoardContextMenu = ({
|
|||||||
|
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ gallery }) => {
|
createMemoizedSelector(selectGallerySlice, (gallery) => {
|
||||||
const isAutoAdd = gallery.autoAddBoardId === board_id;
|
const isAutoAdd = gallery.autoAddBoardId === board_id;
|
||||||
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
||||||
return { isAutoAdd, autoAssignBoardOnClick };
|
return { isAutoAdd, autoAssignBoardOnClick };
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { Collapse, Flex, Grid, GridItem } from '@chakra-ui/react';
|
import { Collapse, Flex, Grid, GridItem } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
||||||
import DeleteBoardModal from 'features/gallery/components/Boards/DeleteBoardModal';
|
import DeleteBoardModal from 'features/gallery/components/Boards/DeleteBoardModal';
|
||||||
@ -20,18 +18,18 @@ const overlayScrollbarsStyles: CSSProperties = {
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
};
|
};
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ gallery }) => {
|
|
||||||
const { selectedBoardId, boardSearchText } = gallery;
|
|
||||||
return { selectedBoardId, boardSearchText };
|
|
||||||
});
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BoardsList = (props: Props) => {
|
const BoardsList = (props: Props) => {
|
||||||
const { isOpen } = props;
|
const { isOpen } = props;
|
||||||
const { selectedBoardId, boardSearchText } = useAppSelector(selector);
|
const selectedBoardId = useAppSelector(
|
||||||
|
(s) => s.gallery.selectedBoardId
|
||||||
|
);
|
||||||
|
const boardSearchText = useAppSelector(
|
||||||
|
(s) => s.gallery.boardSearchText
|
||||||
|
);
|
||||||
const { data: boards } = useListAllBoardsQuery();
|
const { data: boards } = useListAllBoardsQuery();
|
||||||
const filteredBoards = boardSearchText
|
const filteredBoards = boardSearchText
|
||||||
? boards?.filter((board) =>
|
? boards?.filter((board) =>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { CloseIcon } from '@chakra-ui/icons';
|
import { CloseIcon } from '@chakra-ui/icons';
|
||||||
import { Input, InputGroup, InputRightElement } from '@chakra-ui/react';
|
import { Input, InputGroup, InputRightElement } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { boardSearchTextChanged } from 'features/gallery/store/gallerySlice';
|
import { boardSearchTextChanged } from 'features/gallery/store/gallerySlice';
|
||||||
@ -9,14 +7,9 @@ import type { ChangeEvent, KeyboardEvent } from 'react';
|
|||||||
import { memo, useCallback, useEffect, useRef } from 'react';
|
import { memo, useCallback, useEffect, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ gallery }) => {
|
|
||||||
const { boardSearchText } = gallery;
|
|
||||||
return { boardSearchText };
|
|
||||||
});
|
|
||||||
|
|
||||||
const BoardsSearch = () => {
|
const BoardsSearch = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { boardSearchText } = useAppSelector(selector);
|
const boardSearchText = useAppSelector((s) => s.gallery.boardSearchText);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIDroppable from 'common/components/IAIDroppable';
|
import IAIDroppable from 'common/components/IAIDroppable';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
@ -22,6 +21,7 @@ import BoardContextMenu from 'features/gallery/components/Boards/BoardContextMen
|
|||||||
import {
|
import {
|
||||||
autoAddBoardIdChanged,
|
autoAddBoardIdChanged,
|
||||||
boardIdSelected,
|
boardIdSelected,
|
||||||
|
selectGallerySlice,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import { memo, useCallback, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -56,7 +56,7 @@ const GalleryBoard = ({
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const selector = useMemo(
|
const selector = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector(stateSelector, ({ gallery }) => {
|
createMemoizedSelector(selectGallerySlice, (gallery) => {
|
||||||
const isSelectedForAutoAdd = board.board_id === gallery.autoAddBoardId;
|
const isSelectedForAutoAdd = board.board_id === gallery.autoAddBoardId;
|
||||||
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
const autoAssignBoardOnClick = gallery.autoAssignBoardOnClick;
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { Box, Flex, Image } from '@chakra-ui/react';
|
import { Box, Flex, Image } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import InvokeAILogoImage from 'assets/images/logo.png';
|
import InvokeAILogoImage from 'assets/images/logo.png';
|
||||||
import IAIDroppable from 'common/components/IAIDroppable';
|
import IAIDroppable from 'common/components/IAIDroppable';
|
||||||
@ -26,14 +24,12 @@ interface Props {
|
|||||||
isSelected: boolean;
|
isSelected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ gallery }) => {
|
|
||||||
const { autoAddBoardId, autoAssignBoardOnClick } = gallery;
|
|
||||||
return { autoAddBoardId, autoAssignBoardOnClick };
|
|
||||||
});
|
|
||||||
|
|
||||||
const NoBoardBoard = memo(({ isSelected }: Props) => {
|
const NoBoardBoard = memo(({ isSelected }: Props) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { autoAddBoardId, autoAssignBoardOnClick } = useAppSelector(selector);
|
const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId);
|
||||||
|
const autoAssignBoardOnClick = useAppSelector(
|
||||||
|
(s) => s.gallery.autoAssignBoardOnClick
|
||||||
|
);
|
||||||
const boardName = useBoardName('none');
|
const boardName = useBoardName('none');
|
||||||
const handleSelectBoard = useCallback(() => {
|
const handleSelectBoard = useCallback(() => {
|
||||||
dispatch(boardIdSelected({ boardId: 'none' }));
|
dispatch(boardIdSelected({ boardId: 'none' }));
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Flex, Skeleton } from '@chakra-ui/react';
|
import { Flex, Skeleton } from '@chakra-ui/react';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
InvAlertDialog,
|
InvAlertDialog,
|
||||||
@ -13,9 +12,13 @@ import {
|
|||||||
} from 'common/components/InvAlertDialog/wrapper';
|
} from 'common/components/InvAlertDialog/wrapper';
|
||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
|
import { selectControlAdaptersSlice } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import ImageUsageMessage from 'features/deleteImageModal/components/ImageUsageMessage';
|
import ImageUsageMessage from 'features/deleteImageModal/components/ImageUsageMessage';
|
||||||
import { getImageUsage } from 'features/deleteImageModal/store/selectors';
|
import { getImageUsage } from 'features/deleteImageModal/store/selectors';
|
||||||
import type { ImageUsage } from 'features/deleteImageModal/store/types';
|
import type { ImageUsage } from 'features/deleteImageModal/store/types';
|
||||||
|
import { selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
||||||
|
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
||||||
import { some } from 'lodash-es';
|
import { some } from 'lodash-es';
|
||||||
import { memo, useCallback, useMemo, useRef } from 'react';
|
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -35,26 +38,34 @@ const DeleteBoardModal = (props: Props) => {
|
|||||||
const { boardToDelete, setBoardToDelete } = props;
|
const { boardToDelete, setBoardToDelete } = props;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const canRestoreDeletedImagesFromBin = useAppSelector(
|
const canRestoreDeletedImagesFromBin = useAppSelector(
|
||||||
(state) => state.config.canRestoreDeletedImagesFromBin
|
(s) => s.config.canRestoreDeletedImagesFromBin
|
||||||
);
|
);
|
||||||
const { currentData: boardImageNames, isFetching: isFetchingBoardNames } =
|
const { currentData: boardImageNames, isFetching: isFetchingBoardNames } =
|
||||||
useListAllImageNamesForBoardQuery(boardToDelete?.board_id ?? skipToken);
|
useListAllImageNamesForBoardQuery(boardToDelete?.board_id ?? skipToken);
|
||||||
|
|
||||||
const selectImageUsageSummary = useMemo(
|
const selectImageUsageSummary = useMemo(
|
||||||
() =>
|
() =>
|
||||||
createMemoizedSelector([stateSelector], (state) => {
|
createMemoizedSelector(
|
||||||
const allImageUsage = (boardImageNames ?? []).map((imageName) =>
|
[
|
||||||
getImageUsage(state, imageName)
|
selectGenerationSlice,
|
||||||
);
|
selectCanvasSlice,
|
||||||
|
selectNodesSlice,
|
||||||
|
selectControlAdaptersSlice,
|
||||||
|
],
|
||||||
|
(generation, canvas, nodes, controlAdapters) => {
|
||||||
|
const allImageUsage = (boardImageNames ?? []).map((imageName) =>
|
||||||
|
getImageUsage(generation, canvas, nodes, controlAdapters, imageName)
|
||||||
|
);
|
||||||
|
|
||||||
const imageUsageSummary: ImageUsage = {
|
const imageUsageSummary: ImageUsage = {
|
||||||
isInitialImage: some(allImageUsage, (i) => i.isInitialImage),
|
isInitialImage: some(allImageUsage, (i) => i.isInitialImage),
|
||||||
isCanvasImage: some(allImageUsage, (i) => i.isCanvasImage),
|
isCanvasImage: some(allImageUsage, (i) => i.isCanvasImage),
|
||||||
isNodesImage: some(allImageUsage, (i) => i.isNodesImage),
|
isNodesImage: some(allImageUsage, (i) => i.isNodesImage),
|
||||||
isControlImage: some(allImageUsage, (i) => i.isControlImage),
|
isControlImage: some(allImageUsage, (i) => i.isControlImage),
|
||||||
};
|
};
|
||||||
return { imageUsageSummary };
|
return { imageUsageSummary };
|
||||||
}),
|
}
|
||||||
|
),
|
||||||
[boardImageNames]
|
[boardImageNames]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ import { skipToken } from '@reduxjs/toolkit/query';
|
|||||||
import { useAppToaster } from 'app/components/Toaster';
|
import { useAppToaster } from 'app/components/Toaster';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { upscaleRequested } from 'app/store/middleware/listenerMiddleware/listeners/upscaleRequested';
|
import { upscaleRequested } from 'app/store/middleware/listenerMiddleware/listeners/upscaleRequested';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
@ -13,13 +12,17 @@ import { DeleteImageButton } from 'features/deleteImageModal/components/DeleteIm
|
|||||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||||
import SingleSelectionMenuItems from 'features/gallery/components/ImageContextMenu/SingleSelectionMenuItems';
|
import SingleSelectionMenuItems from 'features/gallery/components/ImageContextMenu/SingleSelectionMenuItems';
|
||||||
import { sentImageToImg2Img } from 'features/gallery/store/actions';
|
import { sentImageToImg2Img } from 'features/gallery/store/actions';
|
||||||
|
import { selectGallerySlice } from 'features/gallery/store/gallerySlice';
|
||||||
import ParamUpscalePopover from 'features/parameters/components/Upscale/ParamUpscaleSettings';
|
import ParamUpscalePopover from 'features/parameters/components/Upscale/ParamUpscaleSettings';
|
||||||
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
|
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
|
||||||
import { initialImageSelected } from 'features/parameters/store/actions';
|
import { initialImageSelected } from 'features/parameters/store/actions';
|
||||||
import { useIsQueueMutationInProgress } from 'features/queue/hooks/useIsQueueMutationInProgress';
|
import { useIsQueueMutationInProgress } from 'features/queue/hooks/useIsQueueMutationInProgress';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
|
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import {
|
import {
|
||||||
|
selectUiSlice,
|
||||||
setShouldShowImageDetails,
|
setShouldShowImageDetails,
|
||||||
setShouldShowProgressInViewer,
|
setShouldShowProgressInViewer,
|
||||||
} from 'features/ui/store/uiSlice';
|
} from 'features/ui/store/uiSlice';
|
||||||
@ -40,8 +43,14 @@ import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
|||||||
import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
|
import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
|
||||||
|
|
||||||
const currentImageButtonsSelector = createMemoizedSelector(
|
const currentImageButtonsSelector = createMemoizedSelector(
|
||||||
[stateSelector, activeTabNameSelector],
|
[
|
||||||
({ gallery, system, ui, config }, activeTabName) => {
|
selectGallerySlice,
|
||||||
|
selectSystemSlice,
|
||||||
|
selectUiSlice,
|
||||||
|
selectConfigSlice,
|
||||||
|
activeTabNameSelector,
|
||||||
|
],
|
||||||
|
(gallery, system, ui, config, activeTabName) => {
|
||||||
const { isConnected, shouldConfirmOnDelete, denoiseProgress } = system;
|
const { isConnected, shouldConfirmOnDelete, denoiseProgress } = system;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Box, Flex } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import IAIDndImage from 'common/components/IAIDndImage';
|
import IAIDndImage from 'common/components/IAIDndImage';
|
||||||
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||||
@ -14,6 +13,8 @@ import ImageMetadataViewer from 'features/gallery/components/ImageMetadataViewer
|
|||||||
import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons';
|
import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons';
|
||||||
import { useNextPrevImage } from 'features/gallery/hooks/useNextPrevImage';
|
import { useNextPrevImage } from 'features/gallery/hooks/useNextPrevImage';
|
||||||
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
import { selectLastSelectedImage } from 'features/gallery/store/gallerySelectors';
|
||||||
|
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||||
|
import { selectUiSlice } from 'features/ui/store/uiSlice';
|
||||||
import type { AnimationProps } from 'framer-motion';
|
import type { AnimationProps } from 'framer-motion';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
@ -24,8 +25,10 @@ import { FaImage } from 'react-icons/fa';
|
|||||||
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
export const imagesSelector = createMemoizedSelector(
|
export const imagesSelector = createMemoizedSelector(
|
||||||
[stateSelector, selectLastSelectedImage],
|
selectUiSlice,
|
||||||
({ ui, system }, lastSelectedImage) => {
|
selectSystemSlice,
|
||||||
|
selectLastSelectedImage,
|
||||||
|
(ui, system, lastSelectedImage) => {
|
||||||
const {
|
const {
|
||||||
shouldShowImageDetails,
|
shouldShowImageDetails,
|
||||||
shouldHidePreview,
|
shouldHidePreview,
|
||||||
|
@ -5,10 +5,10 @@ import { memo, useMemo } from 'react';
|
|||||||
|
|
||||||
const CurrentImagePreview = () => {
|
const CurrentImagePreview = () => {
|
||||||
const progress_image = useAppSelector(
|
const progress_image = useAppSelector(
|
||||||
(state) => state.system.denoiseProgress?.progress_image
|
(s) => s.system.denoiseProgress?.progress_image
|
||||||
);
|
);
|
||||||
const shouldAntialiasProgressImage = useAppSelector(
|
const shouldAntialiasProgressImage = useAppSelector(
|
||||||
(state) => state.system.shouldAntialiasProgressImage
|
(s) => s.system.shouldAntialiasProgressImage
|
||||||
);
|
);
|
||||||
|
|
||||||
const sx = useMemo<SystemStyleObject>(
|
const sx = useMemo<SystemStyleObject>(
|
||||||
|
@ -1,17 +1,9 @@
|
|||||||
import { ChevronUpIcon } from '@chakra-ui/icons';
|
import { ChevronUpIcon } from '@chakra-ui/icons';
|
||||||
import { Button, Flex, Spacer } from '@chakra-ui/react';
|
import { Button, Flex, Spacer } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useBoardName } from 'services/api/hooks/useBoardName';
|
import { useBoardName } from 'services/api/hooks/useBoardName';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], (state) => {
|
|
||||||
const { selectedBoardId } = state.gallery;
|
|
||||||
|
|
||||||
return { selectedBoardId };
|
|
||||||
});
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onToggle: () => void;
|
onToggle: () => void;
|
||||||
@ -19,7 +11,7 @@ type Props = {
|
|||||||
|
|
||||||
const GalleryBoardName = (props: Props) => {
|
const GalleryBoardName = (props: Props) => {
|
||||||
const { isOpen, onToggle } = props;
|
const { isOpen, onToggle } = props;
|
||||||
const { selectedBoardId } = useAppSelector(selector);
|
const selectedBoardId = useAppSelector((s) => s.gallery.selectedBoardId);
|
||||||
const boardName = useBoardName(selectedBoardId);
|
const boardName = useBoardName(selectedBoardId);
|
||||||
|
|
||||||
const formattedBoardName = useMemo(() => {
|
const formattedBoardName = useMemo(() => {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvCheckbox } from 'common/components/InvCheckbox/wrapper';
|
import { InvCheckbox } from 'common/components/InvCheckbox/wrapper';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
@ -15,6 +14,7 @@ import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
|||||||
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
import { InvSwitch } from 'common/components/InvSwitch/wrapper';
|
||||||
import {
|
import {
|
||||||
autoAssignBoardOnClickChanged,
|
autoAssignBoardOnClickChanged,
|
||||||
|
selectGallerySlice,
|
||||||
setGalleryImageMinimumWidth,
|
setGalleryImageMinimumWidth,
|
||||||
shouldAutoSwitchChanged,
|
shouldAutoSwitchChanged,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
@ -25,9 +25,9 @@ import { FaWrench } from 'react-icons/fa';
|
|||||||
|
|
||||||
import BoardAutoAddSelect from './Boards/BoardAutoAddSelect';
|
import BoardAutoAddSelect from './Boards/BoardAutoAddSelect';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], (state) => {
|
const selector = createMemoizedSelector(selectGallerySlice, (gallery) => {
|
||||||
const { galleryImageMinimumWidth, shouldAutoSwitch, autoAssignBoardOnClick } =
|
const { galleryImageMinimumWidth, shouldAutoSwitch, autoAssignBoardOnClick } =
|
||||||
state.gallery;
|
gallery;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
galleryImageMinimumWidth,
|
galleryImageMinimumWidth,
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import type { InvContextMenuProps } from 'common/components/InvContextMenu/InvContextMenu';
|
import type { InvContextMenuProps } from 'common/components/InvContextMenu/InvContextMenu';
|
||||||
import { InvContextMenu } from 'common/components/InvContextMenu/InvContextMenu';
|
import { InvContextMenu } from 'common/components/InvContextMenu/InvContextMenu';
|
||||||
@ -16,14 +14,8 @@ type Props = {
|
|||||||
children: InvContextMenuProps<HTMLDivElement>['children'];
|
children: InvContextMenuProps<HTMLDivElement>['children'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ gallery }) => {
|
|
||||||
const selectionCount = gallery.selection.length;
|
|
||||||
|
|
||||||
return { selectionCount };
|
|
||||||
});
|
|
||||||
|
|
||||||
const ImageContextMenu = ({ imageDTO, children }: Props) => {
|
const ImageContextMenu = ({ imageDTO, children }: Props) => {
|
||||||
const { selectionCount } = useAppSelector(selector);
|
const selectionCount = useAppSelector((s) => s.gallery.selection.length);
|
||||||
|
|
||||||
const skipEvent = useCallback((e: MouseEvent<HTMLDivElement>) => {
|
const skipEvent = useCallback((e: MouseEvent<HTMLDivElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -22,7 +22,7 @@ import {
|
|||||||
const MultipleSelectionMenuItems = () => {
|
const MultipleSelectionMenuItems = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const selection = useAppSelector((state) => state.gallery.selection);
|
const selection = useAppSelector((s) => s.gallery.selection);
|
||||||
const customStarUi = useStore($customStarUI);
|
const customStarUi = useStore($customStarUI);
|
||||||
|
|
||||||
const isBulkDownloadEnabled =
|
const isBulkDownloadEnabled =
|
||||||
|
@ -8,9 +8,7 @@ import {
|
|||||||
VStack,
|
VStack,
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { $galleryHeader } from 'app/store/nanostores/galleryHeader';
|
import { $galleryHeader } from 'app/store/nanostores/galleryHeader';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
@ -24,19 +22,11 @@ import GalleryBoardName from './GalleryBoardName';
|
|||||||
import GallerySettingsPopover from './GallerySettingsPopover';
|
import GallerySettingsPopover from './GallerySettingsPopover';
|
||||||
import GalleryImageGrid from './ImageGrid/GalleryImageGrid';
|
import GalleryImageGrid from './ImageGrid/GalleryImageGrid';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], (state) => {
|
|
||||||
const { galleryView } = state.gallery;
|
|
||||||
|
|
||||||
return {
|
|
||||||
galleryView,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const ImageGalleryContent = () => {
|
const ImageGalleryContent = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const resizeObserverRef = useRef<HTMLDivElement>(null);
|
const resizeObserverRef = useRef<HTMLDivElement>(null);
|
||||||
const galleryGridRef = useRef<HTMLDivElement>(null);
|
const galleryGridRef = useRef<HTMLDivElement>(null);
|
||||||
const { galleryView } = useAppSelector(selector);
|
const galleryView = useAppSelector((s) => s.gallery.galleryView);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const galleryHeader = useStore($galleryHeader);
|
const galleryHeader = useStore($galleryHeader);
|
||||||
const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } =
|
const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } =
|
||||||
|
@ -45,7 +45,7 @@ const GalleryImageGrid = () => {
|
|||||||
overlayScrollbarsParams
|
overlayScrollbarsParams
|
||||||
);
|
);
|
||||||
const selectedBoardId = useAppSelector(
|
const selectedBoardId = useAppSelector(
|
||||||
(state) => state.gallery.selectedBoardId
|
(s) => s.gallery.selectedBoardId
|
||||||
);
|
);
|
||||||
const { currentViewTotal } = useBoardTotal(selectedBoardId);
|
const { currentViewTotal } = useBoardTotal(selectedBoardId);
|
||||||
const queryArgs = useAppSelector(selectListImagesBaseQueryArgs);
|
const queryArgs = useAppSelector(selectListImagesBaseQueryArgs);
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors';
|
import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||||
import { selectionChanged } from 'features/gallery/store/gallerySlice';
|
import { selectGallerySlice, selectionChanged } from 'features/gallery/store/gallerySlice';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
@ -11,13 +10,11 @@ import type { ImageDTO } from 'services/api/types';
|
|||||||
import { imagesSelectors } from 'services/api/util';
|
import { imagesSelectors } from 'services/api/util';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(
|
const selector = createMemoizedSelector(
|
||||||
[stateSelector, selectListImagesBaseQueryArgs],
|
[selectGallerySlice, selectListImagesBaseQueryArgs],
|
||||||
({ gallery }, queryArgs) => {
|
(gallery, queryArgs) => {
|
||||||
const selection = gallery.selection;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
queryArgs,
|
queryArgs,
|
||||||
selection,
|
selection: gallery.selection,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors';
|
import { selectListImagesBaseQueryArgs } from 'features/gallery/store/gallerySelectors';
|
||||||
import { imageSelected } from 'features/gallery/store/gallerySlice';
|
import { imageSelected } from 'features/gallery/store/gallerySlice';
|
||||||
@ -29,7 +29,7 @@ export const $useNextPrevImageState = map<UseNextPrevImageState>({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const nextPrevImageButtonsSelector = createMemoizedSelector(
|
export const nextPrevImageButtonsSelector = createMemoizedSelector(
|
||||||
[stateSelector, selectListImagesBaseQueryArgs],
|
[(state: RootState) => state, selectListImagesBaseQueryArgs],
|
||||||
(state, baseQueryArgs) => {
|
(state, baseQueryArgs) => {
|
||||||
const { data, status } =
|
const { data, status } =
|
||||||
imagesApi.endpoints.listImages.select(baseQueryArgs)(state);
|
imagesApi.endpoints.listImages.select(baseQueryArgs)(state);
|
||||||
|
@ -12,7 +12,7 @@ export const gallerySelector = (state: RootState) => state.gallery;
|
|||||||
|
|
||||||
export const selectLastSelectedImage = createMemoizedSelector(
|
export const selectLastSelectedImage = createMemoizedSelector(
|
||||||
(state: RootState) => state,
|
(state: RootState) => state,
|
||||||
(state) => state.gallery.selection[state.gallery.selection.length - 1]
|
(s) => s.gallery.selection[state.gallery.selection.length - 1]
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectListImagesBaseQueryArgs = createMemoizedSelector(
|
export const selectListImagesBaseQueryArgs = createMemoizedSelector(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice, isAnyOf } from '@reduxjs/toolkit';
|
import { createSlice, isAnyOf } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import { uniqBy } from 'lodash-es';
|
import { uniqBy } from 'lodash-es';
|
||||||
import { boardsApi } from 'services/api/endpoints/boards';
|
import { boardsApi } from 'services/api/endpoints/boards';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
@ -103,3 +104,5 @@ const isAnyBoardDeleted = isAnyOf(
|
|||||||
imagesApi.endpoints.deleteBoard.matchFulfilled,
|
imagesApi.endpoints.deleteBoard.matchFulfilled,
|
||||||
imagesApi.endpoints.deleteBoardAndImages.matchFulfilled
|
imagesApi.endpoints.deleteBoardAndImages.matchFulfilled
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectGallerySlice = (state: RootState) => state.gallery;
|
||||||
|
@ -9,7 +9,7 @@ import ParamHrfToggle from './ParamHrfToggle';
|
|||||||
|
|
||||||
export const HrfSettings = memo(() => {
|
export const HrfSettings = memo(() => {
|
||||||
const isHRFFeatureEnabled = useFeatureStatus('hrf').isFeatureEnabled;
|
const isHRFFeatureEnabled = useFeatureStatus('hrf').isFeatureEnabled;
|
||||||
const hrfEnabled = useAppSelector((state) => state.hrf.hrfEnabled);
|
const hrfEnabled = useAppSelector((s) => s.hrf.hrfEnabled);
|
||||||
|
|
||||||
if (!isHRFFeatureEnabled) {
|
if (!isHRFFeatureEnabled) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -18,7 +18,7 @@ const options: InvSelectOption[] = [
|
|||||||
const ParamHrfMethodSelect = () => {
|
const ParamHrfMethodSelect = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const hrfMethod = useAppSelector((state) => state.hrf.hrfMethod);
|
const hrfMethod = useAppSelector((s) => s.hrf.hrfMethod);
|
||||||
|
|
||||||
const onChange = useCallback<InvSelectOnChange>(
|
const onChange = useCallback<InvSelectOnChange>(
|
||||||
(v) => {
|
(v) => {
|
||||||
|
@ -1,27 +1,31 @@
|
|||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
import { InvSlider } from 'common/components/InvSlider/InvSlider';
|
||||||
import { setHrfStrength } from 'features/hrf/store/hrfSlice';
|
import { selectHrfSlice, setHrfStrength } from 'features/hrf/store/hrfSlice';
|
||||||
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selector = createMemoizedSelector([stateSelector], ({ hrf, config }) => {
|
const selector = createMemoizedSelector(
|
||||||
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
|
selectHrfSlice,
|
||||||
config.sd.hrfStrength;
|
selectConfigSlice,
|
||||||
const { hrfStrength } = hrf;
|
(hrf, config) => {
|
||||||
|
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
|
||||||
|
config.sd.hrfStrength;
|
||||||
|
const { hrfStrength } = hrf;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hrfStrength,
|
hrfStrength,
|
||||||
initial,
|
initial,
|
||||||
min,
|
min,
|
||||||
sliderMax,
|
sliderMax,
|
||||||
inputMax,
|
inputMax,
|
||||||
step: coarseStep,
|
step: coarseStep,
|
||||||
fineStep,
|
fineStep,
|
||||||
};
|
};
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const ParamHrfStrength = () => {
|
const ParamHrfStrength = () => {
|
||||||
const { hrfStrength, initial, min, sliderMax, step, fineStep } =
|
const { hrfStrength, initial, min, sliderMax, step, fineStep } =
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import type {
|
import type {
|
||||||
ParameterHRFMethod,
|
ParameterHRFMethod,
|
||||||
ParameterStrength,
|
ParameterStrength,
|
||||||
@ -38,3 +39,5 @@ export const hrfSlice = createSlice({
|
|||||||
export const { setHrfEnabled, setHrfStrength, setHrfMethod } = hrfSlice.actions;
|
export const { setHrfEnabled, setHrfStrength, setHrfMethod } = hrfSlice.actions;
|
||||||
|
|
||||||
export default hrfSlice.reducer;
|
export default hrfSlice.reducer;
|
||||||
|
|
||||||
|
export const selectHrfSlice = (state: RootState) => state.hrf;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Flex } from '@chakra-ui/layout';
|
import { Flex } from '@chakra-ui/layout';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { LoRACard } from 'features/lora/components/LoRACard';
|
import { LoRACard } from 'features/lora/components/LoRACard';
|
||||||
|
import { selectLoraSlice } from 'features/lora/store/loraSlice';
|
||||||
import { map } from 'lodash-es';
|
import { map } from 'lodash-es';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ lora }) => {
|
const selector = createMemoizedSelector(selectLoraSlice, (lora) => {
|
||||||
return { lorasArray: map(lora.loras) };
|
return { lorasArray: map(lora.loras) };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
import type { ChakraProps } from '@chakra-ui/react';
|
import type { ChakraProps } from '@chakra-ui/react';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { stateSelector } from 'app/store/store';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InvControl } from 'common/components/InvControl/InvControl';
|
import { InvControl } from 'common/components/InvControl/InvControl';
|
||||||
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
import { InvSelect } from 'common/components/InvSelect/InvSelect';
|
||||||
import { useGroupedModelInvSelect } from 'common/components/InvSelect/useGroupedModelInvSelect';
|
import { useGroupedModelInvSelect } from 'common/components/InvSelect/useGroupedModelInvSelect';
|
||||||
import { loraAdded } from 'features/lora/store/loraSlice';
|
import { loraAdded, selectLoraSlice } from 'features/lora/store/loraSlice';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import type { LoRAModelConfigEntity } from 'services/api/endpoints/models';
|
import type { LoRAModelConfigEntity } from 'services/api/endpoints/models';
|
||||||
import { useGetLoRAModelsQuery } from 'services/api/endpoints/models';
|
import { useGetLoRAModelsQuery } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ lora }) => ({
|
const selector = createMemoizedSelector(selectLoraSlice, (lora) => ({
|
||||||
addedLoRAs: lora.loras,
|
addedLoRAs: lora.loras,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -21,7 +20,7 @@ const LoRASelect = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { addedLoRAs } = useAppSelector(selector);
|
const { addedLoRAs } = useAppSelector(selector);
|
||||||
const currentBaseModel = useAppSelector(
|
const currentBaseModel = useAppSelector(
|
||||||
(state) => state.generation.model?.base_model
|
(s) => s.generation.model?.base_model
|
||||||
);
|
);
|
||||||
|
|
||||||
const getIsDisabled = (lora: LoRAModelConfigEntity): boolean => {
|
const getIsDisabled = (lora: LoRAModelConfigEntity): boolean => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
import type { ParameterLoRAModel } from 'features/parameters/types/parameterSchemas';
|
import type { ParameterLoRAModel } from 'features/parameters/types/parameterSchemas';
|
||||||
import type { LoRAModelConfigEntity } from 'services/api/endpoints/models';
|
import type { LoRAModelConfigEntity } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
@ -74,3 +75,5 @@ export const {
|
|||||||
} = loraSlice.actions;
|
} = loraSlice.actions;
|
||||||
|
|
||||||
export default loraSlice.reducer;
|
export default loraSlice.reducer;
|
||||||
|
|
||||||
|
export const selectLoraSlice = (state: RootState) => state.lora;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
import type { RootState } from 'app/store/store';
|
||||||
|
|
||||||
type ModelManagerState = {
|
type ModelManagerState = {
|
||||||
searchFolder: string | null;
|
searchFolder: string | null;
|
||||||
@ -28,3 +29,5 @@ export const { setSearchFolder, setAdvancedAddScanModel } =
|
|||||||
modelManagerSlice.actions;
|
modelManagerSlice.actions;
|
||||||
|
|
||||||
export default modelManagerSlice.reducer;
|
export default modelManagerSlice.reducer;
|
||||||
|
|
||||||
|
export const selectModelManagerSlice = (state: RootState) => state.modelmanager;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user