mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Compare commits
1 Commits
v3.6.0rc2
...
feat/diffu
Author | SHA1 | Date | |
---|---|---|---|
7487f96da2 |
@ -2,13 +2,10 @@
|
|||||||
## Any environment variables supported by InvokeAI can be specified here,
|
## Any environment variables supported by InvokeAI can be specified here,
|
||||||
## in addition to the examples below.
|
## in addition to the examples below.
|
||||||
|
|
||||||
# HOST_INVOKEAI_ROOT is the path on the docker host's filesystem where InvokeAI will store data.
|
# INVOKEAI_ROOT is the path to a path on the local filesystem where InvokeAI will store data.
|
||||||
# Outputs will also be stored here by default.
|
# Outputs will also be stored here by default.
|
||||||
# If relative, it will be relative to the docker directory in which the docker-compose.yml file is located
|
# This **must** be an absolute path.
|
||||||
#HOST_INVOKEAI_ROOT=../../invokeai-data
|
INVOKEAI_ROOT=
|
||||||
|
|
||||||
# INVOKEAI_ROOT is the path to the root of the InvokeAI repository within the container.
|
|
||||||
# INVOKEAI_ROOT=~/invokeai
|
|
||||||
|
|
||||||
# Get this value from your HuggingFace account settings page.
|
# Get this value from your HuggingFace account settings page.
|
||||||
# HUGGING_FACE_HUB_TOKEN=
|
# HUGGING_FACE_HUB_TOKEN=
|
||||||
|
@ -21,9 +21,7 @@ x-invokeai: &invokeai
|
|||||||
ports:
|
ports:
|
||||||
- "${INVOKEAI_PORT:-9090}:9090"
|
- "${INVOKEAI_PORT:-9090}:9090"
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- ${INVOKEAI_ROOT:-~/invokeai}:${INVOKEAI_ROOT:-/invokeai}
|
||||||
source: ${HOST_INVOKEAI_ROOT:-${INVOKEAI_ROOT:-~/invokeai}}
|
|
||||||
target: ${INVOKEAI_ROOT:-/invokeai}
|
|
||||||
- ${HF_HOME:-~/.cache/huggingface}:${HF_HOME:-/invokeai/.cache/huggingface}
|
- ${HF_HOME:-~/.cache/huggingface}:${HF_HOME:-/invokeai/.cache/huggingface}
|
||||||
# - ${INVOKEAI_MODELS_DIR:-${INVOKEAI_ROOT:-/invokeai/models}}
|
# - ${INVOKEAI_MODELS_DIR:-${INVOKEAI_ROOT:-/invokeai/models}}
|
||||||
# - ${INVOKEAI_MODELS_CONFIG_PATH:-${INVOKEAI_ROOT:-/invokeai/configs/models.yaml}}
|
# - ${INVOKEAI_MODELS_CONFIG_PATH:-${INVOKEAI_ROOT:-/invokeai/configs/models.yaml}}
|
||||||
|
@ -37,7 +37,6 @@ To use a community workflow, download the the `.json` node graph file and load i
|
|||||||
+ [Match Histogram](#match-histogram)
|
+ [Match Histogram](#match-histogram)
|
||||||
+ [Metadata-Linked](#metadata-linked-nodes)
|
+ [Metadata-Linked](#metadata-linked-nodes)
|
||||||
+ [Negative Image](#negative-image)
|
+ [Negative Image](#negative-image)
|
||||||
+ [Nightmare Promptgen](#nightmare-promptgen)
|
|
||||||
+ [Oobabooga](#oobabooga)
|
+ [Oobabooga](#oobabooga)
|
||||||
+ [Prompt Tools](#prompt-tools)
|
+ [Prompt Tools](#prompt-tools)
|
||||||
+ [Remote Image](#remote-image)
|
+ [Remote Image](#remote-image)
|
||||||
@ -347,13 +346,6 @@ Node Link: https://github.com/VeyDlin/negative-image-node
|
|||||||
View:
|
View:
|
||||||
</br><img src="https://raw.githubusercontent.com/VeyDlin/negative-image-node/master/.readme/node.png" width="500" />
|
</br><img src="https://raw.githubusercontent.com/VeyDlin/negative-image-node/master/.readme/node.png" width="500" />
|
||||||
|
|
||||||
--------------------------------
|
|
||||||
### Nightmare Promptgen
|
|
||||||
|
|
||||||
**Description:** Nightmare Prompt Generator - Uses a local text generation model to create unique imaginative (but usually nightmarish) prompts for InvokeAI. By default, it allows you to choose from some gpt-neo models I finetuned on over 2500 of my own InvokeAI prompts in Compel format, but you're able to add your own, as well. Offers support for replacing any troublesome words with a random choice from list you can also define.
|
|
||||||
|
|
||||||
**Node Link:** [https://github.com/gogurtenjoyer/nightmare-promptgen](https://github.com/gogurtenjoyer/nightmare-promptgen)
|
|
||||||
|
|
||||||
--------------------------------
|
--------------------------------
|
||||||
### Oobabooga
|
### Oobabooga
|
||||||
|
|
||||||
|
@ -23,11 +23,10 @@ class DynamicPromptsResponse(BaseModel):
|
|||||||
)
|
)
|
||||||
async def parse_dynamicprompts(
|
async def parse_dynamicprompts(
|
||||||
prompt: str = Body(description="The prompt to parse with dynamicprompts"),
|
prompt: str = Body(description="The prompt to parse with dynamicprompts"),
|
||||||
max_prompts: int = Body(ge=1, le=10000, default=1000, description="The max number of prompts to generate"),
|
max_prompts: int = Body(default=1000, description="The max number of prompts to generate"),
|
||||||
combinatorial: bool = Body(default=True, description="Whether to use the combinatorial generator"),
|
combinatorial: bool = Body(default=True, description="Whether to use the combinatorial generator"),
|
||||||
) -> DynamicPromptsResponse:
|
) -> DynamicPromptsResponse:
|
||||||
"""Creates a batch process"""
|
"""Creates a batch process"""
|
||||||
max_prompts = min(max_prompts, 10000)
|
|
||||||
generator: Union[RandomPromptGenerator, CombinatorialPromptGenerator]
|
generator: Union[RandomPromptGenerator, CombinatorialPromptGenerator]
|
||||||
try:
|
try:
|
||||||
error: Optional[str] = None
|
error: Optional[str] = None
|
||||||
|
@ -24,10 +24,9 @@ from controlnet_aux import (
|
|||||||
)
|
)
|
||||||
from controlnet_aux.util import HWC3, ade_palette
|
from controlnet_aux.util import HWC3, ade_palette
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
||||||
|
|
||||||
from invokeai.app.invocations.primitives import ImageField, ImageOutput
|
from invokeai.app.invocations.primitives import ImageField, ImageOutput
|
||||||
from invokeai.app.invocations.util import validate_begin_end_step, validate_weights
|
|
||||||
from invokeai.app.services.image_records.image_records_common import ImageCategory, ResourceOrigin
|
from invokeai.app.services.image_records.image_records_common import ImageCategory, ResourceOrigin
|
||||||
from invokeai.app.shared.fields import FieldDescriptions
|
from invokeai.app.shared.fields import FieldDescriptions
|
||||||
|
|
||||||
@ -76,16 +75,17 @@ class ControlField(BaseModel):
|
|||||||
resize_mode: CONTROLNET_RESIZE_VALUES = Field(default="just_resize", description="The resize mode to use")
|
resize_mode: CONTROLNET_RESIZE_VALUES = Field(default="just_resize", description="The resize mode to use")
|
||||||
|
|
||||||
@field_validator("control_weight")
|
@field_validator("control_weight")
|
||||||
@classmethod
|
|
||||||
def validate_control_weight(cls, v):
|
def validate_control_weight(cls, v):
|
||||||
validate_weights(v)
|
"""Validate that all control weights in the valid range"""
|
||||||
|
if isinstance(v, list):
|
||||||
|
for i in v:
|
||||||
|
if i < -1 or i > 2:
|
||||||
|
raise ValueError("Control weights must be within -1 to 2 range")
|
||||||
|
else:
|
||||||
|
if v < -1 or v > 2:
|
||||||
|
raise ValueError("Control weights must be within -1 to 2 range")
|
||||||
return v
|
return v
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def validate_begin_end_step_percent(self):
|
|
||||||
validate_begin_end_step(self.begin_step_percent, self.end_step_percent)
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
@invocation_output("control_output")
|
@invocation_output("control_output")
|
||||||
class ControlOutput(BaseInvocationOutput):
|
class ControlOutput(BaseInvocationOutput):
|
||||||
@ -95,17 +95,17 @@ class ControlOutput(BaseInvocationOutput):
|
|||||||
control: ControlField = OutputField(description=FieldDescriptions.control)
|
control: ControlField = OutputField(description=FieldDescriptions.control)
|
||||||
|
|
||||||
|
|
||||||
@invocation("controlnet", title="ControlNet", tags=["controlnet"], category="controlnet", version="1.1.1")
|
@invocation("controlnet", title="ControlNet", tags=["controlnet"], category="controlnet", version="1.1.0")
|
||||||
class ControlNetInvocation(BaseInvocation):
|
class ControlNetInvocation(BaseInvocation):
|
||||||
"""Collects ControlNet info to pass to other nodes"""
|
"""Collects ControlNet info to pass to other nodes"""
|
||||||
|
|
||||||
image: ImageField = InputField(description="The control image")
|
image: ImageField = InputField(description="The control image")
|
||||||
control_model: ControlNetModelField = InputField(description=FieldDescriptions.controlnet_model, input=Input.Direct)
|
control_model: ControlNetModelField = InputField(description=FieldDescriptions.controlnet_model, input=Input.Direct)
|
||||||
control_weight: Union[float, List[float]] = InputField(
|
control_weight: Union[float, List[float]] = InputField(
|
||||||
default=1.0, ge=-1, le=2, description="The weight given to the ControlNet"
|
default=1.0, description="The weight given to the ControlNet"
|
||||||
)
|
)
|
||||||
begin_step_percent: float = InputField(
|
begin_step_percent: float = InputField(
|
||||||
default=0, ge=0, le=1, description="When the ControlNet is first applied (% of total steps)"
|
default=0, ge=-1, le=2, description="When the ControlNet is first applied (% of total steps)"
|
||||||
)
|
)
|
||||||
end_step_percent: float = InputField(
|
end_step_percent: float = InputField(
|
||||||
default=1, ge=0, le=1, description="When the ControlNet is last applied (% of total steps)"
|
default=1, ge=0, le=1, description="When the ControlNet is last applied (% of total steps)"
|
||||||
@ -113,17 +113,6 @@ class ControlNetInvocation(BaseInvocation):
|
|||||||
control_mode: CONTROLNET_MODE_VALUES = InputField(default="balanced", description="The control mode used")
|
control_mode: CONTROLNET_MODE_VALUES = InputField(default="balanced", description="The control mode used")
|
||||||
resize_mode: CONTROLNET_RESIZE_VALUES = InputField(default="just_resize", description="The resize mode used")
|
resize_mode: CONTROLNET_RESIZE_VALUES = InputField(default="just_resize", description="The resize mode used")
|
||||||
|
|
||||||
@field_validator("control_weight")
|
|
||||||
@classmethod
|
|
||||||
def validate_control_weight(cls, v):
|
|
||||||
validate_weights(v)
|
|
||||||
return v
|
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def validate_begin_end_step_percent(self) -> "ControlNetInvocation":
|
|
||||||
validate_begin_end_step(self.begin_step_percent, self.end_step_percent)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def invoke(self, context: InvocationContext) -> ControlOutput:
|
def invoke(self, context: InvocationContext) -> ControlOutput:
|
||||||
return ControlOutput(
|
return ControlOutput(
|
||||||
control=ControlField(
|
control=ControlField(
|
||||||
|
@ -2,7 +2,7 @@ import os
|
|||||||
from builtins import float
|
from builtins import float
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
from invokeai.app.invocations.baseinvocation import (
|
from invokeai.app.invocations.baseinvocation import (
|
||||||
BaseInvocation,
|
BaseInvocation,
|
||||||
@ -15,7 +15,6 @@ from invokeai.app.invocations.baseinvocation import (
|
|||||||
invocation_output,
|
invocation_output,
|
||||||
)
|
)
|
||||||
from invokeai.app.invocations.primitives import ImageField
|
from invokeai.app.invocations.primitives import ImageField
|
||||||
from invokeai.app.invocations.util import validate_begin_end_step, validate_weights
|
|
||||||
from invokeai.app.shared.fields import FieldDescriptions
|
from invokeai.app.shared.fields import FieldDescriptions
|
||||||
from invokeai.backend.model_management.models.base import BaseModelType, ModelType
|
from invokeai.backend.model_management.models.base import BaseModelType, ModelType
|
||||||
from invokeai.backend.model_management.models.ip_adapter import get_ip_adapter_image_encoder_model_id
|
from invokeai.backend.model_management.models.ip_adapter import get_ip_adapter_image_encoder_model_id
|
||||||
@ -40,6 +39,7 @@ class IPAdapterField(BaseModel):
|
|||||||
ip_adapter_model: IPAdapterModelField = Field(description="The IP-Adapter model to use.")
|
ip_adapter_model: IPAdapterModelField = Field(description="The IP-Adapter model to use.")
|
||||||
image_encoder_model: CLIPVisionModelField = Field(description="The name of the CLIP image encoder model.")
|
image_encoder_model: CLIPVisionModelField = Field(description="The name of the CLIP image encoder model.")
|
||||||
weight: Union[float, List[float]] = Field(default=1, description="The weight given to the ControlNet")
|
weight: Union[float, List[float]] = Field(default=1, description="The weight given to the ControlNet")
|
||||||
|
# weight: float = Field(default=1.0, ge=0, description="The weight of the IP-Adapter.")
|
||||||
begin_step_percent: float = Field(
|
begin_step_percent: float = Field(
|
||||||
default=0, ge=0, le=1, description="When the IP-Adapter is first applied (% of total steps)"
|
default=0, ge=0, le=1, description="When the IP-Adapter is first applied (% of total steps)"
|
||||||
)
|
)
|
||||||
@ -47,17 +47,6 @@ class IPAdapterField(BaseModel):
|
|||||||
default=1, ge=0, le=1, description="When the IP-Adapter is last applied (% of total steps)"
|
default=1, ge=0, le=1, description="When the IP-Adapter is last applied (% of total steps)"
|
||||||
)
|
)
|
||||||
|
|
||||||
@field_validator("weight")
|
|
||||||
@classmethod
|
|
||||||
def validate_ip_adapter_weight(cls, v):
|
|
||||||
validate_weights(v)
|
|
||||||
return v
|
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def validate_begin_end_step_percent(self):
|
|
||||||
validate_begin_end_step(self.begin_step_percent, self.end_step_percent)
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
@invocation_output("ip_adapter_output")
|
@invocation_output("ip_adapter_output")
|
||||||
class IPAdapterOutput(BaseInvocationOutput):
|
class IPAdapterOutput(BaseInvocationOutput):
|
||||||
@ -65,7 +54,7 @@ class IPAdapterOutput(BaseInvocationOutput):
|
|||||||
ip_adapter: IPAdapterField = OutputField(description=FieldDescriptions.ip_adapter, title="IP-Adapter")
|
ip_adapter: IPAdapterField = OutputField(description=FieldDescriptions.ip_adapter, title="IP-Adapter")
|
||||||
|
|
||||||
|
|
||||||
@invocation("ip_adapter", title="IP-Adapter", tags=["ip_adapter", "control"], category="ip_adapter", version="1.1.1")
|
@invocation("ip_adapter", title="IP-Adapter", tags=["ip_adapter", "control"], category="ip_adapter", version="1.1.0")
|
||||||
class IPAdapterInvocation(BaseInvocation):
|
class IPAdapterInvocation(BaseInvocation):
|
||||||
"""Collects IP-Adapter info to pass to other nodes."""
|
"""Collects IP-Adapter info to pass to other nodes."""
|
||||||
|
|
||||||
@ -75,27 +64,18 @@ class IPAdapterInvocation(BaseInvocation):
|
|||||||
description="The IP-Adapter model.", title="IP-Adapter Model", input=Input.Direct, ui_order=-1
|
description="The IP-Adapter model.", title="IP-Adapter Model", input=Input.Direct, ui_order=-1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# weight: float = InputField(default=1.0, description="The weight of the IP-Adapter.", ui_type=UIType.Float)
|
||||||
weight: Union[float, List[float]] = InputField(
|
weight: Union[float, List[float]] = InputField(
|
||||||
default=1, description="The weight given to the IP-Adapter", title="Weight"
|
default=1, ge=-1, description="The weight given to the IP-Adapter", title="Weight"
|
||||||
)
|
)
|
||||||
|
|
||||||
begin_step_percent: float = InputField(
|
begin_step_percent: float = InputField(
|
||||||
default=0, ge=0, le=1, description="When the IP-Adapter is first applied (% of total steps)"
|
default=0, ge=-1, le=2, description="When the IP-Adapter is first applied (% of total steps)"
|
||||||
)
|
)
|
||||||
end_step_percent: float = InputField(
|
end_step_percent: float = InputField(
|
||||||
default=1, ge=0, le=1, description="When the IP-Adapter is last applied (% of total steps)"
|
default=1, ge=0, le=1, description="When the IP-Adapter is last applied (% of total steps)"
|
||||||
)
|
)
|
||||||
|
|
||||||
@field_validator("weight")
|
|
||||||
@classmethod
|
|
||||||
def validate_ip_adapter_weight(cls, v):
|
|
||||||
validate_weights(v)
|
|
||||||
return v
|
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def validate_begin_end_step_percent(self):
|
|
||||||
validate_begin_end_step(self.begin_step_percent, self.end_step_percent)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def invoke(self, context: InvocationContext) -> IPAdapterOutput:
|
def invoke(self, context: InvocationContext) -> IPAdapterOutput:
|
||||||
# Lookup the CLIP Vision encoder that is intended to be used with the IP-Adapter model.
|
# Lookup the CLIP Vision encoder that is intended to be used with the IP-Adapter model.
|
||||||
ip_adapter_info = context.services.model_manager.model_info(
|
ip_adapter_info = context.services.model_manager.model_info(
|
||||||
|
@ -220,7 +220,7 @@ def get_scheduler(
|
|||||||
title="Denoise Latents",
|
title="Denoise Latents",
|
||||||
tags=["latents", "denoise", "txt2img", "t2i", "t2l", "img2img", "i2i", "l2l"],
|
tags=["latents", "denoise", "txt2img", "t2i", "t2l", "img2img", "i2i", "l2l"],
|
||||||
category="latents",
|
category="latents",
|
||||||
version="1.5.1",
|
version="1.5.0",
|
||||||
)
|
)
|
||||||
class DenoiseLatentsInvocation(BaseInvocation):
|
class DenoiseLatentsInvocation(BaseInvocation):
|
||||||
"""Denoises noisy latents to decodable images"""
|
"""Denoises noisy latents to decodable images"""
|
||||||
@ -279,7 +279,7 @@ class DenoiseLatentsInvocation(BaseInvocation):
|
|||||||
ui_order=7,
|
ui_order=7,
|
||||||
)
|
)
|
||||||
cfg_rescale_multiplier: float = InputField(
|
cfg_rescale_multiplier: float = InputField(
|
||||||
title="CFG Rescale Multiplier", default=0, ge=0, lt=1, description=FieldDescriptions.cfg_rescale_multiplier
|
default=0, ge=0, lt=1, description=FieldDescriptions.cfg_rescale_multiplier
|
||||||
)
|
)
|
||||||
latents: Optional[LatentsField] = InputField(
|
latents: Optional[LatentsField] = InputField(
|
||||||
default=None,
|
default=None,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
from invokeai.app.invocations.baseinvocation import (
|
from invokeai.app.invocations.baseinvocation import (
|
||||||
BaseInvocation,
|
BaseInvocation,
|
||||||
@ -14,7 +14,6 @@ from invokeai.app.invocations.baseinvocation import (
|
|||||||
)
|
)
|
||||||
from invokeai.app.invocations.controlnet_image_processors import CONTROLNET_RESIZE_VALUES
|
from invokeai.app.invocations.controlnet_image_processors import CONTROLNET_RESIZE_VALUES
|
||||||
from invokeai.app.invocations.primitives import ImageField
|
from invokeai.app.invocations.primitives import ImageField
|
||||||
from invokeai.app.invocations.util import validate_begin_end_step, validate_weights
|
|
||||||
from invokeai.app.shared.fields import FieldDescriptions
|
from invokeai.app.shared.fields import FieldDescriptions
|
||||||
from invokeai.backend.model_management.models.base import BaseModelType
|
from invokeai.backend.model_management.models.base import BaseModelType
|
||||||
|
|
||||||
@ -38,17 +37,6 @@ class T2IAdapterField(BaseModel):
|
|||||||
)
|
)
|
||||||
resize_mode: CONTROLNET_RESIZE_VALUES = Field(default="just_resize", description="The resize mode to use")
|
resize_mode: CONTROLNET_RESIZE_VALUES = Field(default="just_resize", description="The resize mode to use")
|
||||||
|
|
||||||
@field_validator("weight")
|
|
||||||
@classmethod
|
|
||||||
def validate_ip_adapter_weight(cls, v):
|
|
||||||
validate_weights(v)
|
|
||||||
return v
|
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def validate_begin_end_step_percent(self):
|
|
||||||
validate_begin_end_step(self.begin_step_percent, self.end_step_percent)
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
@invocation_output("t2i_adapter_output")
|
@invocation_output("t2i_adapter_output")
|
||||||
class T2IAdapterOutput(BaseInvocationOutput):
|
class T2IAdapterOutput(BaseInvocationOutput):
|
||||||
@ -56,7 +44,7 @@ class T2IAdapterOutput(BaseInvocationOutput):
|
|||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
"t2i_adapter", title="T2I-Adapter", tags=["t2i_adapter", "control"], category="t2i_adapter", version="1.0.1"
|
"t2i_adapter", title="T2I-Adapter", tags=["t2i_adapter", "control"], category="t2i_adapter", version="1.0.0"
|
||||||
)
|
)
|
||||||
class T2IAdapterInvocation(BaseInvocation):
|
class T2IAdapterInvocation(BaseInvocation):
|
||||||
"""Collects T2I-Adapter info to pass to other nodes."""
|
"""Collects T2I-Adapter info to pass to other nodes."""
|
||||||
@ -73,7 +61,7 @@ class T2IAdapterInvocation(BaseInvocation):
|
|||||||
default=1, ge=0, description="The weight given to the T2I-Adapter", title="Weight"
|
default=1, ge=0, description="The weight given to the T2I-Adapter", title="Weight"
|
||||||
)
|
)
|
||||||
begin_step_percent: float = InputField(
|
begin_step_percent: float = InputField(
|
||||||
default=0, ge=0, le=1, description="When the T2I-Adapter is first applied (% of total steps)"
|
default=0, ge=-1, le=2, description="When the T2I-Adapter is first applied (% of total steps)"
|
||||||
)
|
)
|
||||||
end_step_percent: float = InputField(
|
end_step_percent: float = InputField(
|
||||||
default=1, ge=0, le=1, description="When the T2I-Adapter is last applied (% of total steps)"
|
default=1, ge=0, le=1, description="When the T2I-Adapter is last applied (% of total steps)"
|
||||||
@ -83,17 +71,6 @@ class T2IAdapterInvocation(BaseInvocation):
|
|||||||
description="The resize mode applied to the T2I-Adapter input image so that it matches the target output size.",
|
description="The resize mode applied to the T2I-Adapter input image so that it matches the target output size.",
|
||||||
)
|
)
|
||||||
|
|
||||||
@field_validator("weight")
|
|
||||||
@classmethod
|
|
||||||
def validate_ip_adapter_weight(cls, v):
|
|
||||||
validate_weights(v)
|
|
||||||
return v
|
|
||||||
|
|
||||||
@model_validator(mode="after")
|
|
||||||
def validate_begin_end_step_percent(self):
|
|
||||||
validate_begin_end_step(self.begin_step_percent, self.end_step_percent)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def invoke(self, context: InvocationContext) -> T2IAdapterOutput:
|
def invoke(self, context: InvocationContext) -> T2IAdapterOutput:
|
||||||
return T2IAdapterOutput(
|
return T2IAdapterOutput(
|
||||||
t2i_adapter=T2IAdapterField(
|
t2i_adapter=T2IAdapterField(
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
from typing import Union
|
|
||||||
|
|
||||||
|
|
||||||
def validate_weights(weights: Union[float, list[float]]) -> None:
|
|
||||||
"""Validate that all control weights in the valid range"""
|
|
||||||
to_validate = weights if isinstance(weights, list) else [weights]
|
|
||||||
if any(i < -1 or i > 2 for i in to_validate):
|
|
||||||
raise ValueError("Control weights must be within -1 to 2 range")
|
|
||||||
|
|
||||||
|
|
||||||
def validate_begin_end_step(begin_step_percent: float, end_step_percent: float) -> None:
|
|
||||||
"""Validate that begin_step_percent is less than end_step_percent"""
|
|
||||||
if begin_step_percent >= end_step_percent:
|
|
||||||
raise ValueError("Begin step percent must be less than or equal to end step percent")
|
|
File diff suppressed because it is too large
Load Diff
@ -68,9 +68,12 @@ def welcome(latest_release: str, latest_prerelease: str):
|
|||||||
yield ""
|
yield ""
|
||||||
yield "This script will update InvokeAI to the latest release, or to the development version of your choice."
|
yield "This script will update InvokeAI to the latest release, or to the development version of your choice."
|
||||||
yield ""
|
yield ""
|
||||||
|
yield "When updating to an arbitrary tag or branch, be aware that the front end may be mismatched to the backend,"
|
||||||
|
yield "making the web frontend unusable. Please downgrade to the latest release if this happens."
|
||||||
|
yield ""
|
||||||
yield "[bold yellow]Options:"
|
yield "[bold yellow]Options:"
|
||||||
yield f"""[1] Update to the latest [bold]official release[/bold] ([italic]{latest_release}[/italic])
|
yield f"""[1] Update to the latest [bold]official release[/bold] ([italic]{latest_release}[/italic])
|
||||||
[2] Update to the latest [bold]pre-release[/bold] (may be buggy, database backups are recommended before installation; caveat emptor!) ([italic]{latest_prerelease}[/italic])
|
[2] Update to the latest [bold]pre-release[/bold] (may be buggy; caveat emptor!) ([italic]{latest_prerelease}[/italic])
|
||||||
[3] Manually enter the [bold]version[/bold] you wish to update to"""
|
[3] Manually enter the [bold]version[/bold] you wish to update to"""
|
||||||
|
|
||||||
console.rule()
|
console.rule()
|
||||||
|
@ -7,4 +7,4 @@ stats.html
|
|||||||
index.html
|
index.html
|
||||||
.yarn/
|
.yarn/
|
||||||
*.scss
|
*.scss
|
||||||
src/services/api/schema.ts
|
src/services/api/schema.d.ts
|
||||||
|
@ -28,16 +28,12 @@ module.exports = {
|
|||||||
'i18next',
|
'i18next',
|
||||||
'path',
|
'path',
|
||||||
'unused-imports',
|
'unused-imports',
|
||||||
'simple-import-sort',
|
|
||||||
'eslint-plugin-import',
|
|
||||||
// These rules are too strict for normal usage, but are useful for optimizing rerenders
|
|
||||||
// '@arthurgeron/react-usememo',
|
|
||||||
],
|
],
|
||||||
root: true,
|
root: true,
|
||||||
rules: {
|
rules: {
|
||||||
'path/no-relative-imports': ['error', { maxDepth: 0 }],
|
'path/no-relative-imports': ['error', { maxDepth: 0 }],
|
||||||
curly: 'error',
|
curly: 'error',
|
||||||
'i18next/no-literal-string': 'warn',
|
'i18next/no-literal-string': 2,
|
||||||
'react/jsx-no-bind': ['error', { allowBind: true }],
|
'react/jsx-no-bind': ['error', { allowBind: true }],
|
||||||
'react/jsx-curly-brace-presence': [
|
'react/jsx-curly-brace-presence': [
|
||||||
'error',
|
'error',
|
||||||
@ -47,7 +43,6 @@ module.exports = {
|
|||||||
'no-var': 'error',
|
'no-var': 'error',
|
||||||
'brace-style': 'error',
|
'brace-style': 'error',
|
||||||
'prefer-template': 'error',
|
'prefer-template': 'error',
|
||||||
'import/no-duplicates': 'error',
|
|
||||||
radix: 'error',
|
radix: 'error',
|
||||||
'space-before-blocks': 'error',
|
'space-before-blocks': 'error',
|
||||||
'import/prefer-default-export': 'off',
|
'import/prefer-default-export': 'off',
|
||||||
@ -62,18 +57,6 @@ module.exports = {
|
|||||||
argsIgnorePattern: '^_',
|
argsIgnorePattern: '^_',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// These rules are too strict for normal usage, but are useful for optimizing rerenders
|
|
||||||
// '@arthurgeron/react-usememo/require-usememo': [
|
|
||||||
// 'warn',
|
|
||||||
// {
|
|
||||||
// strict: false,
|
|
||||||
// checkHookReturnObject: false,
|
|
||||||
// fix: { addImports: true },
|
|
||||||
// checkHookCalls: false,
|
|
||||||
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// '@arthurgeron/react-usememo/require-memo': 'warn',
|
|
||||||
'@typescript-eslint/ban-ts-comment': 'warn',
|
'@typescript-eslint/ban-ts-comment': 'warn',
|
||||||
'@typescript-eslint/no-explicit-any': 'warn',
|
'@typescript-eslint/no-explicit-any': 'warn',
|
||||||
'@typescript-eslint/no-empty-interface': [
|
'@typescript-eslint/no-empty-interface': [
|
||||||
@ -82,26 +65,7 @@ module.exports = {
|
|||||||
allowSingleExtends: true,
|
allowSingleExtends: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'@typescript-eslint/consistent-type-imports': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
prefer: 'type-imports',
|
|
||||||
fixStyle: 'separate-type-imports',
|
|
||||||
disallowTypeAnnotations: true,
|
|
||||||
},
|
},
|
||||||
],
|
|
||||||
'@typescript-eslint/no-import-type-side-effects': 'error',
|
|
||||||
'simple-import-sort/imports': 'error',
|
|
||||||
'simple-import-sort/exports': 'error',
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['*.stories.tsx'],
|
|
||||||
rules: {
|
|
||||||
'i18next/no-literal-string': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
settings: {
|
settings: {
|
||||||
react: {
|
react: {
|
||||||
version: 'detect',
|
version: 'detect',
|
||||||
|
@ -9,8 +9,7 @@ index.html
|
|||||||
.yarn/
|
.yarn/
|
||||||
.yalc/
|
.yalc/
|
||||||
*.scss
|
*.scss
|
||||||
src/services/api/schema.ts
|
src/services/api/schema.d.ts
|
||||||
static/
|
static/
|
||||||
src/theme/css/overlayscrollbars.css
|
src/theme/css/overlayscrollbars.css
|
||||||
src/theme_/css/overlayscrollbars.css
|
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { PropsWithChildren, memo, useEffect } from 'react';
|
|
||||||
import { modelChanged } from '../src/features/parameters/store/generationSlice';
|
|
||||||
import { useAppDispatch } from '../src/app/store/storeHooks';
|
|
||||||
import { useGlobalModifiersInit } from '../src/common/hooks/useGlobalModifiers';
|
|
||||||
/**
|
|
||||||
* Initializes some state for storybook. Must be in a different component
|
|
||||||
* so that it is run inside the redux context.
|
|
||||||
*/
|
|
||||||
export const ReduxInit = memo((props: PropsWithChildren) => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
useGlobalModifiersInit();
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(
|
|
||||||
modelChanged({
|
|
||||||
model_name: 'test_model',
|
|
||||||
base_model: 'sd-1',
|
|
||||||
model_type: 'main',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return props.children;
|
|
||||||
});
|
|
||||||
|
|
||||||
ReduxInit.displayName = 'ReduxInit';
|
|
@ -6,7 +6,6 @@ const config: StorybookConfig = {
|
|||||||
'@storybook/addon-links',
|
'@storybook/addon-links',
|
||||||
'@storybook/addon-essentials',
|
'@storybook/addon-essentials',
|
||||||
'@storybook/addon-interactions',
|
'@storybook/addon-interactions',
|
||||||
'@storybook/addon-storysource',
|
|
||||||
],
|
],
|
||||||
framework: {
|
framework: {
|
||||||
name: '@storybook/react-vite',
|
name: '@storybook/react-vite',
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
import { Preview } from '@storybook/react';
|
import { Preview } from '@storybook/react';
|
||||||
import { themes } from '@storybook/theming';
|
import { themes } from '@storybook/theming';
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
|
import React from 'react';
|
||||||
import { initReactI18next } from 'react-i18next';
|
import { initReactI18next } from 'react-i18next';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
import GlobalHotkeys from '../src/app/components/GlobalHotkeys';
|
||||||
import ThemeLocaleProvider from '../src/app/components/ThemeLocaleProvider';
|
import ThemeLocaleProvider from '../src/app/components/ThemeLocaleProvider';
|
||||||
import { $baseUrl } from '../src/app/store/nanostores/baseUrl';
|
|
||||||
import { createStore } from '../src/app/store/store';
|
import { createStore } from '../src/app/store/store';
|
||||||
import { Container } from '@chakra-ui/react';
|
|
||||||
// TODO: Disabled for IDE performance issues with our translation JSON
|
// TODO: Disabled for IDE performance issues with our translation JSON
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import translationEN from '../public/locales/en.json';
|
import translationEN from '../public/locales/en.json';
|
||||||
import { ReduxInit } from './ReduxInit';
|
|
||||||
|
|
||||||
i18n.use(initReactI18next).init({
|
i18n.use(initReactI18next).init({
|
||||||
lng: 'en',
|
lng: 'en',
|
||||||
@ -26,21 +25,17 @@ i18n.use(initReactI18next).init({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const store = createStore(undefined, false);
|
const store = createStore(undefined, false);
|
||||||
$baseUrl.set('http://localhost:9090');
|
|
||||||
|
|
||||||
const preview: Preview = {
|
const preview: Preview = {
|
||||||
decorators: [
|
decorators: [
|
||||||
(Story) => {
|
(Story) => (
|
||||||
return (
|
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ThemeLocaleProvider>
|
<ThemeLocaleProvider>
|
||||||
<ReduxInit>
|
<GlobalHotkeys />
|
||||||
<Story />
|
<Story />
|
||||||
</ReduxInit>
|
|
||||||
</ThemeLocaleProvider>
|
</ThemeLocaleProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
),
|
||||||
},
|
|
||||||
],
|
],
|
||||||
parameters: {
|
parameters: {
|
||||||
docs: {
|
docs: {
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"entry": ["src/main.tsx"],
|
|
||||||
"extensions": [".ts", ".tsx"],
|
|
||||||
"ignorePatterns": [
|
|
||||||
"**/node_modules/**",
|
|
||||||
"dist/**",
|
|
||||||
"public/**",
|
|
||||||
"**/*.stories.tsx",
|
|
||||||
"config/**"
|
|
||||||
],
|
|
||||||
"ignoreUnresolved": [],
|
|
||||||
"ignoreUnimported": ["src/i18.d.ts", "vite.config.ts", "src/vite-env.d.ts"],
|
|
||||||
"respectGitignore": true,
|
|
||||||
"ignoreUnused": []
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import react from '@vitejs/plugin-react-swc';
|
import react from '@vitejs/plugin-react-swc';
|
||||||
import { visualizer } from 'rollup-plugin-visualizer';
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
import type { PluginOption, UserConfig } from 'vite';
|
import { PluginOption, UserConfig } from 'vite';
|
||||||
import eslint from 'vite-plugin-eslint';
|
import eslint from 'vite-plugin-eslint';
|
||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
import type { UserConfig } from 'vite';
|
import { UserConfig } from 'vite';
|
||||||
|
import { commonPlugins } from './common';
|
||||||
import { commonPlugins } from './common.mjs';
|
|
||||||
|
|
||||||
export const appConfig: UserConfig = {
|
export const appConfig: UserConfig = {
|
||||||
base: './',
|
base: './',
|
@ -1,9 +1,8 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import type { UserConfig } from 'vite';
|
import { UserConfig } from 'vite';
|
||||||
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
|
||||||
import dts from 'vite-plugin-dts';
|
import dts from 'vite-plugin-dts';
|
||||||
|
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
||||||
import { commonPlugins } from './common.mjs';
|
import { commonPlugins } from './common';
|
||||||
|
|
||||||
export const packageConfig: UserConfig = {
|
export const packageConfig: UserConfig = {
|
||||||
base: './',
|
base: './',
|
@ -31,17 +31,13 @@
|
|||||||
"lint": "concurrently -g -n eslint,prettier,tsc,madge -c cyan,green,magenta,yellow \"pnpm run lint:eslint\" \"pnpm run lint:prettier\" \"pnpm run lint:tsc\" \"pnpm run lint:madge\"",
|
"lint": "concurrently -g -n eslint,prettier,tsc,madge -c cyan,green,magenta,yellow \"pnpm run lint:eslint\" \"pnpm run lint:prettier\" \"pnpm run lint:tsc\" \"pnpm run lint:madge\"",
|
||||||
"fix": "eslint --fix . && prettier --log-level warn --write .",
|
"fix": "eslint --fix . && prettier --log-level warn --write .",
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
"postinstall": "pnpm run theme",
|
"postinstall": "patch-package && pnpm run theme",
|
||||||
"theme": "chakra-cli tokens src/theme/theme.ts",
|
"theme": "chakra-cli tokens src/theme/theme.ts",
|
||||||
"theme:watch": "chakra-cli tokens src/theme/theme.ts --watch",
|
"theme:watch": "chakra-cli tokens src/theme/theme.ts --watch",
|
||||||
"storybook": "storybook dev -p 6006",
|
"storybook": "storybook dev -p 6006",
|
||||||
"build-storybook": "storybook build",
|
"build-storybook": "storybook build"
|
||||||
"unimported": "npx unimported"
|
|
||||||
},
|
},
|
||||||
"madge": {
|
"madge": {
|
||||||
"excludeRegExp": [
|
|
||||||
"^index.ts$"
|
|
||||||
],
|
|
||||||
"detectiveOptions": {
|
"detectiveOptions": {
|
||||||
"ts": {
|
"ts": {
|
||||||
"skipTypeImports": true
|
"skipTypeImports": true
|
||||||
@ -57,56 +53,56 @@
|
|||||||
"@chakra-ui/layout": "^2.3.1",
|
"@chakra-ui/layout": "^2.3.1",
|
||||||
"@chakra-ui/portal": "^2.1.0",
|
"@chakra-ui/portal": "^2.1.0",
|
||||||
"@chakra-ui/react": "^2.8.2",
|
"@chakra-ui/react": "^2.8.2",
|
||||||
"@chakra-ui/react-use-size": "^2.1.0",
|
|
||||||
"@chakra-ui/styled-system": "^2.9.2",
|
"@chakra-ui/styled-system": "^2.9.2",
|
||||||
"@chakra-ui/theme-tools": "^2.1.2",
|
"@chakra-ui/theme-tools": "^2.1.2",
|
||||||
"@dagrejs/graphlib": "^2.1.13",
|
"@dagrejs/graphlib": "^2.1.13",
|
||||||
"@dnd-kit/core": "^6.1.0",
|
"@dnd-kit/core": "^6.1.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@emotion/react": "^11.11.3",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@fontsource-variable/inter": "^5.0.16",
|
"@fontsource-variable/inter": "^5.0.16",
|
||||||
"@mantine/form": "6.0.21",
|
"@mantine/core": "^6.0.19",
|
||||||
|
"@mantine/form": "^6.0.19",
|
||||||
|
"@mantine/hooks": "^6.0.19",
|
||||||
"@nanostores/react": "^0.7.1",
|
"@nanostores/react": "^0.7.1",
|
||||||
"@reduxjs/toolkit": "^2.0.1",
|
"@reduxjs/toolkit": "^2.0.1",
|
||||||
"@roarr/browser-log-writer": "^1.3.0",
|
"@roarr/browser-log-writer": "^1.3.0",
|
||||||
"chakra-react-select": "^4.7.6",
|
"@storybook/manager-api": "^7.6.4",
|
||||||
|
"@storybook/theming": "^7.6.4",
|
||||||
"compare-versions": "^6.1.0",
|
"compare-versions": "^6.1.0",
|
||||||
"dateformat": "^5.0.3",
|
"dateformat": "^5.0.3",
|
||||||
"framer-motion": "^10.16.16",
|
"framer-motion": "^10.16.15",
|
||||||
"i18next": "^23.7.13",
|
"i18next": "^23.7.8",
|
||||||
"i18next-http-backend": "^2.4.2",
|
"i18next-http-backend": "^2.4.2",
|
||||||
"idb-keyval": "^6.2.1",
|
"idb-keyval": "^6.2.1",
|
||||||
"konva": "^9.3.0",
|
"konva": "^9.2.3",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nanostores": "^0.9.5",
|
"nanostores": "^0.9.5",
|
||||||
"new-github-issue-url": "^1.0.0",
|
"new-github-issue-url": "^1.0.0",
|
||||||
"overlayscrollbars": "^2.4.6",
|
"overlayscrollbars": "^2.4.5",
|
||||||
"overlayscrollbars-react": "^0.5.3",
|
"overlayscrollbars-react": "^0.5.3",
|
||||||
|
"patch-package": "^8.0.0",
|
||||||
"query-string": "^8.1.0",
|
"query-string": "^8.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-colorful": "^5.6.1",
|
"react-colorful": "^5.6.1",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
"react-error-boundary": "^4.0.12",
|
"react-error-boundary": "^4.0.11",
|
||||||
"react-hook-form": "^7.49.2",
|
|
||||||
"react-hotkeys-hook": "4.4.1",
|
"react-hotkeys-hook": "4.4.1",
|
||||||
"react-i18next": "^14.0.0",
|
"react-i18next": "^13.5.0",
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-konva": "^18.2.10",
|
"react-konva": "^18.2.10",
|
||||||
"react-redux": "^9.0.4",
|
"react-redux": "^9.0.2",
|
||||||
"react-resizable-panels": "^1.0.7",
|
"react-resizable-panels": "^0.0.55",
|
||||||
"react-select": "5.8.0",
|
|
||||||
"react-textarea-autosize": "^8.5.3",
|
|
||||||
"react-use": "^17.4.2",
|
"react-use": "^17.4.2",
|
||||||
"react-virtuoso": "^4.6.2",
|
"react-virtuoso": "^4.6.2",
|
||||||
"reactflow": "^11.10.1",
|
"reactflow": "^11.10.1",
|
||||||
"redux-dynamic-middlewares": "^2.2.0",
|
"redux-dynamic-middlewares": "^2.2.0",
|
||||||
"redux-remember": "^5.0.1",
|
"redux-remember": "^5.0.0",
|
||||||
"roarr": "^7.21.0",
|
"roarr": "^7.21.0",
|
||||||
"serialize-error": "^11.0.3",
|
"serialize-error": "^11.0.3",
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.2",
|
||||||
"type-fest": "^4.9.0",
|
"type-fest": "^4.8.3",
|
||||||
"use-debounce": "^10.0.0",
|
"use-debounce": "^10.0.0",
|
||||||
"use-image": "^1.1.1",
|
"use-image": "^1.1.1",
|
||||||
"uuid": "^9.0.1",
|
"uuid": "^9.0.1",
|
||||||
@ -121,51 +117,44 @@
|
|||||||
"ts-toolbelt": "^9.6.0"
|
"ts-toolbelt": "^9.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arthurgeron/eslint-plugin-react-usememo": "^2.2.2",
|
|
||||||
"@chakra-ui/cli": "^2.4.1",
|
"@chakra-ui/cli": "^2.4.1",
|
||||||
"@storybook/addon-docs": "^7.6.6",
|
"@storybook/addon-essentials": "^7.6.4",
|
||||||
"@storybook/addon-essentials": "^7.6.6",
|
"@storybook/addon-interactions": "^7.6.4",
|
||||||
"@storybook/addon-interactions": "^7.6.6",
|
"@storybook/addon-links": "^7.6.4",
|
||||||
"@storybook/addon-links": "^7.6.6",
|
"@storybook/blocks": "^7.6.4",
|
||||||
"@storybook/addon-storysource": "^7.6.6",
|
"@storybook/react": "^7.6.4",
|
||||||
"@storybook/blocks": "^7.6.6",
|
"@storybook/react-vite": "^7.6.4",
|
||||||
"@storybook/manager-api": "^7.6.6",
|
"@storybook/test": "^7.6.4",
|
||||||
"@storybook/react": "^7.6.6",
|
|
||||||
"@storybook/react-vite": "^7.6.6",
|
|
||||||
"@storybook/test": "^7.6.6",
|
|
||||||
"@storybook/theming": "^7.6.6",
|
|
||||||
"@types/dateformat": "^5.0.2",
|
"@types/dateformat": "^5.0.2",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.10.6",
|
"@types/node": "^20.9.0",
|
||||||
"@types/react": "^18.2.46",
|
"@types/react": "^18.2.37",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.17",
|
||||||
"@types/uuid": "^9.0.7",
|
"@types/uuid": "^9.0.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.16.0",
|
"@typescript-eslint/eslint-plugin": "^6.13.2",
|
||||||
"@typescript-eslint/parser": "^6.16.0",
|
"@typescript-eslint/parser": "^6.13.2",
|
||||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^8.2.2",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.55.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-i18next": "^6.0.3",
|
"eslint-plugin-i18next": "^6.0.3",
|
||||||
"eslint-plugin-import": "^2.29.1",
|
"eslint-plugin-path": "^1.2.2",
|
||||||
"eslint-plugin-path": "^1.2.3",
|
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
|
||||||
"eslint-plugin-storybook": "^0.6.15",
|
"eslint-plugin-storybook": "^0.6.15",
|
||||||
"eslint-plugin-unused-imports": "^3.0.0",
|
"eslint-plugin-unused-imports": "^3.0.0",
|
||||||
"madge": "^6.1.0",
|
"madge": "^6.1.0",
|
||||||
"openapi-types": "^12.1.3",
|
"openapi-types": "^12.1.3",
|
||||||
"openapi-typescript": "^6.7.3",
|
"openapi-typescript": "^6.7.2",
|
||||||
"prettier": "^3.1.1",
|
"prettier": "^3.1.0",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.10.0",
|
||||||
"storybook": "^7.6.6",
|
"storybook": "^7.6.4",
|
||||||
"ts-toolbelt": "^9.6.0",
|
"ts-toolbelt": "^9.6.0",
|
||||||
"typescript": "^5.3.3",
|
"typescript": "^5.3.3",
|
||||||
"vite": "^5.0.10",
|
"vite": "^4.5.1",
|
||||||
"vite-plugin-css-injected-by-js": "^3.3.1",
|
"vite-plugin-css-injected-by-js": "^3.3.0",
|
||||||
"vite-plugin-dts": "^3.7.0",
|
"vite-plugin-dts": "^3.6.4",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^4.2.3"
|
"vite-tsconfig-paths": "^4.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4633
invokeai/frontend/web/pnpm-lock.yaml
generated
4633
invokeai/frontend/web/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -760,6 +760,7 @@
|
|||||||
"w": "W",
|
"w": "W",
|
||||||
"addControlNet": "$t(common.controlNet) hinzufügen",
|
"addControlNet": "$t(common.controlNet) hinzufügen",
|
||||||
"none": "Kein",
|
"none": "Kein",
|
||||||
|
"incompatibleBaseModel": "Inkompatibles Basismodell:",
|
||||||
"enableControlnet": "Aktiviere ControlNet",
|
"enableControlnet": "Aktiviere ControlNet",
|
||||||
"detectResolution": "Auflösung erkennen",
|
"detectResolution": "Auflösung erkennen",
|
||||||
"controlNetT2IMutexDesc": "$t(common.controlNet) und $t(common.t2iAdapter) zur gleichen Zeit wird nicht unterstützt.",
|
"controlNetT2IMutexDesc": "$t(common.controlNet) und $t(common.t2iAdapter) zur gleichen Zeit wird nicht unterstützt.",
|
||||||
|
@ -50,33 +50,9 @@
|
|||||||
"uncategorized": "Uncategorized",
|
"uncategorized": "Uncategorized",
|
||||||
"downloadBoard": "Download Board"
|
"downloadBoard": "Download Board"
|
||||||
},
|
},
|
||||||
"accordions": {
|
|
||||||
"generation": {
|
|
||||||
"title": "Generation",
|
|
||||||
"modelTab": "Model",
|
|
||||||
"conceptsTab": "Concepts"
|
|
||||||
},
|
|
||||||
"image": {
|
|
||||||
"title": "Image"
|
|
||||||
},
|
|
||||||
"advanced": {
|
|
||||||
"title": "Advanced"
|
|
||||||
},
|
|
||||||
"control": {
|
|
||||||
"title": "Control",
|
|
||||||
"controlAdaptersTab": "Control Adapters",
|
|
||||||
"ipTab": "Image Prompts"
|
|
||||||
},
|
|
||||||
"compositing": {
|
|
||||||
"title": "Compositing",
|
|
||||||
"coherenceTab": "Coherence Pass",
|
|
||||||
"infillTab": "Infill"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"common": {
|
"common": {
|
||||||
"accept": "Accept",
|
"accept": "Accept",
|
||||||
"advanced": "Advanced",
|
"advanced": "Advanced",
|
||||||
"advancedOptions": "Advanced Options",
|
|
||||||
"ai": "ai",
|
"ai": "ai",
|
||||||
"areYouSure": "Are you sure?",
|
"areYouSure": "Are you sure?",
|
||||||
"auto": "Auto",
|
"auto": "Auto",
|
||||||
@ -103,7 +79,6 @@
|
|||||||
"file": "File",
|
"file": "File",
|
||||||
"folder": "Folder",
|
"folder": "Folder",
|
||||||
"format": "format",
|
"format": "format",
|
||||||
"free": "Free",
|
|
||||||
"generate": "Generate",
|
"generate": "Generate",
|
||||||
"githubLabel": "Github",
|
"githubLabel": "Github",
|
||||||
"hotkeysLabel": "Hotkeys",
|
"hotkeysLabel": "Hotkeys",
|
||||||
@ -246,6 +221,7 @@
|
|||||||
"colorMapTileSize": "Tile Size",
|
"colorMapTileSize": "Tile Size",
|
||||||
"importImageFromCanvas": "Import Image From Canvas",
|
"importImageFromCanvas": "Import Image From Canvas",
|
||||||
"importMaskFromCanvas": "Import Mask From Canvas",
|
"importMaskFromCanvas": "Import Mask From Canvas",
|
||||||
|
"incompatibleBaseModel": "Incompatible base model:",
|
||||||
"lineart": "Lineart",
|
"lineart": "Lineart",
|
||||||
"lineartAnime": "Lineart Anime",
|
"lineartAnime": "Lineart Anime",
|
||||||
"lineartAnimeDescription": "Anime-style lineart processing",
|
"lineartAnimeDescription": "Anime-style lineart processing",
|
||||||
@ -270,7 +246,6 @@
|
|||||||
"prompt": "Prompt",
|
"prompt": "Prompt",
|
||||||
"resetControlImage": "Reset Control Image",
|
"resetControlImage": "Reset Control Image",
|
||||||
"resize": "Resize",
|
"resize": "Resize",
|
||||||
"resizeSimple": "Resize (Simple)",
|
|
||||||
"resizeMode": "Resize Mode",
|
"resizeMode": "Resize Mode",
|
||||||
"safe": "Safe",
|
"safe": "Safe",
|
||||||
"saveControlImage": "Save Control Image",
|
"saveControlImage": "Save Control Image",
|
||||||
@ -309,7 +284,7 @@
|
|||||||
"queue": "Queue",
|
"queue": "Queue",
|
||||||
"queueFront": "Add to Front of Queue",
|
"queueFront": "Add to Front of Queue",
|
||||||
"queueBack": "Add to Queue",
|
"queueBack": "Add to Queue",
|
||||||
"queueCountPrediction": "{{promptsCount}} prompts × {{iterations}} iterations -> {{count}} generations",
|
"queueCountPrediction": "Add {{predicted}} to Queue",
|
||||||
"queueMaxExceeded": "Max of {{max_queue_size}} exceeded, would skip {{skip}}",
|
"queueMaxExceeded": "Max of {{max_queue_size}} exceeded, would skip {{skip}}",
|
||||||
"queuedCount": "{{pending}} Pending",
|
"queuedCount": "{{pending}} Pending",
|
||||||
"queueTotal": "{{total}} Total",
|
"queueTotal": "{{total}} Total",
|
||||||
@ -365,8 +340,7 @@
|
|||||||
"back": "back",
|
"back": "back",
|
||||||
"batchFailedToQueue": "Failed to Queue Batch",
|
"batchFailedToQueue": "Failed to Queue Batch",
|
||||||
"graphQueued": "Graph queued",
|
"graphQueued": "Graph queued",
|
||||||
"graphFailedToQueue": "Failed to queue graph",
|
"graphFailedToQueue": "Failed to queue graph"
|
||||||
"openQueue": "Open Queue"
|
|
||||||
},
|
},
|
||||||
"invocationCache": {
|
"invocationCache": {
|
||||||
"invocationCache": "Invocation Cache",
|
"invocationCache": "Invocation Cache",
|
||||||
@ -436,13 +410,9 @@
|
|||||||
},
|
},
|
||||||
"appHotkeys": "App Hotkeys",
|
"appHotkeys": "App Hotkeys",
|
||||||
"cancel": {
|
"cancel": {
|
||||||
"desc": "Cancel current queue item",
|
"desc": "Cancel image generation",
|
||||||
"title": "Cancel"
|
"title": "Cancel"
|
||||||
},
|
},
|
||||||
"cancelAndClear": {
|
|
||||||
"desc": "Cancel current queue item and clear all pending items",
|
|
||||||
"title": "Cancel and Clear"
|
|
||||||
},
|
|
||||||
"changeTabs": {
|
"changeTabs": {
|
||||||
"desc": "Switch to another workspace",
|
"desc": "Switch to another workspace",
|
||||||
"title": "Change Tabs"
|
"title": "Change Tabs"
|
||||||
@ -818,23 +788,17 @@
|
|||||||
},
|
},
|
||||||
"models": {
|
"models": {
|
||||||
"addLora": "Add LoRA",
|
"addLora": "Add LoRA",
|
||||||
"allLoRAsAdded": "All LoRAs added",
|
|
||||||
"loraAlreadyAdded": "LoRA already added",
|
|
||||||
"esrganModel": "ESRGAN Model",
|
"esrganModel": "ESRGAN Model",
|
||||||
"loading": "loading",
|
"loading": "loading",
|
||||||
"incompatibleBaseModel": "Incompatible base model",
|
|
||||||
"noMainModelSelected": "No main model selected",
|
|
||||||
"noLoRAsAvailable": "No LoRAs available",
|
"noLoRAsAvailable": "No LoRAs available",
|
||||||
"noLoRAsLoaded": "No LoRAs Loaded",
|
"noLoRAsLoaded": "No LoRAs Loaded",
|
||||||
"noMatchingLoRAs": "No matching LoRAs",
|
"noMatchingLoRAs": "No matching LoRAs",
|
||||||
"noMatchingModels": "No matching Models",
|
"noMatchingModels": "No matching Models",
|
||||||
"noModelsAvailable": "No models available",
|
"noModelsAvailable": "No models available",
|
||||||
"lora": "LoRA",
|
|
||||||
"selectLoRA": "Select a LoRA",
|
"selectLoRA": "Select a LoRA",
|
||||||
"selectModel": "Select a Model",
|
"selectModel": "Select a Model",
|
||||||
"noLoRAsInstalled": "No LoRAs installed",
|
"noLoRAsInstalled": "No LoRAs installed",
|
||||||
"noRefinerModelsInstalled": "No SDXL Refiner models installed",
|
"noRefinerModelsInstalled": "No SDXL Refiner models installed"
|
||||||
"defaultVAE": "Default VAE"
|
|
||||||
},
|
},
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"addNode": "Add Node",
|
"addNode": "Add Node",
|
||||||
@ -1073,7 +1037,6 @@
|
|||||||
"prototypeDesc": "This invocation is a prototype. It may have breaking changes during app updates and may be removed at any time."
|
"prototypeDesc": "This invocation is a prototype. It may have breaking changes during app updates and may be removed at any time."
|
||||||
},
|
},
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"aspect": "Aspect",
|
|
||||||
"aspectRatio": "Aspect Ratio",
|
"aspectRatio": "Aspect Ratio",
|
||||||
"aspectRatioFree": "Free",
|
"aspectRatioFree": "Free",
|
||||||
"boundingBoxHeader": "Bounding Box",
|
"boundingBoxHeader": "Bounding Box",
|
||||||
@ -1114,7 +1077,6 @@
|
|||||||
"imageFit": "Fit Initial Image To Output Size",
|
"imageFit": "Fit Initial Image To Output Size",
|
||||||
"images": "Images",
|
"images": "Images",
|
||||||
"imageToImage": "Image to Image",
|
"imageToImage": "Image to Image",
|
||||||
"imageSize": "Image Size",
|
|
||||||
"img2imgStrength": "Image To Image Strength",
|
"img2imgStrength": "Image To Image Strength",
|
||||||
"infillMethod": "Infill Method",
|
"infillMethod": "Infill Method",
|
||||||
"infillScalingHeader": "Infill and Scaling",
|
"infillScalingHeader": "Infill and Scaling",
|
||||||
@ -1129,7 +1091,7 @@
|
|||||||
"noControlImageForControlAdapter": "Control Adapter #{{number}} has no control image",
|
"noControlImageForControlAdapter": "Control Adapter #{{number}} has no control image",
|
||||||
"noInitialImageSelected": "No initial image selected",
|
"noInitialImageSelected": "No initial image selected",
|
||||||
"noModelForControlAdapter": "Control Adapter #{{number}} has no model selected.",
|
"noModelForControlAdapter": "Control Adapter #{{number}} has no model selected.",
|
||||||
"incompatibleBaseModelForControlAdapter": "Control Adapter #{{number}} model is incompatible with main model.",
|
"incompatibleBaseModelForControlAdapter": "Control Adapter #{{number}} model is invalid with main model.",
|
||||||
"noModelSelected": "No model selected",
|
"noModelSelected": "No model selected",
|
||||||
"noPrompts": "No prompts generated",
|
"noPrompts": "No prompts generated",
|
||||||
"noNodesInGraph": "No nodes in graph",
|
"noNodesInGraph": "No nodes in graph",
|
||||||
@ -1165,8 +1127,8 @@
|
|||||||
"seamCorrectionHeader": "Seam Correction",
|
"seamCorrectionHeader": "Seam Correction",
|
||||||
"seamHighThreshold": "High",
|
"seamHighThreshold": "High",
|
||||||
"seamlessTiling": "Seamless Tiling",
|
"seamlessTiling": "Seamless Tiling",
|
||||||
"seamlessXAxis": "Seamless Tiling X Axis",
|
"seamlessXAxis": "X Axis",
|
||||||
"seamlessYAxis": "Seamless Tiling Y Axis",
|
"seamlessYAxis": "Y Axis",
|
||||||
"seamlessX": "Seamless X",
|
"seamlessX": "Seamless X",
|
||||||
"seamlessY": "Seamless Y",
|
"seamlessY": "Seamless Y",
|
||||||
"seamlessX&Y": "Seamless X & Y",
|
"seamlessX&Y": "Seamless X & Y",
|
||||||
@ -1209,7 +1171,6 @@
|
|||||||
},
|
},
|
||||||
"dynamicPrompts": {
|
"dynamicPrompts": {
|
||||||
"combinatorial": "Combinatorial Generation",
|
"combinatorial": "Combinatorial Generation",
|
||||||
"showDynamicPrompts": "Show Dynamic Prompts",
|
|
||||||
"dynamicPrompts": "Dynamic Prompts",
|
"dynamicPrompts": "Dynamic Prompts",
|
||||||
"enableDynamicPrompts": "Enable Dynamic Prompts",
|
"enableDynamicPrompts": "Enable Dynamic Prompts",
|
||||||
"maxPrompts": "Max Prompts",
|
"maxPrompts": "Max Prompts",
|
||||||
@ -1222,13 +1183,11 @@
|
|||||||
"perIterationDesc": "Use a different seed for each iteration",
|
"perIterationDesc": "Use a different seed for each iteration",
|
||||||
"perPromptLabel": "Seed per Image",
|
"perPromptLabel": "Seed per Image",
|
||||||
"perPromptDesc": "Use a different seed for each image"
|
"perPromptDesc": "Use a different seed for each image"
|
||||||
},
|
}
|
||||||
"loading": "Generating Dynamic Prompts..."
|
|
||||||
},
|
},
|
||||||
"sdxl": {
|
"sdxl": {
|
||||||
"cfgScale": "CFG Scale",
|
"cfgScale": "CFG Scale",
|
||||||
"concatPromptStyle": "Linking Prompt & Style",
|
"concatPromptStyle": "Concatenate Prompt & Style",
|
||||||
"freePromptStyle": "Manual Style Prompting",
|
|
||||||
"denoisingStrength": "Denoising Strength",
|
"denoisingStrength": "Denoising Strength",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"negAestheticScore": "Negative Aesthetic Score",
|
"negAestheticScore": "Negative Aesthetic Score",
|
||||||
|
@ -1178,6 +1178,7 @@
|
|||||||
"w": "W",
|
"w": "W",
|
||||||
"processor": "Processore",
|
"processor": "Processore",
|
||||||
"none": "Nessuno",
|
"none": "Nessuno",
|
||||||
|
"incompatibleBaseModel": "Modello base incompatibile:",
|
||||||
"pidiDescription": "Elaborazione immagini PIDI",
|
"pidiDescription": "Elaborazione immagini PIDI",
|
||||||
"fill": "Riempie",
|
"fill": "Riempie",
|
||||||
"colorMapDescription": "Genera una mappa dei colori dall'immagine",
|
"colorMapDescription": "Genera una mappa dei colori dall'immagine",
|
||||||
|
@ -590,6 +590,7 @@
|
|||||||
"processor": "プロセッサー",
|
"processor": "プロセッサー",
|
||||||
"addControlNet": "$t(common.controlNet)を追加",
|
"addControlNet": "$t(common.controlNet)を追加",
|
||||||
"none": "なし",
|
"none": "なし",
|
||||||
|
"incompatibleBaseModel": "互換性のないベースモデル:",
|
||||||
"enableControlnet": "コントロールネットを有効化",
|
"enableControlnet": "コントロールネットを有効化",
|
||||||
"detectResolution": "検出解像度",
|
"detectResolution": "検出解像度",
|
||||||
"controlNetT2IMutexDesc": "$t(common.controlNet)と$t(common.t2iAdapter)の同時使用は現在サポートされていません。",
|
"controlNetT2IMutexDesc": "$t(common.controlNet)と$t(common.t2iAdapter)の同時使用は現在サポートされていません。",
|
||||||
|
@ -363,6 +363,7 @@
|
|||||||
"processor": "프로세서",
|
"processor": "프로세서",
|
||||||
"addControlNet": "$t(common.controlNet) 추가",
|
"addControlNet": "$t(common.controlNet) 추가",
|
||||||
"none": "해당없음",
|
"none": "해당없음",
|
||||||
|
"incompatibleBaseModel": "호환되지 않는 기본 모델:",
|
||||||
"enableControlnet": "사용 가능한 ControlNet",
|
"enableControlnet": "사용 가능한 ControlNet",
|
||||||
"detectResolution": "해상도 탐지",
|
"detectResolution": "해상도 탐지",
|
||||||
"controlNetT2IMutexDesc": "$t(common.controlNet)와 $t(common.t2iAdapter)는 현재 동시에 지원되지 않습니다.",
|
"controlNetT2IMutexDesc": "$t(common.controlNet)와 $t(common.t2iAdapter)는 현재 동시에 지원되지 않습니다.",
|
||||||
|
@ -1071,6 +1071,7 @@
|
|||||||
"processor": "Verwerker",
|
"processor": "Verwerker",
|
||||||
"addControlNet": "Voeg $t(common.controlNet) toe",
|
"addControlNet": "Voeg $t(common.controlNet) toe",
|
||||||
"none": "Geen",
|
"none": "Geen",
|
||||||
|
"incompatibleBaseModel": "Niet-compatibel basismodel:",
|
||||||
"enableControlnet": "Schakel ControlNet in",
|
"enableControlnet": "Schakel ControlNet in",
|
||||||
"detectResolution": "Herken resolutie",
|
"detectResolution": "Herken resolutie",
|
||||||
"controlNetT2IMutexDesc": "Gelijktijdig gebruik van $t(common.controlNet) en $t(common.t2iAdapter) wordt op dit moment niet ondersteund.",
|
"controlNetT2IMutexDesc": "Gelijktijdig gebruik van $t(common.controlNet) en $t(common.t2iAdapter) wordt op dit moment niet ondersteund.",
|
||||||
|
@ -523,7 +523,7 @@
|
|||||||
"parameters": {
|
"parameters": {
|
||||||
"images": "Изображения",
|
"images": "Изображения",
|
||||||
"steps": "Шаги",
|
"steps": "Шаги",
|
||||||
"cfgScale": "Шкала точности (CFG)",
|
"cfgScale": "Точность следования запросу (CFG)",
|
||||||
"width": "Ширина",
|
"width": "Ширина",
|
||||||
"height": "Высота",
|
"height": "Высота",
|
||||||
"seed": "Сид",
|
"seed": "Сид",
|
||||||
@ -1162,6 +1162,7 @@
|
|||||||
"processor": "Процессор",
|
"processor": "Процессор",
|
||||||
"addControlNet": "Добавить $t(common.controlNet)",
|
"addControlNet": "Добавить $t(common.controlNet)",
|
||||||
"none": "ничего",
|
"none": "ничего",
|
||||||
|
"incompatibleBaseModel": "Несовместимая базовая модель:",
|
||||||
"controlNetT2IMutexDesc": "$t(common.controlNet) и $t(common.t2iAdapter) одновременно в настоящее время не поддерживаются.",
|
"controlNetT2IMutexDesc": "$t(common.controlNet) и $t(common.t2iAdapter) одновременно в настоящее время не поддерживаются.",
|
||||||
"ip_adapter": "$t(controlnet.controlAdapter_one) №{{number}} $t(common.ipAdapter)",
|
"ip_adapter": "$t(controlnet.controlAdapter_one) №{{number}} $t(common.ipAdapter)",
|
||||||
"pidiDescription": "PIDI-обработка изображений",
|
"pidiDescription": "PIDI-обработка изображений",
|
||||||
|
@ -1149,6 +1149,7 @@
|
|||||||
"crop": "裁剪",
|
"crop": "裁剪",
|
||||||
"processor": "处理器",
|
"processor": "处理器",
|
||||||
"none": "无",
|
"none": "无",
|
||||||
|
"incompatibleBaseModel": "不兼容的基础模型:",
|
||||||
"enableControlnet": "启用 ControlNet",
|
"enableControlnet": "启用 ControlNet",
|
||||||
"detectResolution": "检测分辨率",
|
"detectResolution": "检测分辨率",
|
||||||
"pidiDescription": "像素差分 (PIDI) 图像处理",
|
"pidiDescription": "像素差分 (PIDI) 图像处理",
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
|
||||||
import openapiTS from 'openapi-typescript';
|
import openapiTS from 'openapi-typescript';
|
||||||
|
|
||||||
const OPENAPI_URL = 'http://127.0.0.1:9090/openapi.json';
|
const OPENAPI_URL = 'http://127.0.0.1:9090/openapi.json';
|
||||||
const OUTPUT_FILE = 'src/services/api/schema.ts';
|
const OUTPUT_FILE = 'src/services/api/schema.d.ts';
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
process.stdout.write(
|
process.stdout.write(
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
import { Flex, Grid } from '@chakra-ui/react';
|
import { Flex, Grid } from '@chakra-ui/react';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { useSocketIO } from 'app/hooks/useSocketIO';
|
|
||||||
import { useLogger } from 'app/logging/useLogger';
|
import { useLogger } from 'app/logging/useLogger';
|
||||||
import { appStarted } from 'app/store/middleware/listenerMiddleware/listeners/appStarted';
|
import { appStarted } from 'app/store/middleware/listenerMiddleware/listeners/appStarted';
|
||||||
import { $headerComponent } from 'app/store/nanostores/headerComponent';
|
import { $headerComponent } from 'app/store/nanostores/headerComponent';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import type { PartialAppConfig } from 'app/types/invokeai';
|
import { PartialAppConfig } from 'app/types/invokeai';
|
||||||
import ImageUploader from 'common/components/ImageUploader';
|
import ImageUploader from 'common/components/ImageUploader';
|
||||||
import { useClearStorage } from 'common/hooks/useClearStorage';
|
|
||||||
import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys';
|
|
||||||
import { useGlobalModifiersInit } from 'common/hooks/useGlobalModifiers';
|
|
||||||
import ChangeBoardModal from 'features/changeBoardModal/components/ChangeBoardModal';
|
import ChangeBoardModal from 'features/changeBoardModal/components/ChangeBoardModal';
|
||||||
import DeleteImageModal from 'features/deleteImageModal/components/DeleteImageModal';
|
import DeleteImageModal from 'features/deleteImageModal/components/DeleteImageModal';
|
||||||
import { DynamicPromptsModal } from 'features/dynamicPrompts/components/DynamicPromptsPreviewModal';
|
|
||||||
import SiteHeader from 'features/system/components/SiteHeader';
|
import SiteHeader from 'features/system/components/SiteHeader';
|
||||||
import { configChanged } from 'features/system/store/configSlice';
|
import { configChanged } from 'features/system/store/configSlice';
|
||||||
import { languageSelector } from 'features/system/store/systemSelectors';
|
import { languageSelector } from 'features/system/store/systemSelectors';
|
||||||
@ -21,10 +16,12 @@ import i18n from 'i18n';
|
|||||||
import { size } from 'lodash-es';
|
import { size } from 'lodash-es';
|
||||||
import { memo, useCallback, useEffect } from 'react';
|
import { memo, useCallback, useEffect } from 'react';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
|
|
||||||
import AppErrorBoundaryFallback from './AppErrorBoundaryFallback';
|
import AppErrorBoundaryFallback from './AppErrorBoundaryFallback';
|
||||||
|
import GlobalHotkeys from './GlobalHotkeys';
|
||||||
import PreselectedImage from './PreselectedImage';
|
import PreselectedImage from './PreselectedImage';
|
||||||
import Toaster from './Toaster';
|
import Toaster from './Toaster';
|
||||||
|
import { useSocketIO } from 'app/hooks/useSocketIO';
|
||||||
|
import { useClearStorage } from 'common/hooks/useClearStorage';
|
||||||
|
|
||||||
const DEFAULT_CONFIG = {};
|
const DEFAULT_CONFIG = {};
|
||||||
|
|
||||||
@ -44,8 +41,6 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => {
|
|||||||
|
|
||||||
// singleton!
|
// singleton!
|
||||||
useSocketIO();
|
useSocketIO();
|
||||||
useGlobalModifiersInit();
|
|
||||||
useGlobalHotkeys();
|
|
||||||
|
|
||||||
const handleReset = useCallback(() => {
|
const handleReset = useCallback(() => {
|
||||||
clearStorage();
|
clearStorage();
|
||||||
@ -77,9 +72,23 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => {
|
|||||||
>
|
>
|
||||||
<Grid w="100vw" h="100vh" position="relative" overflow="hidden">
|
<Grid w="100vw" h="100vh" position="relative" overflow="hidden">
|
||||||
<ImageUploader>
|
<ImageUploader>
|
||||||
<Grid p={4} gridAutoRows="min-content auto" w="full" h="full">
|
<Grid
|
||||||
|
sx={{
|
||||||
|
gap: 4,
|
||||||
|
p: 4,
|
||||||
|
gridAutoRows: 'min-content auto',
|
||||||
|
w: 'full',
|
||||||
|
h: 'full',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{headerComponent || <SiteHeader />}
|
{headerComponent || <SiteHeader />}
|
||||||
<Flex gap={4} w="full" h="full">
|
<Flex
|
||||||
|
sx={{
|
||||||
|
gap: 4,
|
||||||
|
w: 'full',
|
||||||
|
h: 'full',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<InvokeTabs />
|
<InvokeTabs />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -87,8 +96,8 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => {
|
|||||||
</Grid>
|
</Grid>
|
||||||
<DeleteImageModal />
|
<DeleteImageModal />
|
||||||
<ChangeBoardModal />
|
<ChangeBoardModal />
|
||||||
<DynamicPromptsModal />
|
|
||||||
<Toaster />
|
<Toaster />
|
||||||
|
<GlobalHotkeys />
|
||||||
<PreselectedImage selectedImage={selectedImage} />
|
<PreselectedImage selectedImage={selectedImage} />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Flex, Heading, Link, useToast } from '@chakra-ui/react';
|
import { Flex, Heading, Link, Text, useToast } from '@chakra-ui/react';
|
||||||
import { InvButton } from 'common/components/InvButton/InvButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
|
||||||
import newGithubIssueUrl from 'new-github-issue-url';
|
import newGithubIssueUrl from 'new-github-issue-url';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -38,48 +37,60 @@ const AppErrorBoundaryFallback = ({ error, resetErrorBoundary }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
layerStyle="body"
|
layerStyle="body"
|
||||||
w="100vw"
|
sx={{
|
||||||
h="100vh"
|
w: '100vw',
|
||||||
alignItems="center"
|
h: '100vh',
|
||||||
justifyContent="center"
|
alignItems: 'center',
|
||||||
p={4}
|
justifyContent: 'center',
|
||||||
|
p: 4,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
layerStyle="first"
|
layerStyle="first"
|
||||||
flexDir="column"
|
sx={{
|
||||||
borderRadius="base"
|
flexDir: 'column',
|
||||||
justifyContent="center"
|
borderRadius: 'base',
|
||||||
gap={8}
|
justifyContent: 'center',
|
||||||
p={16}
|
gap: 8,
|
||||||
|
p: 16,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Heading>{t('common.somethingWentWrong')}</Heading>
|
<Heading>{t('common.somethingWentWrong')}</Heading>
|
||||||
<Flex
|
<Flex
|
||||||
layerStyle="second"
|
layerStyle="second"
|
||||||
px={8}
|
sx={{
|
||||||
py={4}
|
px: 8,
|
||||||
gap={4}
|
py: 4,
|
||||||
borderRadius="base"
|
borderRadius: 'base',
|
||||||
justifyContent="space-between"
|
gap: 4,
|
||||||
alignItems="center"
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
sx={{
|
||||||
|
fontWeight: 600,
|
||||||
|
color: 'error.500',
|
||||||
|
_dark: { color: 'error.400' },
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<InvText fontWeight="semibold" color="error.400">
|
|
||||||
{error.name}: {error.message}
|
{error.name}: {error.message}
|
||||||
</InvText>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex gap={4}>
|
<Flex sx={{ gap: 4 }}>
|
||||||
<InvButton
|
<IAIButton
|
||||||
leftIcon={<FaArrowRotateLeft />}
|
leftIcon={<FaArrowRotateLeft />}
|
||||||
onClick={resetErrorBoundary}
|
onClick={resetErrorBoundary}
|
||||||
>
|
>
|
||||||
{t('accessibility.resetUI')}
|
{t('accessibility.resetUI')}
|
||||||
</InvButton>
|
</IAIButton>
|
||||||
<InvButton leftIcon={<FaCopy />} onClick={handleCopy}>
|
<IAIButton leftIcon={<FaCopy />} onClick={handleCopy}>
|
||||||
{t('common.copyError')}
|
{t('common.copyError')}
|
||||||
</InvButton>
|
</IAIButton>
|
||||||
<Link href={url} isExternal>
|
<Link href={url} isExternal>
|
||||||
<InvButton leftIcon={<FaExternalLinkAlt />}>
|
<IAIButton leftIcon={<FaExternalLinkAlt />}>
|
||||||
{t('accessibility.createIssue')}
|
{t('accessibility.createIssue')}
|
||||||
</InvButton>
|
</IAIButton>
|
||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
112
invokeai/frontend/web/src/app/components/GlobalHotkeys.ts
Normal file
112
invokeai/frontend/web/src/app/components/GlobalHotkeys.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
|
import { stateSelector } from 'app/store/store';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { useQueueBack } from 'features/queue/hooks/useQueueBack';
|
||||||
|
import { useQueueFront } from 'features/queue/hooks/useQueueFront';
|
||||||
|
import {
|
||||||
|
ctrlKeyPressed,
|
||||||
|
metaKeyPressed,
|
||||||
|
shiftKeyPressed,
|
||||||
|
} from 'features/ui/store/hotkeysSlice';
|
||||||
|
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||||
|
import React, { memo } from 'react';
|
||||||
|
import { isHotkeyPressed, useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
|
const globalHotkeysSelector = createMemoizedSelector(
|
||||||
|
[stateSelector],
|
||||||
|
({ hotkeys }) => {
|
||||||
|
const { shift, ctrl, meta } = hotkeys;
|
||||||
|
return { shift, ctrl, meta };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Does not catch keypresses while focused in an input. Maybe there is a way?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logical component. Handles app-level global hotkeys.
|
||||||
|
* @returns null
|
||||||
|
*/
|
||||||
|
const GlobalHotkeys: React.FC = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { shift, ctrl, meta } = useAppSelector(globalHotkeysSelector);
|
||||||
|
const {
|
||||||
|
queueBack,
|
||||||
|
isDisabled: isDisabledQueueBack,
|
||||||
|
isLoading: isLoadingQueueBack,
|
||||||
|
} = useQueueBack();
|
||||||
|
|
||||||
|
useHotkeys(
|
||||||
|
['ctrl+enter', 'meta+enter'],
|
||||||
|
queueBack,
|
||||||
|
{
|
||||||
|
enabled: () => !isDisabledQueueBack && !isLoadingQueueBack,
|
||||||
|
preventDefault: true,
|
||||||
|
enableOnFormTags: ['input', 'textarea', 'select'],
|
||||||
|
},
|
||||||
|
[queueBack, isDisabledQueueBack, isLoadingQueueBack]
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
queueFront,
|
||||||
|
isDisabled: isDisabledQueueFront,
|
||||||
|
isLoading: isLoadingQueueFront,
|
||||||
|
} = useQueueFront();
|
||||||
|
|
||||||
|
useHotkeys(
|
||||||
|
['ctrl+shift+enter', 'meta+shift+enter'],
|
||||||
|
queueFront,
|
||||||
|
{
|
||||||
|
enabled: () => !isDisabledQueueFront && !isLoadingQueueFront,
|
||||||
|
preventDefault: true,
|
||||||
|
enableOnFormTags: ['input', 'textarea', 'select'],
|
||||||
|
},
|
||||||
|
[queueFront, isDisabledQueueFront, isLoadingQueueFront]
|
||||||
|
);
|
||||||
|
|
||||||
|
useHotkeys(
|
||||||
|
'*',
|
||||||
|
() => {
|
||||||
|
if (isHotkeyPressed('shift')) {
|
||||||
|
!shift && dispatch(shiftKeyPressed(true));
|
||||||
|
} else {
|
||||||
|
shift && dispatch(shiftKeyPressed(false));
|
||||||
|
}
|
||||||
|
if (isHotkeyPressed('ctrl')) {
|
||||||
|
!ctrl && dispatch(ctrlKeyPressed(true));
|
||||||
|
} else {
|
||||||
|
ctrl && dispatch(ctrlKeyPressed(false));
|
||||||
|
}
|
||||||
|
if (isHotkeyPressed('meta')) {
|
||||||
|
!meta && dispatch(metaKeyPressed(true));
|
||||||
|
} else {
|
||||||
|
meta && dispatch(metaKeyPressed(false));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ keyup: true, keydown: true },
|
||||||
|
[shift, ctrl, meta]
|
||||||
|
);
|
||||||
|
|
||||||
|
useHotkeys('1', () => {
|
||||||
|
dispatch(setActiveTab('txt2img'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('2', () => {
|
||||||
|
dispatch(setActiveTab('img2img'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('3', () => {
|
||||||
|
dispatch(setActiveTab('unifiedCanvas'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('4', () => {
|
||||||
|
dispatch(setActiveTab('nodes'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('5', () => {
|
||||||
|
dispatch(setActiveTab('modelManager'));
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(GlobalHotkeys);
|
@ -1,25 +1,29 @@
|
|||||||
import 'i18n';
|
import { Middleware } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import type { Middleware } from '@reduxjs/toolkit';
|
|
||||||
import { $socketOptions } from 'app/hooks/useSocketIO';
|
import { $socketOptions } from 'app/hooks/useSocketIO';
|
||||||
import { $authToken } from 'app/store/nanostores/authToken';
|
import { $authToken } from 'app/store/nanostores/authToken';
|
||||||
import { $baseUrl } from 'app/store/nanostores/baseUrl';
|
import { $baseUrl } from 'app/store/nanostores/baseUrl';
|
||||||
import type { CustomStarUi } from 'app/store/nanostores/customStarUI';
|
import { $customStarUI, CustomStarUi } from 'app/store/nanostores/customStarUI';
|
||||||
import { $customStarUI } from 'app/store/nanostores/customStarUI';
|
|
||||||
import { $headerComponent } from 'app/store/nanostores/headerComponent';
|
import { $headerComponent } from 'app/store/nanostores/headerComponent';
|
||||||
import { $isDebugging } from 'app/store/nanostores/isDebugging';
|
import { $isDebugging } from 'app/store/nanostores/isDebugging';
|
||||||
import { $projectId } from 'app/store/nanostores/projectId';
|
import { $projectId } from 'app/store/nanostores/projectId';
|
||||||
import { $queueId, DEFAULT_QUEUE_ID } from 'app/store/nanostores/queueId';
|
import { $queueId, DEFAULT_QUEUE_ID } from 'app/store/nanostores/queueId';
|
||||||
import { $store } from 'app/store/nanostores/store';
|
import { $store } from 'app/store/nanostores/store';
|
||||||
import { createStore } from 'app/store/store';
|
import { createStore } from 'app/store/store';
|
||||||
import type { PartialAppConfig } from 'app/types/invokeai';
|
import { PartialAppConfig } from 'app/types/invokeai';
|
||||||
import Loading from 'common/components/Loading/Loading';
|
import Loading from 'common/components/Loading/Loading';
|
||||||
import AppDndContext from 'features/dnd/components/AppDndContext';
|
import AppDndContext from 'features/dnd/components/AppDndContext';
|
||||||
import type { PropsWithChildren, ReactNode } from 'react';
|
import 'i18n';
|
||||||
import React, { lazy, memo, useEffect, useMemo } from 'react';
|
import React, {
|
||||||
|
PropsWithChildren,
|
||||||
|
ReactNode,
|
||||||
|
lazy,
|
||||||
|
memo,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
} from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { addMiddleware, resetMiddlewares } from 'redux-dynamic-middlewares';
|
import { addMiddleware, resetMiddlewares } from 'redux-dynamic-middlewares';
|
||||||
import type { ManagerOptions, SocketOptions } from 'socket.io-client';
|
import { ManagerOptions, SocketOptions } from 'socket.io-client';
|
||||||
|
|
||||||
const App = lazy(() => import('./App'));
|
const App = lazy(() => import('./App'));
|
||||||
const ThemeLocaleProvider = lazy(() => import('./ThemeLocaleProvider'));
|
const ThemeLocaleProvider = lazy(() => import('./ThemeLocaleProvider'));
|
||||||
@ -141,15 +145,6 @@ const InvokeAIUI = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
$store.set(store);
|
$store.set(store);
|
||||||
if (import.meta.env.MODE === 'development') {
|
|
||||||
window.$store = $store;
|
|
||||||
}
|
|
||||||
() => {
|
|
||||||
$store.set(undefined);
|
|
||||||
if (import.meta.env.MODE === 'development') {
|
|
||||||
window.$store = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [store]);
|
}, [store]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
import '@fontsource-variable/inter';
|
import {
|
||||||
import 'overlayscrollbars/overlayscrollbars.css';
|
ChakraProvider,
|
||||||
import 'common/components/OverlayScrollbars/overlayscrollbars.css';
|
createLocalStorageManager,
|
||||||
|
extendTheme,
|
||||||
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import type { ReactNode } from 'react';
|
import { ReactNode, memo, useEffect, useMemo } from 'react';
|
||||||
import { memo, useEffect, useMemo } from 'react';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { theme as invokeAITheme, TOAST_OPTIONS } from 'theme/theme';
|
import { TOAST_OPTIONS, theme as invokeAITheme } from 'theme/theme';
|
||||||
|
|
||||||
|
import '@fontsource-variable/inter';
|
||||||
|
import { MantineProvider } from '@mantine/core';
|
||||||
|
import { useMantineTheme } from 'mantine-theme/theme';
|
||||||
|
import 'overlayscrollbars/overlayscrollbars.css';
|
||||||
|
import 'theme/css/overlayscrollbars.css';
|
||||||
|
|
||||||
type ThemeLocaleProviderProps = {
|
type ThemeLocaleProviderProps = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const manager = createLocalStorageManager('@@invokeai-color-mode');
|
||||||
|
|
||||||
function ThemeLocaleProvider({ children }: ThemeLocaleProviderProps) {
|
function ThemeLocaleProvider({ children }: ThemeLocaleProviderProps) {
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
|
|
||||||
@ -28,10 +35,18 @@ function ThemeLocaleProvider({ children }: ThemeLocaleProviderProps) {
|
|||||||
document.body.dir = direction;
|
document.body.dir = direction;
|
||||||
}, [direction]);
|
}, [direction]);
|
||||||
|
|
||||||
|
const mantineTheme = useMantineTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChakraProvider theme={theme} toastOptions={TOAST_OPTIONS}>
|
<MantineProvider theme={mantineTheme}>
|
||||||
|
<ChakraProvider
|
||||||
|
theme={theme}
|
||||||
|
colorModeManager={manager}
|
||||||
|
toastOptions={TOAST_OPTIONS}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</ChakraProvider>
|
</ChakraProvider>
|
||||||
|
</MantineProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { useToast } from '@chakra-ui/react';
|
import { useToast } from '@chakra-ui/react';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { addToast, clearToastQueue } from 'features/system/store/systemSlice';
|
import { addToast, clearToastQueue } from 'features/system/store/systemSlice';
|
||||||
import type { MakeToastArg } from 'features/system/util/makeToast';
|
import { MakeToastArg, makeToast } from 'features/system/util/makeToast';
|
||||||
import { makeToast } from 'features/system/util/makeToast';
|
|
||||||
import { memo, useCallback, useEffect } from 'react';
|
import { memo, useCallback, useEffect } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
94
invokeai/frontend/web/src/app/features.ts
Normal file
94
invokeai/frontend/web/src/app/features.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
type FeatureHelpInfo = {
|
||||||
|
text: string;
|
||||||
|
href: string;
|
||||||
|
guideImage: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum Feature {
|
||||||
|
PROMPT,
|
||||||
|
GALLERY,
|
||||||
|
OTHER,
|
||||||
|
SEED,
|
||||||
|
VARIATIONS,
|
||||||
|
UPSCALE,
|
||||||
|
FACE_CORRECTION,
|
||||||
|
IMAGE_TO_IMAGE,
|
||||||
|
BOUNDING_BOX,
|
||||||
|
SEAM_CORRECTION,
|
||||||
|
INFILL_AND_SCALING,
|
||||||
|
}
|
||||||
|
/** For each tooltip in the UI, the below feature definitions & props will pull relevant information into the tooltip.
|
||||||
|
*
|
||||||
|
* To-do: href & GuideImages are placeholders, and are not currently utilized, but will be updated (along with the tooltip UI) as feature and UI develop and we get a better idea on where things "forever homes" will be .
|
||||||
|
*/
|
||||||
|
const useFeatures = (): Record<Feature, FeatureHelpInfo> => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return useMemo(
|
||||||
|
() => ({
|
||||||
|
[Feature.PROMPT]: {
|
||||||
|
text: t('tooltip.feature.prompt'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.GALLERY]: {
|
||||||
|
text: t('tooltip.feature.gallery'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.OTHER]: {
|
||||||
|
text: t('tooltip.feature.other'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.SEED]: {
|
||||||
|
text: t('tooltip.feature.seed'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.VARIATIONS]: {
|
||||||
|
text: t('tooltip.feature.variations'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.UPSCALE]: {
|
||||||
|
text: t('tooltip.feature.upscale'),
|
||||||
|
href: 'link/to/docs/feature1.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.FACE_CORRECTION]: {
|
||||||
|
text: t('tooltip.feature.faceCorrection'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.IMAGE_TO_IMAGE]: {
|
||||||
|
text: t('tooltip.feature.imageToImage'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.BOUNDING_BOX]: {
|
||||||
|
text: t('tooltip.feature.boundingBox'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.SEAM_CORRECTION]: {
|
||||||
|
text: t('tooltip.feature.seamCorrection'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
[Feature.INFILL_AND_SCALING]: {
|
||||||
|
text: t('tooltip.feature.infillAndScaling'),
|
||||||
|
href: 'link/to/docs/feature3.html',
|
||||||
|
guideImage: 'asset/path.gif',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[t]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useFeatureHelpInfo = (feature: Feature): FeatureHelpInfo => {
|
||||||
|
const features = useFeatures();
|
||||||
|
return features[feature];
|
||||||
|
};
|
@ -3,16 +3,14 @@ import { $authToken } from 'app/store/nanostores/authToken';
|
|||||||
import { $baseUrl } from 'app/store/nanostores/baseUrl';
|
import { $baseUrl } from 'app/store/nanostores/baseUrl';
|
||||||
import { $isDebugging } from 'app/store/nanostores/isDebugging';
|
import { $isDebugging } from 'app/store/nanostores/isDebugging';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import type { MapStore } from 'nanostores';
|
import { MapStore, atom, map } from 'nanostores';
|
||||||
import { atom, map } from 'nanostores';
|
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import type {
|
import {
|
||||||
ClientToServerEvents,
|
ClientToServerEvents,
|
||||||
ServerToClientEvents,
|
ServerToClientEvents,
|
||||||
} from 'services/events/types';
|
} from 'services/events/types';
|
||||||
import { setEventListeners } from 'services/events/util/setEventListeners';
|
import { setEventListeners } from 'services/events/util/setEventListeners';
|
||||||
import type { ManagerOptions, Socket, SocketOptions } from 'socket.io-client';
|
import { ManagerOptions, Socket, SocketOptions, io } from 'socket.io-client';
|
||||||
import { io } from 'socket.io-client';
|
|
||||||
|
|
||||||
// Inject socket options and url into window for debugging
|
// Inject socket options and url into window for debugging
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { createLogWriter } from '@roarr/browser-log-writer';
|
import { createLogWriter } from '@roarr/browser-log-writer';
|
||||||
import { atom } from 'nanostores';
|
import { atom } from 'nanostores';
|
||||||
import type { Logger } from 'roarr';
|
import { Logger, ROARR, Roarr } from 'roarr';
|
||||||
import { ROARR, Roarr } from 'roarr';
|
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
ROARR.write = createLogWriter();
|
ROARR.write = createLogWriter();
|
||||||
|
|
||||||
@ -28,20 +26,19 @@ export type LoggerNamespace =
|
|||||||
export const logger = (namespace: LoggerNamespace) =>
|
export const logger = (namespace: LoggerNamespace) =>
|
||||||
$logger.get().child({ namespace });
|
$logger.get().child({ namespace });
|
||||||
|
|
||||||
export const zLogLevel = z.enum([
|
export const VALID_LOG_LEVELS = [
|
||||||
'trace',
|
'trace',
|
||||||
'debug',
|
'debug',
|
||||||
'info',
|
'info',
|
||||||
'warn',
|
'warn',
|
||||||
'error',
|
'error',
|
||||||
'fatal',
|
'fatal',
|
||||||
]);
|
] as const;
|
||||||
export type LogLevel = z.infer<typeof zLogLevel>;
|
|
||||||
export const isLogLevel = (v: unknown): v is LogLevel =>
|
export type InvokeLogLevel = (typeof VALID_LOG_LEVELS)[number];
|
||||||
zLogLevel.safeParse(v).success;
|
|
||||||
|
|
||||||
// Translate human-readable log levels to numbers, used for log filtering
|
// Translate human-readable log levels to numbers, used for log filtering
|
||||||
export const LOG_LEVEL_MAP: Record<LogLevel, number> = {
|
export const LOG_LEVEL_MAP: Record<InvokeLogLevel, number> = {
|
||||||
trace: 10,
|
trace: 10,
|
||||||
debug: 20,
|
debug: 20,
|
||||||
info: 30,
|
info: 30,
|
||||||
|
@ -4,9 +4,13 @@ import { stateSelector } from 'app/store/store';
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useEffect, useMemo } from 'react';
|
||||||
import { ROARR, Roarr } from 'roarr';
|
import { ROARR, Roarr } from 'roarr';
|
||||||
|
import {
|
||||||
import type { LoggerNamespace } from './logger';
|
$logger,
|
||||||
import { $logger, BASE_CONTEXT, LOG_LEVEL_MAP, logger } from './logger';
|
BASE_CONTEXT,
|
||||||
|
LOG_LEVEL_MAP,
|
||||||
|
LoggerNamespace,
|
||||||
|
logger,
|
||||||
|
} from './logger';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(stateSelector, ({ system }) => {
|
const selector = createMemoizedSelector(stateSelector, ({ system }) => {
|
||||||
const { consoleLogLevel, shouldLogToConsole } = system;
|
const { consoleLogLevel, shouldLogToConsole } = system;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createAction } from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
import type { InvokeTabName } from 'features/ui/store/tabMap';
|
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||||
import type { BatchConfig } from 'services/api/types';
|
import { BatchConfig } from 'services/api/types';
|
||||||
|
|
||||||
export const enqueueRequested = createAction<{
|
export const enqueueRequested = createAction<{
|
||||||
tabName: InvokeTabName;
|
tabName: InvokeTabName;
|
||||||
|
@ -9,13 +9,4 @@ export const createMemoizedSelector = createSelectorCreator({
|
|||||||
memoizeOptions: {
|
memoizeOptions: {
|
||||||
resultEqualityCheck: isEqual,
|
resultEqualityCheck: isEqual,
|
||||||
},
|
},
|
||||||
argsMemoize: lruMemoize,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A memoized selector creator that uses LRU cache default shallow equality check.
|
|
||||||
*/
|
|
||||||
export const createLruSelector = createSelectorCreator({
|
|
||||||
memoize: lruMemoize,
|
|
||||||
argsMemoize: lruMemoize,
|
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@ import { postprocessingPersistDenylist } from 'features/parameters/store/postpro
|
|||||||
import { systemPersistDenylist } from 'features/system/store/systemPersistDenylist';
|
import { systemPersistDenylist } from 'features/system/store/systemPersistDenylist';
|
||||||
import { uiPersistDenylist } from 'features/ui/store/uiPersistDenylist';
|
import { uiPersistDenylist } from 'features/ui/store/uiPersistDenylist';
|
||||||
import { omit } from 'lodash-es';
|
import { omit } from 'lodash-es';
|
||||||
import type { SerializeFunction } from 'redux-remember';
|
import { SerializeFunction } from 'redux-remember';
|
||||||
|
|
||||||
const serializationDenylist: {
|
const serializationDenylist: {
|
||||||
[key: string]: string[];
|
[key: string]: string[];
|
||||||
|
@ -11,7 +11,7 @@ import { initialSystemState } from 'features/system/store/systemSlice';
|
|||||||
import { initialHotkeysState } from 'features/ui/store/hotkeysSlice';
|
import { initialHotkeysState } from 'features/ui/store/hotkeysSlice';
|
||||||
import { initialUIState } from 'features/ui/store/uiSlice';
|
import { initialUIState } from 'features/ui/store/uiSlice';
|
||||||
import { defaultsDeep } from 'lodash-es';
|
import { defaultsDeep } from 'lodash-es';
|
||||||
import type { UnserializeFunction } from 'redux-remember';
|
import { UnserializeFunction } from 'redux-remember';
|
||||||
|
|
||||||
const initialStates: {
|
const initialStates: {
|
||||||
[key: string]: object; // TODO: type this properly
|
[key: string]: object; // TODO: type this properly
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import type { UnknownAction } from '@reduxjs/toolkit';
|
import { UnknownAction } from '@reduxjs/toolkit';
|
||||||
import { isAnyGraphBuilt } from 'features/nodes/store/actions';
|
import { isAnyGraphBuilt } from 'features/nodes/store/actions';
|
||||||
import { nodeTemplatesBuilt } from 'features/nodes/store/nodeTemplatesSlice';
|
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
|
||||||
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
||||||
import type { Graph } from 'services/api/types';
|
import { Graph } from 'services/api/types';
|
||||||
|
|
||||||
export const actionSanitizer = <A extends UnknownAction>(action: A): A => {
|
export const actionSanitizer = <A extends UnknownAction>(action: A): A => {
|
||||||
if (isAnyGraphBuilt(action)) {
|
if (isAnyGraphBuilt(action)) {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import type {
|
import type { TypedAddListener, TypedStartListening } from '@reduxjs/toolkit';
|
||||||
ListenerEffect,
|
import {
|
||||||
TypedAddListener,
|
|
||||||
TypedStartListening,
|
|
||||||
UnknownAction,
|
UnknownAction,
|
||||||
|
ListenerEffect,
|
||||||
|
addListener,
|
||||||
|
createListenerMiddleware,
|
||||||
} from '@reduxjs/toolkit';
|
} from '@reduxjs/toolkit';
|
||||||
import { addListener, createListenerMiddleware } from '@reduxjs/toolkit';
|
|
||||||
import type { AppDispatch, RootState } from 'app/store/store';
|
import type { AppDispatch, RootState } from 'app/store/store';
|
||||||
|
|
||||||
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
|
import { addCommitStagingAreaImageListener } from './listeners/addCommitStagingAreaImageListener';
|
||||||
import { addFirstListImagesListener } from './listeners/addFirstListImagesListener.ts';
|
import { addFirstListImagesListener } from './listeners/addFirstListImagesListener.ts';
|
||||||
import { addAnyEnqueuedListener } from './listeners/anyEnqueued';
|
import { addAnyEnqueuedListener } from './listeners/anyEnqueued';
|
||||||
@ -43,13 +42,13 @@ import {
|
|||||||
addImageRemovedFromBoardFulfilledListener,
|
addImageRemovedFromBoardFulfilledListener,
|
||||||
addImageRemovedFromBoardRejectedListener,
|
addImageRemovedFromBoardRejectedListener,
|
||||||
} from './listeners/imageRemovedFromBoard';
|
} from './listeners/imageRemovedFromBoard';
|
||||||
import { addImagesStarredListener } from './listeners/imagesStarred';
|
|
||||||
import { addImagesUnstarredListener } from './listeners/imagesUnstarred';
|
|
||||||
import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected';
|
import { addImageToDeleteSelectedListener } from './listeners/imageToDeleteSelected';
|
||||||
import {
|
import {
|
||||||
addImageUploadedFulfilledListener,
|
addImageUploadedFulfilledListener,
|
||||||
addImageUploadedRejectedListener,
|
addImageUploadedRejectedListener,
|
||||||
} from './listeners/imageUploaded';
|
} from './listeners/imageUploaded';
|
||||||
|
import { addImagesStarredListener } from './listeners/imagesStarred';
|
||||||
|
import { addImagesUnstarredListener } from './listeners/imagesUnstarred';
|
||||||
import { addInitialImageSelectedListener } from './listeners/initialImageSelected';
|
import { addInitialImageSelectedListener } from './listeners/initialImageSelected';
|
||||||
import { addModelSelectedListener } from './listeners/modelSelected';
|
import { addModelSelectedListener } from './listeners/modelSelected';
|
||||||
import { addModelsLoadedListener } from './listeners/modelsLoaded';
|
import { addModelsLoadedListener } from './listeners/modelsLoaded';
|
||||||
@ -70,9 +69,9 @@ import { addSocketSubscribedEventListener as addSocketSubscribedListener } from
|
|||||||
import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed';
|
import { addSocketUnsubscribedEventListener as addSocketUnsubscribedListener } from './listeners/socketio/socketUnsubscribed';
|
||||||
import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSaved';
|
import { addStagingAreaImageSavedListener } from './listeners/stagingAreaImageSaved';
|
||||||
import { addTabChangedListener } from './listeners/tabChanged';
|
import { addTabChangedListener } from './listeners/tabChanged';
|
||||||
import { addUpdateAllNodesRequestedListener } from './listeners/updateAllNodesRequested';
|
|
||||||
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
|
import { addUpscaleRequestedListener } from './listeners/upscaleRequested';
|
||||||
import { addWorkflowLoadRequestedListener } from './listeners/workflowLoadRequested';
|
import { addWorkflowLoadRequestedListener } from './listeners/workflowLoadRequested';
|
||||||
|
import { addUpdateAllNodesRequestedListener } from './listeners/updateAllNodesRequested';
|
||||||
|
|
||||||
export const listenerMiddleware = createListenerMiddleware();
|
export const listenerMiddleware = createListenerMiddleware();
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
const matcher = isAnyOf(commitStagingAreaImage, discardStagedImages);
|
const matcher = isAnyOf(commitStagingAreaImage, discardStagedImages);
|
||||||
|
@ -2,10 +2,9 @@ import { createAction } from '@reduxjs/toolkit';
|
|||||||
import { imageSelected } from 'features/gallery/store/gallerySlice';
|
import { imageSelected } from 'features/gallery/store/gallerySlice';
|
||||||
import { IMAGE_CATEGORIES } from 'features/gallery/store/types';
|
import { IMAGE_CATEGORIES } from 'features/gallery/store/types';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import type { ImageCache } from 'services/api/types';
|
|
||||||
import { getListImagesUrl, imagesAdapter } from 'services/api/util';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { getListImagesUrl, imagesAdapter } from 'services/api/util';
|
||||||
|
import { ImageCache } from 'services/api/types';
|
||||||
|
|
||||||
export const appStarted = createAction('app/appStarted');
|
export const appStarted = createAction('app/appStarted');
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addAnyEnqueuedListener = () => {
|
export const addAnyEnqueuedListener = () => {
|
||||||
|
@ -4,7 +4,6 @@ import {
|
|||||||
shouldUseWatermarkerChanged,
|
shouldUseWatermarkerChanged,
|
||||||
} from 'features/system/store/systemSlice';
|
} from 'features/system/store/systemSlice';
|
||||||
import { appInfoApi } from 'services/api/endpoints/appInfo';
|
import { appInfoApi } from 'services/api/endpoints/appInfo';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addAppConfigReceivedListener = () => {
|
export const addAppConfigReceivedListener = () => {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { createAction } from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const appStarted = createAction('app/appStarted');
|
export const appStarted = createAction('app/appStarted');
|
||||||
|
@ -5,8 +5,7 @@ import { zPydanticValidationError } from 'features/system/store/zodSchemas';
|
|||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { truncate, upperFirst } from 'lodash-es';
|
import { truncate, upperFirst } from 'lodash-es';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
import { theme, TOAST_OPTIONS } from 'theme/theme';
|
import { TOAST_OPTIONS, theme } from 'theme/theme';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
const { toast } = createStandaloneToast({
|
const { toast } = createStandaloneToast({
|
||||||
|
@ -4,7 +4,6 @@ import { getImageUsage } from 'features/deleteImageModal/store/selectors';
|
|||||||
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
|
||||||
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addDeleteBoardAndImagesFulfilledListener = () => {
|
export const addDeleteBoardAndImagesFulfilledListener = () => {
|
||||||
|
@ -9,9 +9,8 @@ import {
|
|||||||
IMAGE_CATEGORIES,
|
IMAGE_CATEGORIES,
|
||||||
} from 'features/gallery/store/types';
|
} from 'features/gallery/store/types';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import { imagesSelectors } from 'services/api/util';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { imagesSelectors } from 'services/api/util';
|
||||||
|
|
||||||
export const addBoardIdSelectedListener = () => {
|
export const addBoardIdSelectedListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { $logger } from 'app/logging/logger';
|
|
||||||
import { canvasCopiedToClipboard } from 'features/canvas/store/actions';
|
import { canvasCopiedToClipboard } from 'features/canvas/store/actions';
|
||||||
|
import { startAppListening } from '..';
|
||||||
|
import { $logger } from 'app/logging/logger';
|
||||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard';
|
import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
|
||||||
|
|
||||||
export const addCanvasCopiedToClipboardListener = () => {
|
export const addCanvasCopiedToClipboardListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: canvasCopiedToClipboard,
|
actionCreator: canvasCopiedToClipboard,
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { $logger } from 'app/logging/logger';
|
|
||||||
import { canvasDownloadedAsImage } from 'features/canvas/store/actions';
|
import { canvasDownloadedAsImage } from 'features/canvas/store/actions';
|
||||||
|
import { startAppListening } from '..';
|
||||||
|
import { $logger } from 'app/logging/logger';
|
||||||
import { downloadBlob } from 'features/canvas/util/downloadBlob';
|
import { downloadBlob } from 'features/canvas/util/downloadBlob';
|
||||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
|
||||||
|
|
||||||
export const addCanvasDownloadedAsImageListener = () => {
|
export const addCanvasDownloadedAsImageListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
actionCreator: canvasDownloadedAsImage,
|
actionCreator: canvasDownloadedAsImage,
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { canvasImageToControlAdapter } from 'features/canvas/store/actions';
|
|
||||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||||
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
import { controlAdapterImageChanged } from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { canvasImageToControlAdapter } from 'features/canvas/store/actions';
|
||||||
|
|
||||||
export const addCanvasImageToControlNetListener = () => {
|
export const addCanvasImageToControlNetListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -2,10 +2,9 @@ import { logger } from 'app/logging/logger';
|
|||||||
import { canvasMaskSavedToGallery } from 'features/canvas/store/actions';
|
import { canvasMaskSavedToGallery } from 'features/canvas/store/actions';
|
||||||
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
export const addCanvasMaskSavedToGalleryListener = () => {
|
export const addCanvasMaskSavedToGalleryListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -5,7 +5,6 @@ import { controlAdapterImageChanged } from 'features/controlAdapters/store/contr
|
|||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addCanvasMaskToControlNetListener = () => {
|
export const addCanvasMaskToControlNetListener = () => {
|
||||||
|
@ -4,10 +4,9 @@ import { setMergedCanvas } from 'features/canvas/store/canvasSlice';
|
|||||||
import { getFullBaseLayerBlob } from 'features/canvas/util/getFullBaseLayerBlob';
|
import { getFullBaseLayerBlob } from 'features/canvas/util/getFullBaseLayerBlob';
|
||||||
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
export const addCanvasMergedListener = () => {
|
export const addCanvasMergedListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -2,10 +2,9 @@ import { logger } from 'app/logging/logger';
|
|||||||
import { canvasSavedToGallery } from 'features/canvas/store/actions';
|
import { canvasSavedToGallery } from 'features/canvas/store/actions';
|
||||||
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
export const addCanvasSavedToGalleryListener = () => {
|
export const addCanvasSavedToGalleryListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { AnyListenerPredicate } from '@reduxjs/toolkit';
|
import { AnyListenerPredicate } from '@reduxjs/toolkit';
|
||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import type { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { controlAdapterImageProcessed } from 'features/controlAdapters/store/actions';
|
import { controlAdapterImageProcessed } from 'features/controlAdapters/store/actions';
|
||||||
import {
|
import {
|
||||||
controlAdapterAutoConfigToggled,
|
controlAdapterAutoConfigToggled,
|
||||||
@ -10,9 +10,8 @@ import {
|
|||||||
controlAdapterProcessortTypeChanged,
|
controlAdapterProcessortTypeChanged,
|
||||||
selectControlAdapterById,
|
selectControlAdapterById,
|
||||||
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
|
|
||||||
type AnyControlAdapterParamChangeAction =
|
type AnyControlAdapterParamChangeAction =
|
||||||
| ReturnType<typeof controlAdapterProcessorParamsChanged>
|
| ReturnType<typeof controlAdapterProcessorParamsChanged>
|
||||||
|
@ -8,15 +8,14 @@ import {
|
|||||||
selectControlAdapterById,
|
selectControlAdapterById,
|
||||||
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
import { isControlNetOrT2IAdapter } from 'features/controlAdapters/store/types';
|
||||||
import { isImageOutput } from 'features/nodes/types/common';
|
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
import type { BatchConfig, ImageDTO } from 'services/api/types';
|
import { BatchConfig, ImageDTO } from 'services/api/types';
|
||||||
import { socketInvocationComplete } from 'services/events/actions';
|
import { socketInvocationComplete } from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { isImageOutput } from 'features/nodes/types/common';
|
||||||
|
|
||||||
export const addControlNetImageProcessedListener = () => {
|
export const addControlNetImageProcessedListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -14,8 +14,7 @@ import { buildCanvasGraph } from 'features/nodes/util/graph/buildCanvasGraph';
|
|||||||
import { prepareLinearUIBatch } from 'features/nodes/util/graph/buildLinearBatchConfig';
|
import { prepareLinearUIBatch } from 'features/nodes/util/graph/buildLinearBatchConfig';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
import { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,6 @@ import { buildLinearSDXLImageToImageGraph } from 'features/nodes/util/graph/buil
|
|||||||
import { buildLinearSDXLTextToImageGraph } from 'features/nodes/util/graph/buildLinearSDXLTextToImageGraph';
|
import { buildLinearSDXLTextToImageGraph } from 'features/nodes/util/graph/buildLinearSDXLTextToImageGraph';
|
||||||
import { buildLinearTextToImageGraph } from 'features/nodes/util/graph/buildLinearTextToImageGraph';
|
import { buildLinearTextToImageGraph } from 'features/nodes/util/graph/buildLinearTextToImageGraph';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addEnqueueRequestedLinear = () => {
|
export const addEnqueueRequestedLinear = () => {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { enqueueRequested } from 'app/store/actions';
|
import { enqueueRequested } from 'app/store/actions';
|
||||||
import { buildNodesGraph } from 'features/nodes/util/graph/buildNodesGraph';
|
import { buildNodesGraph } from 'features/nodes/util/graph/buildNodesGraph';
|
||||||
import { buildWorkflowRight } from 'features/nodes/util/workflow/buildWorkflow';
|
import { buildWorkflow } from 'features/nodes/util/workflow/buildWorkflow';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
import type { BatchConfig } from 'services/api/types';
|
import { BatchConfig } from 'services/api/types';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addEnqueueRequestedNodes = () => {
|
export const addEnqueueRequestedNodes = () => {
|
||||||
@ -15,16 +14,14 @@ export const addEnqueueRequestedNodes = () => {
|
|||||||
const { nodes, edges } = state.nodes;
|
const { nodes, edges } = state.nodes;
|
||||||
const workflow = state.workflow;
|
const workflow = state.workflow;
|
||||||
const graph = buildNodesGraph(state.nodes);
|
const graph = buildNodesGraph(state.nodes);
|
||||||
const builtWorkflow = buildWorkflowRight({
|
const builtWorkflow = buildWorkflow({
|
||||||
nodes,
|
nodes,
|
||||||
edges,
|
edges,
|
||||||
workflow,
|
workflow,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (builtWorkflow) {
|
|
||||||
// embedded workflows don't have an id
|
// embedded workflows don't have an id
|
||||||
delete builtWorkflow.id;
|
delete builtWorkflow.id;
|
||||||
}
|
|
||||||
|
|
||||||
const batchConfig: BatchConfig = {
|
const batchConfig: BatchConfig = {
|
||||||
batch: {
|
batch: {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addImageAddedToBoardFulfilledListener = () => {
|
export const addImageAddedToBoardFulfilledListener = () => {
|
||||||
|
@ -18,7 +18,6 @@ import { clamp, forEach } from 'lodash-es';
|
|||||||
import { api } from 'services/api';
|
import { api } from 'services/api';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import { imagesAdapter } from 'services/api/util';
|
import { imagesAdapter } from 'services/api/util';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addRequestedSingleImageDeletionListener = () => {
|
export const addRequestedSingleImageDeletionListener = () => {
|
||||||
|
@ -6,17 +6,16 @@ import {
|
|||||||
controlAdapterImageChanged,
|
controlAdapterImageChanged,
|
||||||
controlAdapterIsEnabledChanged,
|
controlAdapterIsEnabledChanged,
|
||||||
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import type {
|
import {
|
||||||
TypesafeDraggableData,
|
TypesafeDraggableData,
|
||||||
TypesafeDroppableData,
|
TypesafeDroppableData,
|
||||||
} from 'features/dnd/types';
|
} from 'features/dnd/types';
|
||||||
import { imageSelected } from 'features/gallery/store/gallerySlice';
|
import { imageSelected } from 'features/gallery/store/gallerySlice';
|
||||||
import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
|
import { fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
|
||||||
import { workflowExposedFieldAdded } from 'features/nodes/store/workflowSlice';
|
|
||||||
import { initialImageChanged } from 'features/parameters/store/generationSlice';
|
import { initialImageChanged } from 'features/parameters/store/generationSlice';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '../';
|
import { startAppListening } from '../';
|
||||||
|
import { workflowExposedFieldAdded } from 'features/nodes/store/workflowSlice';
|
||||||
|
|
||||||
export const dndDropped = createAction<{
|
export const dndDropped = createAction<{
|
||||||
overData: TypesafeDroppableData;
|
overData: TypesafeDroppableData;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addImageRemovedFromBoardFulfilledListener = () => {
|
export const addImageRemovedFromBoardFulfilledListener = () => {
|
||||||
|
@ -4,7 +4,6 @@ import {
|
|||||||
imagesToDeleteSelected,
|
imagesToDeleteSelected,
|
||||||
isModalOpenChanged,
|
isModalOpenChanged,
|
||||||
} from 'features/deleteImageModal/store/slice';
|
} from 'features/deleteImageModal/store/slice';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addImageToDeleteSelectedListener = () => {
|
export const addImageToDeleteSelectedListener = () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { UseToastOptions } from '@chakra-ui/react';
|
import { UseToastOptions } from '@chakra-ui/react';
|
||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||||
import {
|
import {
|
||||||
@ -11,9 +11,8 @@ import { addToast } from 'features/system/store/systemSlice';
|
|||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { omit } from 'lodash-es';
|
import { omit } from 'lodash-es';
|
||||||
import { boardsApi } from 'services/api/endpoints/boards';
|
import { boardsApi } from 'services/api/endpoints/boards';
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
export const addImageUploadedFulfilledListener = () => {
|
export const addImageUploadedFulfilledListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { selectionChanged } from 'features/gallery/store/gallerySlice';
|
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { selectionChanged } from 'features/gallery/store/gallerySlice';
|
||||||
|
import { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
export const addImagesStarredListener = () => {
|
export const addImagesStarredListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { selectionChanged } from 'features/gallery/store/gallerySlice';
|
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { selectionChanged } from 'features/gallery/store/gallerySlice';
|
||||||
|
import { ImageDTO } from 'services/api/types';
|
||||||
|
|
||||||
export const addImagesUnstarredListener = () => {
|
export const addImagesUnstarredListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -3,7 +3,6 @@ import { initialImageChanged } from 'features/parameters/store/generationSlice';
|
|||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { makeToast } from 'features/system/util/makeToast';
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addInitialImageSelectedListener = () => {
|
export const addInitialImageSelectedListener = () => {
|
||||||
|
@ -7,18 +7,17 @@ import {
|
|||||||
import { loraRemoved } from 'features/lora/store/loraSlice';
|
import { loraRemoved } from 'features/lora/store/loraSlice';
|
||||||
import { modelSelected } from 'features/parameters/store/actions';
|
import { modelSelected } from 'features/parameters/store/actions';
|
||||||
import {
|
import {
|
||||||
heightChanged,
|
|
||||||
modelChanged,
|
modelChanged,
|
||||||
|
setHeight,
|
||||||
|
setWidth,
|
||||||
vaeSelected,
|
vaeSelected,
|
||||||
widthChanged,
|
|
||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import { zParameterModel } from 'features/parameters/types/parameterSchemas';
|
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { makeToast } from 'features/system/util/makeToast';
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { forEach } from 'lodash-es';
|
import { forEach } from 'lodash-es';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { zParameterModel } from 'features/parameters/types/parameterSchemas';
|
||||||
|
|
||||||
export const addModelSelectedListener = () => {
|
export const addModelSelectedListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
@ -90,12 +89,12 @@ export const addModelSelectedListener = () => {
|
|||||||
state.ui.shouldAutoChangeDimensions
|
state.ui.shouldAutoChangeDimensions
|
||||||
) {
|
) {
|
||||||
if (['sdxl', 'sdxl-refiner'].includes(newModel.base_model)) {
|
if (['sdxl', 'sdxl-refiner'].includes(newModel.base_model)) {
|
||||||
dispatch(widthChanged(1024));
|
dispatch(setWidth(1024));
|
||||||
dispatch(heightChanged(1024));
|
dispatch(setHeight(1024));
|
||||||
dispatch(setBoundingBoxDimensions({ width: 1024, height: 1024 }));
|
dispatch(setBoundingBoxDimensions({ width: 1024, height: 1024 }));
|
||||||
} else {
|
} else {
|
||||||
dispatch(widthChanged(512));
|
dispatch(setWidth(512));
|
||||||
dispatch(heightChanged(512));
|
dispatch(setHeight(512));
|
||||||
dispatch(setBoundingBoxDimensions({ width: 512, height: 512 }));
|
dispatch(setBoundingBoxDimensions({ width: 512, height: 512 }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,17 +12,20 @@ import {
|
|||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/parameters/store/generationSlice';
|
||||||
import {
|
import {
|
||||||
zParameterModel,
|
zParameterModel,
|
||||||
|
zParameterSDXLRefinerModel,
|
||||||
zParameterVAEModel,
|
zParameterVAEModel,
|
||||||
} from 'features/parameters/types/parameterSchemas';
|
} from 'features/parameters/types/parameterSchemas';
|
||||||
import { refinerModelChanged } from 'features/sdxl/store/sdxlSlice';
|
import {
|
||||||
|
refinerModelChanged,
|
||||||
|
setShouldUseSDXLRefiner,
|
||||||
|
} from 'features/sdxl/store/sdxlSlice';
|
||||||
import { forEach, some } from 'lodash-es';
|
import { forEach, some } from 'lodash-es';
|
||||||
import {
|
import {
|
||||||
mainModelsAdapter,
|
mainModelsAdapter,
|
||||||
modelsApi,
|
modelsApi,
|
||||||
vaeModelsAdapter,
|
vaeModelsAdapter,
|
||||||
} from 'services/api/endpoints/models';
|
} from 'services/api/endpoints/models';
|
||||||
import type { TypeGuardFor } from 'services/api/types';
|
import { TypeGuardFor } from 'services/api/types';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addModelsLoadedListener = () => {
|
export const addModelsLoadedListener = () => {
|
||||||
@ -99,6 +102,7 @@ export const addModelsLoadedListener = () => {
|
|||||||
if (models.length === 0) {
|
if (models.length === 0) {
|
||||||
// No models loaded at all
|
// No models loaded at all
|
||||||
dispatch(refinerModelChanged(null));
|
dispatch(refinerModelChanged(null));
|
||||||
|
dispatch(setShouldUseSDXLRefiner(false));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,10 +115,21 @@ export const addModelsLoadedListener = () => {
|
|||||||
)
|
)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
if (!isCurrentModelAvailable) {
|
if (isCurrentModelAvailable) {
|
||||||
dispatch(refinerModelChanged(null));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const result = zParameterSDXLRefinerModel.safeParse(models[0]);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
log.error(
|
||||||
|
{ error: result.error.format() },
|
||||||
|
'Failed to parse SDXL Refiner Model'
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(refinerModelChanged(result.data));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -8,11 +8,9 @@ import {
|
|||||||
parsingErrorChanged,
|
parsingErrorChanged,
|
||||||
promptsChanged,
|
promptsChanged,
|
||||||
} from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
} from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||||
import { getShouldProcessPrompt } from 'features/dynamicPrompts/util/getShouldProcessPrompt';
|
|
||||||
import { setPositivePrompt } from 'features/parameters/store/generationSlice';
|
import { setPositivePrompt } from 'features/parameters/store/generationSlice';
|
||||||
import { utilitiesApi } from 'services/api/endpoints/utilities';
|
import { utilitiesApi } from 'services/api/endpoints/utilities';
|
||||||
import { appSocketConnected } from 'services/events/actions';
|
import { appSocketConnected } from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
const matcher = isAnyOf(
|
const matcher = isAnyOf(
|
||||||
@ -30,39 +28,20 @@ export const addDynamicPromptsListener = () => {
|
|||||||
action,
|
action,
|
||||||
{ dispatch, getState, cancelActiveListeners, delay }
|
{ dispatch, getState, cancelActiveListeners, delay }
|
||||||
) => {
|
) => {
|
||||||
|
// debounce request
|
||||||
cancelActiveListeners();
|
cancelActiveListeners();
|
||||||
|
await delay(1000);
|
||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { positivePrompt } = state.generation;
|
|
||||||
const { maxPrompts } = state.dynamicPrompts;
|
|
||||||
|
|
||||||
if (state.config.disabledFeatures.includes('dynamicPrompting')) {
|
if (state.config.disabledFeatures.includes('dynamicPrompting')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cachedPrompts = utilitiesApi.endpoints.dynamicPrompts.select({
|
const { positivePrompt } = state.generation;
|
||||||
prompt: positivePrompt,
|
const { maxPrompts } = state.dynamicPrompts;
|
||||||
max_prompts: maxPrompts,
|
|
||||||
})(getState()).data;
|
|
||||||
|
|
||||||
if (cachedPrompts) {
|
|
||||||
dispatch(promptsChanged(cachedPrompts.prompts));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!getShouldProcessPrompt(state.generation.positivePrompt)) {
|
|
||||||
if (state.dynamicPrompts.isLoading) {
|
|
||||||
dispatch(isLoadingChanged(false));
|
|
||||||
}
|
|
||||||
dispatch(promptsChanged([state.generation.positivePrompt]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!state.dynamicPrompts.isLoading) {
|
|
||||||
dispatch(isLoadingChanged(true));
|
dispatch(isLoadingChanged(true));
|
||||||
}
|
|
||||||
|
|
||||||
// debounce request
|
|
||||||
await delay(1000);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const req = dispatch(
|
const req = dispatch(
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { parseify } from 'common/util/serialize';
|
import { parseify } from 'common/util/serialize';
|
||||||
import { nodeTemplatesBuilt } from 'features/nodes/store/nodeTemplatesSlice';
|
import { nodeTemplatesBuilt } from 'features/nodes/store/nodesSlice';
|
||||||
import { parseSchema } from 'features/nodes/util/schema/parseSchema';
|
import { parseSchema } from 'features/nodes/util/schema/parseSchema';
|
||||||
import { size } from 'lodash-es';
|
import { size } from 'lodash-es';
|
||||||
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addReceivedOpenAPISchemaListener = () => {
|
export const addReceivedOpenAPISchemaListener = () => {
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { isInitializedChanged } from 'features/system/store/systemSlice';
|
|
||||||
import { size } from 'lodash-es';
|
import { size } from 'lodash-es';
|
||||||
import { api } from 'services/api';
|
import { api } from 'services/api';
|
||||||
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
import { receivedOpenAPISchema } from 'services/api/thunks/schema';
|
||||||
import { appSocketConnected, socketConnected } from 'services/events/actions';
|
import { appSocketConnected, socketConnected } from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
import { isInitializedChanged } from 'features/system/store/systemSlice';
|
||||||
|
|
||||||
export const addSocketConnectedEventListener = () => {
|
export const addSocketConnectedEventListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
@ -15,11 +14,11 @@ export const addSocketConnectedEventListener = () => {
|
|||||||
|
|
||||||
log.debug('Connected');
|
log.debug('Connected');
|
||||||
|
|
||||||
const { nodeTemplates, config, system } = getState();
|
const { nodes, config, system } = getState();
|
||||||
|
|
||||||
const { disabledTabs } = config;
|
const { disabledTabs } = config;
|
||||||
|
|
||||||
if (!size(nodeTemplates.templates) && !disabledTabs.includes('nodes')) {
|
if (!size(nodes.nodeTemplates) && !disabledTabs.includes('nodes')) {
|
||||||
dispatch(receivedOpenAPISchema());
|
dispatch(receivedOpenAPISchema());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketDisconnected,
|
appSocketDisconnected,
|
||||||
socketDisconnected,
|
socketDisconnected,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addSocketDisconnectedEventListener = () => {
|
export const addSocketDisconnectedEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketGeneratorProgress,
|
appSocketGeneratorProgress,
|
||||||
socketGeneratorProgress,
|
socketGeneratorProgress,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addGeneratorProgressEventListener = () => {
|
export const addGeneratorProgressEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketGraphExecutionStateComplete,
|
appSocketGraphExecutionStateComplete,
|
||||||
socketGraphExecutionStateComplete,
|
socketGraphExecutionStateComplete,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addGraphExecutionStateCompleteEventListener = () => {
|
export const addGraphExecutionStateCompleteEventListener = () => {
|
||||||
|
@ -7,7 +7,6 @@ import {
|
|||||||
imageSelected,
|
imageSelected,
|
||||||
} from 'features/gallery/store/gallerySlice';
|
} from 'features/gallery/store/gallerySlice';
|
||||||
import { IMAGE_CATEGORIES } from 'features/gallery/store/types';
|
import { IMAGE_CATEGORIES } from 'features/gallery/store/types';
|
||||||
import { isImageOutput } from 'features/nodes/types/common';
|
|
||||||
import {
|
import {
|
||||||
LINEAR_UI_OUTPUT,
|
LINEAR_UI_OUTPUT,
|
||||||
nodeIDDenyList,
|
nodeIDDenyList,
|
||||||
@ -19,8 +18,8 @@ import {
|
|||||||
appSocketInvocationComplete,
|
appSocketInvocationComplete,
|
||||||
socketInvocationComplete,
|
socketInvocationComplete,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
import { isImageOutput } from 'features/nodes/types/common';
|
||||||
|
|
||||||
// These nodes output an image, but do not actually *save* an image, so we don't want to handle the gallery logic on them
|
// These nodes output an image, but do not actually *save* an image, so we don't want to handle the gallery logic on them
|
||||||
const nodeTypeDenylist = ['load_image', 'image'];
|
const nodeTypeDenylist = ['load_image', 'image'];
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketInvocationError,
|
appSocketInvocationError,
|
||||||
socketInvocationError,
|
socketInvocationError,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addInvocationErrorEventListener = () => {
|
export const addInvocationErrorEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketInvocationRetrievalError,
|
appSocketInvocationRetrievalError,
|
||||||
socketInvocationRetrievalError,
|
socketInvocationRetrievalError,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addInvocationRetrievalErrorEventListener = () => {
|
export const addInvocationRetrievalErrorEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketInvocationStarted,
|
appSocketInvocationStarted,
|
||||||
socketInvocationStarted,
|
socketInvocationStarted,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addInvocationStartedEventListener = () => {
|
export const addInvocationStartedEventListener = () => {
|
||||||
|
@ -5,7 +5,6 @@ import {
|
|||||||
socketModelLoadCompleted,
|
socketModelLoadCompleted,
|
||||||
socketModelLoadStarted,
|
socketModelLoadStarted,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addModelLoadEventListener = () => {
|
export const addModelLoadEventListener = () => {
|
||||||
|
@ -4,7 +4,6 @@ import {
|
|||||||
appSocketQueueItemStatusChanged,
|
appSocketQueueItemStatusChanged,
|
||||||
socketQueueItemStatusChanged,
|
socketQueueItemStatusChanged,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addSocketQueueItemStatusChangedEventListener = () => {
|
export const addSocketQueueItemStatusChangedEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketSessionRetrievalError,
|
appSocketSessionRetrievalError,
|
||||||
socketSessionRetrievalError,
|
socketSessionRetrievalError,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addSessionRetrievalErrorEventListener = () => {
|
export const addSessionRetrievalErrorEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketSubscribedSession,
|
appSocketSubscribedSession,
|
||||||
socketSubscribedSession,
|
socketSubscribedSession,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addSocketSubscribedEventListener = () => {
|
export const addSocketSubscribedEventListener = () => {
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
appSocketUnsubscribedSession,
|
appSocketUnsubscribedSession,
|
||||||
socketUnsubscribedSession,
|
socketUnsubscribedSession,
|
||||||
} from 'services/events/actions';
|
} from 'services/events/actions';
|
||||||
|
|
||||||
import { startAppListening } from '../..';
|
import { startAppListening } from '../..';
|
||||||
|
|
||||||
export const addSocketUnsubscribedEventListener = () => {
|
export const addSocketUnsubscribedEventListener = () => {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { stagingAreaImageSaved } from 'features/canvas/store/actions';
|
import { stagingAreaImageSaved } from 'features/canvas/store/actions';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
|
||||||
import { imagesApi } from 'services/api/endpoints/images';
|
import { imagesApi } from 'services/api/endpoints/images';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
export const addStagingAreaImageSavedListener = () => {
|
export const addStagingAreaImageSavedListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
|
@ -2,7 +2,6 @@ import { modelChanged } from 'features/parameters/store/generationSlice';
|
|||||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||||
import { NON_REFINER_BASE_MODELS } from 'services/api/constants';
|
import { NON_REFINER_BASE_MODELS } from 'services/api/constants';
|
||||||
import { mainModelsAdapter, modelsApi } from 'services/api/endpoints/models';
|
import { mainModelsAdapter, modelsApi } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addTabChangedListener = () => {
|
export const addTabChangedListener = () => {
|
||||||
@ -36,12 +35,12 @@ export const addTabChangedListener = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to filter out all the invalid canvas models (currently refiner & any)
|
// need to filter out all the invalid canvas models (currently sdxl & refiner)
|
||||||
const validCanvasModels = mainModelsAdapter
|
const validCanvasModels = mainModelsAdapter
|
||||||
.getSelectors()
|
.getSelectors()
|
||||||
.selectAll(models)
|
.selectAll(models)
|
||||||
.filter((model) =>
|
.filter((model) =>
|
||||||
['sd-1', 'sd-2', 'sdxl'].includes(model.base_model)
|
['sd-1', 'sd-2', 'sxdl'].includes(model.base_model)
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstValidCanvasModel = validCanvasModels[0];
|
const firstValidCanvasModel = validCanvasModels[0];
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { updateAllNodesRequested } from 'features/nodes/store/actions';
|
import { updateAllNodesRequested } from 'features/nodes/store/actions';
|
||||||
import { nodeReplaced } from 'features/nodes/store/nodesSlice';
|
import { nodeReplaced } from 'features/nodes/store/nodesSlice';
|
||||||
import { NodeUpdateError } from 'features/nodes/types/error';
|
|
||||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
|
||||||
import {
|
import {
|
||||||
getNeedsUpdate,
|
getNeedsUpdate,
|
||||||
updateNode,
|
updateNode,
|
||||||
} from 'features/nodes/util/node/nodeUpdate';
|
} from 'features/nodes/util/node/nodeUpdate';
|
||||||
|
import { NodeUpdateError } from 'features/nodes/types/error';
|
||||||
|
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { makeToast } from 'features/system/util/makeToast';
|
import { makeToast } from 'features/system/util/makeToast';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addUpdateAllNodesRequestedListener = () => {
|
export const addUpdateAllNodesRequestedListener = () => {
|
||||||
@ -19,7 +18,7 @@ export const addUpdateAllNodesRequestedListener = () => {
|
|||||||
effect: (action, { dispatch, getState }) => {
|
effect: (action, { dispatch, getState }) => {
|
||||||
const log = logger('nodes');
|
const log = logger('nodes');
|
||||||
const nodes = getState().nodes.nodes;
|
const nodes = getState().nodes.nodes;
|
||||||
const templates = getState().nodeTemplates.templates;
|
const templates = getState().nodes.nodeTemplates;
|
||||||
|
|
||||||
let unableToUpdateCount = 0;
|
let unableToUpdateCount = 0;
|
||||||
|
|
||||||
|
@ -2,13 +2,12 @@ import { createAction } from '@reduxjs/toolkit';
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { parseify } from 'common/util/serialize';
|
import { parseify } from 'common/util/serialize';
|
||||||
import { buildAdHocUpscaleGraph } from 'features/nodes/util/graph/buildAdHocUpscaleGraph';
|
import { buildAdHocUpscaleGraph } from 'features/nodes/util/graph/buildAdHocUpscaleGraph';
|
||||||
import { createIsAllowedToUpscaleSelector } from 'features/parameters/hooks/useIsAllowedToUpscale';
|
|
||||||
import { addToast } from 'features/system/store/systemSlice';
|
import { addToast } from 'features/system/store/systemSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { queueApi } from 'services/api/endpoints/queue';
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
import type { BatchConfig, ImageDTO } from 'services/api/types';
|
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
import { BatchConfig, ImageDTO } from 'services/api/types';
|
||||||
|
import { createIsAllowedToUpscaleSelector } from 'features/parameters/hooks/useIsAllowedToUpscale';
|
||||||
|
|
||||||
export const upscaleRequested = createAction<{ imageDTO: ImageDTO }>(
|
export const upscaleRequested = createAction<{ imageDTO: ImageDTO }>(
|
||||||
`upscale/upscaleRequested`
|
`upscale/upscaleRequested`
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { parseify } from 'common/util/serialize';
|
import { parseify } from 'common/util/serialize';
|
||||||
import {
|
import { workflowLoadRequested } from 'features/nodes/store/actions';
|
||||||
workflowLoaded,
|
import { workflowLoaded } from 'features/nodes/store/actions';
|
||||||
workflowLoadRequested,
|
|
||||||
} from 'features/nodes/store/actions';
|
|
||||||
import { $flow } from 'features/nodes/store/reactFlowInstance';
|
import { $flow } from 'features/nodes/store/reactFlowInstance';
|
||||||
import {
|
import {
|
||||||
WorkflowMigrationError,
|
WorkflowMigrationError,
|
||||||
@ -16,7 +14,6 @@ import { setActiveTab } from 'features/ui/store/uiSlice';
|
|||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { fromZodError } from 'zod-validation-error';
|
import { fromZodError } from 'zod-validation-error';
|
||||||
|
|
||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
|
|
||||||
export const addWorkflowLoadRequestedListener = () => {
|
export const addWorkflowLoadRequestedListener = () => {
|
||||||
@ -25,7 +22,7 @@ export const addWorkflowLoadRequestedListener = () => {
|
|||||||
effect: (action, { dispatch, getState }) => {
|
effect: (action, { dispatch, getState }) => {
|
||||||
const log = logger('nodes');
|
const log = logger('nodes');
|
||||||
const { workflow, asCopy } = action.payload;
|
const { workflow, asCopy } = action.payload;
|
||||||
const nodeTemplates = getState().nodeTemplates.templates;
|
const nodeTemplates = getState().nodes.nodeTemplates;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { workflow: validatedWorkflow, warnings } = validateWorkflow(
|
const { workflow: validatedWorkflow, warnings } = validateWorkflow(
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
# nanostores
|
|
||||||
|
|
||||||
For non-serializable data that needs to be available throughout the app, or when redux is not appropriate, use nanostores.
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user