Updates code quality tooling and formats codebase

- `eslint` and `prettier` configs
- `husky` to format and lint via pre-commit hook
- `babel-plugin-transform-imports` to treeshake `lodash` and other packages if needed

Lints and formats codebase.
This commit is contained in:
psychedelicious 2023-02-04 11:36:31 +11:00 committed by mauwii
parent f80a64a0f4
commit 45a5ccba84
No known key found for this signature in database
GPG Key ID: D923DB04ADB3F5AB
185 changed files with 1933 additions and 868 deletions

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

@ -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/ && yarn 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

@ -48,7 +48,6 @@
"sendTo": "Send to", "sendTo": "Send to",
"sendToImg2Img": "Send to Image to Image", "sendToImg2Img": "Send to Image to Image",
"sendToUnifiedCanvas": "Send To Unified Canvas", "sendToUnifiedCanvas": "Send To Unified Canvas",
"copyImage": "Copy Image",
"copyImageToLink": "Copy Image To Link", "copyImageToLink": "Copy Image To Link",
"downloadImage": "Download Image", "downloadImage": "Download Image",
"openInViewer": "Open In Viewer", "openInViewer": "Open In Viewer",

View File

@ -2,15 +2,16 @@
"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", "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"
}, },
@ -64,13 +65,20 @@
"@typescript-eslint/parser": "^5.36.2", "@typescript-eslint/parser": "^5.36.2",
"@vitejs/plugin-legacy": "^3.0.1", "@vitejs/plugin-legacy": "^3.0.1",
"@vitejs/plugin-react": "^2.0.1", "@vitejs/plugin-react": "^2.0.1",
"babel-plugin-transform-imports": "^2.0.0",
"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",
"prettier-plugin-organize-imports": "^3.2.2",
"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",
@ -88,5 +96,11 @@
"skipTypeImports": true "skipTypeImports": true
} }
} }
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx,cjs}": [
"npx prettier --write",
"npx eslint --fix"
]
} }
} }

View File

@ -49,7 +49,6 @@
"sendToImg2Img": "Send to Image to Image", "sendToImg2Img": "Send to Image to Image",
"sendToUnifiedCanvas": "Send To Unified Canvas", "sendToUnifiedCanvas": "Send To Unified Canvas",
"copyImageToLink": "Copy Image To Link", "copyImageToLink": "Copy Image To Link",
"copyImage": "Copy Image",
"downloadImage": "Download Image", "downloadImage": "Download Image",
"openInViewer": "Open In Viewer", "openInViewer": "Open In Viewer",
"closeViewer": "Close Viewer", "closeViewer": "Close Viewer",

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 { keepGUIAlive } from './utils';
import InvokeTabs from 'features/ui/components/InvokeTabs'; import InvokeTabs from 'features/ui/components/InvokeTabs';
import ImageUploader from 'common/components/ImageUploader'; import { keepGUIAlive } from './utils';
import useToastWatcher from 'features/system/hooks/useToastWatcher'; import useToastWatcher from 'features/system/hooks/useToastWatcher';
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton'; import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
keepGUIAlive(); keepGUIAlive();

View File

