Merge branch 'main' into patch-1

This commit is contained in:
Lincoln Stein 2023-02-07 17:45:15 -05:00 committed by GitHub
commit e3419c82e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
276 changed files with 10682 additions and 3685 deletions

View File

@ -54,8 +54,7 @@ Please enter 1, 2, 3, or 4: [1] 3
``` ```
From the command line, with the InvokeAI virtual environment active, From the command line, with the InvokeAI virtual environment active,
you can launch the front end with the command `textual_inversion you can launch the front end with the command `invokeai-ti --gui`.
--gui`.
This will launch a text-based front end that will look like this: This will launch a text-based front end that will look like this:
@ -227,12 +226,12 @@ It accepts a large number of arguments, which can be summarized by
passing the `--help` argument: passing the `--help` argument:
```sh ```sh
textual_inversion --help invokeai-ti --help
``` ```
Typical usage is shown here: Typical usage is shown here:
```sh ```sh
textual_inversion \ invokeai-ti \
--model=stable-diffusion-1.5 \ --model=stable-diffusion-1.5 \
--resolution=512 \ --resolution=512 \
--learnable_property=style \ --learnable_property=style \

View File

@ -0,0 +1,13 @@
{
"plugins": [
[
"transform-imports",
{
"lodash": {
"transform": "lodash/${member}",
"preventFullImport": true
}
}
]
]
}

View File

@ -0,0 +1,5 @@
dist/
.husky/
node_modules/
patches/
public/

View File

@ -1,13 +0,0 @@
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-react-hooks'],
root: true,
rules: {
'@typescript-eslint/no-unused-vars': ['warn', { varsIgnorePattern: '_+' }],
},
};

View File

@ -0,0 +1,40 @@
module.exports = {
env: {
browser: true,
es6: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:prettier/recommended',
'plugin:react/jsx-runtime',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: ['react', '@typescript-eslint', 'eslint-plugin-react-hooks'],
root: true,
rules: {
'react-hooks/exhaustive-deps': 'error',
'no-var': 'error',
'brace-style': 'error',
'prefer-template': 'error',
radix: 'error',
'space-before-blocks': 'error',
'import/prefer-default-export': 'off',
'@typescript-eslint/no-unused-vars': ['warn', { varsIgnorePattern: '_+' }],
},
settings: {
react: {
version: 'detect',
},
},
};

View File

@ -23,3 +23,6 @@ dist-ssr
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
# build stats
stats.html

View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd invokeai/frontend/ && npx run lint

View File

@ -0,0 +1,5 @@
dist/
.husky/
node_modules/
patches/
public/

View File

@ -0,0 +1,6 @@
module.exports = {
trailingComma: 'es5',
tabWidth: 2,
semi: true,
singleQuote: true,
};

View File

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,23 +1,16 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<script type="module" crossorigin src="./assets/polyfills.1ff60148.js"></script>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InvokeAI - A Stable Diffusion Toolkit</title> <title>InvokeAI - A Stable Diffusion Toolkit</title>
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" /> <link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
<script type="module" crossorigin src="./assets/index.b7daf15c.js"></script> <script type="module" crossorigin src="./assets/index-34c8aef8.js"></script>
<link rel="stylesheet" href="./assets/index.1536494e.css"> <link rel="stylesheet" href="./assets/index-b0bf79f4.css">
<script type="module">try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.__vite_is_modern_browser=true;</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-dde3a68a.js"></script>
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-7649c4ae.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
</body> </body>
</html> </html>

View File

@ -1,23 +0,0 @@
{
"eslintConfig": {
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "eslint-plugin-react-hooks"],
"root": true,
"settings": {
"import/resolver": {
"node": {
"paths": ["src"],
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
},
"rules": {
"react/jsx-filename-extension": [1, { "extensions": [".tsx", ".ts"] }]
}
}
}

View File

@ -2,15 +2,15 @@
"name": "invoke-ai-ui", "name": "invoke-ai-ui",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.1",
"type": "module",
"scripts": { "scripts": {
"prepare": "cd ../../ && husky install invokeai/frontend/.husky",
"dev": "vite dev", "dev": "vite dev",
"build": "tsc && vite build", "build": "tsc && vite build",
"build-dev": "tsc && vite build -m development",
"preview": "vite preview", "preview": "vite preview",
"madge": "madge --circular src/main.tsx", "madge": "madge --circular src/main.tsx",
"lint": "eslint src/", "lint": "eslint --fix .",
"prettier": "prettier *.{json,cjs,ts,html} src/**/*.{ts,tsx}", "lint-staged": "lint-staged",
"prettier": "prettier *.{json,js,ts,html} src/**/*.{ts,tsx,scss} --write .",
"fmt": "npm run prettier -- --write", "fmt": "npm run prettier -- --write",
"postinstall": "patch-package" "postinstall": "patch-package"
}, },
@ -25,6 +25,7 @@
"@radix-ui/react-tooltip": "^1.0.2", "@radix-ui/react-tooltip": "^1.0.2",
"@reduxjs/toolkit": "^1.8.5", "@reduxjs/toolkit": "^1.8.5",
"@types/uuid": "^8.3.4", "@types/uuid": "^8.3.4",
"@vitejs/plugin-react-swc": "^3.1.0",
"add": "^2.0.6", "add": "^2.0.6",
"dateformat": "^5.0.3", "dateformat": "^5.0.3",
"formik": "^2.2.9", "formik": "^2.2.9",
@ -62,22 +63,26 @@
"@types/react-transition-group": "^4.4.5", "@types/react-transition-group": "^4.4.5",
"@typescript-eslint/eslint-plugin": "^5.36.2", "@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2", "@typescript-eslint/parser": "^5.36.2",
"@vitejs/plugin-legacy": "^3.0.1", "babel-plugin-transform-imports": "^2.0.0",
"@vitejs/plugin-react": "^2.0.1",
"eslint": "^8.23.0", "eslint": "^8.23.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.3",
"lint-staged": "^13.1.0",
"madge": "^5.0.1", "madge": "^5.0.1",
"patch-package": "^6.5.0", "patch-package": "^6.5.0",
"postinstall-postinstall": "^2.1.0", "postinstall-postinstall": "^2.1.0",
"prettier": "^2.8.1", "prettier": "^2.8.3",
"rollup-plugin-visualizer": "^5.9.0",
"sass": "^1.55.0", "sass": "^1.55.0",
"terser": "^5.16.1", "terser": "^5.16.1",
"tsc-watch": "^5.0.3", "tsc-watch": "^5.0.3",
"typescript": "^4.6.4", "typescript": "^5.0.0-beta",
"vite": "^3.0.7", "vite": "^4.1.1",
"vite-plugin-eslint": "^1.8.1", "vite-plugin-eslint": "^1.8.1",
"vite-tsconfig-paths": "^3.5.2" "vite-tsconfig-paths": "^4.0.5"
}, },
"madge": { "madge": {
"detectiveOptions": { "detectiveOptions": {
@ -88,5 +93,11 @@
"skipTypeImports": true "skipTypeImports": true
} }
} }
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx,cjs}": [
"npx prettier --write",
"npx eslint --fix"
]
} }
} }

View File

