mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
Merge branch 'main' into fix/ui/control-adapter-translation-string
This commit is contained in:
commit
3ad1226d1e
@ -152,6 +152,7 @@ async def import_model(
|
|||||||
) -> ImportModelResponse:
|
) -> ImportModelResponse:
|
||||||
"""Add a model using its local path, repo_id, or remote URL. Model characteristics will be probed and configured automatically"""
|
"""Add a model using its local path, repo_id, or remote URL. Model characteristics will be probed and configured automatically"""
|
||||||
|
|
||||||
|
location = location.strip("\"' ")
|
||||||
items_to_import = {location}
|
items_to_import = {location}
|
||||||
prediction_types = {x.value: x for x in SchedulerPredictionType}
|
prediction_types = {x.value: x for x in SchedulerPredictionType}
|
||||||
logger = ApiDependencies.invoker.services.logger
|
logger = ApiDependencies.invoker.services.logger
|
||||||
|
@ -46,6 +46,8 @@ class FaceResultData(TypedDict):
|
|||||||
y_center: float
|
y_center: float
|
||||||
mesh_width: int
|
mesh_width: int
|
||||||
mesh_height: int
|
mesh_height: int
|
||||||
|
chunk_x_offset: int
|
||||||
|
chunk_y_offset: int
|
||||||
|
|
||||||
|
|
||||||
class FaceResultDataWithId(FaceResultData):
|
class FaceResultDataWithId(FaceResultData):
|
||||||
@ -78,6 +80,48 @@ FONT_SIZE = 32
|
|||||||
FONT_STROKE_WIDTH = 4
|
FONT_STROKE_WIDTH = 4
|
||||||
|
|
||||||
|
|
||||||
|
def coalesce_faces(face1: FaceResultData, face2: FaceResultData) -> FaceResultData:
|
||||||
|
face1_x_offset = face1["chunk_x_offset"] - min(face1["chunk_x_offset"], face2["chunk_x_offset"])
|
||||||
|
face2_x_offset = face2["chunk_x_offset"] - min(face1["chunk_x_offset"], face2["chunk_x_offset"])
|
||||||
|
face1_y_offset = face1["chunk_y_offset"] - min(face1["chunk_y_offset"], face2["chunk_y_offset"])
|
||||||
|
face2_y_offset = face2["chunk_y_offset"] - min(face1["chunk_y_offset"], face2["chunk_y_offset"])
|
||||||
|
|
||||||
|
new_im_width = (
|
||||||
|
max(face1["image"].width, face2["image"].width)
|
||||||
|
+ max(face1["chunk_x_offset"], face2["chunk_x_offset"])
|
||||||
|
- min(face1["chunk_x_offset"], face2["chunk_x_offset"])
|
||||||
|
)
|
||||||
|
new_im_height = (
|
||||||
|
max(face1["image"].height, face2["image"].height)
|
||||||
|
+ max(face1["chunk_y_offset"], face2["chunk_y_offset"])
|
||||||
|
- min(face1["chunk_y_offset"], face2["chunk_y_offset"])
|
||||||
|
)
|
||||||
|
pil_image = Image.new(mode=face1["image"].mode, size=(new_im_width, new_im_height))
|
||||||
|
pil_image.paste(face1["image"], (face1_x_offset, face1_y_offset))
|
||||||
|
pil_image.paste(face2["image"], (face2_x_offset, face2_y_offset))
|
||||||
|
|
||||||
|
# Mask images are always from the origin
|
||||||
|
new_mask_im_width = max(face1["mask"].width, face2["mask"].width)
|
||||||
|
new_mask_im_height = max(face1["mask"].height, face2["mask"].height)
|
||||||
|
mask_pil = create_white_image(new_mask_im_width, new_mask_im_height)
|
||||||
|
black_image = create_black_image(face1["mask"].width, face1["mask"].height)
|
||||||
|
mask_pil.paste(black_image, (0, 0), ImageOps.invert(face1["mask"]))
|
||||||
|
black_image = create_black_image(face2["mask"].width, face2["mask"].height)
|
||||||
|
mask_pil.paste(black_image, (0, 0), ImageOps.invert(face2["mask"]))
|
||||||
|
|
||||||
|
new_face = FaceResultData(
|
||||||
|
image=pil_image,
|
||||||
|
mask=mask_pil,
|
||||||
|
x_center=max(face1["x_center"], face2["x_center"]),
|
||||||
|
y_center=max(face1["y_center"], face2["y_center"]),
|
||||||
|
mesh_width=max(face1["mesh_width"], face2["mesh_width"]),
|
||||||
|
mesh_height=max(face1["mesh_height"], face2["mesh_height"]),
|
||||||
|
chunk_x_offset=max(face1["chunk_x_offset"], face2["chunk_x_offset"]),
|
||||||
|
chunk_y_offset=max(face2["chunk_y_offset"], face2["chunk_y_offset"]),
|
||||||
|
)
|
||||||
|
return new_face
|
||||||
|
|
||||||
|
|
||||||
def prepare_faces_list(
|
def prepare_faces_list(
|
||||||
face_result_list: list[FaceResultData],
|
face_result_list: list[FaceResultData],
|
||||||
) -> list[FaceResultDataWithId]:
|
) -> list[FaceResultDataWithId]:
|
||||||
@ -91,7 +135,7 @@ def prepare_faces_list(
|
|||||||
should_add = True
|
should_add = True
|
||||||
candidate_x_center = candidate["x_center"]
|
candidate_x_center = candidate["x_center"]
|
||||||
candidate_y_center = candidate["y_center"]
|
candidate_y_center = candidate["y_center"]
|
||||||
for face in deduped_faces:
|
for idx, face in enumerate(deduped_faces):
|
||||||
face_center_x = face["x_center"]
|
face_center_x = face["x_center"]
|
||||||
face_center_y = face["y_center"]
|
face_center_y = face["y_center"]
|
||||||
face_radius_w = face["mesh_width"] / 2
|
face_radius_w = face["mesh_width"] / 2
|
||||||
@ -105,6 +149,7 @@ def prepare_faces_list(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if p < 1: # Inside of the already-added face's radius
|
if p < 1: # Inside of the already-added face's radius
|
||||||
|
deduped_faces[idx] = coalesce_faces(face, candidate)
|
||||||
should_add = False
|
should_add = False
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -138,7 +183,6 @@ def generate_face_box_mask(
|
|||||||
chunk_x_offset: int = 0,
|
chunk_x_offset: int = 0,
|
||||||
chunk_y_offset: int = 0,
|
chunk_y_offset: int = 0,
|
||||||
draw_mesh: bool = True,
|
draw_mesh: bool = True,
|
||||||
check_bounds: bool = True,
|
|
||||||
) -> list[FaceResultData]:
|
) -> list[FaceResultData]:
|
||||||
result = []
|
result = []
|
||||||
mask_pil = None
|
mask_pil = None
|
||||||
@ -211,33 +255,20 @@ def generate_face_box_mask(
|
|||||||
mask_pil = create_white_image(w + chunk_x_offset, h + chunk_y_offset)
|
mask_pil = create_white_image(w + chunk_x_offset, h + chunk_y_offset)
|
||||||
mask_pil.paste(init_mask_pil, (chunk_x_offset, chunk_y_offset))
|
mask_pil.paste(init_mask_pil, (chunk_x_offset, chunk_y_offset))
|
||||||
|
|
||||||
left_side = x_center - mesh_width
|
x_center = float(x_center)
|
||||||
right_side = x_center + mesh_width
|
y_center = float(y_center)
|
||||||
top_side = y_center - mesh_height
|
face = FaceResultData(
|
||||||
bottom_side = y_center + mesh_height
|
image=pil_image,
|
||||||
im_width, im_height = pil_image.size
|
mask=mask_pil or create_white_image(*pil_image.size),
|
||||||
over_w = im_width * 0.1
|
x_center=x_center + chunk_x_offset,
|
||||||
over_h = im_height * 0.1
|
y_center=y_center + chunk_y_offset,
|
||||||
if not check_bounds or (
|
mesh_width=mesh_width,
|
||||||
(left_side >= -over_w)
|
mesh_height=mesh_height,
|
||||||
and (right_side < im_width + over_w)
|
chunk_x_offset=chunk_x_offset,
|
||||||
and (top_side >= -over_h)
|
chunk_y_offset=chunk_y_offset,
|
||||||
and (bottom_side < im_height + over_h)
|
)
|
||||||
):
|
|
||||||
x_center = float(x_center)
|
|
||||||
y_center = float(y_center)
|
|
||||||
face = FaceResultData(
|
|
||||||
image=pil_image,
|
|
||||||
mask=mask_pil or create_white_image(*pil_image.size),
|
|
||||||
x_center=x_center + chunk_x_offset,
|
|
||||||
y_center=y_center + chunk_y_offset,
|
|
||||||
mesh_width=mesh_width,
|
|
||||||
mesh_height=mesh_height,
|
|
||||||
)
|
|
||||||
|
|
||||||
result.append(face)
|
result.append(face)
|
||||||
else:
|
|
||||||
context.services.logger.info("FaceTools --> Face out of bounds, ignoring.")
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -346,7 +377,6 @@ def get_faces_list(
|
|||||||
chunk_x_offset=0,
|
chunk_x_offset=0,
|
||||||
chunk_y_offset=0,
|
chunk_y_offset=0,
|
||||||
draw_mesh=draw_mesh,
|
draw_mesh=draw_mesh,
|
||||||
check_bounds=False,
|
|
||||||
)
|
)
|
||||||
if should_chunk or len(result) == 0:
|
if should_chunk or len(result) == 0:
|
||||||
context.services.logger.info("FaceTools --> Chunking image (chunk toggled on, or no face found in full image).")
|
context.services.logger.info("FaceTools --> Chunking image (chunk toggled on, or no face found in full image).")
|
||||||
@ -360,24 +390,26 @@ def get_faces_list(
|
|||||||
if width > height:
|
if width > height:
|
||||||
# Landscape - slice the image horizontally
|
# Landscape - slice the image horizontally
|
||||||
fx = 0.0
|
fx = 0.0
|
||||||
steps = int(width * 2 / height)
|
steps = int(width * 2 / height) + 1
|
||||||
|
increment = (width - height) / (steps - 1)
|
||||||
while fx <= (width - height):
|
while fx <= (width - height):
|
||||||
x = int(fx)
|
x = int(fx)
|
||||||
image_chunks.append(image.crop((x, 0, x + height - 1, height - 1)))
|
image_chunks.append(image.crop((x, 0, x + height, height)))
|
||||||
x_offsets.append(x)
|
x_offsets.append(x)
|
||||||
y_offsets.append(0)
|
y_offsets.append(0)
|
||||||
fx += (width - height) / steps
|
fx += increment
|
||||||
context.services.logger.info(f"FaceTools --> Chunk starting at x = {x}")
|
context.services.logger.info(f"FaceTools --> Chunk starting at x = {x}")
|
||||||
elif height > width:
|
elif height > width:
|
||||||
# Portrait - slice the image vertically
|
# Portrait - slice the image vertically
|
||||||
fy = 0.0
|
fy = 0.0
|
||||||
steps = int(height * 2 / width)
|
steps = int(height * 2 / width) + 1
|
||||||
|
increment = (height - width) / (steps - 1)
|
||||||
while fy <= (height - width):
|
while fy <= (height - width):
|
||||||
y = int(fy)
|
y = int(fy)
|
||||||
image_chunks.append(image.crop((0, y, width - 1, y + width - 1)))
|
image_chunks.append(image.crop((0, y, width, y + width)))
|
||||||
x_offsets.append(0)
|
x_offsets.append(0)
|
||||||
y_offsets.append(y)
|
y_offsets.append(y)
|
||||||
fy += (height - width) / steps
|
fy += increment
|
||||||
context.services.logger.info(f"FaceTools --> Chunk starting at y = {y}")
|
context.services.logger.info(f"FaceTools --> Chunk starting at y = {y}")
|
||||||
|
|
||||||
for idx in range(len(image_chunks)):
|
for idx in range(len(image_chunks)):
|
||||||
@ -404,7 +436,7 @@ def get_faces_list(
|
|||||||
return all_faces
|
return all_faces
|
||||||
|
|
||||||
|
|
||||||
@invocation("face_off", title="FaceOff", tags=["image", "faceoff", "face", "mask"], category="image", version="1.0.1")
|
@invocation("face_off", title="FaceOff", tags=["image", "faceoff", "face", "mask"], category="image", version="1.0.2")
|
||||||
class FaceOffInvocation(BaseInvocation):
|
class FaceOffInvocation(BaseInvocation):
|
||||||
"""Bound, extract, and mask a face from an image using MediaPipe detection"""
|
"""Bound, extract, and mask a face from an image using MediaPipe detection"""
|
||||||
|
|
||||||
@ -498,7 +530,7 @@ class FaceOffInvocation(BaseInvocation):
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
@invocation("face_mask_detection", title="FaceMask", tags=["image", "face", "mask"], category="image", version="1.0.1")
|
@invocation("face_mask_detection", title="FaceMask", tags=["image", "face", "mask"], category="image", version="1.0.2")
|
||||||
class FaceMaskInvocation(BaseInvocation):
|
class FaceMaskInvocation(BaseInvocation):
|
||||||
"""Face mask creation using mediapipe face detection"""
|
"""Face mask creation using mediapipe face detection"""
|
||||||
|
|
||||||
@ -616,7 +648,7 @@ class FaceMaskInvocation(BaseInvocation):
|
|||||||
|
|
||||||
|
|
||||||
@invocation(
|
@invocation(
|
||||||
"face_identifier", title="FaceIdentifier", tags=["image", "face", "identifier"], category="image", version="1.0.1"
|
"face_identifier", title="FaceIdentifier", tags=["image", "face", "identifier"], category="image", version="1.0.2"
|
||||||
)
|
)
|
||||||
class FaceIdentifierInvocation(BaseInvocation):
|
class FaceIdentifierInvocation(BaseInvocation):
|
||||||
"""Outputs an image with detected face IDs printed on each face. For use with other FaceTools."""
|
"""Outputs an image with detected face IDs printed on each face. For use with other FaceTools."""
|
||||||
|
@ -236,9 +236,16 @@ class ModelInstall(object):
|
|||||||
if not models_installed:
|
if not models_installed:
|
||||||
models_installed = dict()
|
models_installed = dict()
|
||||||
|
|
||||||
|
model_path_id_or_url = str(model_path_id_or_url).strip("\"' ")
|
||||||
|
|
||||||
# A little hack to allow nested routines to retrieve info on the requested ID
|
# A little hack to allow nested routines to retrieve info on the requested ID
|
||||||
self.current_id = model_path_id_or_url
|
self.current_id = model_path_id_or_url
|
||||||
path = Path(model_path_id_or_url)
|
path = Path(model_path_id_or_url)
|
||||||
|
|
||||||
|
# fix relative paths
|
||||||
|
if path.exists() and not path.is_absolute():
|
||||||
|
path = path.absolute() # make relative to current WD
|
||||||
|
|
||||||
# checkpoint file, or similar
|
# checkpoint file, or similar
|
||||||
if path.is_file():
|
if path.is_file():
|
||||||
models_installed.update({str(path): self._install_path(path)})
|
models_installed.update({str(path): self._install_path(path)})
|
||||||
|
@ -986,6 +986,8 @@ class ModelManager(object):
|
|||||||
|
|
||||||
for model_path in models_dir.iterdir():
|
for model_path in models_dir.iterdir():
|
||||||
if model_path not in loaded_files: # TODO: check
|
if model_path not in loaded_files: # TODO: check
|
||||||
|
if model_path.name.startswith("."):
|
||||||
|
continue
|
||||||
model_name = model_path.name if model_path.is_dir() else model_path.stem
|
model_name = model_path.name if model_path.is_dir() else model_path.stem
|
||||||
model_key = self.create_key(model_name, cur_base_model, cur_model_type)
|
model_key = self.create_key(model_name, cur_base_model, cur_model_type)
|
||||||
|
|
||||||
|
@ -54,42 +54,42 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/anatomy": "^2.2.0",
|
"@chakra-ui/anatomy": "^2.2.1",
|
||||||
"@chakra-ui/icons": "^2.1.0",
|
"@chakra-ui/icons": "^2.1.1",
|
||||||
"@chakra-ui/react": "^2.8.0",
|
"@chakra-ui/react": "^2.8.1",
|
||||||
"@chakra-ui/styled-system": "^2.9.1",
|
"@chakra-ui/styled-system": "^2.9.1",
|
||||||
"@chakra-ui/theme-tools": "^2.1.0",
|
"@chakra-ui/theme-tools": "^2.1.1",
|
||||||
"@dagrejs/graphlib": "^2.1.13",
|
"@dagrejs/graphlib": "^2.1.13",
|
||||||
"@dnd-kit/core": "^6.0.8",
|
"@dnd-kit/core": "^6.0.8",
|
||||||
"@dnd-kit/modifiers": "^6.0.1",
|
"@dnd-kit/modifiers": "^6.0.1",
|
||||||
"@dnd-kit/utilities": "^3.2.1",
|
"@dnd-kit/utilities": "^3.2.1",
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@floating-ui/react-dom": "^2.0.1",
|
"@floating-ui/react-dom": "^2.0.2",
|
||||||
"@fontsource-variable/inter": "^5.0.8",
|
"@fontsource-variable/inter": "^5.0.13",
|
||||||
"@fontsource/inter": "^5.0.8",
|
"@fontsource/inter": "^5.0.13",
|
||||||
"@mantine/core": "^6.0.19",
|
"@mantine/core": "^6.0.19",
|
||||||
"@mantine/form": "^6.0.19",
|
"@mantine/form": "^6.0.19",
|
||||||
"@mantine/hooks": "^6.0.19",
|
"@mantine/hooks": "^6.0.19",
|
||||||
"@nanostores/react": "^0.7.1",
|
"@nanostores/react": "^0.7.1",
|
||||||
"@reduxjs/toolkit": "^1.9.5",
|
"@reduxjs/toolkit": "^1.9.7",
|
||||||
"@roarr/browser-log-writer": "^1.1.5",
|
"@roarr/browser-log-writer": "^1.3.0",
|
||||||
"@stevebel/png": "^1.5.1",
|
"@stevebel/png": "^1.5.1",
|
||||||
"compare-versions": "^6.1.0",
|
"compare-versions": "^6.1.0",
|
||||||
"dateformat": "^5.0.3",
|
"dateformat": "^5.0.3",
|
||||||
"formik": "^2.4.3",
|
"formik": "^2.4.5",
|
||||||
"framer-motion": "^10.16.1",
|
"framer-motion": "^10.16.4",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"i18next": "^23.4.4",
|
"i18next": "^23.5.1",
|
||||||
"i18next-browser-languagedetector": "^7.0.2",
|
"i18next-browser-languagedetector": "^7.0.2",
|
||||||
"i18next-http-backend": "^2.2.1",
|
"i18next-http-backend": "^2.2.2",
|
||||||
"konva": "^9.2.0",
|
"konva": "^9.2.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nanostores": "^0.9.2",
|
"nanostores": "^0.9.2",
|
||||||
"new-github-issue-url": "^1.0.0",
|
"new-github-issue-url": "^1.0.0",
|
||||||
"openapi-fetch": "^0.7.4",
|
"openapi-fetch": "^0.7.10",
|
||||||
"overlayscrollbars": "^2.2.0",
|
"overlayscrollbars": "^2.3.2",
|
||||||
"overlayscrollbars-react": "^0.5.0",
|
"overlayscrollbars-react": "^0.5.2",
|
||||||
"patch-package": "^8.0.0",
|
"patch-package": "^8.0.0",
|
||||||
"query-string": "^8.1.0",
|
"query-string": "^8.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
@ -98,25 +98,25 @@
|
|||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
"react-error-boundary": "^4.0.11",
|
"react-error-boundary": "^4.0.11",
|
||||||
"react-hotkeys-hook": "4.4.1",
|
"react-hotkeys-hook": "4.4.1",
|
||||||
"react-i18next": "^13.1.2",
|
"react-i18next": "^13.3.0",
|
||||||
"react-icons": "^4.10.1",
|
"react-icons": "^4.11.0",
|
||||||
"react-konva": "^18.2.10",
|
"react-konva": "^18.2.10",
|
||||||
"react-redux": "^8.1.2",
|
"react-redux": "^8.1.3",
|
||||||
"react-resizable-panels": "^0.0.55",
|
"react-resizable-panels": "^0.0.55",
|
||||||
"react-use": "^17.4.0",
|
"react-use": "^17.4.0",
|
||||||
"react-virtuoso": "^4.5.0",
|
"react-virtuoso": "^4.6.1",
|
||||||
"react-zoom-pan-pinch": "^3.0.8",
|
"react-zoom-pan-pinch": "^3.2.0",
|
||||||
"reactflow": "^11.8.3",
|
"reactflow": "^11.9.3",
|
||||||
"redux-dynamic-middlewares": "^2.2.0",
|
"redux-dynamic-middlewares": "^2.2.0",
|
||||||
"redux-remember": "^4.0.1",
|
"redux-remember": "^4.0.4",
|
||||||
"roarr": "^7.15.1",
|
"roarr": "^7.15.1",
|
||||||
"serialize-error": "^11.0.1",
|
"serialize-error": "^11.0.2",
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.2",
|
||||||
"type-fest": "^4.2.0",
|
"type-fest": "^4.4.0",
|
||||||
"use-debounce": "^9.0.4",
|
"use-debounce": "^9.0.4",
|
||||||
"use-image": "^1.1.1",
|
"use-image": "^1.1.1",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.1",
|
||||||
"zod": "^3.22.2",
|
"zod": "^3.22.4",
|
||||||
"zod-validation-error": "^1.5.0"
|
"zod-validation-error": "^1.5.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@ -129,40 +129,40 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chakra-ui/cli": "^2.4.1",
|
"@chakra-ui/cli": "^2.4.1",
|
||||||
"@types/dateformat": "^5.0.0",
|
"@types/dateformat": "^5.0.0",
|
||||||
"@types/lodash-es": "^4.14.194",
|
"@types/lodash-es": "^4.17.9",
|
||||||
"@types/node": "^20.5.1",
|
"@types/node": "^20.8.6",
|
||||||
"@types/react": "^18.2.20",
|
"@types/react": "^18.2.28",
|
||||||
"@types/react-dom": "^18.2.6",
|
"@types/react-dom": "^18.2.13",
|
||||||
"@types/react-redux": "^7.1.25",
|
"@types/react-redux": "^7.1.27",
|
||||||
"@types/react-transition-group": "^4.4.6",
|
"@types/react-transition-group": "^4.4.7",
|
||||||
"@types/uuid": "^9.0.2",
|
"@types/uuid": "^9.0.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
"@typescript-eslint/eslint-plugin": "^6.7.5",
|
||||||
"@typescript-eslint/parser": "^6.4.1",
|
"@typescript-eslint/parser": "^6.7.5",
|
||||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
"@vitejs/plugin-react-swc": "^3.4.0",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.5.1",
|
||||||
"babel-plugin-transform-imports": "^2.0.0",
|
"babel-plugin-transform-imports": "^2.0.0",
|
||||||
"concurrently": "^8.2.0",
|
"concurrently": "^8.2.1",
|
||||||
"eslint": "^8.47.0",
|
"eslint": "^8.51.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^5.0.0",
|
"eslint-plugin-prettier": "^5.0.1",
|
||||||
"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",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^14.0.1",
|
"lint-staged": "^15.0.1",
|
||||||
"madge": "^6.1.0",
|
"madge": "^6.1.0",
|
||||||
"openapi-types": "^12.1.3",
|
"openapi-types": "^12.1.3",
|
||||||
"openapi-typescript": "^6.5.2",
|
"openapi-typescript": "^6.7.0",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"postinstall-postinstall": "^2.1.0",
|
||||||
"prettier": "^3.0.2",
|
"prettier": "^3.0.3",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"ts-toolbelt": "^9.6.0",
|
"ts-toolbelt": "^9.6.0",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^4.4.9",
|
"vite": "^4.4.11",
|
||||||
"vite-plugin-css-injected-by-js": "^3.3.0",
|
"vite-plugin-css-injected-by-js": "^3.3.0",
|
||||||
"vite-plugin-dts": "^3.5.2",
|
"vite-plugin-dts": "^3.6.0",
|
||||||
"vite-plugin-eslint": "^1.8.1",
|
"vite-plugin-eslint": "^1.8.1",
|
||||||
"vite-tsconfig-paths": "^4.2.0",
|
"vite-tsconfig-paths": "^4.2.1",
|
||||||
"yarn": "^1.22.19"
|
"yarn": "^1.22.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ export const addCanvasMergedListener = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const baseLayerRect = canvasBaseLayer.getClientRect({
|
const baseLayerRect = canvasBaseLayer.getClientRect({
|
||||||
relativeTo: canvasBaseLayer.getParent(),
|
relativeTo: canvasBaseLayer.getParent() ?? undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const imageDTO = await dispatch(
|
const imageDTO = await dispatch(
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
isCanvasMaskLine,
|
isCanvasMaskLine,
|
||||||
} from './canvasTypes';
|
} from './canvasTypes';
|
||||||
import { appSocketQueueItemStatusChanged } from 'services/events/actions';
|
import { appSocketQueueItemStatusChanged } from 'services/events/actions';
|
||||||
|
import { queueApi } from 'services/api/endpoints/queue';
|
||||||
|
|
||||||
export const initialLayerState: CanvasLayerState = {
|
export const initialLayerState: CanvasLayerState = {
|
||||||
objects: [],
|
objects: [],
|
||||||
@ -812,6 +813,20 @@ export const canvasSlice = createSlice({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
builder.addMatcher(
|
||||||
|
queueApi.endpoints.clearQueue.matchFulfilled,
|
||||||
|
(state) => {
|
||||||
|
state.batchIds = [];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
builder.addMatcher(
|
||||||
|
queueApi.endpoints.cancelByBatchIds.matchFulfilled,
|
||||||
|
(state, action) => {
|
||||||
|
state.batchIds = state.batchIds.filter(
|
||||||
|
(id) => !action.meta.arg.originalArgs.batch_ids.includes(id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user