mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into 2.3-documentation-fixes
This commit is contained in:
commit
13d12a0ceb
6
.github/workflows/build-container.yml
vendored
6
.github/workflows/build-container.yml
vendored
@ -3,6 +3,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- 'main'
|
- 'main'
|
||||||
|
- 'update/ci/*'
|
||||||
tags:
|
tags:
|
||||||
- 'v*.*.*'
|
- 'v*.*.*'
|
||||||
|
|
||||||
@ -47,11 +48,10 @@ jobs:
|
|||||||
type=semver,pattern={{version}}
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=sha,enable=true,prefix=sha-,suffix=${{ matrix.flavor}},format=short
|
type=sha,enable=true,prefix=sha-,format=short
|
||||||
type=raw,value={{branch}}-${{ matrix.flavor }}
|
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=${{ matrix.flavor == 'cuda' && github.ref == 'refs/heads/main' }}
|
latest=${{ matrix.flavor == 'cuda' && github.ref == 'refs/heads/main' }}
|
||||||
|
suffix=-${{ matrix.flavor }},onlatest=false
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v2
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
57
.github/workflows/test-invoke-pip.yml
vendored
57
.github/workflows/test-invoke-pip.yml
vendored
@ -8,10 +8,11 @@ on:
|
|||||||
- 'ready_for_review'
|
- 'ready_for_review'
|
||||||
- 'opened'
|
- 'opened'
|
||||||
- 'synchronize'
|
- 'synchronize'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
matrix:
|
matrix:
|
||||||
@ -62,28 +63,13 @@ jobs:
|
|||||||
# github-env: $env:GITHUB_ENV
|
# github-env: $env:GITHUB_ENV
|
||||||
name: ${{ matrix.pytorch }} on ${{ matrix.python-version }}
|
name: ${{ matrix.pytorch }} on ${{ matrix.python-version }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
PIP_USE_PEP517: '1'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
id: checkout-sources
|
id: checkout-sources
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: setup python
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python-version }}
|
|
||||||
|
|
||||||
- name: Set Cache-Directory Windows
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
id: set-cache-dir-windows
|
|
||||||
run: |
|
|
||||||
echo "CACHE_DIR=$HOME\invokeai\models" >> ${{ matrix.github-env }}
|
|
||||||
echo "PIP_NO_CACHE_DIR=1" >> ${{ matrix.github-env }}
|
|
||||||
|
|
||||||
- name: Set Cache-Directory others
|
|
||||||
if: runner.os != 'Windows'
|
|
||||||
id: set-cache-dir-others
|
|
||||||
run: echo "CACHE_DIR=$HOME/invokeai/models" >> ${{ matrix.github-env }}
|
|
||||||
|
|
||||||
- name: set test prompt to main branch validation
|
- name: set test prompt to main branch validation
|
||||||
if: ${{ github.ref == 'refs/heads/main' }}
|
if: ${{ github.ref == 'refs/heads/main' }}
|
||||||
run: echo "TEST_PROMPTS=tests/preflight_prompts.txt" >> ${{ matrix.github-env }}
|
run: echo "TEST_PROMPTS=tests/preflight_prompts.txt" >> ${{ matrix.github-env }}
|
||||||
@ -92,26 +78,29 @@ jobs:
|
|||||||
if: ${{ github.ref != 'refs/heads/main' }}
|
if: ${{ github.ref != 'refs/heads/main' }}
|
||||||
run: echo "TEST_PROMPTS=tests/validate_pr_prompt.txt" >> ${{ matrix.github-env }}
|
run: echo "TEST_PROMPTS=tests/validate_pr_prompt.txt" >> ${{ matrix.github-env }}
|
||||||
|
|
||||||
|
- name: setup python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
cache: pip
|
||||||
|
cache-dependency-path: pyproject.toml
|
||||||
|
|
||||||
- name: install invokeai
|
- name: install invokeai
|
||||||
env:
|
env:
|
||||||
PIP_EXTRA_INDEX_URL: ${{ matrix.extra-index-url }}
|
PIP_EXTRA_INDEX_URL: ${{ matrix.extra-index-url }}
|
||||||
run: >
|
run: >
|
||||||
pip3 install
|
pip3 install
|
||||||
--use-pep517
|
|
||||||
--editable=".[test]"
|
--editable=".[test]"
|
||||||
|
|
||||||
- name: run pytest
|
- name: run pytest
|
||||||
|
id: run-pytest
|
||||||
run: pytest
|
run: pytest
|
||||||
|
|
||||||
- name: Use Cached models
|
- name: set INVOKEAI_OUTDIR
|
||||||
id: cache-sd-model
|
run: >
|
||||||
uses: actions/cache@v3
|
python -c
|
||||||
env:
|
"import os;from ldm.invoke.globals import Globals;OUTDIR=os.path.join(Globals.root,str('outputs'));print(f'INVOKEAI_OUTDIR={OUTDIR}')"
|
||||||
cache-name: huggingface-models
|
>> ${{ matrix.github-env }}
|
||||||
with:
|
|
||||||
path: ${{ env.CACHE_DIR }}
|
|
||||||
key: ${{ env.cache-name }}
|
|
||||||
enableCrossOsArchive: true
|
|
||||||
|
|
||||||
- name: run invokeai-configure
|
- name: run invokeai-configure
|
||||||
id: run-preload-models
|
id: run-preload-models
|
||||||
@ -124,9 +113,8 @@ jobs:
|
|||||||
--full-precision
|
--full-precision
|
||||||
# can't use fp16 weights without a GPU
|
# can't use fp16 weights without a GPU
|
||||||
|
|
||||||
- name: Run the tests
|
- name: run invokeai
|
||||||
if: runner.os != 'Windows'
|
id: run-invokeai
|
||||||
id: run-tests
|
|
||||||
env:
|
env:
|
||||||
# Set offline mode to make sure configure preloaded successfully.
|
# Set offline mode to make sure configure preloaded successfully.
|
||||||
HF_HUB_OFFLINE: 1
|
HF_HUB_OFFLINE: 1
|
||||||
@ -137,10 +125,11 @@ jobs:
|
|||||||
--no-patchmatch
|
--no-patchmatch
|
||||||
--no-nsfw_checker
|
--no-nsfw_checker
|
||||||
--from_file ${{ env.TEST_PROMPTS }}
|
--from_file ${{ env.TEST_PROMPTS }}
|
||||||
|
--outdir ${{ env.INVOKEAI_OUTDIR }}/${{ matrix.python-version }}/${{ matrix.pytorch }}
|
||||||
|
|
||||||
- name: Archive results
|
- name: Archive results
|
||||||
id: archive-results
|
id: archive-results
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: results_${{ matrix.pytorch }}_${{ matrix.python-version }}
|
name: results
|
||||||
path: ${{ env.INVOKEAI_ROOT }}/outputs
|
path: ${{ env.INVOKEAI_OUTDIR }}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
# syntax=docker/dockerfile:1
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
# Maintained by Matthias Wild <mauwii@outlook.de>
|
|
||||||
|
|
||||||
ARG PYTHON_VERSION=3.9
|
ARG PYTHON_VERSION=3.9
|
||||||
##################
|
##################
|
||||||
## base image ##
|
## base image ##
|
||||||
@ -85,3 +82,5 @@ ENV INVOKE_MODEL_RECONFIGURE="--yes --default_only"
|
|||||||
ENTRYPOINT [ "invokeai" ]
|
ENTRYPOINT [ "invokeai" ]
|
||||||
CMD [ "--web", "--host=0.0.0.0" ]
|
CMD [ "--web", "--host=0.0.0.0" ]
|
||||||
VOLUME [ "/data" ]
|
VOLUME [ "/data" ]
|
||||||
|
|
||||||
|
LABEL org.opencontainers.image.authors="mauwii@outlook.de"
|
||||||
|
@ -54,8 +54,7 @@ Please enter 1, 2, 3, or 4: [1] 3
|
|||||||
```
|
```
|
||||||
|
|
||||||
From the command line, with the InvokeAI virtual environment active,
|
From the command line, with the InvokeAI virtual environment active,
|
||||||
you can launch the front end with the command `textual_inversion
|
you can launch the front end with the command `invokeai-ti --gui`.
|
||||||
--gui`.
|
|
||||||
|
|
||||||
This will launch a text-based front end that will look like this:
|
This will launch a text-based front end that will look like this:
|
||||||
|
|
||||||
@ -227,12 +226,12 @@ It accepts a large number of arguments, which can be summarized by
|
|||||||
passing the `--help` argument:
|
passing the `--help` argument:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
textual_inversion --help
|
invokeai-ti --help
|
||||||
```
|
```
|
||||||
|
|
||||||
Typical usage is shown here:
|
Typical usage is shown here:
|
||||||
```sh
|
```sh
|
||||||
textual_inversion \
|
invokeai-ti \
|
||||||
--model=stable-diffusion-1.5 \
|
--model=stable-diffusion-1.5 \
|
||||||
--resolution=512 \
|
--resolution=512 \
|
||||||
--learnable_property=style \
|
--learnable_property=style \
|
||||||
|
@ -249,6 +249,7 @@ class InvokeAiInstance:
|
|||||||
"--require-virtualenv",
|
"--require-virtualenv",
|
||||||
"torch",
|
"torch",
|
||||||
"torchvision",
|
"torchvision",
|
||||||
|
"--force-reinstall",
|
||||||
"--find-links" if find_links is not None else None,
|
"--find-links" if find_links is not None else None,
|
||||||
find_links,
|
find_links,
|
||||||
"--extra-index-url" if extra_index_url is not None else None,
|
"--extra-index-url" if extra_index_url is not None else None,
|
||||||
@ -325,6 +326,7 @@ class InvokeAiInstance:
|
|||||||
Configure the InvokeAI runtime directory
|
Configure the InvokeAI runtime directory
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# set sys.argv to a consistent state
|
||||||
new_argv = [sys.argv[0]]
|
new_argv = [sys.argv[0]]
|
||||||
for i in range(1,len(sys.argv)):
|
for i in range(1,len(sys.argv)):
|
||||||
el = sys.argv[i]
|
el = sys.argv[i]
|
||||||
@ -344,9 +346,6 @@ class InvokeAiInstance:
|
|||||||
# NOTE: currently the config script does its own arg parsing! this means the command-line switches
|
# NOTE: currently the config script does its own arg parsing! this means the command-line switches
|
||||||
# from the installer will also automatically propagate down to the config script.
|
# from the installer will also automatically propagate down to the config script.
|
||||||
# this may change in the future with config refactoring!
|
# this may change in the future with config refactoring!
|
||||||
|
|
||||||
# set sys.argv to a consistent state
|
|
||||||
|
|
||||||
invokeai_configure.main()
|
invokeai_configure.main()
|
||||||
|
|
||||||
def install_user_scripts(self):
|
def install_user_scripts(self):
|
||||||
|
@ -1208,12 +1208,18 @@ class InvokeAIWebServer:
|
|||||||
)
|
)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
# Clear the CUDA cache on an exception
|
||||||
|
self.empty_cuda_cache()
|
||||||
self.socketio.emit("processingCanceled")
|
self.socketio.emit("processingCanceled")
|
||||||
raise
|
raise
|
||||||
except CanceledException:
|
except CanceledException:
|
||||||
|
# Clear the CUDA cache on an exception
|
||||||
|
self.empty_cuda_cache()
|
||||||
self.socketio.emit("processingCanceled")
|
self.socketio.emit("processingCanceled")
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# Clear the CUDA cache on an exception
|
||||||
|
self.empty_cuda_cache()
|
||||||
print(e)
|
print(e)
|
||||||
self.socketio.emit("error", {"message": (str(e))})
|
self.socketio.emit("error", {"message": (str(e))})
|
||||||
print("\n")
|
print("\n")
|
||||||
@ -1221,6 +1227,12 @@ class InvokeAIWebServer:
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
print("\n")
|
print("\n")
|
||||||
|
|
||||||
|
def empty_cuda_cache(self):
|
||||||
|
if self.generate.device.type == "cuda":
|
||||||
|
import torch.cuda
|
||||||
|
|
||||||
|
torch.cuda.empty_cache()
|
||||||
|
|
||||||
def parameters_to_generated_image_metadata(self, parameters):
|
def parameters_to_generated_image_metadata(self, parameters):
|
||||||
try:
|
try:
|
||||||
# top-level metadata minus `image` or `images`
|
# top-level metadata minus `image` or `images`
|
||||||
|
13
invokeai/frontend/.babelrc
Normal file
13
invokeai/frontend/.babelrc
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"transform-imports",
|
||||||
|
{
|
||||||
|
"lodash": {
|
||||||
|
"transform": "lodash/${member}",
|
||||||
|
"preventFullImport": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
5
invokeai/frontend/.eslintignore
Normal file
5
invokeai/frontend/.eslintignore
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
dist/
|
||||||
|
.husky/
|
||||||
|
node_modules/
|
||||||
|
patches/
|
||||||
|
public/
|
@ -1,13 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:react-hooks/recommended',
|
|
||||||
],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['@typescript-eslint', 'eslint-plugin-react-hooks'],
|
|
||||||
root: true,
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-unused-vars': ['warn', { varsIgnorePattern: '_+' }],
|
|
||||||
},
|
|
||||||
};
|
|
40
invokeai/frontend/.eslintrc.js
Normal file
40
invokeai/frontend/.eslintrc.js
Normal 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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
3
invokeai/frontend/.gitignore
vendored
3
invokeai/frontend/.gitignore
vendored
@ -23,3 +23,6 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
|
# build stats
|
||||||
|
stats.html
|
4
invokeai/frontend/.husky/pre-commit
Executable file
4
invokeai/frontend/.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
cd invokeai/frontend/ && npx run lint
|
5
invokeai/frontend/.prettierignore
Normal file
5
invokeai/frontend/.prettierignore
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
dist/
|
||||||
|
.husky/
|
||||||
|
node_modules/
|
||||||
|
patches/
|
||||||
|
public/
|
6
invokeai/frontend/.prettierrc.js
Normal file
6
invokeai/frontend/.prettierrc.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
trailingComma: 'es5',
|
||||||
|
tabWidth: 2,
|
||||||
|
semi: true,
|
||||||
|
singleQuote: true,
|
||||||
|
};
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
638
invokeai/frontend/dist/assets/index-34c8aef8.js
vendored
Normal file
638
invokeai/frontend/dist/assets/index-34c8aef8.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
invokeai/frontend/dist/assets/index-b0bf79f4.css
vendored
Normal file
1
invokeai/frontend/dist/assets/index-b0bf79f4.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
625
invokeai/frontend/dist/assets/index.dd4ad8a1.js
vendored
625
invokeai/frontend/dist/assets/index.dd4ad8a1.js
vendored
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
13
invokeai/frontend/dist/index.html
vendored
13
invokeai/frontend/dist/index.html
vendored
@ -1,23 +1,16 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script type="module" crossorigin src="./assets/polyfills.1ff60148.js"></script>
|
|
||||||
|
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
<title>InvokeAI - A Stable Diffusion Toolkit</title>
|
||||||
<link rel="shortcut icon" type="icon" href="./assets/favicon.0d253ced.ico" />
|
<link rel="shortcut icon" type="icon" href="./assets/favicon-0d253ced.ico" />
|
||||||
<script type="module" crossorigin src="./assets/index.dd4ad8a1.js"></script>
|
<script type="module" crossorigin src="./assets/index-34c8aef8.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/index.8badc8b4.css">
|
<link rel="stylesheet" href="./assets/index-b0bf79f4.css">
|
||||||
<script type="module">try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.__vite_is_modern_browser=true;</script>
|
|
||||||
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|
||||||
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
|
|
||||||
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-dde3a68a.js"></script>
|
|
||||||
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-8219c08f.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"otherOptions": "Other Options",
|
"otherOptions": "Other Options",
|
||||||
"seamlessTiling": "Seamless Tiling",
|
"seamlessTiling": "Seamless Tiling",
|
||||||
"hiresOptim": "High Res Optimization",
|
"hiresOptim": "High Res Optimization",
|
||||||
|
"hiresStrength": "High Res Strength",
|
||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"codeformerFidelity": "Fidelity",
|
"codeformerFidelity": "Fidelity",
|
||||||
"seamSize": "Seam Size",
|
"seamSize": "Seam Size",
|
@ -24,6 +24,7 @@
|
|||||||
"otherOptions": "Other Options",
|
"otherOptions": "Other Options",
|
||||||
"seamlessTiling": "Seamless Tiling",
|
"seamlessTiling": "Seamless Tiling",
|
||||||
"hiresOptim": "High Res Optimization",
|
"hiresOptim": "High Res Optimization",
|
||||||
|
"hiresStrength": "High Res Strength",
|
||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"codeformerFidelity": "Fidelity",
|
"codeformerFidelity": "Fidelity",
|
||||||
"seamSize": "Seam Size",
|
"seamSize": "Seam Size",
|
||||||
@ -43,6 +44,7 @@
|
|||||||
"invoke": "Invoke",
|
"invoke": "Invoke",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||||
|
"negativePrompts": "Negative Prompts",
|
||||||
"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",
|
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"plugin:react-hooks/recommended"
|
|
||||||
],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"plugins": ["@typescript-eslint", "eslint-plugin-react-hooks"],
|
|
||||||
"root": true,
|
|
||||||
"settings": {
|
|
||||||
"import/resolver": {
|
|
||||||
"node": {
|
|
||||||
"paths": ["src"],
|
|
||||||
"extensions": [".js", ".jsx", ".ts", ".tsx"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"react/jsx-filename-extension": [1, { "extensions": [".tsx", ".ts"] }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,15 +2,15 @@
|
|||||||
"name": "invoke-ai-ui",
|
"name": "invoke-ai-ui",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"prepare": "cd ../../ && husky install invokeai/frontend/.husky",
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"build-dev": "tsc && vite build -m development",
|
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"madge": "madge --circular src/main.tsx",
|
"madge": "madge --circular src/main.tsx",
|
||||||
"lint": "eslint src/",
|
"lint": "eslint --fix .",
|
||||||
"prettier": "prettier *.{json,cjs,ts,html} src/**/*.{ts,tsx}",
|
"lint-staged": "lint-staged",
|
||||||
|
"prettier": "prettier *.{json,js,ts,html} src/**/*.{ts,tsx,scss} --write .",
|
||||||
"fmt": "npm run prettier -- --write",
|
"fmt": "npm run prettier -- --write",
|
||||||
"postinstall": "patch-package"
|
"postinstall": "patch-package"
|
||||||
},
|
},
|
||||||
@ -25,6 +25,7 @@
|
|||||||
"@radix-ui/react-tooltip": "^1.0.2",
|
"@radix-ui/react-tooltip": "^1.0.2",
|
||||||
"@reduxjs/toolkit": "^1.8.5",
|
"@reduxjs/toolkit": "^1.8.5",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
|
"@vitejs/plugin-react-swc": "^3.1.0",
|
||||||
"add": "^2.0.6",
|
"add": "^2.0.6",
|
||||||
"dateformat": "^5.0.3",
|
"dateformat": "^5.0.3",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
@ -62,22 +63,26 @@
|
|||||||
"@types/react-transition-group": "^4.4.5",
|
"@types/react-transition-group": "^4.4.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
||||||
"@typescript-eslint/parser": "^5.36.2",
|
"@typescript-eslint/parser": "^5.36.2",
|
||||||
"@vitejs/plugin-legacy": "^3.0.1",
|
"babel-plugin-transform-imports": "^2.0.0",
|
||||||
"@vitejs/plugin-react": "^2.0.1",
|
|
||||||
"eslint": "^8.23.0",
|
"eslint": "^8.23.0",
|
||||||
|
"eslint-config-prettier": "^8.6.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
|
"eslint-plugin-react": "^7.32.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"husky": "^8.0.3",
|
||||||
|
"lint-staged": "^13.1.0",
|
||||||
"madge": "^5.0.1",
|
"madge": "^5.0.1",
|
||||||
"patch-package": "^6.5.0",
|
"patch-package": "^6.5.0",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"postinstall-postinstall": "^2.1.0",
|
||||||
"prettier": "^2.8.1",
|
"prettier": "^2.8.3",
|
||||||
|
"rollup-plugin-visualizer": "^5.9.0",
|
||||||
"sass": "^1.55.0",
|
"sass": "^1.55.0",
|
||||||
"terser": "^5.16.1",
|
"terser": "^5.16.1",
|
||||||
"tsc-watch": "^5.0.3",
|
"tsc-watch": "^5.0.3",
|
||||||
"typescript": "^4.6.4",
|
"typescript": "^5.0.0-beta",
|
||||||
"vite": "^3.0.7",
|
"vite": "^4.1.1",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^3.5.2"
|
"vite-tsconfig-paths": "^4.0.5"
|
||||||
},
|
},
|
||||||
"madge": {
|
"madge": {
|
||||||
"detectiveOptions": {
|
"detectiveOptions": {
|
||||||
@ -88,5 +93,11 @@
|
|||||||
"skipTypeImports": true
|
"skipTypeImports": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"**/*.{js,jsx,ts,tsx,cjs}": [
|
||||||
|
"npx prettier --write",
|
||||||
|
"npx eslint --fix"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"otherOptions": "Other Options",
|
"otherOptions": "Other Options",
|
||||||
"seamlessTiling": "Seamless Tiling",
|
"seamlessTiling": "Seamless Tiling",
|
||||||
"hiresOptim": "High Res Optimization",
|
"hiresOptim": "High Res Optimization",
|
||||||
|
"hiresStrength": "High Res Strength",
|
||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"codeformerFidelity": "Fidelity",
|
"codeformerFidelity": "Fidelity",
|
||||||
"seamSize": "Seam Size",
|
"seamSize": "Seam Size",
|
@ -24,6 +24,7 @@
|
|||||||
"otherOptions": "Other Options",
|
"otherOptions": "Other Options",
|
||||||
"seamlessTiling": "Seamless Tiling",
|
"seamlessTiling": "Seamless Tiling",
|
||||||
"hiresOptim": "High Res Optimization",
|
"hiresOptim": "High Res Optimization",
|
||||||
|
"hiresStrength": "High Res Strength",
|
||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"codeformerFidelity": "Fidelity",
|
"codeformerFidelity": "Fidelity",
|
||||||
"seamSize": "Seam Size",
|
"seamSize": "Seam Size",
|
||||||
@ -43,6 +44,7 @@
|
|||||||
"invoke": "Invoke",
|
"invoke": "Invoke",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
"promptPlaceholder": "Type prompt here. [negative tokens], (upweight)++, (downweight)--, swap and blend are available (see docs)",
|
||||||
|
"negativePrompts": "Negative Prompts",
|
||||||
"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",
|
@ -1,14 +1,14 @@
|
|||||||
|
import ImageUploader from 'common/components/ImageUploader';
|
||||||
|
import Console from 'features/system/components/Console';
|
||||||
import ProgressBar from 'features/system/components/ProgressBar';
|
import ProgressBar from 'features/system/components/ProgressBar';
|
||||||
import SiteHeader from 'features/system/components/SiteHeader';
|
import SiteHeader from 'features/system/components/SiteHeader';
|
||||||
import Console from 'features/system/components/Console';
|
import InvokeTabs from 'features/ui/components/InvokeTabs';
|
||||||
import { keepGUIAlive } from './utils';
|
import { keepGUIAlive } from './utils';
|
||||||
import InvokeTabs from 'features/tabs/components/InvokeTabs';
|
|
||||||
import ImageUploader from 'common/components/ImageUploader';
|
|
||||||
|
|
||||||
import useToastWatcher from 'features/system/hooks/useToastWatcher';
|
import useToastWatcher from 'features/system/hooks/useToastWatcher';
|
||||||
|
|
||||||
import FloatingOptionsPanelButtons from 'features/tabs/components/FloatingOptionsPanelButtons';
|
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
|
||||||
import FloatingGalleryButton from 'features/tabs/components/FloatingGalleryButton';
|
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
|
||||||
|
|
||||||
keepGUIAlive();
|
keepGUIAlive();
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ const App = () => {
|
|||||||
<Console />
|
<Console />
|
||||||
</div>
|
</div>
|
||||||
</ImageUploader>
|
</ImageUploader>
|
||||||
<FloatingOptionsPanelButtons />
|
<FloatingParametersPanelButtons />
|
||||||
<FloatingGalleryButton />
|
<FloatingGalleryButton />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -16,6 +16,20 @@ export const SAMPLERS: Array<string> = [
|
|||||||
'k_heun',
|
'k_heun',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Valid Diffusers Samplers
|
||||||
|
export const DIFFUSERS_SAMPLERS: Array<string> = [
|
||||||
|
'ddim',
|
||||||
|
'plms',
|
||||||
|
'k_lms',
|
||||||
|
'dpmpp_2',
|
||||||
|
'k_dpm_2',
|
||||||
|
'k_dpm_2_a',
|
||||||
|
'k_dpmpp_2',
|
||||||
|
'k_euler',
|
||||||
|
'k_euler_a',
|
||||||
|
'k_heun',
|
||||||
|
];
|
||||||
|
|
||||||
// Valid image widths
|
// Valid image widths
|
||||||
export const WIDTHS: Array<number> = [
|
export const WIDTHS: Array<number> = [
|
||||||
64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960,
|
64, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960,
|
||||||
|
2
invokeai/frontend/src/app/invokeai.d.ts
vendored
2
invokeai/frontend/src/app/invokeai.d.ts
vendored
@ -12,7 +12,7 @@
|
|||||||
* 'gfpgan'.
|
* 'gfpgan'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import { IRect } from 'konva/lib/types';
|
import { IRect } from 'konva/lib/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,32 +1,26 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import _ from 'lodash';
|
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
import { validateSeedWeights } from 'common/util/seedWeightPairs';
|
||||||
import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors';
|
import { initialCanvasImageSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
import { generationSelector } from 'features/parameters/store/generationSelectors';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
|
||||||
export const readinessSelector = createSelector(
|
export const readinessSelector = createSelector(
|
||||||
[
|
[
|
||||||
(state: RootState) => state.options,
|
generationSelector,
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
initialCanvasImageSelector,
|
initialCanvasImageSelector,
|
||||||
activeTabNameSelector,
|
activeTabNameSelector,
|
||||||
],
|
],
|
||||||
(
|
(generation, system, initialCanvasImage, activeTabName) => {
|
||||||
options: OptionsState,
|
|
||||||
system: SystemState,
|
|
||||||
initialCanvasImage,
|
|
||||||
activeTabName
|
|
||||||
) => {
|
|
||||||
const {
|
const {
|
||||||
prompt,
|
prompt,
|
||||||
shouldGenerateVariations,
|
shouldGenerateVariations,
|
||||||
seedWeights,
|
seedWeights,
|
||||||
initialImage,
|
initialImage,
|
||||||
seed,
|
seed,
|
||||||
} = options;
|
} = generation;
|
||||||
|
|
||||||
const { isProcessing, isConnected } = system;
|
const { isProcessing, isConnected } = system;
|
||||||
|
|
||||||
@ -71,8 +65,8 @@ export const readinessSelector = createSelector(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
memoizeOptions: {
|
memoizeOptions: {
|
||||||
equalityCheck: _.isEqual,
|
equalityCheck: isEqual,
|
||||||
resultEqualityCheck: _.isEqual,
|
resultEqualityCheck: isEqual,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createAction } from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
import { GalleryCategory } from 'features/gallery/store/gallerySlice';
|
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
|
import { GalleryCategory } from 'features/gallery/store/gallerySlice';
|
||||||
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We can't use redux-toolkit's createSlice() to make these actions,
|
* We can't use redux-toolkit's createSlice() to make these actions,
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit';
|
import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit';
|
||||||
import dateFormat from 'dateformat';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
import { Socket } from 'socket.io-client';
|
import type { RootState } from 'app/store';
|
||||||
import {
|
import {
|
||||||
frontendToBackendParameters,
|
frontendToBackendParameters,
|
||||||
FrontendToBackendParametersConfig,
|
FrontendToBackendParametersConfig,
|
||||||
} from 'common/util/parameterTranslation';
|
} from 'common/util/parameterTranslation';
|
||||||
|
import dateFormat from 'dateformat';
|
||||||
import {
|
import {
|
||||||
GalleryCategory,
|
GalleryCategory,
|
||||||
GalleryState,
|
GalleryState,
|
||||||
removeImage,
|
removeImage,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
|
||||||
import {
|
import {
|
||||||
addLogEntry,
|
addLogEntry,
|
||||||
generationRequested,
|
generationRequested,
|
||||||
modelChangeRequested,
|
modelChangeRequested,
|
||||||
setIsProcessing,
|
setIsProcessing,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import { Socket } from 'socket.io-client';
|
||||||
import type { RootState } from 'app/store';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an object containing all functions which use `socketio.emit()`.
|
* Returns an object containing all functions which use `socketio.emit()`.
|
||||||
@ -39,7 +38,8 @@ const makeSocketIOEmitters = (
|
|||||||
const state: RootState = getState();
|
const state: RootState = getState();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
options: optionsState,
|
generation: generationState,
|
||||||
|
postprocessing: postprocessingState,
|
||||||
system: systemState,
|
system: systemState,
|
||||||
canvas: canvasState,
|
canvas: canvasState,
|
||||||
} = state;
|
} = state;
|
||||||
@ -47,7 +47,8 @@ const makeSocketIOEmitters = (
|
|||||||
const frontendToBackendParametersConfig: FrontendToBackendParametersConfig =
|
const frontendToBackendParametersConfig: FrontendToBackendParametersConfig =
|
||||||
{
|
{
|
||||||
generationMode,
|
generationMode,
|
||||||
optionsState,
|
generationState,
|
||||||
|
postprocessingState,
|
||||||
canvasState,
|
canvasState,
|
||||||
systemState,
|
systemState,
|
||||||
};
|
};
|
||||||
@ -90,8 +91,11 @@ const makeSocketIOEmitters = (
|
|||||||
},
|
},
|
||||||
emitRunESRGAN: (imageToProcess: InvokeAI.Image) => {
|
emitRunESRGAN: (imageToProcess: InvokeAI.Image) => {
|
||||||
dispatch(setIsProcessing(true));
|
dispatch(setIsProcessing(true));
|
||||||
const options: OptionsState = getState().options;
|
|
||||||
const { upscalingLevel, upscalingStrength } = options;
|
const {
|
||||||
|
postprocessing: { upscalingLevel, upscalingStrength },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
const esrganParameters = {
|
const esrganParameters = {
|
||||||
upscale: [upscalingLevel, upscalingStrength],
|
upscale: [upscalingLevel, upscalingStrength],
|
||||||
};
|
};
|
||||||
@ -111,8 +115,10 @@ const makeSocketIOEmitters = (
|
|||||||
},
|
},
|
||||||
emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
|
emitRunFacetool: (imageToProcess: InvokeAI.Image) => {
|
||||||
dispatch(setIsProcessing(true));
|
dispatch(setIsProcessing(true));
|
||||||
const options: OptionsState = getState().options;
|
|
||||||
const { facetoolType, facetoolStrength, codeformerFidelity } = options;
|
const {
|
||||||
|
postprocessing: { facetoolType, facetoolStrength, codeformerFidelity },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
const facetoolParameters: Record<string, unknown> = {
|
const facetoolParameters: Record<string, unknown> = {
|
||||||
facetool_strength: facetoolStrength,
|
facetool_strength: facetoolStrength,
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import { AnyAction, MiddlewareAPI, Dispatch } from '@reduxjs/toolkit';
|
import { AnyAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import dateFormat from 'dateformat';
|
import dateFormat from 'dateformat';
|
||||||
import i18n from 'i18n';
|
import i18n from 'i18n';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
import * as InvokeAI from 'app/invokeai';
|
import * as InvokeAI from 'app/invokeai';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addLogEntry,
|
addLogEntry,
|
||||||
|
addToast,
|
||||||
|
errorOccurred,
|
||||||
|
processingCanceled,
|
||||||
|
setCurrentStatus,
|
||||||
|
setFoundModels,
|
||||||
|
setIsCancelable,
|
||||||
setIsConnected,
|
setIsConnected,
|
||||||
setIsProcessing,
|
setIsProcessing,
|
||||||
setSystemStatus,
|
|
||||||
setCurrentStatus,
|
|
||||||
setSystemConfig,
|
|
||||||
processingCanceled,
|
|
||||||
errorOccurred,
|
|
||||||
setModelList,
|
setModelList,
|
||||||
setIsCancelable,
|
|
||||||
addToast,
|
|
||||||
setFoundModels,
|
|
||||||
setSearchFolder,
|
setSearchFolder,
|
||||||
|
setSystemConfig,
|
||||||
|
setSystemStatus,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -30,20 +30,20 @@ import {
|
|||||||
setIntermediateImage,
|
setIntermediateImage,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
|
|
||||||
|
import type { RootState } from 'app/store';
|
||||||
|
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
|
||||||
import {
|
import {
|
||||||
clearInitialImage,
|
clearInitialImage,
|
||||||
setInfillMethod,
|
setInfillMethod,
|
||||||
setInitialImage,
|
setInitialImage,
|
||||||
setMaskPath,
|
setMaskPath,
|
||||||
} from 'features/options/store/optionsSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
|
import { tabMap } from 'features/ui/store/tabMap';
|
||||||
import {
|
import {
|
||||||
requestImages,
|
requestImages,
|
||||||
requestNewImages,
|
requestNewImages,
|
||||||
requestSystemConfig,
|
requestSystemConfig,
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { addImageToStagingArea } from 'features/canvas/store/canvasSlice';
|
|
||||||
import { tabMap } from 'features/tabs/tabMap';
|
|
||||||
import type { RootState } from 'app/store';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an object containing listener callbacks for socketio events.
|
* Returns an object containing listener callbacks for socketio events.
|
||||||
@ -104,8 +104,9 @@ const makeSocketIOListeners = (
|
|||||||
*/
|
*/
|
||||||
onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
|
onGenerationResult: (data: InvokeAI.ImageResultResponse) => {
|
||||||
try {
|
try {
|
||||||
const state: RootState = getState();
|
const state = getState();
|
||||||
const { shouldLoopback, activeTab } = state.options;
|
const { activeTab } = state.ui;
|
||||||
|
const { shouldLoopback } = state.postprocessing;
|
||||||
const { boundingBox: _, generationMode, ...rest } = data;
|
const { boundingBox: _, generationMode, ...rest } = data;
|
||||||
|
|
||||||
const newImage = {
|
const newImage = {
|
||||||
@ -327,7 +328,9 @@ const makeSocketIOListeners = (
|
|||||||
dispatch(removeImage(data));
|
dispatch(removeImage(data));
|
||||||
|
|
||||||
// remove references to image in options
|
// remove references to image in options
|
||||||
const { initialImage, maskPath } = getState().options;
|
const {
|
||||||
|
generation: { initialImage, maskPath },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
initialImage === url ||
|
initialImage === url ||
|
||||||
|
@ -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;
|
||||||
|
@ -5,10 +5,13 @@ import storage from 'redux-persist/lib/storage'; // defaults to localStorage for
|
|||||||
|
|
||||||
import { getPersistConfig } from 'redux-deep-persist';
|
import { getPersistConfig } from 'redux-deep-persist';
|
||||||
|
|
||||||
import optionsReducer from 'features/options/store/optionsSlice';
|
|
||||||
import galleryReducer from 'features/gallery/store/gallerySlice';
|
|
||||||
import systemReducer from 'features/system/store/systemSlice';
|
|
||||||
import canvasReducer from 'features/canvas/store/canvasSlice';
|
import canvasReducer from 'features/canvas/store/canvasSlice';
|
||||||
|
import galleryReducer from 'features/gallery/store/gallerySlice';
|
||||||
|
import lightboxReducer from 'features/lightbox/store/lightboxSlice';
|
||||||
|
import generationReducer from 'features/parameters/store/generationSlice';
|
||||||
|
import postprocessingReducer from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import systemReducer from 'features/system/store/systemSlice';
|
||||||
|
import uiReducer from 'features/ui/store/uiSlice';
|
||||||
|
|
||||||
import { socketioMiddleware } from './socketio/middleware';
|
import { socketioMiddleware } from './socketio/middleware';
|
||||||
|
|
||||||
@ -58,10 +61,13 @@ const galleryBlacklist = [
|
|||||||
].map((blacklistItem) => `gallery.${blacklistItem}`);
|
].map((blacklistItem) => `gallery.${blacklistItem}`);
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
options: optionsReducer,
|
generation: generationReducer,
|
||||||
|
postprocessing: postprocessingReducer,
|
||||||
gallery: galleryReducer,
|
gallery: galleryReducer,
|
||||||
system: systemReducer,
|
system: systemReducer,
|
||||||
canvas: canvasReducer,
|
canvas: canvasReducer,
|
||||||
|
ui: uiReducer,
|
||||||
|
lightbox: lightboxReducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootPersistConfig = getPersistConfig({
|
const rootPersistConfig = getPersistConfig({
|
||||||
@ -89,8 +95,8 @@ export const store = configureStore({
|
|||||||
'canvas/setStageCoordinates',
|
'canvas/setStageCoordinates',
|
||||||
'canvas/setStageScale',
|
'canvas/setStageScale',
|
||||||
'canvas/setIsDrawing',
|
'canvas/setIsDrawing',
|
||||||
// 'canvas/setBoundingBoxCoordinates',
|
'canvas/setBoundingBoxCoordinates',
|
||||||
// 'canvas/setBoundingBoxDimensions',
|
'canvas/setBoundingBoxDimensions',
|
||||||
'canvas/setIsDrawing',
|
'canvas/setIsDrawing',
|
||||||
'canvas/addPointToCurrentLine',
|
'canvas/addPointToCurrentLine',
|
||||||
],
|
],
|
||||||
|
@ -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 = {
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
import {
|
import {
|
||||||
|
Box,
|
||||||
Popover,
|
Popover,
|
||||||
PopoverArrow,
|
PopoverArrow,
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
Box,
|
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
|
||||||
import { useAppSelector } from 'app/storeHooks';
|
|
||||||
import { RootState } from 'app/store';
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { ReactElement } from 'react';
|
|
||||||
import { Feature, useFeatureHelpInfo } from 'app/features';
|
import { Feature, useFeatureHelpInfo } from 'app/features';
|
||||||
|
import { useAppSelector } from 'app/storeHooks';
|
||||||
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
|
import { ReactElement } from 'react';
|
||||||
|
|
||||||
type GuideProps = {
|
type GuideProps = {
|
||||||
children: ReactElement;
|
children: ReactElement;
|
||||||
feature: Feature;
|
feature: Feature;
|
||||||
};
|
};
|
||||||
|
|
||||||
const systemSelector = createSelector(
|
const guidePopoverSelector = createSelector(
|
||||||
(state: RootState) => state.system,
|
systemSelector,
|
||||||
(system: SystemState) => system.shouldDisplayGuides
|
(system: SystemState) => system.shouldDisplayGuides
|
||||||
);
|
);
|
||||||
|
|
||||||
const GuidePopover = ({ children, feature }: GuideProps) => {
|
const GuidePopover = ({ children, feature }: GuideProps) => {
|
||||||
const shouldDisplayGuides = useAppSelector(systemSelector);
|
const shouldDisplayGuides = useAppSelector(guidePopoverSelector);
|
||||||
const { text } = useFeatureHelpInfo(feature);
|
const { text } = useFeatureHelpInfo(feature);
|
||||||
|
|
||||||
if (!shouldDisplayGuides) return null;
|
if (!shouldDisplayGuides) return null;
|
||||||
|
@ -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 & {
|
||||||
|
@ -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
|
||||||
|
@ -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 & {
|
||||||
|
@ -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
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import {
|
|
||||||
useCallback,
|
|
||||||
ReactNode,
|
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
KeyboardEvent,
|
|
||||||
} from 'react';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
|
||||||
import { FileRejection, useDropzone } from 'react-dropzone';
|
|
||||||
import { useToast } from '@chakra-ui/react';
|
import { useToast } from '@chakra-ui/react';
|
||||||
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
|
import { ImageUploaderTriggerContext } from 'app/contexts/ImageUploaderTriggerContext';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { tabDict } from 'features/tabs/components/InvokeTabs';
|
|
||||||
import ImageUploadOverlay from './ImageUploadOverlay';
|
|
||||||
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
|
|
||||||
import useImageUploader from 'common/hooks/useImageUploader';
|
import useImageUploader from 'common/hooks/useImageUploader';
|
||||||
|
import { uploadImage } from 'features/gallery/store/thunks/uploadImage';
|
||||||
|
import { tabDict } from 'features/ui/components/InvokeTabs';
|
||||||
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import {
|
||||||
|
KeyboardEvent,
|
||||||
|
ReactNode,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
import { FileRejection, useDropzone } from 'react-dropzone';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import ImageUploadOverlay from './ImageUploadOverlay';
|
||||||
|
|
||||||
type ImageUploaderProps = {
|
type ImageUploaderProps = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
@ -33,7 +33,7 @@ const ImageUploader = (props: ImageUploaderProps) => {
|
|||||||
(rejection: FileRejection) => {
|
(rejection: FileRejection) => {
|
||||||
setIsHandlingUpload(true);
|
setIsHandlingUpload(true);
|
||||||
const msg = rejection.errors.reduce(
|
const msg = rejection.errors.reduce(
|
||||||
(acc: string, cur: { message: string }) => acc + '\n' + cur.message,
|
(acc: string, cur: { message: string }) => `${acc}\n${cur.message}`,
|
||||||
''
|
''
|
||||||
);
|
);
|
||||||
toast({
|
toast({
|
||||||
|
@ -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;
|
||||||
|
@ -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 = () => {
|
||||||
|
@ -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() {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const PostProcessingWIP = () => {
|
export const PostProcessingWIP = () => {
|
||||||
|
@ -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() {
|
||||||
|
@ -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[];
|
||||||
|
@ -11,7 +11,6 @@ const useClickOutsideWatcher = () => {
|
|||||||
function handleClickOutside(e: MouseEvent) {
|
function handleClickOutside(e: MouseEvent) {
|
||||||
watchers.forEach(({ ref, enable, callback }) => {
|
watchers.forEach(({ ref, enable, callback }) => {
|
||||||
if (enable && ref.current && !ref.current.contains(e.target as Node)) {
|
if (enable && ref.current && !ref.current.contains(e.target as Node)) {
|
||||||
console.log('callback');
|
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
20
invokeai/frontend/src/common/util/getPromptAndNegative.ts
Normal file
20
invokeai/frontend/src/common/util/getPromptAndNegative.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import * as InvokeAI from 'app/invokeai';
|
||||||
|
import promptToString from './promptToString';
|
||||||
|
|
||||||
|
export function getPromptAndNegative(input_prompt: InvokeAI.Prompt) {
|
||||||
|
let prompt: string = promptToString(input_prompt);
|
||||||
|
let negativePrompt: string | null = null;
|
||||||
|
|
||||||
|
const negativePromptRegExp = new RegExp(/(?<=\[)[^\][]*(?=])/, 'gi');
|
||||||
|
const negativePromptMatches = [...prompt.matchAll(negativePromptRegExp)];
|
||||||
|
|
||||||
|
if (negativePromptMatches && negativePromptMatches.length > 0) {
|
||||||
|
negativePrompt = negativePromptMatches.join(', ');
|
||||||
|
prompt = prompt
|
||||||
|
.replaceAll(negativePromptRegExp, '')
|
||||||
|
.replaceAll('[]', '')
|
||||||
|
.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [prompt, negativePrompt];
|
||||||
|
}
|
@ -1,27 +1,29 @@
|
|||||||
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
||||||
import { OptionsState } from 'features/options/store/optionsSlice';
|
import { Dimensions } from 'features/canvas/store/canvasTypes';
|
||||||
|
import { GenerationState } from 'features/parameters/store/generationSlice';
|
||||||
import { SystemState } from 'features/system/store/systemSlice';
|
import { SystemState } from 'features/system/store/systemSlice';
|
||||||
import { Vector2d } from 'konva/lib/types';
|
import { Vector2d } from 'konva/lib/types';
|
||||||
import { Dimensions } from 'features/canvas/store/canvasTypes';
|
|
||||||
|
|
||||||
import { stringToSeedWeightsArray } from './seedWeightPairs';
|
|
||||||
import randomInt from './randomInt';
|
|
||||||
import { InvokeTabName } from 'features/tabs/tabMap';
|
|
||||||
import {
|
import {
|
||||||
CanvasState,
|
CanvasState,
|
||||||
isCanvasMaskLine,
|
isCanvasMaskLine,
|
||||||
} from 'features/canvas/store/canvasTypes';
|
} from 'features/canvas/store/canvasTypes';
|
||||||
import generateMask from 'features/canvas/util/generateMask';
|
import generateMask from 'features/canvas/util/generateMask';
|
||||||
import openBase64ImageInTab from './openBase64ImageInTab';
|
|
||||||
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
||||||
import type {
|
import type {
|
||||||
UpscalingLevel,
|
|
||||||
FacetoolType,
|
FacetoolType,
|
||||||
} from 'features/options/store/optionsSlice';
|
UpscalingLevel,
|
||||||
|
} from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { PostprocessingState } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
|
import openBase64ImageInTab from './openBase64ImageInTab';
|
||||||
|
import randomInt from './randomInt';
|
||||||
|
import { stringToSeedWeightsArray } from './seedWeightPairs';
|
||||||
|
|
||||||
export type FrontendToBackendParametersConfig = {
|
export type FrontendToBackendParametersConfig = {
|
||||||
generationMode: InvokeTabName;
|
generationMode: InvokeTabName;
|
||||||
optionsState: OptionsState;
|
generationState: GenerationState;
|
||||||
|
postprocessingState: PostprocessingState;
|
||||||
canvasState: CanvasState;
|
canvasState: CanvasState;
|
||||||
systemState: SystemState;
|
systemState: SystemState;
|
||||||
imageToProcessUrl?: string;
|
imageToProcessUrl?: string;
|
||||||
@ -91,21 +93,38 @@ export const frontendToBackendParameters = (
|
|||||||
): BackendParameters => {
|
): BackendParameters => {
|
||||||
const canvasBaseLayer = getCanvasBaseLayer();
|
const canvasBaseLayer = getCanvasBaseLayer();
|
||||||
|
|
||||||
const { generationMode, optionsState, canvasState, systemState } = config;
|
const {
|
||||||
|
generationMode,
|
||||||
|
generationState,
|
||||||
|
postprocessingState,
|
||||||
|
canvasState,
|
||||||
|
systemState,
|
||||||
|
} = config;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
cfgScale,
|
|
||||||
codeformerFidelity,
|
codeformerFidelity,
|
||||||
facetoolStrength,
|
facetoolStrength,
|
||||||
facetoolType,
|
facetoolType,
|
||||||
height,
|
|
||||||
hiresFix,
|
hiresFix,
|
||||||
|
hiresStrength,
|
||||||
|
shouldRunESRGAN,
|
||||||
|
shouldRunFacetool,
|
||||||
|
upscalingLevel,
|
||||||
|
upscalingStrength,
|
||||||
|
} = postprocessingState;
|
||||||
|
|
||||||
|
const {
|
||||||
|
cfgScale,
|
||||||
|
|
||||||
|
height,
|
||||||
|
|
||||||
img2imgStrength,
|
img2imgStrength,
|
||||||
infillMethod,
|
infillMethod,
|
||||||
initialImage,
|
initialImage,
|
||||||
iterations,
|
iterations,
|
||||||
perlin,
|
perlin,
|
||||||
prompt,
|
prompt,
|
||||||
|
negativePrompt,
|
||||||
sampler,
|
sampler,
|
||||||
seamBlur,
|
seamBlur,
|
||||||
seamless,
|
seamless,
|
||||||
@ -117,16 +136,14 @@ export const frontendToBackendParameters = (
|
|||||||
shouldFitToWidthHeight,
|
shouldFitToWidthHeight,
|
||||||
shouldGenerateVariations,
|
shouldGenerateVariations,
|
||||||
shouldRandomizeSeed,
|
shouldRandomizeSeed,
|
||||||
shouldRunESRGAN,
|
|
||||||
shouldRunFacetool,
|
|
||||||
steps,
|
steps,
|
||||||
threshold,
|
threshold,
|
||||||
tileSize,
|
tileSize,
|
||||||
upscalingLevel,
|
|
||||||
upscalingStrength,
|
|
||||||
variationAmount,
|
variationAmount,
|
||||||
width,
|
width,
|
||||||
} = optionsState;
|
} = generationState;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shouldDisplayInProgressType,
|
shouldDisplayInProgressType,
|
||||||
@ -155,6 +172,10 @@ export const frontendToBackendParameters = (
|
|||||||
let esrganParameters: false | BackendEsrGanParameters = false;
|
let esrganParameters: false | BackendEsrGanParameters = false;
|
||||||
let facetoolParameters: false | BackendFacetoolParameters = false;
|
let facetoolParameters: false | BackendFacetoolParameters = false;
|
||||||
|
|
||||||
|
if (negativePrompt !== '') {
|
||||||
|
generationParameters.prompt = `${prompt} [${negativePrompt}]`;
|
||||||
|
}
|
||||||
|
|
||||||
generationParameters.seed = shouldRandomizeSeed
|
generationParameters.seed = shouldRandomizeSeed
|
||||||
? randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX)
|
? randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX)
|
||||||
: seed;
|
: seed;
|
||||||
@ -164,6 +185,8 @@ export const frontendToBackendParameters = (
|
|||||||
generationParameters.seamless = seamless;
|
generationParameters.seamless = seamless;
|
||||||
generationParameters.hires_fix = hiresFix;
|
generationParameters.hires_fix = hiresFix;
|
||||||
|
|
||||||
|
if (hiresFix) generationParameters.strength = hiresStrength;
|
||||||
|
|
||||||
if (shouldRunESRGAN) {
|
if (shouldRunESRGAN) {
|
||||||
esrganParameters = {
|
esrganParameters = {
|
||||||
level: upscalingLevel,
|
level: upscalingLevel,
|
||||||
|
@ -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])]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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}
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { Spinner } from '@chakra-ui/react';
|
import { Spinner } from '@chakra-ui/react';
|
||||||
import { useLayoutEffect, useRef } from 'react';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
import {
|
||||||
|
canvasSelector,
|
||||||
|
initialCanvasImageSelector,
|
||||||
|
} from 'features/canvas/store/canvasSelectors';
|
||||||
import {
|
import {
|
||||||
resizeAndScaleCanvas,
|
resizeAndScaleCanvas,
|
||||||
resizeCanvas,
|
resizeCanvas,
|
||||||
setCanvasContainerDimensions,
|
setCanvasContainerDimensions,
|
||||||
setDoesCanvasNeedScaling,
|
setDoesCanvasNeedScaling,
|
||||||
} from 'features/canvas/store/canvasSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import {
|
import { useLayoutEffect, useRef } from 'react';
|
||||||
canvasSelector,
|
|
||||||
initialCanvasImageSelector,
|
|
||||||
} from 'features/canvas/store/canvasSelectors';
|
|
||||||
|
|
||||||
const canvasResizerSelector = createSelector(
|
const canvasResizerSelector = createSelector(
|
||||||
canvasSelector,
|
canvasSelector,
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
import { FaRedo } from 'react-icons/fa';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
import { activeTabNameSelector } from 'features/options/store/optionsSelectors';
|
|
||||||
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import { FaRedo } from 'react-icons/fa';
|
||||||
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { redo } from 'features/canvas/store/canvasSlice';
|
import { redo } from 'features/canvas/store/canvasSlice';
|
||||||
import { systemSelector } from 'features/system/store/systemSelectors';
|
import { systemSelector } from 'features/system/store/systemSelectors';
|
||||||
|
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const canvasRedoSelector = createSelector(
|
const canvasRedoSelector = createSelector(
|
||||||
@ -23,7 +24,7 @@ const canvasRedoSelector = createSelector(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
memoizeOptions: {
|
memoizeOptions: {
|
||||||
resultEqualityCheck: _.isEqual,
|
resultEqualityCheck: isEqual,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -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),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user