@ -1,14 +1,14 @@
import ImageUploader from 'common/components/ImageUploader';
import Console from 'features/system/components/Console';
import ProgressBar from 'features/system/components/ProgressBar'; import ProgressBar from 'features/system/components/ProgressBar';
import SiteHeader from 'features/system/components/SiteHeader'; import SiteHeader from 'features/system/components/SiteHeader';
import Console from 'features/system/components/Console'; import InvokeTabs from 'features/ui/components/InvokeTabs';
import { keepGUIAlive } from './utils'; import { keepGUIAlive } from './utils';
import InvokeTabs from 'features/tabs/components/InvokeTabs';
import ImageUploader from 'common/components/ImageUploader';
import useToastWatcher from 'features/system/hooks/useToastWatcher'; import useToastWatcher from 'features/system/hooks/useToastWatcher';
import FloatingOptionsPanelButtons from 'features/tabs/components/FloatingOptionsPanelButtons'; import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
import FloatingGalleryButton from 'features/tabs/components/FloatingGalleryButton'; import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
keepGUIAlive(); keepGUIAlive();
@ -27,7 +27,7 @@ const App = () => {
<Console /> <Console />
</div> </div>
</ImageUploader> </ImageUploader>
<FloatingOptionsPanelButtons /> <FloatingParametersPanelButtons />
<FloatingGalleryButton /> <FloatingGalleryButton />
</div> </div>
); );

View File