@ -1,10 +1,10 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { systemSelector } from 'features/system/store/systemSelectors';
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 { 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(
[ [
@ -65,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 * as InvokeAI from 'app/invokeai';
import { GalleryCategory } from 'features/gallery/store/gallerySlice'; import { GalleryCategory } from 'features/gallery/store/gallerySlice';
import { InvokeTabName } from 'features/ui/store/tabMap'; import { InvokeTabName } from 'features/ui/store/tabMap';
import * as InvokeAI from 'app/invokeai';
/** /**
* 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,10 +1,11 @@
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,
@ -17,8 +18,7 @@ import {
setIsProcessing, setIsProcessing,
} from 'features/system/store/systemSlice'; } from 'features/system/store/systemSlice';
import { InvokeTabName } from 'features/ui/store/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()`.

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/parameters/store/generationSlice'; } 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/ui/store/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.

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,13 +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 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 generationReducer from 'features/parameters/store/generationSlice';
import postprocessingReducer from 'features/parameters/store/postprocessingSlice'; import postprocessingReducer from 'features/parameters/store/postprocessingSlice';
import galleryReducer from 'features/gallery/store/gallerySlice';
import systemReducer from 'features/system/store/systemSlice'; import systemReducer from 'features/system/store/systemSlice';
import canvasReducer from 'features/canvas/store/canvasSlice';
import uiReducer from 'features/ui/store/uiSlice'; import uiReducer from 'features/ui/store/uiSlice';
import lightboxReducer from 'features/lightbox/store/lightboxSlice';
import { socketioMiddleware } from './socketio/middleware'; import { socketioMiddleware } from './socketio/middleware';

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,16 +1,16 @@
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 { 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 { 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;

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/ui/store/uiSelectors'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { tabDict } from 'features/ui/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,24 +1,24 @@
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants'; import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
import { Dimensions } from 'features/canvas/store/canvasTypes';
import { GenerationState } from 'features/parameters/store/generationSlice'; 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/ui/store/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,
UpscalingLevel,
} from 'features/parameters/store/postprocessingSlice'; } from 'features/parameters/store/postprocessingSlice';
import { PostprocessingState } 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;

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/ui/store/uiSelectors'; 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/ui/store/uiSelectors';
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/ui/store/uiSelectors';
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/ui/store/uiSelectors'; 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/ui/store/uiSelectors';
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/ui/store/uiSelectors';
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();

View File

@ -1,9 +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/ui/store/uiSelectors';
import Konva from 'konva';
import _ from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import { import {
canvasSelector, canvasSelector,
isStagingSelector, isStagingSelector,
@ -14,6 +10,11 @@ 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 { isEqual } from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import getScaledCursorPosition from '../util/getScaledCursorPosition'; import getScaledCursorPosition from '../util/getScaledCursorPosition';
const selector = createSelector( const selector = createSelector(
@ -27,7 +28,7 @@ const selector = createSelector(
isStaging, isStaging,
}; };
}, },
{ memoizeOptions: { resultEqualityCheck: _.isEqual } } { memoizeOptions: { resultEqualityCheck: isEqual } }
); );
const useCanvasMouseUp = ( const useCanvasMouseUp = (

View File

@ -1,14 +1,15 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node';
import _ from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { import {
setStageCoordinates, setStageCoordinates,
setStageScale, setStageScale,
} from 'features/canvas/store/canvasSlice'; } from 'features/canvas/store/canvasSlice';
import Konva from 'konva';
import { KonvaEventObject } from 'konva/lib/Node';
import { clamp, isEqual } from 'lodash';
import { MutableRefObject, useCallback } from 'react';
import { import {
CANVAS_SCALE_BY, CANVAS_SCALE_BY,
MAX_CANVAS_SCALE, MAX_CANVAS_SCALE,
@ -24,7 +25,7 @@ const selector = createSelector(
stageScale, stageScale,
}; };
}, },
{ memoizeOptions: { resultEqualityCheck: _.isEqual } } { memoizeOptions: { resultEqualityCheck: isEqual } }
); );
const useCanvasWheel = (stageRef: MutableRefObject<Konva.Stage | null>) => { const useCanvasWheel = (stageRef: MutableRefObject<Konva.Stage | null>) => {
@ -55,7 +56,7 @@ const useCanvasWheel = (stageRef: MutableRefObject<Konva.Stage | null>) => {
delta = -delta; delta = -delta;
} }
const newScale = _.clamp( const newScale = clamp(
stageScale * CANVAS_SCALE_BY ** delta, stageScale * CANVAS_SCALE_BY ** delta,
MIN_CANVAS_SCALE, MIN_CANVAS_SCALE,
MAX_CANVAS_SCALE MAX_CANVAS_SCALE

View File

@ -1,6 +1,5 @@
import { useAppDispatch } from 'app/storeHooks'; import { useAppDispatch } from 'app/storeHooks';
import Konva from 'konva'; import Konva from 'konva';
import _ from 'lodash';
import { import {
commitColorPickerColor, commitColorPickerColor,
setColorPickerColor, setColorPickerColor,

View File

@ -1,7 +1,7 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { CanvasImage, CanvasState, isCanvasBaseImage } from './canvasTypes'; import { CanvasImage, CanvasState, isCanvasBaseImage } from './canvasTypes';
export const canvasSelector = (state: RootState): CanvasState => state.canvas; export const canvasSelector = (state: RootState): CanvasState => state.canvas;

View File

@ -6,7 +6,8 @@ import {
roundToMultiple, roundToMultiple,
} from 'common/util/roundDownToMultiple'; } from 'common/util/roundDownToMultiple';
import { IRect, Vector2d } from 'konva/lib/types'; import { IRect, Vector2d } from 'konva/lib/types';
import _ from 'lodash'; import { clamp, cloneDeep } from 'lodash';
//
import { RgbaColor } from 'react-colorful'; import { RgbaColor } from 'react-colorful';
import calculateCoordinates from '../util/calculateCoordinates'; import calculateCoordinates from '../util/calculateCoordinates';
import calculateScale from '../util/calculateScale'; import calculateScale from '../util/calculateScale';
@ -16,10 +17,10 @@ import getScaledBoundingBoxDimensions from '../util/getScaledBoundingBoxDimensio
import roundDimensionsTo64 from '../util/roundDimensionsTo64'; import roundDimensionsTo64 from '../util/roundDimensionsTo64';
import { import {
BoundingBoxScale, BoundingBoxScale,
CanvasBaseLine,
CanvasImage, CanvasImage,
CanvasLayer, CanvasLayer,
CanvasLayerState, CanvasLayerState,
CanvasBaseLine,
CanvasMaskLine, CanvasMaskLine,
CanvasState, CanvasState,
CanvasTool, CanvasTool,
@ -120,7 +121,7 @@ export const canvasSlice = createSlice({
state.brushSize = action.payload; state.brushSize = action.payload;
}, },
clearMask: (state) => { clearMask: (state) => {
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
state.layerState.objects = state.layerState.objects.filter( state.layerState.objects = state.layerState.objects.filter(
(obj) => !isCanvasMaskLine(obj) (obj) => !isCanvasMaskLine(obj)
); );
@ -160,8 +161,8 @@ export const canvasSlice = createSlice({
const { stageDimensions } = state; const { stageDimensions } = state;
const newBoundingBoxDimensions = { const newBoundingBoxDimensions = {
width: roundDownToMultiple(_.clamp(image.width, 64, 512), 64), width: roundDownToMultiple(clamp(image.width, 64, 512), 64),
height: roundDownToMultiple(_.clamp(image.height, 64, 512), 64), height: roundDownToMultiple(clamp(image.height, 64, 512), 64),
}; };
const newBoundingBoxCoordinates = { const newBoundingBoxCoordinates = {
@ -185,7 +186,7 @@ export const canvasSlice = createSlice({
state.boundingBoxDimensions = newBoundingBoxDimensions; state.boundingBoxDimensions = newBoundingBoxDimensions;
state.boundingBoxCoordinates = newBoundingBoxCoordinates; state.boundingBoxCoordinates = newBoundingBoxCoordinates;
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
state.layerState = { state.layerState = {
...initialLayerState, ...initialLayerState,
@ -297,7 +298,7 @@ export const canvasSlice = createSlice({
if (!boundingBox || !image) return; if (!boundingBox || !image) return;
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -316,7 +317,7 @@ export const canvasSlice = createSlice({
state.futureLayerStates = []; state.futureLayerStates = [];
}, },
discardStagedImages: (state) => { discardStagedImages: (state) => {
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -334,7 +335,7 @@ export const canvasSlice = createSlice({
const { boundingBoxCoordinates, boundingBoxDimensions, brushColor } = const { boundingBoxCoordinates, boundingBoxDimensions, brushColor } =
state; state;
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -353,7 +354,7 @@ export const canvasSlice = createSlice({
addEraseRect: (state) => { addEraseRect: (state) => {
const { boundingBoxCoordinates, boundingBoxDimensions } = state; const { boundingBoxCoordinates, boundingBoxDimensions } = state;
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -380,7 +381,7 @@ export const canvasSlice = createSlice({
const newColor = const newColor =
layer === 'base' && tool === 'brush' ? { color: brushColor } : {}; layer === 'base' && tool === 'brush' ? { color: brushColor } : {};
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -418,7 +419,7 @@ export const canvasSlice = createSlice({
if (!targetState) return; if (!targetState) return;
state.futureLayerStates.unshift(_.cloneDeep(state.layerState)); state.futureLayerStates.unshift(cloneDeep(state.layerState));
if (state.futureLayerStates.length > state.maxHistory) { if (state.futureLayerStates.length > state.maxHistory) {
state.futureLayerStates.pop(); state.futureLayerStates.pop();
@ -431,7 +432,7 @@ export const canvasSlice = createSlice({
if (!targetState) return; if (!targetState) return;
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -455,7 +456,7 @@ export const canvasSlice = createSlice({
state.shouldShowIntermediates = action.payload; state.shouldShowIntermediates = action.payload;
}, },
resetCanvas: (state) => { resetCanvas: (state) => {
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
state.layerState = initialLayerState; state.layerState = initialLayerState;
state.futureLayerStates = []; state.futureLayerStates = [];
@ -681,7 +682,7 @@ export const canvasSlice = createSlice({
commitStagingAreaImage: (state) => { commitStagingAreaImage: (state) => {
const { images, selectedImageIndex } = state.layerState.stagingArea; const { images, selectedImageIndex } = state.layerState.stagingArea;
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
if (state.pastLayerStates.length > state.maxHistory) { if (state.pastLayerStates.length > state.maxHistory) {
state.pastLayerStates.shift(); state.pastLayerStates.shift();
@ -718,8 +719,8 @@ export const canvasSlice = createSlice({
scaledStageHeight scaledStageHeight
) { ) {
const newBoundingBoxDimensions = { const newBoundingBoxDimensions = {
width: roundDownToMultiple(_.clamp(scaledStageWidth, 64, 512), 64), width: roundDownToMultiple(clamp(scaledStageWidth, 64, 512), 64),
height: roundDownToMultiple(_.clamp(scaledStageHeight, 64, 512), 64), height: roundDownToMultiple(clamp(scaledStageHeight, 64, 512), 64),
}; };
const newBoundingBoxCoordinates = { const newBoundingBoxCoordinates = {
@ -792,7 +793,7 @@ export const canvasSlice = createSlice({
state.tool = 'brush'; state.tool = 'brush';
}, },
setMergedCanvas: (state, action: PayloadAction<CanvasImage>) => { setMergedCanvas: (state, action: PayloadAction<CanvasImage>) => {
state.pastLayerStates.push(_.cloneDeep(state.layerState)); state.pastLayerStates.push(cloneDeep(state.layerState));
state.futureLayerStates = []; state.futureLayerStates = [];

View File

@ -9,7 +9,7 @@ export const LAYER_NAMES_DICT = [
export const LAYER_NAMES = ['base', 'mask'] as const; export const LAYER_NAMES = ['base', 'mask'] as const;
export type CanvasLayer = typeof LAYER_NAMES[number]; export type CanvasLayer = (typeof LAYER_NAMES)[number];
export const BOUNDING_BOX_SCALES_DICT = [ export const BOUNDING_BOX_SCALES_DICT = [
{ key: 'Auto', value: 'auto' }, { key: 'Auto', value: 'auto' },
@ -19,7 +19,7 @@ export const BOUNDING_BOX_SCALES_DICT = [
export const BOUNDING_BOX_SCALES = ['none', 'auto', 'manual'] as const; export const BOUNDING_BOX_SCALES = ['none', 'auto', 'manual'] as const;
export type BoundingBoxScale = typeof BOUNDING_BOX_SCALES[number]; export type BoundingBoxScale = (typeof BOUNDING_BOX_SCALES)[number];
export type CanvasDrawingTool = 'brush' | 'eraser'; export type CanvasDrawingTool = 'brush' | 'eraser';

View File

@ -1,11 +1,7 @@
import { AnyAction, ThunkAction } from '@reduxjs/toolkit'; import { AnyAction, ThunkAction } from '@reduxjs/toolkit';
import { RootState } from 'app/store';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { v4 as uuidv4 } from 'uuid'; import { RootState } from 'app/store';
import layerToDataURL from '../../util/layerToDataURL'; import { addImage } from 'features/gallery/store/gallerySlice';
import downloadFile from '../../util/downloadFile';
import copyImage from '../../util/copyImage';
import { getCanvasBaseLayer } from '../../util/konvaInstanceProvider';
import { import {
addToast, addToast,
setCurrentStatus, setCurrentStatus,
@ -13,10 +9,14 @@ import {
setIsProcessing, setIsProcessing,
setProcessingIndeterminateTask, setProcessingIndeterminateTask,
} from 'features/system/store/systemSlice'; } from 'features/system/store/systemSlice';
import { addImage } from 'features/gallery/store/gallerySlice'; import i18n from 'i18n';
import { v4 as uuidv4 } from 'uuid';
import copyImage from '../../util/copyImage';
import downloadFile from '../../util/downloadFile';
import { getCanvasBaseLayer } from '../../util/konvaInstanceProvider';
import layerToDataURL from '../../util/layerToDataURL';
import { setMergedCanvas } from '../canvasSlice'; import { setMergedCanvas } from '../canvasSlice';
import { CanvasState } from '../canvasTypes'; import { CanvasState } from '../canvasTypes';
import i18n from 'i18n';
type MergeAndUploadCanvasConfig = { type MergeAndUploadCanvasConfig = {
cropVisible?: boolean; cropVisible?: boolean;
@ -96,7 +96,7 @@ export const mergeAndUploadCanvas =
}) })
); );
const response = await fetch(window.location.origin + '/upload', { const response = await fetch(`${window.location.origin}/upload`, {
method: 'POST', method: 'POST',
body: formData, body: formData,
}); });

View File

@ -1,6 +1,6 @@
import { CanvasMaskLine } from 'features/canvas/store/canvasTypes';
import Konva from 'konva'; import Konva from 'konva';
import { IRect } from 'konva/lib/types'; import { IRect } from 'konva/lib/types';
import { CanvasMaskLine } from 'features/canvas/store/canvasTypes';
/** /**
* Generating a mask image from InpaintingCanvas.tsx is not as simple * Generating a mask image from InpaintingCanvas.tsx is not as simple

View File

@ -1,15 +1,16 @@
import { useAppSelector } from 'app/storeHooks';
import CurrentImageButtons from './CurrentImageButtons';
import { MdPhoto } from 'react-icons/md';
import CurrentImagePreview from './CurrentImagePreview';
import { GalleryState } from 'features/gallery/store/gallerySlice';
import _ from 'lodash';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/storeHooks';
import { GalleryState } from 'features/gallery/store/gallerySlice';
import { import {
activeTabNameSelector, activeTabNameSelector,
uiSelector, uiSelector,
} from 'features/ui/store/uiSelectors'; } from 'features/ui/store/uiSelectors';
import { isEqual } from 'lodash';
import { MdPhoto } from 'react-icons/md';
import { gallerySelector } from '../store/gallerySelectors'; import { gallerySelector } from '../store/gallerySelectors';
import CurrentImageButtons from './CurrentImageButtons';
import CurrentImagePreview from './CurrentImagePreview';
export const currentImageDisplaySelector = createSelector( export const currentImageDisplaySelector = createSelector(
[gallerySelector, uiSelector, activeTabNameSelector], [gallerySelector, uiSelector, activeTabNameSelector],
@ -25,7 +26,7 @@ export const currentImageDisplaySelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,6 +1,5 @@
import { IconButton, Image } from '@chakra-ui/react'; import { IconButton, Image } from '@chakra-ui/react';
import { useState } from 'react'; import { createSelector } from '@reduxjs/toolkit';
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { import {
GalleryCategory, GalleryCategory,
@ -8,11 +7,13 @@ import {
selectNextImage, selectNextImage,
selectPrevImage, selectPrevImage,
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import { createSelector } from '@reduxjs/toolkit';
import _ from 'lodash';
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
import { uiSelector } from 'features/ui/store/uiSelectors'; import { uiSelector } from 'features/ui/store/uiSelectors';
import { isEqual } from 'lodash';
import { useState } from 'react';
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';
import { gallerySelector } from '../store/gallerySelectors'; import { gallerySelector } from '../store/gallerySelectors';
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
export const imagesSelector = createSelector( export const imagesSelector = createSelector(
[gallerySelector, uiSelector], [gallerySelector, uiSelector],
@ -45,7 +46,7 @@ export const imagesSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,31 +1,38 @@
import { import {
Text,
AlertDialog, AlertDialog,
AlertDialogBody, AlertDialogBody,
AlertDialogContent,
AlertDialogFooter, AlertDialogFooter,
AlertDialogHeader, AlertDialogHeader,
AlertDialogContent,
AlertDialogOverlay, AlertDialogOverlay,
useDisclosure,
Button, Button,
Switch, Flex,
FormControl, FormControl,
FormLabel, FormLabel,
Flex, Switch,
Text,
useDisclosure,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { ChangeEvent, ReactElement, SyntheticEvent } from 'react'; import * as InvokeAI from 'app/invokeai';
import { cloneElement, forwardRef, useRef } from 'react';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { deleteImage } from 'app/socketio/actions'; import { deleteImage } from 'app/socketio/actions';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { import {
setShouldConfirmOnDelete, setShouldConfirmOnDelete,
SystemState, SystemState,
} from 'features/system/store/systemSlice'; } from 'features/system/store/systemSlice';
import * as InvokeAI from 'app/invokeai'; import { isEqual } from 'lodash';
import {
ChangeEvent,
cloneElement,
forwardRef,
ReactElement,
SyntheticEvent,
useRef,
} from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import _ from 'lodash';
import { systemSelector } from 'features/system/store/systemSelectors';
const deleteImageModalSelector = createSelector( const deleteImageModalSelector = createSelector(
systemSelector, systemSelector,
@ -35,7 +42,7 @@ const deleteImageModalSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );
@ -116,7 +123,7 @@ const DeleteImageModal = forwardRef(
</Text> </Text>
<FormControl> <FormControl>
<Flex alignItems={'center'}> <Flex alignItems={'center'}>
<FormLabel mb={0}>Don't ask me again</FormLabel> <FormLabel mb={0}>Don&apos;t ask me again</FormLabel>
<Switch <Switch
checked={!shouldConfirmOnDelete} checked={!shouldConfirmOnDelete}
onChange={handleChangeShouldConfirmOnDelete} onChange={handleChangeShouldConfirmOnDelete}
@ -145,4 +152,6 @@ const DeleteImageModal = forwardRef(
} }
); );
DeleteImageModal.displayName = 'DeleteImageModal';
export default DeleteImageModal; export default DeleteImageModal;

View File

@ -272,4 +272,6 @@ const HoverableImage = memo((props: HoverableImageProps) => {
); );
}, memoEqualityCheck); }, memoEqualityCheck);
HoverableImage.displayName = 'HoverableImage';
export default HoverableImage; export default HoverableImage;

View File

@ -1,19 +1,16 @@
import { Button } from '@chakra-ui/button'; import { Button } from '@chakra-ui/button';
import { NumberSize, Resizable } from 're-resizable'; import { NumberSize, Resizable } from 're-resizable';
import React, { import { ButtonGroup } from '@chakra-ui/react';
ChangeEvent,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { MdPhotoLibrary } from 'react-icons/md';
import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
import { requestImages } from 'app/socketio/actions'; import { requestImages } from 'app/socketio/actions';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIButton from 'common/components/IAIButton';
import IAICheckbox from 'common/components/IAICheckbox';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import IAIPopover from 'common/components/IAIPopover';
import IAISlider from 'common/components/IAISlider';
import { setDoesCanvasNeedScaling } from 'features/canvas/store/canvasSlice';
import { imageGallerySelector } from 'features/gallery/store/gallerySelectors';
import { import {
selectNextImage, selectNextImage,
selectPrevImage, selectPrevImage,
@ -25,24 +22,28 @@ import {
setShouldAutoSwitchToNewImages, setShouldAutoSwitchToNewImages,
setShouldHoldGalleryOpen, setShouldHoldGalleryOpen,
setShouldPinGallery, setShouldPinGallery,
setShouldShowGallery,
setShouldUseSingleGalleryColumn, setShouldUseSingleGalleryColumn,
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import HoverableImage from './HoverableImage';
import { setShouldShowGallery } from 'features/gallery/store/gallerySlice';
import { ButtonGroup } from '@chakra-ui/react';
import { CSSTransition } from 'react-transition-group';
import { Direction } from 're-resizable/lib/resizer';
import { imageGallerySelector } from 'features/gallery/store/gallerySelectors';
import { FaImage, FaUser, FaWrench } from 'react-icons/fa';
import IAIPopover from 'common/components/IAIPopover';
import IAISlider from 'common/components/IAISlider';
import { BiReset } from 'react-icons/bi';
import IAICheckbox from 'common/components/IAICheckbox';
import { setDoesCanvasNeedScaling } from 'features/canvas/store/canvasSlice';
import _ from 'lodash';
import IAIButton from 'common/components/IAIButton';
import { InvokeTabName } from 'features/ui/store/tabMap'; import { InvokeTabName } from 'features/ui/store/tabMap';
import { clamp } from 'lodash';
import { Direction } from 're-resizable/lib/resizer';
import React, {
ChangeEvent,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { BiReset } from 'react-icons/bi';
import { BsPinAngle, BsPinAngleFill } from 'react-icons/bs';
import { FaImage, FaUser, FaWrench } from 'react-icons/fa';
import { MdPhotoLibrary } from 'react-icons/md';
import { CSSTransition } from 'react-transition-group';
import HoverableImage from './HoverableImage';
const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 320; const GALLERY_SHOW_BUTTONS_MIN_WIDTH = 320;
const GALLERY_IMAGE_WIDTH_OFFSET = 40; const GALLERY_IMAGE_WIDTH_OFFSET = 40;
@ -212,7 +213,7 @@ export default function ImageGallery() {
'shift+up', 'shift+up',
() => { () => {
if (galleryImageMinimumWidth < 256) { if (galleryImageMinimumWidth < 256) {
const newMinWidth = _.clamp( const newMinWidth = clamp(
galleryImageMinimumWidth + IMAGE_SIZE_STEP, galleryImageMinimumWidth + IMAGE_SIZE_STEP,
32, 32,
256 256
@ -227,7 +228,7 @@ export default function ImageGallery() {
'shift+down', 'shift+down',
() => { () => {
if (galleryImageMinimumWidth > 32) { if (galleryImageMinimumWidth > 32) {
const newMinWidth = _.clamp( const newMinWidth = clamp(
galleryImageMinimumWidth - IMAGE_SIZE_STEP, galleryImageMinimumWidth - IMAGE_SIZE_STEP,
32, 32,
256 256
@ -315,7 +316,7 @@ export default function ImageGallery() {
delta: NumberSize delta: NumberSize
) => { ) => {
const newWidth = shouldPinGallery const newWidth = shouldPinGallery
? _.clamp( ? clamp(
Number(galleryWidth) + delta.width, Number(galleryWidth) + delta.width,
galleryMinWidth, galleryMinWidth,
Number(galleryMaxWidth) Number(galleryMaxWidth)
@ -342,7 +343,7 @@ export default function ImageGallery() {
elementRef: HTMLElement, elementRef: HTMLElement,
delta: NumberSize delta: NumberSize
) => { ) => {
const newWidth = _.clamp( const newWidth = clamp(
Number(galleryWidth) + delta.width, Number(galleryWidth) + delta.width,
galleryMinWidth, galleryMinWidth,
Number( Number(
@ -553,7 +554,7 @@ export default function ImageGallery() {
{isResizing && ( {isResizing && (
<div <div
style={{ style={{
width: galleryWidth + 'px', width: `${galleryWidth}px`,
height: '100%', height: '100%',
}} }}
/> />

View File

@ -1,3 +1,4 @@
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { import {
Center, Center,
Flex, Flex,
@ -7,16 +8,17 @@ import {
Text, Text,
Tooltip, Tooltip,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { memo } from 'react';
import { IoArrowUndoCircleOutline } from 'react-icons/io5';
import { useAppDispatch } from 'app/storeHooks';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { useAppDispatch } from 'app/storeHooks';
import promptToString from 'common/util/promptToString';
import { seedWeightsToString } from 'common/util/seedWeightPairs';
import { import {
setCfgScale, setCfgScale,
setHeight, setHeight,
setImg2imgStrength, setImg2imgStrength,
setInitialImage,
setMaskPath, setMaskPath,
setPerlin,
setPrompt, setPrompt,
setSampler, setSampler,
setSeamless, setSeamless,
@ -24,24 +26,22 @@ import {
setSeedWeights, setSeedWeights,
setShouldFitToWidthHeight, setShouldFitToWidthHeight,
setSteps, setSteps,
setWidth,
setInitialImage,
setThreshold, setThreshold,
setPerlin, setWidth,
} from 'features/parameters/store/generationSlice'; } from 'features/parameters/store/generationSlice';
import { import {
setFacetoolStrength,
setCodeformerFidelity, setCodeformerFidelity,
setFacetoolStrength,
setFacetoolType, setFacetoolType,
setHiresFix, setHiresFix,
setUpscalingLevel, setUpscalingLevel,
setUpscalingStrength, setUpscalingStrength,
} from 'features/parameters/store/postprocessingSlice'; } from 'features/parameters/store/postprocessingSlice';
import { setShouldShowImageDetails } from 'features/ui/store/uiSlice'; import { setShouldShowImageDetails } from 'features/ui/store/uiSlice';
import promptToString from 'common/util/promptToString'; import { memo } from 'react';
import { seedWeightsToString } from 'common/util/seedWeightPairs';
import { FaCopy } from 'react-icons/fa';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { FaCopy } from 'react-icons/fa';
import { IoArrowUndoCircleOutline } from 'react-icons/io5';
type MetadataItemProps = { type MetadataItemProps = {
isLink?: boolean; isLink?: boolean;
@ -459,4 +459,6 @@ const ImageMetadataViewer = memo(
memoEqualityCheck memoEqualityCheck
); );
ImageMetadataViewer.displayName = 'ImageMetadataViewer';
export default ImageMetadataViewer; export default ImageMetadataViewer;

View File

@ -1,11 +1,12 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { GalleryState } from './gallerySlice';
import _ from 'lodash';
import { isStagingSelector } from 'features/canvas/store/canvasSelectors'; import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors'; import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
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 { GalleryState } from './gallerySlice';
export const gallerySelector = (state: RootState) => state.gallery; export const gallerySelector = (state: RootState) => state.gallery;
@ -59,7 +60,7 @@ export const imageGallerySelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );
@ -78,7 +79,7 @@ export const hoverableImageSelector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -1,9 +1,9 @@
import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit'; import type { PayloadAction } from '@reduxjs/toolkit';
import _, { clamp } from 'lodash'; import { createSlice } from '@reduxjs/toolkit';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { IRect } from 'konva/lib/types';
import { InvokeTabName } from 'features/ui/store/tabMap'; import { InvokeTabName } from 'features/ui/store/tabMap';
import { IRect } from 'konva/lib/types';
import { clamp } from 'lodash';
export type GalleryCategory = 'user' | 'result'; export type GalleryCategory = 'user' | 'result';

View File

@ -1,10 +1,10 @@
import { AnyAction, ThunkAction } from '@reduxjs/toolkit'; import { AnyAction, ThunkAction } from '@reduxjs/toolkit';
import { RootState } from 'app/store';
import * as InvokeAI from 'app/invokeai'; import * as InvokeAI from 'app/invokeai';
import { v4 as uuidv4 } from 'uuid'; import { RootState } from 'app/store';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice'; import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import { setInitialImage } from 'features/parameters/store/generationSlice'; import { setInitialImage } from 'features/parameters/store/generationSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { v4 as uuidv4 } from 'uuid';
import { addImage } from '../gallerySlice'; import { addImage } from '../gallerySlice';
type UploadImageConfig = { type UploadImageConfig = {
@ -32,7 +32,7 @@ export const uploadImage =
}) })
); );
const response = await fetch(window.location.origin + '/upload', { const response = await fetch(`${window.location.origin}/upload`, {
method: 'POST', method: 'POST',
body: formData, body: formData,
}); });

View File

@ -4,14 +4,14 @@ import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import CurrentImageButtons from 'features/gallery/components/CurrentImageButtons'; import CurrentImageButtons from 'features/gallery/components/CurrentImageButtons';
import { imagesSelector } from 'features/gallery/components/CurrentImagePreview'; import { imagesSelector } from 'features/gallery/components/CurrentImagePreview';
import ImageGallery from 'features/gallery/components/ImageGallery';
import ImageMetadataViewer from 'features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer';
import { import {
selectNextImage, selectNextImage,
selectPrevImage, selectPrevImage,
} from 'features/gallery/store/gallerySlice'; } from 'features/gallery/store/gallerySlice';
import ImageGallery from 'features/gallery/components/ImageGallery';
import ImageMetadataViewer from 'features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer';
import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice'; import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice';
import React, { useState } from 'react'; import { useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook'; import { useHotkeys } from 'react-hotkeys-hook';
import { BiExit } from 'react-icons/bi'; import { BiExit } from 'react-icons/bi';
import { FaAngleLeft, FaAngleRight } from 'react-icons/fa'; import { FaAngleLeft, FaAngleRight } from 'react-icons/fa';

View File

@ -8,7 +8,7 @@ import {
BiZoomOut, BiZoomOut,
} from 'react-icons/bi'; } from 'react-icons/bi';
import { MdFlip } from 'react-icons/md'; import { MdFlip } from 'react-icons/md';
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'; import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
type ReactPanZoomProps = { type ReactPanZoomProps = {
image: string; image: string;

View File

@ -1,13 +1,13 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import _ from 'lodash'; import { isEqual } from 'lodash';
export const lightboxSelector = createSelector( export const lightboxSelector = createSelector(
(state: RootState) => state.lightbox, (state: RootState) => state.lightbox,
(lightbox) => lightbox, (lightbox) => lightbox,
{ {
memoizeOptions: { memoizeOptions: {
equalityCheck: _.isEqual, equalityCheck: isEqual,
}, },
} }
); );

View File

@ -1,5 +1,5 @@
import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit'; import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
export interface LightboxState { export interface LightboxState {
isLightboxOpen: boolean; isLightboxOpen: boolean;

View File

@ -6,9 +6,9 @@ import {
Box, Box,
Flex, Flex,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { ReactNode } from 'react';
import { Feature } from 'app/features'; import { Feature } from 'app/features';
import GuideIcon from 'common/components/GuideIcon'; import GuideIcon from 'common/components/GuideIcon';
import { ReactNode } from 'react';
export interface InvokeAccordionItemProps { export interface InvokeAccordionItemProps {
header: string; header: string;

View File

@ -4,7 +4,8 @@ import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { canvasSelector } from 'features/canvas/store/canvasSelectors'; import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice'; import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
import _ from 'lodash'; import { isEqual } from 'lodash';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const selector = createSelector( const selector = createSelector(
@ -19,7 +20,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -18,7 +18,8 @@ import {
setTileSize, setTileSize,
} from 'features/parameters/store/generationSlice'; } from 'features/parameters/store/generationSlice';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import _ from 'lodash'; import { isEqual } from 'lodash';
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -45,7 +46,7 @@ const selector = createSelector(
}, },
{ {
memoizeOptions: { memoizeOptions: {
resultEqualityCheck: _.isEqual, resultEqualityCheck: isEqual,
}, },
} }
); );

View File

@ -2,14 +2,15 @@ import type { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { setSeamSize } from 'features/parameters/store/generationSlice'; import { setSeamSize } from 'features/parameters/store/generationSlice';
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function SeamSize() { export default function SeamSize() {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
const seamSize = useAppSelector((state: RootState) => state.generation.seamSize); const seamSize = useAppSelector(
(state: RootState) => state.generation.seamSize
);
return ( return (
<IAISlider <IAISlider

View File

@ -2,7 +2,6 @@ import type { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { setSeamSteps } from 'features/parameters/store/generationSlice'; import { setSeamSteps } from 'features/parameters/store/generationSlice';
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function SeamSteps() { export default function SeamSteps() {

View File

@ -2,7 +2,6 @@ import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';
import { setSeamStrength } from 'features/parameters/store/generationSlice'; import { setSeamStrength } from 'features/parameters/store/generationSlice';
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function SeamStrength() { export default function SeamStrength() {

View File

@ -11,14 +11,14 @@ import {
} from 'features/parameters/store/postprocessingSlice'; } from 'features/parameters/store/postprocessingSlice';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { isEqual } from 'lodash'; import { FACETOOL_TYPES } from 'app/constants';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';
import IAISelect from 'common/components/IAISelect'; import IAISelect from 'common/components/IAISelect';
import { FACETOOL_TYPES } from 'app/constants';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors'; import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
const optionsSelector = createSelector( const optionsSelector = createSelector(
[postprocessingSelector, systemSelector], [postprocessingSelector, systemSelector],

View File

@ -1,8 +1,8 @@
import { ChangeEvent } from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { setShouldRunFacetool } from 'features/parameters/store/postprocessingSlice'; import { setShouldRunFacetool } from 'features/parameters/store/postprocessingSlice';
import { ChangeEvent } from 'react';
export default function FaceRestoreToggle() { export default function FaceRestoreToggle() {
const isGFPGANAvailable = useAppSelector( const isGFPGANAvailable = useAppSelector(

View File

@ -1,8 +1,8 @@
import React, { ChangeEvent } from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { setShouldFitToWidthHeight } from 'features/parameters/store/generationSlice'; import { setShouldFitToWidthHeight } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function ImageFit() { export default function ImageFit() {

View File

@ -1,4 +1,3 @@
import React from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISlider from 'common/components/IAISlider'; import IAISlider from 'common/components/IAISlider';

View File

@ -1,9 +1,9 @@
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { ChangeEvent } from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { setSeamless } from 'features/parameters/store/generationSlice'; import { setSeamless } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
/** /**
@ -12,7 +12,9 @@ import { useTranslation } from 'react-i18next';
const SeamlessSettings = () => { const SeamlessSettings = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const seamless = useAppSelector((state: RootState) => state.generation.seamless); const seamless = useAppSelector(
(state: RootState) => state.generation.seamless
);
const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) => const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) =>
dispatch(setSeamless(e.target.checked)); dispatch(setSeamless(e.target.checked));

View File

@ -1,4 +1,3 @@
import React from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';

View File

@ -1,5 +1,4 @@
import { ChangeEvent } from 'react'; import { ChangeEvent } from 'react';
import React from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';

View File

@ -1,4 +1,3 @@
import React from 'react';
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants'; import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';

View File

@ -1,9 +1,9 @@
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import Perlin from './Perlin';
import RandomizeSeed from './RandomizeSeed'; import RandomizeSeed from './RandomizeSeed';
import Seed from './Seed'; import Seed from './Seed';
import ShuffleSeed from './ShuffleSeed'; import ShuffleSeed from './ShuffleSeed';
import Threshold from './Threshold'; import Threshold from './Threshold';
import Perlin from './Perlin';
/** /**
* Seed & variation options. Includes iteration, seed, seed randomization, variation options. * Seed & variation options. Includes iteration, seed, seed randomization, variation options.

View File

@ -1,5 +1,4 @@
import { Button } from '@chakra-ui/react'; import { Button } from '@chakra-ui/react';
import React from 'react';
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants'; import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';

View File

@ -1,4 +1,3 @@
import React from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';

View File

@ -1,20 +1,20 @@
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { UpscalingLevel } from 'features/parameters/store/postprocessingSlice';
import { import {
setUpscalingLevel, setUpscalingLevel,
setUpscalingStrength, setUpscalingStrength,
UpscalingLevel,
} from 'features/parameters/store/postprocessingSlice'; } from 'features/parameters/store/postprocessingSlice';
import { UPSCALING_LEVELS } from 'app/constants';
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { isEqual } from 'lodash'; import { UPSCALING_LEVELS } from 'app/constants';
import { ChangeEvent } from 'react';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';
import IAISelect from 'common/components/IAISelect'; import IAISelect from 'common/components/IAISelect';
import { useTranslation } from 'react-i18next';
import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors'; import { postprocessingSelector } from 'features/parameters/store/postprocessingSelectors';
import { systemSelector } from 'features/system/store/systemSelectors'; import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
const parametersSelector = createSelector( const parametersSelector = createSelector(
[postprocessingSelector, systemSelector], [postprocessingSelector, systemSelector],

View File

@ -1,8 +1,8 @@
import { ChangeEvent } from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { setShouldRunESRGAN } from 'features/parameters/store/postprocessingSlice'; import { setShouldRunESRGAN } from 'features/parameters/store/postprocessingSlice';
import { ChangeEvent } from 'react';
export default function UpscaleToggle() { export default function UpscaleToggle() {
const isESRGANAvailable = useAppSelector( const isESRGANAvailable = useAppSelector(

View File

@ -1,8 +1,8 @@
import React, { ChangeEvent } from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAISwitch from 'common/components/IAISwitch'; import IAISwitch from 'common/components/IAISwitch';
import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice'; import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react';
export default function GenerateVariationsToggle() { export default function GenerateVariationsToggle() {
const shouldGenerateVariations = useAppSelector( const shouldGenerateVariations = useAppSelector(

View File

@ -1,9 +1,9 @@
import React, { ChangeEvent } from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAIInput from 'common/components/IAIInput'; import IAIInput from 'common/components/IAIInput';
import { validateSeedWeights } from 'common/util/seedWeightPairs'; import { validateSeedWeights } from 'common/util/seedWeightPairs';
import { setSeedWeights } from 'features/parameters/store/generationSlice'; import { setSeedWeights } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export default function SeedWeights() { export default function SeedWeights() {

View File

@ -1,4 +1,3 @@
import React from 'react';
import { RootState } from 'app/store'; import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import IAINumberInput from 'common/components/IAINumberInput'; import IAINumberInput from 'common/components/IAINumberInput';

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