@ -16,6 +16,20 @@ export const SAMPLERS: Array<string> = [
'k_heun', 'k_heun',
]; ];
// Valid Diffusers Samplers
export const DIFFUSERS_SAMPLERS: Array<string> = [
'ddim',
'plms',
'k_lms',
'dpmpp_2',
'k_dpm_2',
'k_dpm_2_a',
'k_dpmpp_2',
'k_euler',
'k_euler_a',
'k_heun',
];
// Valid image widths // Valid image widths
export const WIDTHS: Array<number> = [ export const WIDTHS: Array<number> = [
64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960,

View File

@ -12,7 +12,7 @@
* 'gfpgan'. * 'gfpgan'.
*/ */
import { InvokeTabName } from 'features/tabs/tabMap'; import { InvokeTabName } from 'features/ui/store/tabMap';
import { IRect } from 'konva/lib/types'; import { IRect } from 'konva/lib/types';
/** /**

View File

@ -1,32 +1,26 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash';
import { RootState } from 'app/store';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
import { OptionsState } from 'features/options/store/optionsSlice';
import { SystemState } from 'features/system/store/systemSlice';
import { validateSeedWeights } from 'common/util/seedWeightPairs'; import { validateSeedWeights } from 'common/util/seedWeightPairs';
import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors'; import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { systemSelector } from 'features/system/store/systemSelectors';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { isEqual } from 'lodash';
export const readinessSelector = createSelector( export const readinessSelector = createSelector(
[ [
(state: RootState) => state.options, generationSelector,
(state: RootState) => state.system, systemSelector,
initialCanvasImageSelector, initialCanvasImageSelector,
activeTabNameSelector, activeTabNameSelector,
], ],
( (generation, system, initialCanvasImage, activeTabName) => {
options: OptionsState,
system: SystemState,
initialCanvasImage,
activeTabName
) => {
const { const {
prompt, prompt,
shouldGenerateVariations, shouldGenerateVariations,
seedWeights, seedWeights,
initialImage, initialImage,
seed, seed,
} = options; } = generation;
const { isProcessing, isConnected } = system; const { isProcessing, isConnected } = system;
@ -71,8 +65,8 @@ export const readinessSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
equalityCheck: _.isEqual, equalityCheck: isEqual,
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,7 +1,7 @@
import { createAction } from '@reduxjs/toolkit'; import { createAction } from '@reduxjs/toolkit';
import { GalleryCategory } from 'features/gallery/store/gallerySlice';
import { InvokeTabName } from 'features/tabs/tabMap';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { GalleryCategory } from 'features/gallery/store/gallerySlice';
import { InvokeTabName } from 'features/ui/store/tabMap';
/** /**
* We can't use redux-toolkit's createSlice() to make these actions, * We can't use redux-toolkit's createSlice() to make these actions,

View File

@ -1,25 +1,24 @@
import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit'; import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit';
import dateFormat from 'dateformat'; import * as InvokeAI from 'app/invokeai';
import { Socket } from 'socket.io-client'; import type { RootState } from 'app/store';
import { import {
frontendToBackendParameters, frontendToBackendParameters,
FrontendToBackendParametersConfig, FrontendToBackendParametersConfig,
} from 'common/util/parameterTranslation'; } from 'common/util/parameterTranslation';
import dateFormat from 'dateformat';
import { import {
GalleryCategory, GalleryCategory,
GalleryState, GalleryState,
removeImage, removeImage,
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import { OptionsState } from 'features/options/store/optionsSlice';
import { import {
addLogEntry, addLogEntry,
generationRequested, generationRequested,
modelChangeRequested, modelChangeRequested,
setIsProcessing, setIsProcessing,
} from 'features/system/store/systemSlice'; } from 'features/system/store/systemSlice';
import { InvokeTabName } from 'features/tabs/tabMap'; import { InvokeTabName } from 'features/ui/store/tabMap';
import * as InvokeAI from 'app/invokeai'; import { Socket } from 'socket.io-client';
import type { RootState } from 'app/store';
/** /**
* Returns an object containing all functions which use `socketio.emit()`. * Returns an object containing all functions which use `socketio.emit()`.
@ -39,7 +38,8 @@ const makeSocketIOEmitters = (
const state: RootState = getState(); const state: RootState = getState();
const { const {
options: optionsState, generation: generationState,
postprocessing: postprocessingState,
system: systemState, system: systemState,
canvas: canvasState, canvas: canvasState,
} = state; } = state;
@ -47,7 +47,8 @@ const makeSocketIOEmitters = (
const frontendToBackendParametersConfig: FrontendToBackendParametersConfig = const frontendToBackendParametersConfig: FrontendToBackendParametersConfig =
{ {
generationMode, generationMode,
optionsState, generationState,
postprocessingState,
canvasState, canvasState,
systemState, systemState,
}; };
@ -90,8 +91,11 @@ const makeSocketIOEmitters = (
}, },
emitRunESRGAN: (imageToProcess: InvokeAI.Image) => { emitRunESRGAN: (imageToProcess: InvokeAI.Image) => {
dispatch(setIsProcessing(true)); dispatch(setIsProcessing(true));
const options: OptionsState = getState().options;
const { upscalingLevel, upscalingStrength } = options; const {
postprocessing: { upscalingLevel, upscalingStrength },
} = getState();
const esrganParameters = { const esrganParameters = {
upscale: [upscalingLevel, upscalingStrength], upscale: [upscalingLevel, upscalingStrength],
}; };
@ -111,8 +115,10 @@ const makeSocketIOEmitters = (
}, },
emitRunFacetool: (imageToProcess: InvokeAI.Image) => { emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
dispatch(setIsProcessing(true)); dispatch(setIsProcessing(true));
const options: OptionsState = getState().options;
const { facetoolType, facetoolStrength, codeformerFidelity } = options; const {
postprocessing: { facetoolType, facetoolStrength, codeformerFidelity },
} = getState();
const facetoolParameters: Record<string, unknown> = { const facetoolParameters: Record<string, unknown> = {
facetool_strength: facetoolStrength, facetool_strength: facetoolStrength,

View File

@ -1,24 +1,24 @@
import { AnyAction, MiddlewareAPI, Dispatch } from '@reduxjs/toolkit'; import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit';
import { v4 as uuidv4 } from 'uuid';
import dateFormat from 'dateformat'; import dateFormat from 'dateformat';
import i18n from 'i18n'; import i18n from 'i18n';
import { v4 as uuidv4 } from 'uuid';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { import {
addLogEntry, addLogEntry,
addToast,
errorOccurred,
processingCanceled,
setCurrentStatus,
setFoundModels,
setIsCancelable,
setIsConnected, setIsConnected,
setIsProcessing, setIsProcessing,
setSystemStatus,
setCurrentStatus,
setSystemConfig,
processingCanceled,
errorOccurred,
setModelList, setModelList,
setIsCancelable,
addToast,
setFoundModels,
setSearchFolder, setSearchFolder,
setSystemConfig,
setSystemStatus,
} from 'features/system/store/systemSlice'; } from 'features/system/store/systemSlice';
import { import {
@ -30,20 +30,20 @@ import {
setIntermediateImage, setIntermediateImage,
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import type { RootState } from 'app/store';
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
import { import {
clearInitialImage, clearInitialImage,
setInfillMethod, setInfillMethod,
setInitialImage, setInitialImage,
setMaskPath, setMaskPath,
} from 'features/options/store/optionsSlice'; } from 'features/parameters/store/generationSlice';
import { tabMap } from 'features/ui/store/tabMap';
import { import {
requestImages, requestImages,
requestNewImages, requestNewImages,
requestSystemConfig, requestSystemConfig,
} from './actions'; } from './actions';
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
import { tabMap } from 'features/tabs/tabMap';
import type { RootState } from 'app/store';
/** /**
* Returns an object containing listener callbacks for socketio events. * Returns an object containing listener callbacks for socketio events.
@ -104,8 +104,9 @@ const makeSocketIOListeners = (
*/ */
onGenerationResult: (data: InvokeAI.ImageResultResponse) => { onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
try { try {
const state: RootState = getState(); const state = getState();
const { shouldLoopback, activeTab } = state.options; const { activeTab } = state.ui;
const { shouldLoopback } = state.postprocessing;
const { boundingBox: _, generationMode, ...rest } = data; const { boundingBox: _, generationMode, ...rest } = data;
const newImage = { const newImage = {
@ -327,7 +328,9 @@ const makeSocketIOListeners = (
dispatch(removeImage(data)); dispatch(removeImage(data));
// remove references to image in options // remove references to image in options
const { initialImage, maskPath } = getState().options; const {
generation: { initialImage, maskPath },
} = getState();
if ( if (
initialImage === url || initialImage === url ||

View File

@ -1,8 +1,8 @@
import { Middleware } from '@reduxjs/toolkit'; import { Middleware } from '@reduxjs/toolkit';
import { io } from 'socket.io-client'; import { io } from 'socket.io-client';
import makeSocketIOListeners from './listeners';
import makeSocketIOEmitters from './emitters'; import makeSocketIOEmitters from './emitters';
import makeSocketIOListeners from './listeners';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
@ -26,7 +26,7 @@ export const socketioMiddleware = () => {
const socketio = io(origin, { const socketio = io(origin, {
timeout: 60000, timeout: 60000,
path: window.location.pathname + 'socket.io', path: `${window.location.pathname}socket.io`,
}); });
let areListenersSet = false; let areListenersSet = false;

View File

@ -5,10 +5,13 @@ import storage from 'redux-persist/lib/storage'; // defaults to localStorage for
import { getPersistConfig } from 'redux-deep-persist'; import { getPersistConfig } from 'redux-deep-persist';
import optionsReducer from 'features/options/store/optionsSlice';
import galleryReducer from 'features/gallery/store/gallerySlice';
import systemReducer from 'features/system/store/systemSlice';
import canvasReducer from 'features/canvas/store/canvasSlice'; import canvasReducer from 'features/canvas/store/canvasSlice';
import galleryReducer from 'features/gallery/store/gallerySlice';
import lightboxReducer from 'features/lightbox/store/lightboxSlice';
import generationReducer from 'features/parameters/store/generationSlice';
import postprocessingReducer from 'features/parameters/store/postprocessingSlice';
import systemReducer from 'features/system/store/systemSlice';
import uiReducer from 'features/ui/store/uiSlice';
import { socketioMiddleware } from './socketio/middleware'; import { socketioMiddleware } from './socketio/middleware';
@ -58,10 +61,13 @@ const galleryBlacklist = [
].map((blacklistItem) => `gallery.${blacklistItem}`); ].map((blacklistItem) => `gallery.${blacklistItem}`);
const rootReducer = combineReducers({ const rootReducer = combineReducers({
options: optionsReducer, generation: generationReducer,
postprocessing: postprocessingReducer,
gallery: galleryReducer, gallery: galleryReducer,
system: systemReducer, system: systemReducer,
canvas: canvasReducer, canvas: canvasReducer,
ui: uiReducer,
lightbox: lightboxReducer,
}); });
const rootPersistConfig = getPersistConfig({ const rootPersistConfig = getPersistConfig({
@ -89,8 +95,8 @@ export const store = configureStore({
'canvas/setStageCoordinates', 'canvas/setStageCoordinates',
'canvas/setStageScale', 'canvas/setStageScale',
'canvas/setIsDrawing', 'canvas/setIsDrawing',
// 'canvas/setBoundingBoxCoordinates', 'canvas/setBoundingBoxCoordinates',
// 'canvas/setBoundingBoxDimensions', 'canvas/setBoundingBoxDimensions',
'canvas/setIsDrawing', 'canvas/setIsDrawing',
'canvas/addPointToCurrentLine', 'canvas/addPointToCurrentLine',
], ],

View File

@ -1,7 +1,7 @@
import { Box, forwardRef, Icon } from '@chakra-ui/react'; import { Box, forwardRef, Icon } from '@chakra-ui/react';
import { Feature } from 'app/features';
import { IconType } from 'react-icons'; import { IconType } from 'react-icons';
import { MdHelp } from 'react-icons/md'; import { MdHelp } from 'react-icons/md';
import { Feature } from 'app/features';
import GuidePopover from './GuidePopover'; import GuidePopover from './GuidePopover';
type GuideIconProps = { type GuideIconProps = {

View File

@ -1,29 +1,29 @@
import { import {
Box,
Popover, Popover,
PopoverArrow, PopoverArrow,
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
Box,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { SystemState } from 'features/system/store/systemSlice';
import { useAppSelector } from 'app/storeHooks';
import { RootState } from 'app/store';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { ReactElement } from 'react';
import { Feature, useFeatureHelpInfo } from 'app/features'; import { Feature, useFeatureHelpInfo } from 'app/features';
import { useAppSelector } from 'app/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { SystemState } from 'features/system/store/systemSlice';
import { ReactElement } from 'react';
type GuideProps = { type GuideProps = {
children: ReactElement; children: ReactElement;
feature: Feature; feature: Feature;
}; };
const systemSelector = createSelector( const guidePopoverSelector = createSelector(
(state: RootState) => state.system, systemSelector,
(system: SystemState) => system.shouldDisplayGuides (system: SystemState) => system.shouldDisplayGuides
); );
const GuidePopover = ({ children, feature }: GuideProps) => { const GuidePopover = ({ children, feature }: GuideProps) => {
const shouldDisplayGuides = useAppSelector(systemSelector); const shouldDisplayGuides = useAppSelector(guidePopoverSelector);
const { text } = useFeatureHelpInfo(feature); const { text } = useFeatureHelpInfo(feature);
if (!shouldDisplayGuides) return null; if (!shouldDisplayGuides) return null;

View File

@ -1,9 +1,9 @@
import { import {
IconButtonProps, forwardRef,
IconButton, IconButton,
IconButtonProps,
Tooltip, Tooltip,
TooltipProps, TooltipProps,
forwardRef,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
export type IAIIconButtonProps = IconButtonProps & { export type IAIIconButtonProps = IconButtonProps & {

View File

@ -1,19 +1,20 @@
import { import {
FormControl, FormControl,
FormControlProps,
FormLabel,
FormLabelProps,
NumberDecrementStepper,
NumberIncrementStepper,
NumberInput, NumberInput,
NumberInputField, NumberInputField,
NumberIncrementStepper,
NumberDecrementStepper,
NumberInputProps,
FormLabel,
NumberInputFieldProps, NumberInputFieldProps,
NumberInputProps,
NumberInputStepperProps, NumberInputStepperProps,
FormControlProps,
FormLabelProps,
TooltipProps,
Tooltip, Tooltip,
TooltipProps,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import _ from 'lodash'; import { clamp } from 'lodash';
import { FocusEvent, useEffect, useState } from 'react'; import { FocusEvent, useEffect, useState } from 'react';
const numberStringRegex = /^-?(0\.)?\.?$/; const numberStringRegex = /^-?(0\.)?\.?$/;
@ -104,7 +105,7 @@ const IAINumberInput = (props: Props) => {
* clamp it on blur and floor it if needed. * clamp it on blur and floor it if needed.
*/ */
const handleBlur = (e: FocusEvent<HTMLInputElement>) => { const handleBlur = (e: FocusEvent<HTMLInputElement>) => {
const clamped = _.clamp( const clamped = clamp(
isInteger ? Math.floor(Number(e.target.value)) : Number(e.target.value), isInteger ? Math.floor(Number(e.target.value)) : Number(e.target.value),
min, min,
max max

View File

@ -1,11 +1,11 @@
import { import {
BoxProps,
Popover, Popover,
PopoverArrow, PopoverArrow,
PopoverContent, PopoverContent,
PopoverProps,
PopoverTrigger, PopoverTrigger,
BoxProps,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { PopoverProps } from '@chakra-ui/react';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
type IAIPopoverProps = PopoverProps & { type IAIPopoverProps = PopoverProps & {

View File

@ -23,10 +23,11 @@ import {
Tooltip, Tooltip,
TooltipProps, TooltipProps,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import React, { FocusEvent, useMemo, useState, useEffect } from 'react'; import { clamp } from 'lodash';
import { FocusEvent, useEffect, useMemo, useState } from 'react';
import { BiReset } from 'react-icons/bi'; import { BiReset } from 'react-icons/bi';
import IAIIconButton, { IAIIconButtonProps } from './IAIIconButton'; import IAIIconButton, { IAIIconButtonProps } from './IAIIconButton';
import _ from 'lodash';
export type IAIFullSliderProps = { export type IAIFullSliderProps = {
label: string; label: string;
@ -122,7 +123,7 @@ export default function IAISlider(props: IAIFullSliderProps) {
const handleInputBlur = (e: FocusEvent<HTMLInputElement>) => { const handleInputBlur = (e: FocusEvent<HTMLInputElement>) => {
if (e.target.value === '') e.target.value = String(min); if (e.target.value === '') e.target.value = String(min);
const clamped = _.clamp( const clamped = clamp(
isInteger ? Math.floor(Number(e.target.value)) : Number(localInputValue), isInteger ? Math.floor(Number(e.target.value)) : Number(localInputValue),
min, min,
numberInputMax numberInputMax

View File

@ -1,20 +1,20 @@
import {
useCallback,
ReactNode,
useState,
useEffect,
KeyboardEvent,
} from 'react';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { FileRejection, useDropzone } from 'react-dropzone';
import { useToast } from '@chakra-ui/react'; import { useToast } from '@chakra-ui/react';
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext'; import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { tabDict } from 'features/tabs/components/InvokeTabs';
import ImageUploadOverlay from './ImageUploadOverlay';
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
import useImageUploader from 'common/hooks/useImageUploader'; import useImageUploader from 'common/hooks/useImageUploader';
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
import { tabDict } from 'features/ui/components/InvokeTabs';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import {
KeyboardEvent,
ReactNode,
useCallback,
useEffect,
useState,
} from 'react';
import { FileRejection, useDropzone } from 'react-dropzone';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import ImageUploadOverlay from './ImageUploadOverlay';
type ImageUploaderProps = { type ImageUploaderProps = {
children: ReactNode; children: ReactNode;
@ -33,7 +33,7 @@ const ImageUploader = (props: ImageUploaderProps) => {
(rejection: FileRejection) => { (rejection: FileRejection) => {
setIsHandlingUpload(true); setIsHandlingUpload(true);
const msg = rejection.errors.reduce( const msg = rejection.errors.reduce(
(acc: string, cur: { message: string }) => acc + '\n' + cur.message, (acc: string, cur: { message: string }) => `${acc}\n${cur.message}`,
'' ''
); );
toast({ toast({

View File

@ -1,7 +1,7 @@
import { Heading } from '@chakra-ui/react'; import { Heading } from '@chakra-ui/react';
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
import { useContext } from 'react'; import { useContext } from 'react';
import { FaUpload } from 'react-icons/fa'; import { FaUpload } from 'react-icons/fa';
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
type ImageUploaderButtonProps = { type ImageUploaderButtonProps = {
styleClass?: string; styleClass?: string;

View File

@ -1,6 +1,6 @@
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
import { useContext } from 'react'; import { useContext } from 'react';
import { FaUpload } from 'react-icons/fa'; import { FaUpload } from 'react-icons/fa';
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
import IAIIconButton from './IAIIconButton'; import IAIIconButton from './IAIIconButton';
const ImageUploaderIconButton = () => { const ImageUploaderIconButton = () => {

View File

@ -1,4 +1,3 @@
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function NodesWIP() { export default function NodesWIP() {

View File

@ -1,4 +1,3 @@
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export const PostProcessingWIP = () => { export const PostProcessingWIP = () => {

View File

@ -1,4 +1,3 @@
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function TrainingWIP() { export default function TrainingWIP() {

View File

@ -1,6 +1,5 @@
import { Tooltip } from '@chakra-ui/react'; import { Tooltip } from '@chakra-ui/react';
import * as Slider from '@radix-ui/react-slider'; import * as Slider from '@radix-ui/react-slider';
import React from 'react';
type IAISliderProps = Slider.SliderProps & { type IAISliderProps = Slider.SliderProps & {
value: number[]; value: number[];

View File

@ -1,27 +1,29 @@
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants'; import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
import { OptionsState } from 'features/options/store/optionsSlice'; import { Dimensions } from 'features/canvas/store/canvasTypes';
import { GenerationState } from 'features/parameters/store/generationSlice';
import { SystemState } from 'features/system/store/systemSlice'; import { SystemState } from 'features/system/store/systemSlice';
import { Vector2d } from 'konva/lib/types'; import { Vector2d } from 'konva/lib/types';
import { Dimensions } from 'features/canvas/store/canvasTypes';
import { stringToSeedWeightsArray } from './seedWeightPairs';
import randomInt from './randomInt';
import { InvokeTabName } from 'features/tabs/tabMap';
import { import {
CanvasState, CanvasState,
isCanvasMaskLine, isCanvasMaskLine,
} from 'features/canvas/store/canvasTypes'; } from 'features/canvas/store/canvasTypes';
import generateMask from 'features/canvas/util/generateMask'; import generateMask from 'features/canvas/util/generateMask';
import openBase64ImageInTab from './openBase64ImageInTab';
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider'; import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
import type { import type {
UpscalingLevel,
FacetoolType, FacetoolType,
} from 'features/options/store/optionsSlice'; UpscalingLevel,
} from 'features/parameters/store/postprocessingSlice';
import { PostprocessingState } from 'features/parameters/store/postprocessingSlice';
import { InvokeTabName } from 'features/ui/store/tabMap';
import openBase64ImageInTab from './openBase64ImageInTab';
import randomInt from './randomInt';
import { stringToSeedWeightsArray } from './seedWeightPairs';
export type FrontendToBackendParametersConfig = { export type FrontendToBackendParametersConfig = {
generationMode: InvokeTabName; generationMode: InvokeTabName;
optionsState: OptionsState; generationState: GenerationState;
postprocessingState: PostprocessingState;
canvasState: CanvasState; canvasState: CanvasState;
systemState: SystemState; systemState: SystemState;
imageToProcessUrl?: string; imageToProcessUrl?: string;
@ -91,16 +93,31 @@ export const frontendToBackendParameters = (
): BackendParameters => { ): BackendParameters => {
const canvasBaseLayer = getCanvasBaseLayer(); const canvasBaseLayer = getCanvasBaseLayer();
const { generationMode, optionsState, canvasState, systemState } = config; const {
generationMode,
generationState,
postprocessingState,
canvasState,
systemState,
} = config;
const { const {
cfgScale,
codeformerFidelity, codeformerFidelity,
facetoolStrength, facetoolStrength,
facetoolType, facetoolType,
height,
hiresFix, hiresFix,
hiresStrength, hiresStrength,
shouldRunESRGAN,
shouldRunFacetool,
upscalingLevel,
upscalingStrength,
} = postprocessingState;
const {
cfgScale,
height,
img2imgStrength, img2imgStrength,
infillMethod, infillMethod,
initialImage, initialImage,
@ -119,16 +136,14 @@ export const frontendToBackendParameters = (
shouldFitToWidthHeight, shouldFitToWidthHeight,
shouldGenerateVariations, shouldGenerateVariations,
shouldRandomizeSeed, shouldRandomizeSeed,
shouldRunESRGAN,
shouldRunFacetool,
steps, steps,
threshold, threshold,
tileSize, tileSize,
upscalingLevel,
upscalingStrength,
variationAmount, variationAmount,
width, width,
} = optionsState; } = generationState;
const { const {
shouldDisplayInProgressType, shouldDisplayInProgressType,

View File

@ -63,6 +63,6 @@ export const stringToSeedWeightsArray = (
const stringPairs = string.split(','); const stringPairs = string.split(',');
const arrPairs = stringPairs.map((p) => p.split(':')); const arrPairs = stringPairs.map((p) => p.split(':'));
return arrPairs.map( return arrPairs.map(
(p: Array<string>): Array<number> => [parseInt(p[0]), parseFloat(p[1])] (p: Array<string>): Array<number> => [parseInt(p[0], 10), parseFloat(p[1])]
); );
}; };

View File

@ -1,37 +1,38 @@
import { useCallback, useRef } from 'react'; import { createSelector } from '@reduxjs/toolkit';
import Konva from 'konva';
import { Layer, Stage } from 'react-konva';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import { import {
canvasSelector, canvasSelector,
isStagingSelector, isStagingSelector,
} from 'features/canvas/store/canvasSelectors'; } from 'features/canvas/store/canvasSelectors';
import IAICanvasMaskLines from './IAICanvasMaskLines'; import Konva from 'konva';
import IAICanvasToolPreview from './IAICanvasToolPreview'; import { KonvaEventObject } from 'konva/lib/Node';
import { Vector2d } from 'konva/lib/types'; import { Vector2d } from 'konva/lib/types';
import IAICanvasBoundingBox from './IAICanvasToolbar/IAICanvasBoundingBox'; import { isEqual } from 'lodash';
import { useCallback, useRef } from 'react';
import { Layer, Stage } from 'react-konva';
import useCanvasDragMove from '../hooks/useCanvasDragMove';
import useCanvasHotkeys from '../hooks/useCanvasHotkeys'; import useCanvasHotkeys from '../hooks/useCanvasHotkeys';
import _ from 'lodash';
import { createSelector } from '@reduxjs/toolkit';
import IAICanvasMaskCompositer from './IAICanvasMaskCompositer';
import useCanvasWheel from '../hooks/useCanvasZoom';
import useCanvasMouseDown from '../hooks/useCanvasMouseDown'; import useCanvasMouseDown from '../hooks/useCanvasMouseDown';
import useCanvasMouseUp from '../hooks/useCanvasMouseUp';
import useCanvasMouseMove from '../hooks/useCanvasMouseMove'; import useCanvasMouseMove from '../hooks/useCanvasMouseMove';
import useCanvasMouseOut from '../hooks/useCanvasMouseOut'; import useCanvasMouseOut from '../hooks/useCanvasMouseOut';
import useCanvasDragMove from '../hooks/useCanvasDragMove'; import useCanvasMouseUp from '../hooks/useCanvasMouseUp';
import IAICanvasObjectRenderer from './IAICanvasObjectRenderer'; import useCanvasWheel from '../hooks/useCanvasZoom';
import IAICanvasGrid from './IAICanvasGrid';
import IAICanvasIntermediateImage from './IAICanvasIntermediateImage';
import IAICanvasStatusText from './IAICanvasStatusText';
import IAICanvasStagingArea from './IAICanvasStagingArea';
import IAICanvasStagingAreaToolbar from './IAICanvasStagingAreaToolbar';
import { import {
setCanvasBaseLayer, setCanvasBaseLayer,
setCanvasStage, setCanvasStage,
} from '../util/konvaInstanceProvider'; } from '../util/konvaInstanceProvider';
import { KonvaEventObject } from 'konva/lib/Node';
import IAICanvasBoundingBoxOverlay from './IAICanvasBoundingBoxOverlay'; import IAICanvasBoundingBoxOverlay from './IAICanvasBoundingBoxOverlay';
import IAICanvasGrid from './IAICanvasGrid';
import IAICanvasIntermediateImage from './IAICanvasIntermediateImage';
import IAICanvasMaskCompositer from './IAICanvasMaskCompositer';
import IAICanvasMaskLines from './IAICanvasMaskLines';
import IAICanvasObjectRenderer from './IAICanvasObjectRenderer';
import IAICanvasStagingArea from './IAICanvasStagingArea';
import IAICanvasStagingAreaToolbar from './IAICanvasStagingAreaToolbar';
import IAICanvasStatusText from './IAICanvasStatusText';
import IAICanvasBoundingBox from './IAICanvasToolbar/IAICanvasBoundingBox';
import IAICanvasToolPreview from './IAICanvasToolPreview';
const selector = createSelector( const selector = createSelector(
[canvasSelector, isStagingSelector], [canvasSelector, isStagingSelector],
@ -82,7 +83,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,6 +1,7 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import _ from 'lodash'; import { isEqual } from 'lodash';
import { Group, Rect } from 'react-konva'; import { Group, Rect } from 'react-konva';
import { canvasSelector } from '../store/canvasSelectors'; import { canvasSelector } from '../store/canvasSelectors';
@ -27,7 +28,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -3,10 +3,11 @@
import { useColorMode } from '@chakra-ui/react'; import { useColorMode } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import _ from 'lodash'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { isEqual, range } from 'lodash';
import { ReactNode, useCallback, useLayoutEffect, useState } from 'react'; import { ReactNode, useCallback, useLayoutEffect, useState } from 'react';
import { Group, Line as KonvaLine } from 'react-konva'; import { Group, Line as KonvaLine } from 'react-konva';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
const selector = createSelector( const selector = createSelector(
[canvasSelector], [canvasSelector],
@ -16,7 +17,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );
@ -85,7 +86,7 @@ const IAICanvasGrid = () => {
xSteps = Math.round(xSize / 64) + 1, xSteps = Math.round(xSize / 64) + 1,
ySteps = Math.round(ySize / 64) + 1; ySteps = Math.round(ySize / 64) + 1;
const xLines = _.range(0, xSteps).map((i) => ( const xLines = range(0, xSteps).map((i) => (
<KonvaLine <KonvaLine
key={`x_${i}`} key={`x_${i}`}
x={fullRect.x1 + i * 64} x={fullRect.x1 + i * 64}
@ -95,7 +96,7 @@ const IAICanvasGrid = () => {
strokeWidth={1} strokeWidth={1}
/> />
)); ));
const yLines = _.range(0, ySteps).map((i) => ( const yLines = range(0, ySteps).map((i) => (
<KonvaLine <KonvaLine
key={`y_${i}`} key={`y_${i}`}
x={fullRect.x1} x={fullRect.x1}

View File

@ -3,7 +3,8 @@ import { RootState } from 'app/store';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import { GalleryState } from 'features/gallery/store/gallerySlice'; import { GalleryState } from 'features/gallery/store/gallerySlice';
import { ImageConfig } from 'konva/lib/shapes/Image'; import { ImageConfig } from 'konva/lib/shapes/Image';
import _ from 'lodash'; import { isEqual } from 'lodash';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Image as KonvaImage } from 'react-konva'; import { Image as KonvaImage } from 'react-konva';
@ -14,7 +15,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,13 +1,13 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { RectConfig } from 'konva/lib/shapes/Rect'; import { RectConfig } from 'konva/lib/shapes/Rect';
import { Rect } from 'react-konva'; import { Rect } from 'react-konva';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { rgbaColorToString } from 'features/canvas/util/colorToString'; import { rgbaColorToString } from 'features/canvas/util/colorToString';
import { useCallback, useEffect, useRef, useState } from 'react';
import Konva from 'konva'; import Konva from 'konva';
import { isNumber } from 'lodash'; import { isNumber } from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
export const canvasMaskCompositerSelector = createSelector( export const canvasMaskCompositerSelector = createSelector(
canvasSelector, canvasSelector,

View File

@ -1,10 +1,11 @@
import { GroupConfig } from 'konva/lib/Group';
import { Group, Line } from 'react-konva';
import { useAppSelector } from 'app/storeHooks';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { GroupConfig } from 'konva/lib/Group';
import { isEqual } from 'lodash';
import { Group, Line } from 'react-konva';
import { isCanvasMaskLine } from '../store/canvasTypes'; import { isCanvasMaskLine } from '../store/canvasTypes';
import _ from 'lodash';
export const canvasLinesSelector = createSelector( export const canvasLinesSelector = createSelector(
[canvasSelector], [canvasSelector],
@ -13,7 +14,7 @@ export const canvasLinesSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,6 +1,9 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import _ from 'lodash'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { rgbaColorToString } from 'features/canvas/util/colorToString';
import { isEqual } from 'lodash';
import { Group, Line, Rect } from 'react-konva'; import { Group, Line, Rect } from 'react-konva';
import { import {
isCanvasBaseImage, isCanvasBaseImage,
@ -9,8 +12,6 @@ import {
isCanvasFillRect, isCanvasFillRect,
} from '../store/canvasTypes'; } from '../store/canvasTypes';
import IAICanvasImage from './IAICanvasImage'; import IAICanvasImage from './IAICanvasImage';
import { rgbaColorToString } from 'features/canvas/util/colorToString';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
const selector = createSelector( const selector = createSelector(
[canvasSelector], [canvasSelector],
@ -24,7 +25,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,18 +1,18 @@
import { Spinner } from '@chakra-ui/react'; import { Spinner } from '@chakra-ui/react';
import { useLayoutEffect, useRef } from 'react'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors'; import {
canvasSelector,
initialCanvasImageSelector,
} from 'features/canvas/store/canvasSelectors';
import { import {
resizeAndScaleCanvas, resizeAndScaleCanvas,
resizeCanvas, resizeCanvas,
setCanvasContainerDimensions, setCanvasContainerDimensions,
setDoesCanvasNeedScaling, setDoesCanvasNeedScaling,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { createSelector } from '@reduxjs/toolkit'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { import { useLayoutEffect, useRef } from 'react';
canvasSelector,
initialCanvasImageSelector,
} from 'features/canvas/store/canvasSelectors';
const canvasResizerSelector = createSelector( const canvasResizerSelector = createSelector(
canvasSelector, canvasSelector,

View File

@ -1,9 +1,10 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import { GroupConfig } from 'konva/lib/Group';
import _ from 'lodash';
import { Group, Rect } from 'react-konva';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { GroupConfig } from 'konva/lib/Group';
import { isEqual } from 'lodash';
import { Group, Rect } from 'react-konva';
import IAICanvasImage from './IAICanvasImage'; import IAICanvasImage from './IAICanvasImage';
const selector = createSelector( const selector = createSelector(
@ -34,7 +35,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,18 +1,8 @@
import { ButtonGroup, Flex } from '@chakra-ui/react'; import { ButtonGroup, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { saveStagingAreaImageToGallery } from 'app/socketio/actions';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import _ from 'lodash';
import { useCallback } from 'react';
import {
FaArrowLeft,
FaArrowRight,
FaCheck,
FaEye,
FaEyeSlash,
FaPlus,
FaSave,
} from 'react-icons/fa';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { import {
commitStagingAreaImage, commitStagingAreaImage,
@ -22,9 +12,20 @@ import {
setShouldShowStagingImage, setShouldShowStagingImage,
setShouldShowStagingOutline, setShouldShowStagingOutline,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { isEqual } from 'lodash';
import { useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { saveStagingAreaImageToGallery } from 'app/socketio/actions';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import {
FaArrowLeft,
FaArrowRight,
FaCheck,
FaEye,
FaEyeSlash,
FaPlus,
FaSave,
} from 'react-icons/fa';
const selector = createSelector( const selector = createSelector(
[canvasSelector], [canvasSelector],
@ -48,7 +49,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,10 +1,11 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import _ from 'lodash';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusTextCursorPos'; import { isEqual } from 'lodash';
import roundToHundreth from '../util/roundToHundreth';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import roundToHundreth from '../util/roundToHundreth';
import IAICanvasStatusTextCursorPos from './IAICanvasStatusText/IAICanvasStatusTextCursorPos';
const selector = createSelector( const selector = createSelector(
[canvasSelector], [canvasSelector],
@ -59,7 +60,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,9 +1,9 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import React from 'react';
import _ from 'lodash';
import roundToHundreth from 'features/canvas/util/roundToHundreth'; import roundToHundreth from 'features/canvas/util/roundToHundreth';
import { isEqual } from 'lodash';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const cursorPositionSelector = createSelector( const cursorPositionSelector = createSelector(
@ -23,7 +23,7 @@ const cursorPositionSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,10 +1,11 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { GroupConfig } from 'konva/lib/Group';
import _ from 'lodash';
import { Circle, Group } from 'react-konva';
import { useAppSelector } from 'app/storeHooks'; import { useAppSelector } from 'app/storeHooks';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { rgbaColorToString } from 'features/canvas/util/colorToString'; import { rgbaColorToString } from 'features/canvas/util/colorToString';
import { GroupConfig } from 'konva/lib/Group';
import { isEqual } from 'lodash';
import { Circle, Group } from 'react-konva';
import { import {
COLOR_PICKER_SIZE, COLOR_PICKER_SIZE,
COLOR_PICKER_STROKE_RADIUS, COLOR_PICKER_STROKE_RADIUS,
@ -106,7 +107,7 @@ const canvasBrushPreviewSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,10 +1,4 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node';
import { Vector2d } from 'konva/lib/types';
import _ from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Group, Rect, Transformer } from 'react-konva';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { import {
roundDownToMultiple, roundDownToMultiple,
@ -18,7 +12,14 @@ import {
setIsMovingBoundingBox, setIsMovingBoundingBox,
setIsTransformingBoundingBox, setIsTransformingBoundingBox,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import Konva from 'konva';
import { GroupConfig } from 'konva/lib/Group'; import { GroupConfig } from 'konva/lib/Group';
import { KonvaEventObject } from 'konva/lib/Node';
import { Vector2d } from 'konva/lib/types';
import { isEqual } from 'lodash';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Group, Rect, Transformer } from 'react-konva';
const boundingBoxPreviewSelector = createSelector( const boundingBoxPreviewSelector = createSelector(
canvasSelector, canvasSelector,
@ -48,7 +49,7 @@ const boundingBoxPreviewSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,5 +1,15 @@
import { ButtonGroup, Flex } from '@chakra-ui/react'; import { ButtonGroup, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIButton from 'common/components/IAIButton';
import IAICheckbox from 'common/components/IAICheckbox';
import IAIColorPicker from 'common/components/IAIColorPicker';
import IAIIconButton from 'common/components/IAIIconButton';
import IAIPopover from 'common/components/IAIPopover';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { import {
clearMask, clearMask,
setIsMaskEnabled, setIsMaskEnabled,
@ -7,21 +17,12 @@ import {
setMaskColor, setMaskColor,
setShouldPreserveMaskedArea, setShouldPreserveMaskedArea,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import _ from 'lodash';
import IAIIconButton from 'common/components/IAIIconButton';
import { FaMask, FaTrash } from 'react-icons/fa';
import IAIPopover from 'common/components/IAIPopover';
import IAICheckbox from 'common/components/IAICheckbox';
import IAIColorPicker from 'common/components/IAIColorPicker';
import IAIButton from 'common/components/IAIButton';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { useHotkeys } from 'react-hotkeys-hook';
import { rgbaColorToString } from 'features/canvas/util/colorToString'; import { rgbaColorToString } from 'features/canvas/util/colorToString';
import { isEqual } from 'lodash';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaMask, FaTrash } from 'react-icons/fa';
export const selector = createSelector( export const selector = createSelector(
[canvasSelector, isStagingSelector], [canvasSelector, isStagingSelector],
@ -40,7 +41,7 @@ export const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,14 +1,15 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useHotkeys } from 'react-hotkeys-hook';
import { FaRedo } from 'react-icons/fa';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { useHotkeys } from 'react-hotkeys-hook';
import { FaRedo } from 'react-icons/fa';
import _ from 'lodash';
import { redo } from 'features/canvas/store/canvasSlice'; import { redo } from 'features/canvas/store/canvasSlice';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const canvasRedoSelector = createSelector( const canvasRedoSelector = createSelector(
@ -23,7 +24,7 @@ const canvasRedoSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,5 +1,10 @@
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAICheckbox from 'common/components/IAICheckbox';
import IAIIconButton from 'common/components/IAIIconButton';
import IAIPopover from 'common/components/IAIPopover';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { import {
setShouldAutoSave, setShouldAutoSave,
setShouldCropToBoundingBoxOnSave, setShouldCropToBoundingBoxOnSave,
@ -10,18 +15,14 @@ import {
setShouldShowIntermediates, setShouldShowIntermediates,
setShouldSnapToGrid, setShouldSnapToGrid,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import _ from 'lodash';
import IAIIconButton from 'common/components/IAIIconButton';
import { FaWrench } from 'react-icons/fa';
import IAIPopover from 'common/components/IAIPopover';
import IAICheckbox from 'common/components/IAICheckbox';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import EmptyTempFolderButtonModal from 'features/system/components/ClearTempFolderButtonModal'; import EmptyTempFolderButtonModal from 'features/system/components/ClearTempFolderButtonModal';
import ClearCanvasHistoryButtonModal from '../ClearCanvasHistoryButtonModal'; import { isEqual } from 'lodash';
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FaWrench } from 'react-icons/fa';
import ClearCanvasHistoryButtonModal from '../ClearCanvasHistoryButtonModal';
export const canvasControlsSelector = createSelector( export const canvasControlsSelector = createSelector(
[canvasSelector], [canvasSelector],
@ -50,7 +51,7 @@ export const canvasControlsSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,5 +1,14 @@
import { ButtonGroup, Flex } from '@chakra-ui/react'; import { ButtonGroup, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIColorPicker from 'common/components/IAIColorPicker';
import IAIIconButton from 'common/components/IAIIconButton';
import IAIPopover from 'common/components/IAIPopover';
import IAISlider from 'common/components/IAISlider';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { import {
addEraseRect, addEraseRect,
addFillRect, addFillRect,
@ -7,9 +16,11 @@ import {
setBrushSize, setBrushSize,
setTool, setTool,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { systemSelector } from 'features/system/store/systemSelectors';
import _ from 'lodash'; import { clamp, isEqual } from 'lodash';
import IAIIconButton from 'common/components/IAIIconButton';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import { import {
FaEraser, FaEraser,
FaEyeDropper, FaEyeDropper,
@ -18,16 +29,6 @@ import {
FaPlus, FaPlus,
FaSlidersH, FaSlidersH,
} from 'react-icons/fa'; } from 'react-icons/fa';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { systemSelector } from 'features/system/store/systemSelectors';
import { useHotkeys } from 'react-hotkeys-hook';
import IAIPopover from 'common/components/IAIPopover';
import IAISlider from 'common/components/IAISlider';
import IAIColorPicker from 'common/components/IAIColorPicker';
import { useTranslation } from 'react-i18next';
export const selector = createSelector( export const selector = createSelector(
[canvasSelector, isStagingSelector, systemSelector], [canvasSelector, isStagingSelector, systemSelector],
@ -45,7 +46,7 @@ export const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );
@ -143,7 +144,7 @@ const IAICanvasToolChooserOptions = () => {
dispatch( dispatch(
setBrushColor({ setBrushColor({
...brushColor, ...brushColor,
a: _.clamp(brushColor.a - 0.05, 0.05, 1), a: clamp(brushColor.a - 0.05, 0.05, 1),
}) })
); );
}, },
@ -160,7 +161,7 @@ const IAICanvasToolChooserOptions = () => {
dispatch( dispatch(
setBrushColor({ setBrushColor({
...brushColor, ...brushColor,
a: _.clamp(brushColor.a + 0.05, 0.05, 1), a: clamp(brushColor.a + 0.05, 0.05, 1),
}) })
); );
}, },

View File

@ -1,5 +1,14 @@
import { ButtonGroup } from '@chakra-ui/react'; import { ButtonGroup } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton';
import IAISelect from 'common/components/IAISelect';
import useImageUploader from 'common/hooks/useImageUploader';
import { useSingleAndDoubleClick } from 'common/hooks/useSingleAndDoubleClick';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { import {
resetCanvas, resetCanvas,
resetCanvasView, resetCanvasView,
@ -8,9 +17,18 @@ import {
setLayer, setLayer,
setTool, setTool,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import {
import _ from 'lodash'; CanvasLayer,
import IAIIconButton from 'common/components/IAIIconButton'; LAYER_NAMES_DICT,
} from 'features/canvas/store/canvasTypes';
import { mergeAndUploadCanvas } from 'features/canvas/store/thunks/mergeAndUploadCanvas';
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash';
import { ChangeEvent } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import { import {
FaArrowsAlt, FaArrowsAlt,
FaCopy, FaCopy,
@ -21,28 +39,11 @@ import {
FaTrash, FaTrash,
FaUpload, FaUpload,
} from 'react-icons/fa'; } from 'react-icons/fa';
import IAICanvasUndoButton from './IAICanvasUndoButton'; import IAICanvasMaskOptions from './IAICanvasMaskOptions';
import IAICanvasRedoButton from './IAICanvasRedoButton'; import IAICanvasRedoButton from './IAICanvasRedoButton';
import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover'; import IAICanvasSettingsButtonPopover from './IAICanvasSettingsButtonPopover';
import IAICanvasMaskOptions from './IAICanvasMaskOptions';
import { mergeAndUploadCanvas } from 'features/canvas/store/thunks/mergeAndUploadCanvas';
import { useHotkeys } from 'react-hotkeys-hook';
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
import { systemSelector } from 'features/system/store/systemSelectors';
import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions'; import IAICanvasToolChooserOptions from './IAICanvasToolChooserOptions';
import useImageUploader from 'common/hooks/useImageUploader'; import IAICanvasUndoButton from './IAICanvasUndoButton';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import IAISelect from 'common/components/IAISelect';
import {
CanvasLayer,
LAYER_NAMES_DICT,
} from 'features/canvas/store/canvasTypes';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { useSingleAndDoubleClick } from 'common/hooks/useSingleAndDoubleClick';
export const selector = createSelector( export const selector = createSelector(
[systemSelector, canvasSelector, isStagingSelector], [systemSelector, canvasSelector, isStagingSelector],
@ -62,7 +63,7 @@ export const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,14 +1,15 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useHotkeys } from 'react-hotkeys-hook';
import { FaUndo } from 'react-icons/fa';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { useHotkeys } from 'react-hotkeys-hook';
import { FaUndo } from 'react-icons/fa';
import _ from 'lodash';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
import { undo } from 'features/canvas/store/canvasSlice'; import { undo } from 'features/canvas/store/canvasSlice';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { isEqual } from 'lodash';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const canvasUndoSelector = createSelector( const canvasUndoSelector = createSelector(
@ -23,7 +24,7 @@ const canvasUndoSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,8 +1,5 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { KonvaEventObject } from 'konva/lib/Node';
import _ from 'lodash';
import { useCallback } from 'react';
import { import {
canvasSelector, canvasSelector,
isStagingSelector, isStagingSelector,
@ -11,6 +8,10 @@ import {
setIsMovingStage, setIsMovingStage,
setStageCoordinates, setStageCoordinates,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { KonvaEventObject } from 'konva/lib/Node';
import { isEqual } from 'lodash';
import { useCallback } from 'react';
const selector = createSelector( const selector = createSelector(
[canvasSelector, isStagingSelector], [canvasSelector, isStagingSelector],
@ -22,7 +23,7 @@ const selector = createSelector(
isMovingBoundingBox, isMovingBoundingBox,
}; };
}, },
{ memoizeOptions: { resultEqualityCheck: _.isEqual } } { memoizeOptions: { resultEqualityCheck: isEqual } }
); );
const useCanvasDrag = () => { const useCanvasDrag = () => {

View File

@ -1,7 +1,9 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { useHotkeys } from 'react-hotkeys-hook'; import {
import { activeTabNameSelector } from 'features/options/store/optionsSelectors'; canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { import {
clearMask, clearMask,
resetCanvasInteractionState, resetCanvasInteractionState,
@ -10,12 +12,11 @@ import {
setShouldSnapToGrid, setShouldSnapToGrid,
setTool, setTool,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { isEqual } from 'lodash';
import { useRef } from 'react'; import { useRef } from 'react';
import { import { useHotkeys } from 'react-hotkeys-hook';
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { CanvasTool } from '../store/canvasTypes'; import { CanvasTool } from '../store/canvasTypes';
import { getCanvasStage } from '../util/konvaInstanceProvider'; import { getCanvasStage } from '../util/konvaInstanceProvider';
@ -44,7 +45,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,10 +1,5 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node';
import _ from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import { import {
canvasSelector, canvasSelector,
isStagingSelector, isStagingSelector,
@ -14,6 +9,12 @@ import {
setIsDrawing, setIsDrawing,
setIsMovingStage, setIsMovingStage,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node';
import { isEqual } from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import getScaledCursorPosition from '../util/getScaledCursorPosition'; import getScaledCursorPosition from '../util/getScaledCursorPosition';
import useColorPicker from './useColorUnderCursor'; import useColorPicker from './useColorUnderCursor';
@ -27,7 +28,7 @@ const selector = createSelector(
isStaging, isStaging,
}; };
}, },
{ memoizeOptions: { resultEqualityCheck: _.isEqual } } { memoizeOptions: { resultEqualityCheck: isEqual } }
); );
const useCanvasMouseDown = (stageRef: MutableRefObject<Konva.Stage | null>) => { const useCanvasMouseDown = (stageRef: MutableRefObject<Konva.Stage | null>) => {

View File

@ -1,10 +1,5 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
import Konva from 'konva';
import { Vector2d } from 'konva/lib/types';
import _ from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import { import {
canvasSelector, canvasSelector,
isStagingSelector, isStagingSelector,
@ -13,6 +8,12 @@ import {
addPointToCurrentLine, addPointToCurrentLine,
setCursorPosition, setCursorPosition,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import Konva from 'konva';
import { Vector2d } from 'konva/lib/types';
import { isEqual } from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import getScaledCursorPosition from '../util/getScaledCursorPosition'; import getScaledCursorPosition from '../util/getScaledCursorPosition';
import useColorPicker from './useColorUnderCursor'; import useColorPicker from './useColorUnderCursor';
@ -27,7 +28,7 @@ const selector = createSelector(
isStaging, isStaging,
}; };
}, },
{ memoizeOptions: { resultEqualityCheck: _.isEqual } } { memoizeOptions: { resultEqualityCheck: isEqual } }
); );
const useCanvasMouseMove = ( const useCanvasMouseMove = (

View File

@ -1,6 +1,6 @@
import { useAppDispatch } from 'app/storeHooks'; import { useAppDispatch } from 'app/storeHooks';
import { useCallback } from 'react';
import { mouseLeftCanvas } from 'features/canvas/store/canvasSlice'; import { mouseLeftCanvas } from 'features/canvas/store/canvasSlice';
import { useCallback } from 'react';
const useCanvasMouseOut = () => { const useCanvasMouseOut = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();

Some files were not shown because too many files have changed in this diff Show More